תשתית Kubernetes בענן Yandex: מתכנון ועד CI/CD
לעתים קרובות אנו רואים צוותים שמבזבזים שבועות על הגדרה ידנית של Kubernetes בענן Yandex ונתקלים בבעיות: טופולוגיית רשת שגויה, דליפות משאבים, חוסר ביכולת ניטור. Yandex Managed Kubernetes מסיר חלק מהכאבים, אך ללא ארכיטקטורה נכונה, האשכול עלול להפוך למקור לתקלות. הניסיון שלנו (5+ שנים, 50+ אשכולות) מראה: המפתח לפעולה יציבה הוא הקפדה על שיטות עבודה מומלצות מההתחלה. אם אתם זקוקים לאשכול ברמת production, צרו קשר לבדיקת תשתית.
היתרונות של Yandex Managed Kubernetes
Yandex Managed Kubernetes הוא ה-Managed Kubernetes הבוגר ביותר בקרב ספקי הענן הרוסיים. אינטגרציה עמוקה עם מערכת YC: Container Registry, Managed Databases, Object Storage, Application Load Balancer — הכל מנוהל באופן טבעי דרך משאבי Kubernetes. עבור פרויקטים בענן Yandex, זה מסיר עומס תפעולי משמעותי בהשוואה לאשכול בהתקנה עצמית. אתם מקבלים עדכונים אוטומטיים של control plane, אינטגרציה עם service accounts, ופתרונות ניטור מוכנים.
כיצד אנו מתכננים את ארכיטקטורת האשכול
השאלה הראשונה היא master אזורי לעומת אזורי-מרובה. אזורי (control plane אחד באזור אחד) זול יותר ב-30%. אזורי-מרובה (שלושה master nodes בשלושה אזורים) הוא HA. ל-production אנו משתמשים רק באזורי-מרובה: אובדן אזור אחד לא מפיל את האשכול.
השאלה השנייה היא גרסת Kubernetes. YC תומך בגרסה הנוכחית ובשתי הקודמות (בדרך כלל 1.27–1.29). ערוץ שחרור: STABLE ל-production, REGULAR אם אתם צריכים גרסאות חדשות יותר, RAPID לניסויים.
השלישית היא טופולוגיית רשת. האשכול צריך לחיות ב-subnet פרטי, ללא IP ציבורי על ה-master. גישה ל-kubectl — רק דרך VPN או bastion. זה מקטין את שטח התקיפה.
Terraform: הגדרת אשכול מלאה
# Сервисные аккаунты
resource "yandex_iam_service_account" "k8s_master" {
name = "k8s-master-sa"
folder_id = var.folder_id
}
resource "yandex_iam_service_account" "k8s_nodes" {
name = "k8s-nodes-sa"
folder_id = var.folder_id
}
# Роли для SA мастера
resource "yandex_resourcemanager_folder_iam_member" "k8s_master_roles" {
for_each = toset(["k8s.clusters.agent", "vpc.publicAdmin", "load-balancer.admin"])
folder_id = var.folder_id
role = each.value
member = "serviceAccount:${yandex_iam_service_account.k8s_master.id}"
}
# Роли для SA нод
resource "yandex_resourcemanager_folder_iam_member" "k8s_nodes_roles" {
for_each = toset(["container-registry.images.puller", "monitoring.editor"])
folder_id = var.folder_id
role = each.value
member = "serviceAccount:${yandex_iam_service_account.k8s_nodes.id}"
}
# Кластер
resource "yandex_kubernetes_cluster" "main" {
name = "production-cluster"
folder_id = var.folder_id
network_id = yandex_vpc_network.main.id
master {
regional {
region = "ru-central1"
dynamic "location" {
for_each = {
a = yandex_vpc_subnet.private_a.id
b = yandex_vpc_subnet.private_b.id
d = yandex_vpc_subnet.private_d.id
}
content {
zone = "ru-central1-${location.key}"
subnet_id = location.value
}
}
}
version = "1.28"
public_ip = false
security_group_ids = [yandex_vpc_security_group.k8s_master.id]
maintenance_policy {
auto_upgrade = true
maintenance_window {
day = "sunday"
start_time = "03:00"
duration = "3h"
}
}
}
service_account_id = yandex_iam_service_account.k8s_master.id
node_service_account_id = yandex_iam_service_account.k8s_nodes.id
release_channel = "STABLE"
network_policy_provider = "CALICO"
}
Node Groups: עובדים וצמתים ייעודיים
ל-production אנו ממליצים להפריד צמתים לפי מטרה באמצעות taints/labels:
# Общие worker ноды
resource "yandex_kubernetes_node_group" "workers" {
cluster_id = yandex_kubernetes_cluster.main.id
name = "workers"
version = "1.28"
instance_template {
platform_id = "standard-v3"
resources {
cores = 4
memory = 8
}
boot_disk {
type = "network-ssd"
size = 64
}
network_interface {
subnet_ids = [
yandex_vpc_subnet.private_a.id,
yandex_vpc_subnet.private_b.id,
yandex_vpc_subnet.private_d.id,
]
nat = false
security_group_ids = [yandex_vpc_security_group.k8s_nodes.id]
}
metadata = {
ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}"
}
}
scale_policy {
auto_scale {
initial = 3
min = 3
max = 10
}
}
allocation_policy {
location {
zone = "ru-central1-a"
}
location {
zone = "ru-central1-b"
}
location {
zone = "ru-central1-d"
}
}
node_taints = []
node_labels = {
"node-type" = "worker"
}
}
# Ноды для stateful workloads (БД-sidecar, кэш)
resource "yandex_kubernetes_node_group" "stateful" {
cluster_id = yandex_kubernetes_cluster.main.id
name = "stateful"
version = "1.28"
instance_template {
platform_id = "standard-v3"
resources {
cores = 8
memory = 32
}
boot_disk {
type = "network-ssd"
size = 100
}
network_interface {
subnet_ids = [yandex_vpc_subnet.private_a.id]
nat = false
security_group_ids = [yandex_vpc_security_group.k8s_nodes.id]
}
}
scale_policy {
fixed_scale {
size = 2
}
}
allocation_policy {
location {
zone = "ru-central1-a"
}
}
node_taints = ["dedicated=stateful:NoSchedule"]
node_labels = {
"node-type" = "stateful"
}
} רכיבים בסיסיים ואינטגרציות
ALB Ingress Controller
Application Load Balancer של YC משתלב עם Kubernetes דרך ALB Ingress Controller. זהו מאזן עומסים L7 טבעי של ענן Yandex, המנוהל דרך משאבי Kubernetes Ingress. התקנה:
helm upgrade --install yc-alb-ingress-controller \
oci://cr.yandex/yc-marketplace/yandex-cloud/yc-alb-ingress-controller/chart \
--version 0.1.x \
--namespace yc-alb-ingress-controller-system \
--create-namespace \
--set-string folder_id=<folder-id> \
--set-string cluster_id=<cluster-id>ALB נוצר אוטומטית בענן Yandex, סיום TLS ברמת מאזן העומסים. חלופה — ingress-nginx עם Network Load Balancer (מחסנית מוכרת יותר, פחות ספציפית ל-YC).
סודות דרך Yandex Lockbox
YC Lockbox הוא שירות מנוהל לניהול סודות. אינטגרציה עם Kubernetes דרך External Secrets Operator:
helm upgrade --install external-secrets external-secrets \
--repo https://charts.external-secrets.io \
--namespace external-secrets \
--create-namespaceדוגמה ל-ExternalSecret לסנכרון סיסמת DB ניתן למצוא בתיעוד של External Secrets Operator.
ניטור אשכול
YC אוסף אוטומטית מדדי מערכת של צמתים והאשכול. לניטור יישומים מלא, אנו מתקינים kube-prometheus-stack:
helm upgrade --install kube-prometheus-stack \
prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.retention=30d \
--set grafana.adminPassword=$(openssl rand -base64 24) \
--set alertmanager.config.global.slack_api_url=<webhook-url>ניתן לייצא מדדים מ-Prometheus ל-Yandex Monitoring דרך # Сервисные аккаунты resource "yandex_iam_service_account" "k8s_master" { name = "k8s-master-sa" folder_id = var.folder_id } resource "yandex_iam_service_account" "k8s_nodes" { name = "k8s-nodes-sa" folder_id = var.folder_id } # Роли для SA мастера resource "yandex_resourcemanager_folder_iam_member" "k8s_master_roles" { for_each = toset(["k8s.clusters.agent", "vpc.publicAdmin", "load-balancer.admin"]) folder_id = var.folder_id role = each.value member = "serviceAccount:${yandex_iam_service_account.k8s_master.id}" } # Роли для SA нод resource "yandex_resourcemanager_folder_iam_member" "k8s_nodes_roles" { for_each = toset(["container-registry.images.puller", "monitoring.editor"]) folder_id = var.folder_id role = each.value member = "serviceAccount:${yandex_iam_service_account.k8s_nodes.id}" } # Кластер resource "yandex_kubernetes_cluster" "main" { name = "production-cluster" folder_id = var.folder_id network_id = yandex_vpc_network.main.id master { regional { region = "ru-central1" dynamic "location" { for_each = { a = yandex_vpc_subnet.private_a.id b = yandex_vpc_subnet.private_b.id d = yandex_vpc_subnet.private_d.id } content { zone = "ru-central1-${location.key}" subnet_id = location.value } } } version = "1.28" public_ip = false security_group_ids = [yandex_vpc_security_group.k8s_master.id] maintenance_policy { auto_upgrade = true maintenance_window { day = "sunday" start_time = "03:00" duration = "3h" } } } service_account_id = yandex_iam_service_account.k8s_master.id node_service_account_id = yandex_iam_service_account.k8s_nodes.id release_channel = "STABLE" network_policy_provider = "CALICO" } — ואז התראות ודשבורדים חיים באותו מקום כמו שאר תשתית YC.
NetworkPolicy עם Calico
הפעל ברמת האשכול (# Общие worker ноды resource "yandex_kubernetes_node_group" "workers" { cluster_id = yandex_kubernetes_cluster.main.id name = "workers" version = "1.28" instance_template { platform_id = "standard-v3" resources { cores = 4 memory = 8 } boot_disk { type = "network-ssd" size = 64 } network_interface { subnet_ids = [ yandex_vpc_subnet.private_a.id, yandex_vpc_subnet.private_b.id, yandex_vpc_subnet.private_d.id, ] nat = false security_group_ids = [yandex_vpc_security_group.k8s_nodes.id] } metadata = { ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}" } } scale_policy { auto_scale { initial = 3 min = 3 max = 10 } } allocation_policy { location { zone = "ru-central1-a" } location { zone = "ru-central1-b" } location { zone = "ru-central1-d" } } node_taints = [] node_labels = { "node-type" = "worker" } } # Ноды для stateful workloads (БД-sidecar, кэш) resource "yandex_kubernetes_node_group" "stateful" { cluster_id = yandex_kubernetes_cluster.main.id name = "stateful" version = "1.28" instance_template { platform_id = "standard-v3" resources { cores = 8 memory = 32 } boot_disk { type = "network-ssd" size = 100 } network_interface { subnet_ids = [yandex_vpc_subnet.private_a.id] nat = false security_group_ids = [yandex_vpc_security_group.k8s_nodes.id] } } scale_policy { fixed_scale { size = 2 } } allocation_policy { location { zone = "ru-central1-a" } } node_taints = ["dedicated=stateful:NoSchedule"] node_labels = { "node-type" = "stateful" } } ). העיקרון הבסיסי: default deny עבור כל ה-namespace, אפשר במפורש רק תקשורת הכרחית. לאחר ה-deny, הוסף allow policies לפי label.
כיצד להגדיר CI/CD?
להעברה רציפה לאשכול, אנו משתמשים בגישת GitOps עם ArgoCD או ב-CI/CD pipelines מוכרים כמו GitLab CI / GitHub Actions. הגדר kubectl דרך service account עם תפקיד cluster-admin, וה-pipeline יכול לפרוס manifests. אנו משלבים הכל בתוך הפרויקט, כולל עדכוני תמונות אוטומטיים דרך Flux או ArgoCD Image Updater.
מה אנו מספקים
- עיצוב ארכיטקטורת אשכול תוך התחשבות בעומס ובמגבלות תקציב.
- הגדרה מלאה דרך Terraform (אשכול, node groups, security groups).
- התקנה והגדרה של רכיבים בסיסיים: ALB Ingress Controller, External Secrets, kube-prometheus-stack.
- יישום Network Policy לבידוד שירותים.
- אינטגרציית CI/CD (GitLab CI / GitHub Actions / ArgoCD) ותיעוד.
- הדרכת צוות: כיצד לנהל את האשכול, לפרוס, לנטר.
- תמיכה אחריות לחודש אחד לאחר ההשקה.
שלבי עבודה
- עיצוב — טופולוגיית רשת, מספר וסוגי node groups, בחירת Ingress, הערכת עלויות.
- Terraform — אשכול, node groups, SA, security groups.
- רכיבים בסיסיים — Ingress Controller, External Secrets, ניטור.
- Network Policy — בידוד namespaces, default deny.
- אינטגרציית CI/CD — הגדרת פריסה לאשכול.
- תיעוד והדרכה — Runbook, ארכיטקטורה, הוראות.
לוחות זמנים ועלות
| משימה | משך |
|---|---|
| אשכול + רכיבים בסיסיים | 3-5 ימים |
| תשתית מלאה עם ניטור ו-CI/CD | 1-2 שבועות |
| העברת עומסים קיימים לאשכול | 2-4 שבועות |
| רכיב | מטרה | כלי |
|---|---|---|
| Ingress | איזון עומסים L7 | ALB / ingress-nginx |
| סודות | ניהול סודות | External Secrets + Lockbox |
| ניטור | מדדים, התראות, לוגים | kube-prometheus-stack, Yandex Monitoring |
העלות מחושבת באופן אישי לאחר בדיקת התשתית שלכם. אנו תמיד מציעים יחס מחיר/איכות הטוב ביותר — חיסכון ממוצע בהשוואה לעשייה עצמית הוא 25–40% הודות לאוטומציה ושיטות עבודה מומלצות. שימוש ב-spot instances מאפשר חיסכון של עד 60% במשאבי מחשוב.
רוצים אשכול יציב ומאובטח? צרו קשר — נעריך את הפרויקט שלכם ונציע לוחות זמנים.







