Kubernetes — оркестрация контейнеров
Kubernetes (k8s) — система оркестрации контейнеров. Она автоматически разворачивает, масштабирует и восстанавливает приложения, упакованные в Docker-образы. Это стандарт индустрии для production-нагрузок.
1. Зачем нужен Kubernetes
- Масштабирование — реплики приложений под нагрузкой;
- Самовосстановление — упавший контейнер перезапускается;
- Деплой без даунтайма — rolling update;
- Self-healing сети — балансировка между подами;
- конфигурация хранится в YAML, версионируется в Git (GitOps).
2. Архитектура
┌───────────────────────────┐
│ Control Plane (master) │
│ kube-apiserver │
│ etcd — хранилище │
│ scheduler, controller │
└───────────────────────────┘
│
┌───────▼────────┐ ┌────────▼────────┐
│ Node 1 │ │ Node 2 │
│ kubelet │ │ kubelet │
│ kube-proxy │ │ kube-proxy │
│ поды │ │ поды │
└────────────────┘ └─────────────────┘- Control Plane — управляющий слой: API, хранение, планирование;
- Node (worker) — машина, где крутятся контейнеры;
- etcd — база состояния кластера;
- kubelet — агент на ноде, следит за подами.
3. Установка локально: minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube start --driver=docker
minikube statuskind (Kubernetes in Docker), а для настоящего пром-кластера управляемые решения: EKS (AWS), GKE (Google), AKS (Azure).4. kubectl — главные команды
kubectl get nodes
kubectl get pods -o wide
kubectl get deploy,svc,ingress
kubectl describe pod my-pod
kubectl logs -f deploy/myapp
kubectl exec -it my-pod -- bash
kubectl apply -f manifest.yaml
kubectl delete -f manifest.yaml5. Поды
Под (pod) — минимальная единица развёртывания: один или несколько контейнеров, разделяющих сеть и volumes.
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 806. Deployment
Deployment описывает желаемое состояние: образ, число реплик, стратегию обновления.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: app
image: myapp:v1.2
ports:
- containerPort: 8080kubectl apply -f deploy.yaml
kubectl scale deploy app --replicas=5
kubectl set image deploy app app=myapp:v1.3 # rolling update
kubectl rollout status deploy app
kubectl rollout undo deploy app7. Service
Service — стабильная точка доступа к набору подов и их балансировка.
apiVersion: v1
kind: Service
metadata:
name: app-svc
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
type: ClusterIP # ClusterIP | NodePort | LoadBalancerkubectl port-forward svc/app-svc 8080:80 # проброс для локальной отладки8. Ingress
Ingress открывает сервисы наружу по доменам и маршрутам.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-svc
port:
number: 80Для работы нужен ingress-controller (nginx-ingress, traefik, istio).
9. ConfigMap и Secrets
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: info
DB_HOST: db.example.comapiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData: # данные в base64 (в проде — из vault/external secrets)
API_KEY: "sk-123"Подключение в манифест:
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets10. Volumes
Файловая система контейнера временная. Для данных нужны volumes:
volumes:
- name: data
persistentVolumeClaim:
claimName: app-pvc
containers:
- name: app
volumeMounts:
- name: data
mountPath: /var/lib/dataPersistentVolumeClaim (PVC) запрашивает хранилище; за него отвечает StorageClass (SSD/HDD/cloud-диски).
11. Probes — проверка здоровья
containers:
- name: app
livenessProbe: # жив ли контейнер?
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
readinessProbe: # готов ли принимать трафик?
httpGet:
path: /readyz
port: 8080
periodSeconds: 1012. Helm
Helm упаковывает Kubernetes-манифесты в «чарты» с параметрами:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install redis bitnami/redis
helm upgrade redis bitnami/redis --set auth.password=secret
helm list
helm uninstall redishelm create myapp — в папке появится структура со значениями по умолчанию values.yaml.13. Namespaces и лимиты ресурсов
Namespaces изолируют среды (dev, staging, prod) и упрощают контроль доступа. Внутри каждого работает своя сеть политик:
kubectl create namespace dev
kubectl -n dev get podsБез лимитов один под может съесть память всего узла. Ограничения задаются в спецификации пода на уровне контейнера:
resources:
requests:
cpu: "250m"
memory: 128Mi
limits:
cpu: "500m"
memory: 256Mi- requests — гарантированный минимум при планировании.
- limits — жёсткий потолок: при превышении контейнер перезапускается.
- ResourceQuota — суммарный лимит на namespace целиком.
14. StatefulSets: базы и состояние
Deployment подходит для stateless-сервисов. Базам нужны стабильные идентификаторы и собственные диски — для этого есть StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: db
spec:
serviceName: "db"
replicas: 3
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10GiПоды получают фиксированные имена db-0, db-1 и стартуют строго по порядку — как и положено репликам БД.
clusterIP: None), дающий каждой реплике собственное DNS-имя.15. RBAC и сетевые политики
RBAC ограничивает действия пользователей и сервис-аккаунтов ролями, привязанными к namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]NetworkPolicy управляет трафиком между подами: например, принять входящие только от фронтенда:
spec:
podSelector:
matchLabels: { app: backend }
ingress:
- from:
- podSelector: { matchLabels: { app: frontend } }16. Автоскейлинг и обновления
Horizontal Pod Autoscaler меняет число реплик по метрике CPU или памяти, поддерживая целевое значение:
kubectl autoscale deployment web \
--cpu-percent=70 --min=2 --max=10Rolling update проходит без простоя: смена образа пересоздаёт поды по очереди.
kubectl set image deployment/web web=myapp:2.0
kubectl rollout status deployment/web17. Jobs и CronJobs: разовые задачи
Не всё в кластере — постоянно работающие сервисы. Пакетная обработка, миграции, бэкапы запускаются один раз или по расписанию. Для этого есть Job (одна задача) и CronJob (по расписанию):
kubectl create job sync --image=myapp:1.2 -- sync-db
kubectl create cronjob nightly --image=myapp:1.2 \
--schedule="0 3 * * *" -- backup-all- Job запускает под до успешного завершения; при сбое — рестарт по
backoffLimit. - CronJob работает через CRON-выражение и позволяет
concurrencyPolicy: разрешить параллель, запретить или заменить предыдущий. - Результат проверяют по
kubectl get jobsи логам последнего пода.
ttlSecondsAfterFinished: завершенные задачи очистятся сами, а не будут висеть мусором в истории кластера.18. Service Mesh: Istio в деле
Когда микросервисов много, трафик между ними нужно контролировать: канареечный запуск, ретраи, таймауты, метрики. Service Mesh делает это прозрачно без правки кода:
kubectl apply -n istio-system -f https://istio.io/...
istioctl install --set profile=demo
kubectl label namespace default istio-injection=enabled- Istio подставляет sidecar-прокси (Envoy) в каждый под — перехватывает входящий и исходящий трафик.
- Через
VirtualServiceизолируют канарейки: 10% трафика на новую версию, затем увеличивают долю. - Позволяет задать правило fault injection: искусственные ошибки и задержки для проверки устойчивости.
19. GitOps: ArgoCD и Flux
GitOps переворачивает деплой: желаемое состояние живёт в git, а инструмент сам синхронизирует кластер. Откат — это git revert, а не «панические команды»:
kubectl create ns argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/.../install.yamlargocd app create demo --repo https://github.com/team/manifests \
--path k8s/prod --dest-server https://kubernetes.default.svc- ArgoCD показывает diff между git и кластером, позволяет применять по кнопке и автосинк.
- Flux умеет многое сам через
Kustomizationи люпоть к HR — управление Helm-релизами как кодом. - Права на деплой отдаются пайплайну через
ServiceAccount, а не людям напрямую.
20. Резервное копирование: Velero
Кластер — это манифесты, конфиги и, главное, данные. Velero делает снапшоты объектов и volumes в хранилище (S3, GCS, MinIO):
velero install --provider aws --bucket velero-backups \
--backup-location-config region=eu-west-1 --plugins velero/velero-plugin-for-aws:v1.0velero backup create daily --include-namespaces appvelero backup getпоказывает состояние,velero restore create— возврат из бэкапа.- Бэкап подсистемных объектов (ConfigMap, Secret) и данных уровня приложения можно делать отдельно.
- Для дрейфа кластера полезны и Terraform-манифесты, но снапшот быстрее восстанавливает полноценный кластер.
velero restore в песочницу и проверяй, что данные реально вернулись.21. Канареечные и blue-green деплои
Обычный kubectl rollout переключается сразу. Продвинутые стратегии релиза дают Argo Rollouts и Flagger: они катят новую версию постепенно и автоматически откатываются при ухудшении метрик.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: app
spec:
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 5m}
- setWeight: 100- Канарейка: 20 % трафика, анализ метрик, затем 100 %.
- Blue-green: две полные версии и переключение сервиса одной командой.
- Откат в Argo Rollouts — это переключение веса обратно, а не долгий роллбэк.
22. Pod Disruption Budget и обслуживание узлов
Выкатка и обслуживание узлов неизбежно останавливают поды. Pod Disruption Budget защищает минимальную доступность сервиса во время плановых операций.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api- Drain узла
kubectl drain node-1 --ignore-daemonsetsпереселяет поды на другие ноды. - PDB блокирует drain, если он нарушит минимальную доступность — обслуживание зависнет, но сервис не упадёт.
- Планируйте обслуживание по одному узлу за раз.
23. Pod Security Standards и политики
RBAC ограничивает, кто что может, но не защищает контейнер от опасных привилегий. Pod Security Standards и политики закрывают run-as-root и привилегированные режимы.
kubectl label ns default \
pod-security.kubernetes.io/enforce=restricted- Три уровня: privileged, baseline, restricted — от «как удобно» до «максимально безопасно».
- Kyverno/OPA Gatekeeper добавляют правила как код: запрет latest-тегов, обязательные limits, read-only файловые системы.
- seccomp и AppArmor ограничивают системные вызовы внутри пода.
24. Оптимизация затрат
Счёт за Kubernetes складывается незаметно: избыточные requests, простаивающие ноды, ненужные реплики. Управление стоимостью — часть эксплуатации.
- Rightsizing requests по реальному потреблению: VPA подбирает их автоматически, а не «на глаз».
- Karpenter агрессивнее масштабирует ноды: неиспользуемые узлы закрываются за минуты.
- Spot-инстансы дешевле в разы для batch-нагрузок и очередей.
| Приём | Выгода |
|---|---|
| Понизить requests | меньше нод, плотнее упаковка |
| HPA по метрикам | нет лишних реплик по ночам |
| Удаление забытых volumes | меньше платных дисков |
Что дальше
Мониторь кластер через Prometheus и Grafana, конфигурируй через Terraform, а CI/CD строй на GitLab. Все курсы — на главной странице.