YAML для Kubernetes: основные паттерны манифестов
Kubernetes полностью конфигурируется через YAML-манифесты. Каждый pod, deployment, service и ingress определяется в YAML. Владение этими паттернами необходимо каждому, кто работает с оркестрацией контейнеров. Это руководство охватывает важнейшие типы ресурсов с готовыми к продакшену примерами.
Четыре обязательных поля
Каждый манифест Kubernetes требует:
apiVersion: apps/v1 # API version for this resource type
kind: Deployment # Resource type
metadata: # Resource identification
name: my-app
namespace: production
labels:
app: my-app
spec: # Desired state specification
# ... resource-specific configuration
Deployment
Самый распространённый ресурс — управляет набором идентичных подов:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
labels:
app: api-server
environment: production
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: myapp/api:v1.2.3
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Ключевые паттерны
Всегда задавайте requests и limits ресурсов: без них один pod может потребить все ресурсы узла.
Всегда настраивайте проверки здоровья:
livenessProbe: перезапуск пода при отсутствии откликаreadinessProbe: прекращение отправки трафика до готовности пода
Используйте конкретные теги образов: никогда не используйте latest в продакшене — это делает откат невозможным.
Service
Предоставляет подам доступ к сетевому трафику:
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
type: ClusterIP
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
protocol: TCP
Типы Service:
- ClusterIP (по умолчанию): доступ только внутри кластера
- NodePort: экспорт на IP каждого узла через статический порт
- LoadBalancer: создание облачного балансировщика нагрузки
- ExternalName: сопоставление с DNS-именем
ConfigMap и Secret
ConfigMap (неконфиденциальные данные)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"
config.yaml: |
server:
port: 8080
timeout: 30s
Secret (конфиденциальные данные)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
url: "postgres://user:password@db:5432/myapp"
api-key: "sk-1234567890"
Использование в подах
# As environment variables
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# As a mounted file
volumes:
- name: config
configMap:
name: app-config
Ingress
Маршрутизация внешнего HTTP-трафика к сервисам:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-server
port:
number: 80
Horizontal Pod Autoscaler
Масштабирование подов на основе CPU или пользовательских метрик:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Распространённые ошибки
1. Ошибки отступов
Отступы в YAML критически важны для Kubernetes. Один неверно расположенный пробел полностью меняет структуру. Проверяйте манифесты с помощью нашего YAML Validator.
2. Несоответствие меток
Селектор Service должен точно совпадать с метками Pod. Несоответствие означает, что Service не сможет найти поды для маршрутизации трафика.
3. Отсутствие лимитов ресурсов
Поды без лимитов ресурсов могут лишить ресурсов другие рабочие нагрузки. Всегда указывайте и requests (гарантированный минимум), и limits (максимально допустимый).
4. Изменяемые теги образов
Использование latest или других изменяемых тегов делает откат невозможным, а деплои непредсказуемыми. Привязывайтесь к конкретным версиям или используйте неизменяемые дайджесты.
Многодокументные манифесты
Объединяйте связанные ресурсы в одном файле с помощью --- в качестве разделителя документов:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
# ... deployment spec
---
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
# ... service spec
Подробнее о паттернах синтаксиса YAML читайте в нашем учебнике по синтаксису YAML.
Часто задаваемые вопросы
Стоит ли писать Kubernetes YAML вручную или использовать генераторы?
Начните с написания YAML вручную, чтобы понять структуру. Для продакшена используйте такие инструменты, как Helm (шаблонизированные манифесты), Kustomize (кастомизация на основе наложений) или CDK8s (генерация из кода). Эти инструменты уменьшают повторение и позволяют создавать конфигурации под конкретные среды без дублирования манифестов.
Как отлаживать ошибки в Kubernetes YAML?
Используйте kubectl apply --dry-run=client -f manifest.yaml для валидации без применения. Для синтаксических ошибок kubectl explain deployment.spec.template.spec.containers показывает ожидаемую структуру. Инструменты kubeval и kubeconform проверяют соответствие API-схемам Kubernetes перед деплоем.
Связанные ресурсы
- YAML Validator — валидация манифестов Kubernetes
- YAML для Docker Compose — паттерны Docker YAML
- Лучшие практики линтинга YAML — выявление ошибок до деплоя