Что вы опишете в Deployment YAML для развертывания stateless-приложения в Kubernetes?

«Что вы опишете в Deployment YAML для развертывания stateless-приложения в Kubernetes?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для развертывания типичного stateless-приложения (например, веб-сервиса на Go) я создаю Deployment со следующим основным набором полей:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service          # Уникальное имя деплоймента в неймспейсе
  labels:
    app: api-service
    tier: backend
spec:
  replicas: 3                # Желаемое количество идентичных подов для отказоустойчивости
  selector:                  # Селектор, по которому Deployment находит свои поды
    matchLabels:
      app: api-service
  strategy:                  # Стратегия обновления (по умолчанию RollingUpdate)
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1            # На сколько подов можно превысить replicas во время обновления
      maxUnavailable: 0      # Сколько подов могут быть недоступны (0 для zero-downtime)
  template:                  # Шаблон пода (Pod template)
    metadata:
      labels:
        app: api-service     # Должны совпадать с selector.matchLabels
    spec:
      containers:
      - name: api-container
        image: my-registry/company/api:v1.2.3  # Всегда использую конкретный тег, не latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080                  # Порт, который слушает контейнер
        env:                                   # Конфигурация через переменные окружения
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:                   # Часто выношу в ConfigMap
              name: app-config
              key: database.host
        - name: API_SECRET
          valueFrom:
            secretKeyRef:                      # Секреты через Secret
              name: api-secrets
              key: token
        resources:                             # Ограничения и запросы ресурсов — обязательно!
          requests:                            # Гарантированное выделение
            cpu: "100m"
            memory: "128Mi"
          limits:                              # Жесткий лимит
            cpu: "500m"
            memory: "256Mi"
        livenessProbe:                         # Проверка, что приложение "живое"
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 15              # Даю время на старт
          periodSeconds: 10
        readinessProbe:                        # Проверка готовности принимать трафик
          httpGet:
            path: /ready
            port: 8080
          periodSeconds: 5

Ключевые моменты, которые я всегда проверяю: реплики для HA, стратегия обновления, конкретный тег образа, resources (без них пода может быть убит или занять весь узел), пробы liveness/readiness и конфигурация через ConfigMap/Secret.