Архитектура Kubernetes: полное руководство
Kubernetes (K8s) — это оркестратор контейнеров, ставший стандартом де-факто для управления контейнеризированными приложениями. В этой статье мы пройдём путь от базовых понятий до организации полноценного кластера. Вы узнаете, как устроены Pod, Deployment, Service и как они взаимодействуют друг с другом для запуска приложений в продакшене.
Core Concepts
Pod
Pod — минимальная единица развёртывания в Kubernetes. Это группа из одного или нескольких контейнеров, которые:
- Делят хранилище и сеть
- Запускаются на одном узле
- Живут и умирают вместе
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
ReplicaSet
ReplicaSet гарантирует, что указанное количество реплик Pod работает в кластере. Если Pod падает, ReplicaSet создаёт новый.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-app-rs
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:latest
Deployment
Deployment добавляет управление версиями и rollback поверх ReplicaSet. Это основной ресурс для развёртывания приложений.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:latest
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Архитектура кластера
Control Plane (Master Node)
- kube-apiserver — API-сервер, единственная точка входа
- etcd — распределённое хранилище состояния
- kube-scheduler — планировщик, выбирает узел для Pod
- kube-controller-manager — набор контроллеров
- cloud-controller-manager — интеграция с облаком
Worker Nodes
- kubelet — агент на узле, управляет Pod
- kube-proxy — сетевой прокси, правила iptables
- container runtime — Docker, containerd, CRI-O
Services и Networking
Service
Стабильный IP для набора Pod:
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 80
type: ClusterIP # или LoadBalancer, NodePort
Ingress
HTTP/HTTPS маршрутизация:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-svc
port:
number: 80
ConfigMap и Secrets
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgres://db:5432/app"
config.yaml: |
log_level: info
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
api_key: "your-api-key"
Volumes
PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: standard
hostPath:
path: /mnt/data
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Namespace
Логическое разделение кластера:
kubectl create namespace myapp
kubectl get pods -n myapp
Основные команды
# Деплой
kubectl apply -f deployment.yaml
# Масштабирование
kubectl scale deployment my-app --replicas=5
# Логи
kubectl logs -f deployment/my-app
# Отладка
kubectl exec -it my-app-pod -- /bin/bash
# Проверка статуса
kubectl get pods,svc,deployments
# Удаление
kubectl delete -f deployment.yaml
Как это работает вместе
Давайте соберём всё в единую картину. Типичный поток развёртывания выглядит так:
- Вы создаёте Deployment — описываете желаемое состояние приложения (сколько реплик, какой образ)
- Deployment создаёт ReplicaSet — который гарантирует нужное количество Pod
- Scheduler выбирает узел — на основе доступных ресурсов и политик
- Kubelet запускает Pod — через container runtime
- Service предоставляет доступ — стабильный IP для подключения к Pod
- Ingress маршрутизирует трафик — снаружи кластера внутрь
┌──────────────────────────────────────┐
│ Cluster │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Control │ │ Worker Node │ │
│ │ Plane │ │ │ │
│ │ │ │ ┌───────┐ │ │
│ │ API Server │────┼─ │ Pod 1 │ │ │
│ │ │ │ │ │ │ │
│ │ Scheduler │ │ ├───────┤ │ │
│ │ │ │ │ Pod 2 │ │ │
│ │ etcd │ │ │ │ │ │
│ └─────────────┘ │ ├───────┤ │ │
│ │ │ Pod 3 │ │ │
│ ┌─────────────┐ │ └───────┘ │ │
│ │ Service │ └─────────────┘ │
│ │ (ClusterIP) │ │
│ └─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ Ingress │────── Internet │
│ └─────────────┘ │
└──────────────────────────────────────┘
Практические рекомендации
Для начинающих
- Начните с minikube или kind — локальный кластер для обучения
- Используйте kubectl alias — сократите команды (
k,kgp,kgl) - Изучите YAML — большая часть работы — это манифесты
- Практикуйтесь на примерах — развёртывайте простые приложения
Для продакшена
- Включите Resource Quotas — лимиты CPU и памяти для namespace
- Настройте Health Checks — liveness и readiness пробы
- Используйте Network Policies — изоляция трафика между Pod
- Включите RBAC — контроль доступа к API
- Настройте мониторинг — Prometheus + Grafana
- Автоматизируйте деплой — GitOps с ArgoCD или Flux
Частые ошибки
- Нет limits/requests — приводит к нехватке ресурсов
- Один большой Pod — нарушает принцип единой ответственности
- Игнорирование readiness probe — трафик идёт на неготовые Pod
- Хранение секретов в коде — используйте Secrets или внешние vault
- Отсутствие тегов образов —
latestусложняет откат
Что дальше
После освоения базовых концепций стоит изучить:
- Helm — менеджер пакетов для Kubernetes
- Operators — кастомные контроллеры для сложных приложений
- Service Mesh — Istio или Linkerd для продвинутой сети
- GitOps — декларативное управление инфраструктурой
- Kustomize — нативная кастомизация манифестов
Заключение
Kubernetes предоставляет мощный инструментарий для управления контейнерами в продакшене. Понимание базовых концепций — Pod, Deployment, Service, Ingress — позволяет эффективно развёртывать и масштабировать приложения.
Главное помнить: Kubernetes — это не просто технология, это экосистема с собственными паттернами и best practices. Начните с малого, экспериментируйте в локальном кластере, и постепенно переходите к более сложным сценариям.