Основы
Kubernetes: основы¶
Kubernetes (K8s) — платформа для оркестрации контейнеров. Docker запускает контейнеры на одной машине, Kubernetes — на кластере из десятков/сотен машин, управляя масштабированием, отказоустойчивостью и деплоем.
Зачем DE: Airflow на K8s (KubernetesExecutor), Spark operator, CI/CD-пайплайны, изоляция задач — каждый ETL-job в своём Pod с нужными ресурсами.
Архитектура¶
┌─────────────── Control Plane ──────────────┐
│ API Server ← kubectl, CI/CD │
│ etcd (state store) │
│ Scheduler (назначает Pod → Node) │
│ Controller Manager (следит за состоянием) │
└─────────────────────────────────────────────┘
│ │ │
┌────▼────┐ ┌───▼────┐ ┌───▼────┐
│ Node 1 │ │ Node 2 │ │ Node 3 │
│ kubelet │ │ kubelet │ │ kubelet │
│ Pod Pod │ │ Pod │ │ Pod Pod │
└─────────┘ └────────┘ └────────┘
| Компонент | Что делает |
|---|---|
| API Server | Точка входа для всех операций (REST API) |
| etcd | Распределённое хранилище состояния кластера |
| Scheduler | Решает, на какой Node запустить Pod |
| kubelet | Агент на каждой Node, запускает контейнеры |
| Pod | Минимальная единица — один или несколько контейнеров |
Основные ресурсы¶
Pod — атомарная единица¶
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: etl-worker
labels:
app: etl
spec:
containers:
- name: python
image: python:3.11-slim
command: ["python", "etl_job.py"]
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
Никогда не создавай Pod напрямую
Pod без Deployment не перезапустится при падении. Всегда используй Deployment, Job или CronJob.
Deployment — управление Pod'ами¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 3 # 3 одинаковых Pod'а
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: api
image: myregistry/backend:v1.2.0
ports:
- containerPort: 8000
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # +1 Pod при обновлении
maxUnavailable: 0 # Все старые Pod'ы живы до готовности нового
Service — сетевой доступ к Pod'ам¶
apiVersion: v1
kind: Service
metadata:
name: backend-svc
spec:
selector:
app: backend # Направлять трафик на Pod'ы с label app=backend
ports:
- port: 80 # Порт сервиса
targetPort: 8000 # Порт контейнера
type: ClusterIP # Доступен только внутри кластера
| Тип | Описание |
|---|---|
ClusterIP |
Внутренний IP (default) |
NodePort |
Порт на каждой Node (30000-32767) |
LoadBalancer |
Внешний балансировщик (cloud) |
ConfigMap — конфигурация¶
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "INFO"
WORKERS: "4"
config.yaml: |
database:
pool_size: 10
timeout: 30
# Использование в Pod
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# Или как volume (файл)
volumes:
- name: config
configMap:
name: app-config
Secret — чувствительные данные¶
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData: # stringData → автоматическое base64
url: postgresql://user:pass@db:5432/etl
password: strong_password
# Создать через kubectl
kubectl create secret generic db-secret \
--from-literal=url='postgresql://user:pass@db:5432/etl'
Secret — не шифрование
Secret хранится в etcd в base64 (не шифрованном виде). Для серьёзной безопасности используй Sealed Secrets, HashiCorp Vault или cloud KMS.
kubectl — основные команды¶
# Получить ресурсы
kubectl get pods # Pod'ы
kubectl get pods -o wide # + Node, IP
kubectl get deployments # Deployment'ы
kubectl get svc # Service'ы
kubectl get all # Всё
# Детали
kubectl describe pod backend-7f8b9-xk2lm
kubectl logs backend-7f8b9-xk2lm # Логи
kubectl logs -f backend-7f8b9-xk2lm # Follow
# Выполнить команду в Pod
kubectl exec -it backend-7f8b9-xk2lm -- /bin/bash
# Применить манифест
kubectl apply -f deployment.yaml
kubectl apply -f k8s/ # Всю директорию
# Масштабирование
kubectl scale deployment backend --replicas=5
# Удалить
kubectl delete pod backend-7f8b9-xk2lm
kubectl delete -f deployment.yaml
Namespace — изоляция¶
kubectl create namespace data-platform
kubectl get pods -n data-platform
kubectl apply -f job.yaml -n data-platform
# Переключить контекст на namespace
kubectl config set-context --current --namespace=data-platform
Типичная структура:
- default — тестовое/дефолтное
- data-platform — ETL-пайплайны
- monitoring — Prometheus, Grafana
- airflow — Airflow
Helm — пакетный менеджер¶
Helm — «apt/brew для Kubernetes». Helm chart — шаблон из K8s-манифестов с параметрами.
# Добавить репозиторий
helm repo add apache-airflow https://airflow.apache.org
helm repo update
# Установить Airflow
helm install airflow apache-airflow/airflow \
--namespace airflow --create-namespace \
--set executor=KubernetesExecutor \
--set dags.gitSync.enabled=true \
--set dags.gitSync.repo=git@github.com:org/dags.git
# Обновить
helm upgrade airflow apache-airflow/airflow -f values.yaml
# Удалить
helm uninstall airflow -n airflow
values.yaml¶
# values.yaml — параметры для Helm chart
executor: KubernetesExecutor
webserver:
replicas: 2
resources:
limits:
memory: 2Gi
postgresql:
enabled: true
postgresqlPassword: airflow
dags:
gitSync:
enabled: true
repo: git@github.com:org/dags.git
branch: main
Minikube — K8s на ноутбуке¶
# Установка
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Запуск
minikube start --cpus=4 --memory=8g --driver=docker
# Dashboard
minikube dashboard
# Доступ к сервису
minikube service backend-svc
Проверь себя¶
Источники¶
- Kubernetes: Concepts — официальная документация
- Kubernetes: kubectl Cheat Sheet — команды
- Helm: Documentation — пакетный менеджер