Основы оркестрации: Kubernetes и Docker Swarm
Когда контейнеров становится много, нужна оркестрация. Изучите основы Kubernetes и Docker Swarm для управления кластерами.
Оркестрация — автоматизация развёртывания, масштабирования и управления контейнеризированными приложениями.
Проблемы, которые решает оркестрация:
Docker Swarm — нативный инструмент оркестрации от Docker.
# Инициализация manager
docker swarm init --advertise-addr 192.168.1.100
# Получить команду для добавления worker
docker swarm join-token worker
# Добавить worker (выполнить на worker)
docker swarm join --token <token> 192.168.1.100:2377
# Добавить manager (выполнить на manager)
docker swarm join --token <manager-token> 192.168.1.100:2377
# Посмотреть узлы
docker node ls
# Информация об узле
docker node inspect self# Создать сервис
docker service create \
--name nginx \
--replicas 3 \
-p 80:80 \
nginx:alpine
# Посмотреть сервисы
docker service ls
# Детали сервиса
docker service inspect nginx
# Логи сервиса
docker service logs nginx
# Масштабирование
docker service scale nginx=5
# Обновление образа
docker service update \
--image nginx:1.25 \
nginx
# Rolling update с настройками
docker service update \
--image nginx:1.25 \
--update-parallelism 1 \
--update-delay 10s \
--update-failure-action rollback \
nginx
# Откат
docker service rollback nginx
# Удаление
docker service rm nginx# Создать overlay сеть
docker network create \
--driver overlay \
--attachable \
my-overlay
# Сервисы в overlay сети автоматически видят друг друга
docker service create \
--name api \
--network my-overlay \
myapi:latest
docker service create \
--name db \
--network my-overlay \
postgres:15# docker-stack.yml
version: '3.8'
services:
web:
image: nginx:alpine
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
resources:
limits:
cpus: '0.5'
memory: 128M
ports:
- "80:80"
depends_on:
- api
api:
image: myapi:latest
deploy:
replicas: 5
update_config:
parallelism: 2
delay: 10s
resources:
limits:
cpus: '1'
memory: 512M
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
db:
image: postgres:15-alpine
deploy:
placement:
constraints:
- node.role == manager
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
postgres-data:# Развёртывание стека
docker stack deploy -c docker-stack.yml myapp
# Список стеков
docker stack ls
# Сервисы стека
docker stack services myapp
# Удаление стека
docker stack rm myappservices:
api:
image: myapi:latest
deploy:
replicas: 3
update_config:
failure_action: rollback
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10sKubernetes — система оркестрации с открытым исходным кодом от Google.
| Концепция | Описание |
|---|---|
| Pod | Минимальная единица развёртывания (один или несколько контейнеров) |
| Deployment | Управление репликами Pod, rolling updates |
| Service | Стабильный endpoint для доступа к Pod |
| ConfigMap | Хранение конфигурации |
| Secret | Хранение секретов |
| Namespace | Логическое разделение кластера |
| Ingress | Внешний доступ к сервисам |
# macOS
brew install minikube
# Запуск кластера
minikube start
# Проверка
kubectl cluster-info
kubectl get nodes# pod.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.0
ports:
- containerPort: 8000
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5# Создать Pod
kubectl apply -f pod.yml
# Посмотреть Pod
kubectl get pods
# Детали
kubectl describe pod myapp-pod
# Логи
kubectl logs myapp-pod
# Exec в Pod
kubectl exec -it myapp-pod -- bash
# Удалить
kubectl delete pod myapp-pod# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.0
ports:
- containerPort: 8000
resources:
limits:
memory: "512Mi"
cpu: "1"
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url# Создать Deployment
kubectl apply -f deployment.yml
# Посмотреть
kubectl get deployments
kubectl get replicasets
kubectl get pods
# Масштабирование
kubectl scale deployment myapp-deployment --replicas=5
# Обновление образа
kubectl set image deployment/myapp-deployment myapp=myapp:2.0.0
# Откат
kubectl rollout undo deployment/myapp-deployment
# Статус развёртывания
kubectl rollout status deployment/myapp-deployment
# История
kubectl rollout history deployment/myapp-deployment# service.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8000
type: LoadBalancer # или ClusterIP, NodePort# Создать Service
kubectl apply -f service.yml
# Посмотреть
kubectl get services
# External IP (для LoadBalancer)
kubectl get service myapp-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}'# configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
MAX_CONNECTIONS: "100"# secret.yml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
url: postgresql://user:password@db:5432/myapp
password: supersecret# Создать
kubectl apply -f configmap.yml
kubectl apply -f secret.yml
# Посмотреть
kubectl get configmaps
kubectl get secrets
# Значения (base64)
kubectl get secret db-secret -o yaml# ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80# Создать
kubectl apply -f ingress.yml
# Посмотреть
kubectl get ingress# Создать namespace
kubectl create namespace production
# Развёртывание в namespace
kubectl apply -f deployment.yml -n production
# Посмотреть в namespace
kubectl get pods -n production
# Все namespace
kubectl get namespaces| Характеристика | Docker Swarm | Kubernetes |
|---|---|---|
| Сложность | Низкая | Высокая |
| Установка | Встроен в Docker | Требует настройки |
| Масштабирование | До ~1000 узлов | До ~5000 узлов |
| GUI | Нет (Portainer) | Dashboard, Rancher |
| Auto-scaling | Ограниченное | HPA, VPA |
| Service Mesh | Требует интеграции | Istio, Linkerd |
| Сообщество | Меньше | Огромное |
| Использование | Малые/средние проекты | Enterprise, production |
✅ Подходит для:
❌ Не подходит для:
✅ Подходит для:
❌ Не подходит для:
# Установка eksctl
brew install eksctl
# Создание кластера
eksctl create cluster \
--name my-cluster \
--region us-east-1 \
--nodegroup-name standard-workers \
--node-type t3.medium \
--nodes 3
# Подключение kubectl
aws eks update-kubeconfig --name my-cluster --region us-east-1# Создание кластера
gcloud container clusters create my-cluster \
--num-nodes=3 \
--zone us-central1-a
# Подключение kubectl
gcloud container clusters get-credentials my-cluster --zone us-central1-a# Создание кластера
az aks create \
--resource-group my-resource-group \
--name my-cluster \
--node-count 3 \
--enable-addons monitoring
# Подключение kubectl
az aks get-credentials --resource-group my-resource-group --name my-clusterresources:
limits:
memory: "512Mi"
cpu: "1"
requests:
memory: "256Mi"
cpu: "500m"livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5# ✅ Хорошо
image: myapp:v1.0.0
# ❌ Плохо
image: myapp:latestkubectl create namespace production
kubectl create namespace staging
kubectl create namespace development# Установка Helm
brew install helm
# Создание чарта
helm create myapp
# Установка
helm install myapp ./myapp -n production
# Обновление
helm upgrade myapp ./myapp -n production
# Откат
helm rollback myapp -n productionПоздравляем! Вы прошли полный курс по Docker от основ до production и оркестрации.
Что дальше:
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.