Что такое Kubernetes
Kubernetes (K8s) — система для автоматического управления контейнерами. Docker упаковывает приложения в контейнеры, а Kubernetes управляет этими контейнерами: запускает, масштабирует, обновляет и восстанавливает.
Зачем нужен: когда у вас 10 серверов и 50 контейнеров, кто-то должен следить за тем, чтобы всё работало, перезапускать упавшие контейнеры, распределять нагрузку и обновлять без простоя. Kubernetes берёт это на себя.
Ключевые понятия
Cluster — вся инфраструктура целиком. Всё что запускается в Kubernetes живёт внутри кластера.
Node — отдельный сервер (физический или виртуальный) со своими ресурсами: CPU и память.
Pod — минимальная единица запуска. Обычно один Pod = один контейнер. Поды создаются, умирают и пересоздаются — они не вечные.
Deployment — декларативное описание желаемого состояния. «Хочу 5 подов моего сервиса» — Kubernetes поддерживает это количество, что бы ни произошло.
Service — стабильная точка доступа к подам. Поды постоянно меняются, а сервис даёт один адрес, по которому можно до них достучаться.
Control Plane — мозг кластера. Постоянно сверяет текущее состояние с желаемым и вносит корректировки.
kubectl — CLI для работы с кластером. Все команды отдаём через него.
Установка
Для локальной разработки используем minikube — кластер из одного узла на вашем компьютере. Необходим установленный Docker.
# Mac
brew install minikube
# Linux (amd64)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Запуск кластера
minikube start
# Проверка
kubectl get nodes
Поды и деплойменты
# Создать Pod напрямую (не рекомендуется для прода)
kubectl run my-nginx --image=nginx
kubectl get pods
kubectl delete pod my-nginx
# Создать Deployment — правильный подход
kubectl create deployment nginx-app --image=nginx --replicas=3
kubectl get pods
Если удалить один из подов деплоймента — Kubernetes мгновенно создаст новый. Указали 3 реплики — будет 3, что бы ни произошло.
Сервисы
Поды живут внутри кластера и снаружи недоступны. Service открывает к ним доступ:
kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort
minikube service nginx-app --url # получить внешний URL
Запросы идут на один адрес, а Kubernetes сам решает какой Pod их обработает.
YAML вместо команд
В реальности всё описывают в YAML-файлах — их можно хранить в git, ревьюить и откатывать.
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 3
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-app
spec:
type: NodePort
selector:
app: nginx-app
ports:
- port: 80
targetPort: 80
# Применить
kubectl apply -f deployment.yaml -f service.yaml
# Удалить
kubectl delete -f deployment.yaml -f service.yaml
Автоскейлинг — HorizontalPodAutoscaler
HPA автоматически увеличивает и уменьшает количество подов в зависимости от нагрузки.
hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: demo-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demo-app
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Логика: если средняя загрузка CPU по всем подам превышает 50% от requests — HPA добавляет поды. Падает ниже — убирает лишние.
Для работы HPA необходим metrics-server:
minikube addons enable metrics-server
Шпаргалка по командам
# Кластер
minikube start # запустить локальный кластер
minikube stop # остановить
kubectl get nodes # список узлов
# Развёртывание
kubectl create deployment NAME --image=IMAGE --replicas=N
kubectl get deployments
kubectl get pods
kubectl apply -f file.yaml
# Доступ
kubectl expose deployment NAME --port=PORT --type=NodePort
kubectl get services
minikube service NAME --url
# Масштабирование
kubectl scale --replicas=N deployment/NAME # ручное
kubectl get hpa # статус автоскейлера
# Обновления
kubectl set image deployment/NAME CONTAINER=IMAGE:TAG
kubectl rollout status deployment/NAME
kubectl rollout undo deployment/NAME # откат
# Диагностика
kubectl logs POD_NAME
kubectl exec POD_NAME -- COMMAND
kubectl describe pod POD_NAME
kubectl delete deployment NAME