Kubernetes — оркестрация контейнеров

Продолжительность: 20 уроков · Уровень: средний

Kubernetes (k8s) — система оркестрации контейнеров. Она автоматически разворачивает, масштабирует и восстанавливает приложения, упакованные в Docker-образы. Это стандарт индустрии для production-нагрузок.

1. Зачем нужен Kubernetes

2. Архитектура

┌───────────────────────────┐
│  Control Plane (master)   │
│  kube-apiserver           │
│  etcd — хранилище         │
│  scheduler, controller    │
└───────────────────────────┘
        │
┌───────▼────────┐   ┌────────▼────────┐
│ Node 1         │   │ Node 2          │
│ kubelet        │   │ kubelet         │
│ kube-proxy     │   │ kube-proxy      │
│ поды           │   │ поды            │
└────────────────┘   └─────────────────┘

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 status
Альтернатива для CI-тестов — kind (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.yaml

5. Поды

Под (pod) — минимальная единица развёртывания: один или несколько контейнеров, разделяющих сеть и volumes.

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: web
      image: nginx:1.25
      ports:
        - containerPort: 80
Напрямую поды создают редко. Их создают и контролируют контроллеры: Deployment, StatefulSet, DaemonSet, Job.

6. 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: 8080
kubectl 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 app

7. Service

Service — стабильная точка доступа к набору подов и их балансировка.

apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP    # ClusterIP | NodePort | LoadBalancer
kubectl 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.com
apiVersion: 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-secrets
Secrets хранятся в etcd. В серьёзных системах используют внешние решения: External Secrets Operator или HashiCorp Vault.

10. Volumes

Файловая система контейнера временная. Для данных нужны volumes:

volumes:
  - name: data
    persistentVolumeClaim:
      claimName: app-pvc
containers:
  - name: app
    volumeMounts:
      - name: data
        mountPath: /var/lib/data

PersistentVolumeClaim (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: 10

12. 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 redis
Свой чарт создаётся командой helm 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

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 и стартуют строго по порядку — как и положено репликам БД.

Для правильной работы StatefulSet нужен headless-сервис (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 } }
По умолчанию сеть позволяет всё: без NetworkPolicy бэкенд в Kubernetes открыт всем. Вводи политики до того, как сервисы начнут друг другу доверять.

16. Автоскейлинг и обновления

Horizontal Pod Autoscaler меняет число реплик по метрике CPU или памяти, поддерживая целевое значение:

kubectl autoscale deployment web \
  --cpu-percent=70 --min=2 --max=10

Rolling update проходит без простоя: смена образа пересоздаёт поды по очереди.

kubectl set image deployment/web web=myapp:2.0
kubectl rollout status deployment/web
Правильные readiness-пробы решают судьбу обновлений: под считается готовым только после загрузки, и трафик не попадает на «полуживой» инстанс.

17. 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
Ставь 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
Sidecar снижает предельную пропускную способность и добавляет задержку в миллисекунды. Вводи Mesh под нагрузочные тесты, а не «на глазок»: иногда пользы меньше цены.

19. GitOps: ArgoCD и Flux

GitOps переворачивает деплой: желаемое состояние живёт в git, а инструмент сам синхронизирует кластер. Откат — это git revert, а не «панические команды»:

kubectl create ns argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/.../install.yaml
argocd app create demo --repo https://github.com/team/manifests \
    --path k8s/prod --dest-server https://kubernetes.default.svc
GitOps не отменяет approval: PR с манифестами — та же код-ревью. Деплой становится логируемым и воспроизводимым, но требует дисциплины в репозиториях.

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.0
velero backup create daily --include-namespaces app
Back up без restore-тестов — это «волшебная папка», которая не работает в день X. Периодически прогоняй 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
Метрики для анализа берите из Prometheus: AnalysisTemplate проверяет ошибки и время ответа автоматически на каждом шаге.

22. Pod Disruption Budget и обслуживание узлов

Выкатка и обслуживание узлов неизбежно останавливают поды. Pod Disruption Budget защищает минимальную доступность сервиса во время плановых операций.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: api
PDB не защищает от сбоев «железа», только от плановых остановок. Проверяйте, что ваш Deployment реально может запуститься на другом узле.

23. Pod Security Standards и политики

RBAC ограничивает, кто что может, но не защищает контейнер от опасных привилегий. Pod Security Standards и политики закрывают run-as-root и привилегированные режимы.

kubectl label ns default \
  pod-security.kubernetes.io/enforce=restricted
Включайте restricted-режим на этапе разработки: на проде он неожиданно ломает образы, которые «всегда работали».

24. Оптимизация затрат

Счёт за Kubernetes складывается незаметно: избыточные requests, простаивающие ноды, ненужные реплики. Управление стоимостью — часть эксплуатации.

ПриёмВыгода
Понизить requestsменьше нод, плотнее упаковка
HPA по метрикамнет лишних реплик по ночам
Удаление забытых volumesменьше платных дисков
Следите за графиком «запрошенное vs потребляемое» в Grafana: он сразу показывает, где переплачиваете.

Что дальше

Мониторь кластер через Prometheus и Grafana, конфигурируй через Terraform, а CI/CD строй на GitLab. Все курсы — на главной странице.

← Вернуться к курсам