← Назад к вопросам

Что опишешь в yaml для обычного приложения

2.2 Middle🔥 161 комментариев
#Docker и контейнеризация#Kubernetes

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

При развертывании обычного приложения в Kubernetes, YAML-манифест является декларативным описанием его желаемого состояния. Вот ключевые разделы, которые я бы обязательно описал в YAML для Deployment и Service, сгруппированные по основным API-ресурсам.

1. Deployment (kind: Deployment)

Это основной ресурс для управления жизненным циклом подов (Pods) приложения.

Метаданные (metadata)

  • name: Уникальное имя деплоймента в неймспейсе (например, user-service-backend).
  • namespace: (Опционально) Неймспейс для развертывания (например, production).
  • labels: Набор меток для идентификации деплоймента (например, app: myapp, tier: backend).

Спецификация (spec)

  • replicas: Количество идентичных копий (подов) приложения, которые должны работать одновременно. Ключ для обеспечения отказоустойчивости и масштабирования.
  • selector: Определяет, какими подами будет управлять этот деплоймент. Использует matchLabels, которые должны совпадать с метками в шаблоне пода (template.metadata.labels).
  • strategy: Стратегия обновления (например, RollingUpdate с настройками maxUnavailable и maxSurge).
  • template: Шаблон для создания подов.
    *   `metadata.labels`: Метки, которые будут присвоены каждому созданному поду (должны совпадать с `selector.matchLabels`).
    *   `spec`: Спецификация пода - самая важная часть.
        *   **`containers`**: Список контейнеров в поде.
            *   `name`: Имя контейнера.
            *   `image`: Путь к образу в реестре (например, `myregistry.com/app:v1.2.3`). **Всегда указываю конкретный тег, а не `latest`**.
            *   `imagePullPolicy`: Политика загрузки образа (`IfNotPresent`, `Always`).
            *   `ports`: Список портов, которые контейнер открывает.
            *   `env` / `envFrom`: Переменные окружения, которые можно задать напрямую или через **ConfigMap/Secret**.
            *   **`resources`**: **Критически важный раздел.** Определяет запросы (`requests`) и лимиты (`limits`) для CPU и памяти. Без этого невозможно эффективное планирование и стабильность кластера.
        ```yaml
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        ```
            *   **`livenessProbe` и `readinessProbe`**: Проверки жизнеспособности и готовности. Без них Kubernetes не знает, работает ли приложение корректно.
        ```yaml
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        ```
        *   `volumes` и `volumeMounts`: (При необходимости) Для подключения постоянного хранилища (**PersistentVolumeClaim**) или монтирования **ConfigMap/Secret** как файлов.

2. Service (kind: Service)

Ресурс для обеспечения стабильного сетевого доступа к набору подов, обычно создается в паре с Deployment.

Метаданные (metadata)

  • Аналогично Deployment: name, namespace, labels.

Спецификация (spec)

  • type: Тип сервиса - ClusterIP (внутренний доступ), NodePort (для тестов или прямого доступа с нод), LoadBalancer (внешний доступ в облаках) или ExternalName.
  • selector: Должен точно соответствовать меткам подов (template.metadata.labels из Deployment). По этому селектору Service находит поды для балансировки трафика.
  • ports: Определяет, как трафик перенаправляется на поды.
    ports:
      - name: http
        port: 80        # Порт, на котором Service доступен внутри кластера
        targetPort: 8080 # Порт контейнера, на который направляется трафик
        protocol: TCP
    

3. Дополнительные и часто необходимые ресурсы

Для полноценной работы "обычного" приложения почти всегда требуются:

  • ConfigMap (kind: ConfigMap): Для хранения конфигурации приложения (файлы .properties, .yaml, .json), не содержащей секретных данных. Затем монтируется в поды как файлы или переменные окружения.
  • Secret (kind: Secret): Для хранения конфиденциальных данных (пароли, токены, TLS-сертификаты) в закодированном виде (base64). Никогда не храню секреты в репозитории с кодом приложения.
  • PersistentVolumeClaim (kind: PersistentVolumeClaim, PVC): Если приложению нужно постоянное хранилище для данных (базы данных, файловые хранилища). Запрашивает у кластера определенный объем и тип хранилища.

Полный минимальный пример

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: production
  labels:
    app: myapp
    tier: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      tier: backend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: myapp
        tier: backend
    spec:
      containers:
      - name: app-container
        image: myregistry.com/myapp:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        env:
        - name: ENVIRONMENT
          value: "prod"
        - name: CONFIG_FILE
          value: "/config/app.properties"
        envFrom:
        - configMapRef:
            name: myapp-config
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/ready
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
        volumeMounts:
        - name: config-volume
          mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: myapp-config
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: myapp
    tier: backend
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

Итог и лучшие практики

В YAML для обычного приложения я описываю не только "как запустить контейнер", но и полную политику его работы в production-среде:

  • Надежность: Реплики, проверки (probes), стратегия обновлений.
  • Безопасность: Минимальные необходимые привилегии, использование Secrets.
  • Наблюдаемость (Observability): Метки, пробники, корректные лог-потоки.
  • Эффективность: Ограничения ресурсов (resources).
  • Гибкость и управление: Вынесение конфигурации в ConfigMaps, настройка через переменные окружения.

Такой подход обеспечивает отказоустойчивость, удобство управления (обновление, откат через kubectl apply) и интеграцию с системами CI/CD.

Что опишешь в yaml для обычного приложения | PrepBro