Развертывание приложения в Kubernetes для production: пошаговая схема | AdminWiki

Развертывание приложения в Kubernetes для production: пошаговая схема

06 сентября 2026 18 мин. чтения
Содержание статьи

Production-развертывание приложения в Kubernetes строится вокруг нескольких связанных объектов. ConfigMap передает обычные настройки, Secret хранит пароли и токены, Deployment управляет жизненным циклом Pod, Service дает подам стабильный внутренний адрес, а Ingress направляет внешний HTTP или HTTPS-трафик к Service.

Рабочий порядок выглядит так: подготовить Namespace и образ с фиксированным тегом, проверить доступ к кластеру, Registry и Ingress Controller, применить ConfigMap и Secret, создать Deployment, дождаться готовности Pod, связать их с Service, опубликовать Service через Ingress и выполнить внешний запрос. Команда kubectl apply подтверждает прием манифеста API-сервером, но не гарантирует, что приложение уже принимает трафик.

В этой инструкции используется приложение web-api с двумя репликами, портом контейнера 8080, внутренним Service на порту 80 и доменом app.example.com. Число реплик, лимиты CPU и памяти, домен, health endpoints и политика обновления должны соответствовать SLA и результатам нагрузочного тестирования.

Как устроена production-схема развертывания в Kubernetes

Какие объекты участвуют в публикации приложения

Каждый объект отвечает за отдельный участок цепочки. Связи между ними строятся через имена, namespace и labels, поэтому ошибка в одном поле может оставить весь сервис без трафика.

ОбъектНазначениеЧто проверять
NamespaceИзолирует ресурсы приложения и ограничивает область действия имен.Совпадение namespace во всех манифестах и командах kubectl.
DeploymentЗадает желаемое число реплик, образ, probes и стратегию обновления.Selector, labels, состояние ReplicaSet и доступность Pod.
ReplicaSetСоздается Deployment и поддерживает нужное число Pod для конкретной ревизии.Количество desired, current и ready реплик.
PodЗапускает один или несколько контейнеров приложения.Фаза, Ready-состояние, рестарты, события и логи.
ServiceДает стабильный DNS-адрес и распределяет запросы между готовыми Pod.Selector, порт, targetPort и EndpointSlices.
IngressСвязывает host и path с Service для внешнего HTTP или HTTPS-доступа.IngressClass, DNS, TLS, backend и статус контроллера.
ConfigMapХранит обычную конфигурацию: режим работы, таймауты, feature flags.Имена ключей, namespace и факт передачи в контейнер.
SecretПередает пароли, токены, ключи и TLS-материалы.RBAC, ротация, способ хранения и отсутствие значений в логах.

Для дополнительного разбора control plane, worker nodes, Pod, Deployment, Service и Namespace пригодится материал об архитектуре кластера и ключевых объектах API.

В каком порядке проходят запрос и обновление версии

Внешний запрос проходит через DNS к внешнему адресу Ingress Controller. Контроллер выбирает правило по host и path, передает запрос в Service, а Service направляет его на готовый Pod по labels. Pod считается подходящим backend после успешной проверки readinessProbe.

Обновление начинается с изменения image tag в Deployment. Kubernetes создает новую ReplicaSet, запускает новые Pod и ждет их readiness. При параметрах maxUnavailable: 0 и maxSurge: 1 старая версия продолжает обслуживать запросы, пока новая реплика не пройдет проверку. Предыдущая ReplicaSet сохраняется в истории, поэтому Deployment можно вернуть на прошлую ревизию.

Полная схема релиза: образ -> манифесты -> API-сервер -> ReplicaSet -> Pod -> readiness -> Service -> Ingress -> внешний запрос. Значения replicas, ресурсов и времени ожидания нельзя копировать без проверки нагрузки и времени запуска конкретного приложения.

Подготовить production-окружение и набор манифестов

Проверить доступ к кластеру, Registry и Ingress Controller

Начните с проверки контекста и прав. Ошибка в текущем кластере опаснее синтаксической ошибки YAML: манифест может попасть в другой environment.

kubectl config current-context
kubectl cluster-info
kubectl auth can-i get deployments -n production
kubectl auth can-i create deployments -n production
kubectl get namespace production
kubectl get ingressclass
kubectl get pods -A

Для приватного Registry создайте pull-secret в том же namespace, где работает Deployment. Secret с учетными данными Registry не переносится автоматически между namespace.

kubectl create secret docker-registry regcred \
  --docker-server=REGISTRY_HOST \
  --docker-username=REGISTRY_USER \
  --docker-password=REGISTRY_PASSWORD \
  -n production

Проверьте точный image tag, доступность Registry с worker-узлов и наличие образа для нужной архитектуры CPU. Локальный образ на машине администратора не помогает Pod, если worker-узел не может получить его из Registry.

Ingress сам по себе трафик не принимает. Нужен работающий Ingress Controller, его Service с внешним адресом и настроенная DNS-запись. Для размещения кластера в облаке можно рассмотреть облачную инфраструктуру Timeweb Cloud с Kubernetes, но сетевые настройки Ingress, DNS и TLS все равно нужно проверить в выбранной среде.

Зафиксировать параметры приложения до написания YAML

Составьте короткую таблицу параметров. Она устраняет путаницу между портом процесса, портом контейнера, портом Service и внешним адресом.

ПараметрПримерПроверка
Имя приложенияweb-apiОдинаковое значение в Deployment, Service и Ingress.
NamespaceproductionNamespace существует, права выданы.
Образregistry.example.org/team/web-api:2026.09.06Тег существует и не меняет содержимое после публикации.
Порт процесса8080Приложение слушает этот порт внутри контейнера.
Порт Service80На него ссылается Ingress или внутренний клиент.
Health endpoints/startup, /ready, /liveКаждый endpoint возвращает ожидаемый код.
Реплики2В кластере хватает CPU, памяти и worker-узлов.
Доменapp.example.comDNS указывает на внешний адрес Ingress Controller.

Зафиксируйте целевую версию Kubernetes и API-версии ресурсов. Для Ingress используйте networking.k8s.io/v1. Тег latest усложняет диагностику и откат, потому что его содержимое может измениться без изменения YAML.

Описать Deployment для запуска и обновления приложения

Связать Deployment, ReplicaSet и Pod через labels

Deployment выбирает управляемые Pod через spec.selector.matchLabels. Эти labels должны совпадать с labels в spec.template.metadata.labels. Service использует такой же принцип, но его selector задается отдельно.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
  namespace: production
  labels:
    app.kubernetes.io/name: web-api
spec:
  replicas: 2
  revisionHistoryLimit: 5
  progressDeadlineSeconds: 600
  selector:
    matchLabels:
      app.kubernetes.io/name: web-api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-api
    spec:
      imagePullSecrets:
        - name: regcred
      terminationGracePeriodSeconds: 30
      securityContext:
        runAsNonRoot: true
      containers:
        - name: web-api
          image: registry.example.org/team/web-api:2026.09.06
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          envFrom:
            - configMapRef:
                name: web-api-config
            - secretRef:
                name: web-api-secrets
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          startupProbe:
            httpGet:
              path: /startup
              port: http
            periodSeconds: 5
            failureThreshold: 30
          readinessProbe:
            httpGet:
              path: /ready
              port: http
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: /live
              port: http
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3

Поле selector связывает Deployment с Pod и после создания Deployment не меняется произвольно. Для изменения схемы labels создайте новый Deployment или заранее спланируйте миграцию. Подстановка другого selector может привести к ошибке применения или потере управления нужными Pod.

Подробные примеры полей Deployment, RollingUpdate, probes, requests и limits собраны в руководстве по управлению приложениями через Kubernetes Deployment.

Добавить probes и ограничения ресурсов

startupProbe дает медленно запускающемуся процессу время на инициализацию. Пока эта проверка не прошла, Kubernetes не запускает liveness-проверку. Это снижает риск рестартов во время миграции или загрузки большого кэша.

readinessProbe определяет, можно ли отправлять Pod пользовательский трафик. Ошибка readiness убирает Pod из EndpointSlices, но не обязательно перезапускает контейнер. livenessProbe ищет зависший процесс и при повторяющейся ошибке инициирует рестарт контейнера.

Проверяйте endpoints непосредственно в приложении. Если процесс слушает порт 8080, а probe обращается к порту 8000, Pod останется NotReady. Если endpoint зависит от базы данных, решите отдельно, должна ли недоступность базы исключать Pod из трафика или приводить к перезапуску.

requests участвуют в планировании Pod. limits ограничивают потребление ресурсов. Значения 100m CPU и 128Mi памяти подходят только как пример, их нужно подтвердить метриками и нагрузкой. Недостаточный memory limit приводит к OOMKilled, слишком низкий CPU limit увеличивает время ответа.

Настроить управляемое rolling update

Параметр maxUnavailable: 0 запрещает уменьшать число доступных реплик во время обновления. maxSurge: 1 разрешает временно создать одну дополнительную реплику. При двух репликах кластеру нужно место минимум для трех Pod на части процесса обновления.

progressDeadlineSeconds: 600 задает срок, после которого Deployment получит состояние прогресса с ошибкой, если новые Pod не стали готовыми. Это не отменяет обновление автоматически. Статус нужно проверить командой kubectl rollout status.

revisionHistoryLimit: 5 сохраняет пять старых ReplicaSet. Слишком маленькое значение сокращает выбор для rollback, слишком большое увеличивает число объектов, которые нужно обслуживать. Сценарий обновления и отката полезно автоматизировать после проверки ручного процесса, например по схеме из примера скрипта развертывания приложения в Kubernetes.

Настроить ConfigMap и Secret в Kubernetes

Что хранить в ConfigMap

ConfigMap подходит для значений, которые не дают доступа к системе: режима запуска, уровня логирования, URL сервиса без учетных данных, feature flags и таймаутов.

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-api-config
  namespace: production
data:
  APP_ENV: production
  LOG_LEVEL: info
  UPSTREAM_TIMEOUT_MS: '2000'
  FEATURE_CACHE: 'true'

Подключение через envFrom передает все ключи как переменные окружения. Для точечного подключения используйте configMapKeyRef, когда контейнеру нужен один параметр и нежелательно передавать весь набор.

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: web-api-config
        key: LOG_LEVEL
        optional: false

Что хранить в Secret и как защитить данные

В Secret помещают пароль базы данных, API-токен, ключ подписи, строку подключения с credentials и TLS-материалы. Реальные значения нельзя коммитить в публичный репозиторий, помещать в Docker-образ или печатать в логах.

apiVersion: v1
kind: Secret
metadata:
  name: web-api-secrets
  namespace: production
type: Opaque
stringData:
  DB_PASSWORD: replace-before-apply
  API_TOKEN: replace-before-apply

stringData позволяет передать обычный текст при создании объекта, после чего API-сервер преобразует его в формат Secret. Base64 в поле data служит кодированием, не шифрованием. Ограничьте доступ RBAC, включите encryption at rest для etcd и настройте ротацию. Для production с большим числом секретов разумно использовать внешний secret manager, который выдает значения по контролируемой политике.

Secret действует внутри своего namespace. Сервисный аккаунт Pod должен получать только нужные ресурсы, а доступ к Secret через RBAC нужно проверять командой kubectl auth can-i.

Проверить обновление конфигурации

При передаче ConfigMap и Secret через environment variables приложение получает значения при старте процесса. Изменение объекта не перезапускает контейнер и не обновляет переменную в уже работающем процессе.

kubectl apply -f web-api-config.yaml -n production
kubectl apply -f web-api-secrets.yaml -n production
kubectl rollout restart deployment/web-api -n production
kubectl rollout status deployment/web-api -n production

При volume mount Kubernetes обновляет файл с учетом механизма синхронизации, но приложение должно перечитать его само. Процесс, который читает конфигурацию только при запуске, потребует restart. После изменения имени ключа проверьте, что Deployment ссылается на актуальный ConfigMap или Secret.

Создать Service для внутреннего доступа к Pod

Сопоставить selector, port и targetPort

Для приложения, которое публикуется через Ingress, обычно достаточно Service типа ClusterIP. Он не получает публичный адрес и доступен внутри кластера по DNS-имени.

apiVersion: v1
kind: Service
metadata:
  name: web-api
  namespace: production
  labels:
    app.kubernetes.io/name: web-api
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: web-api
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP

selector Service должен совпадать с labels Pod. targetPort: http ссылается на именованный порт контейнера 8080. Service port 80 используется клиентом или Ingress. Если задать targetPort: 80, а процесс слушает 8080, запросы не дойдут до приложения.

Проверить endpoints до настройки внешнего доступа

Сначала проверьте, появились ли готовые EndpointSlices. Пустой список означает, что Service не нашел подходящие Ready Pod или все Pod исключены readiness-проверкой.

kubectl get service web-api -n production
kubectl get endpointslices -n production \
  -l kubernetes.io/service-name=web-api
kubectl describe service web-api -n production
kubectl get pods -n production \
  -l app.kubernetes.io/name=web-api \
  -o wide

Выполните тестовый запрос из временного Pod в том же namespace. Для успешного ответа ожидайте HTTP-код, который приложение использует для health endpoint, обычно 200.

kubectl run netcheck -n production --rm -it \
  --restart=Never \
  --image=curlimages/curl:8.10.1 \
  -- curl -i http://web-api.production.svc.cluster.local/ready

Service не делает Pod готовым. В балансировку попадают только адреса, которые Kubernetes считает Ready. Если EndpointSlices пусты, проверяйте labels, readinessProbe и фазу Pod до перехода к Ingress.

Опубликовать Service через Ingress

Настроить host, path и backend Service

Ingress описывает правило маршрутизации, но обработку выполняет Ingress Controller. В примере используется класс nginx, корневой path и Service web-api на порту 80.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-api
  namespace: production
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: web-api-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-api
                port:
                  number: 80

Имя Service и порт должны совпадать с фактическим объектом в том же namespace. Ingress не ищет Service в другом namespace через имя host. Для одного точного URL применяйте pathType: Exact, для всех вложенных путей используйте Prefix. Обработку завершающего slash и rewrite проверьте отдельно, потому что эти правила зависят от контроллера.

Готовые примеры связки Deployment, Service, Ingress, ConfigMap и Secret можно использовать как сверку структуры в практическом руководстве по деплою сервисов в Kubernetes.

Подключить TLS и проверить DNS

TLS Secret должен находиться в namespace production и содержать сертификат для host app.example.com. Создать его из файлов сертификата и ключа можно командой:

kubectl create secret tls web-api-tls \
  --cert=fullchain.pem \
  --key=privkey.pem \
  -n production

DNS-запись должна указывать на внешний адрес Service Ingress Controller. ClusterIP приложения для этого не подходит. Проверьте адрес контроллера и состояние Ingress:

kubectl get service -A
kubectl get ingress web-api -n production
kubectl describe ingress web-api -n production
kubectl get secret web-api-tls -n production

Для проверки TLS используйте имя host при установлении соединения. Переменные позволяют не хранить адрес конкретного окружения в команде:

export APP_HOST=app.example.com
export INGRESS_ADDRESS=INGRESS_EXTERNAL_ADDRESS
openssl s_client -connect ${INGRESS_ADDRESS}:443 -servername ${APP_HOST}
export APP_URL=APP_SCHEME://${APP_HOST}
curl -i ${APP_URL}/health

HTTP-код 404 от контроллера часто означает несовпадение host или path. Код 502 обычно указывает на недоступный backend, неверный Service port или отсутствие Ready endpoints. Ответ приложения с собственным кодом ошибки нужно анализировать по логам контейнера.

Применить манифесты и проверить состояние релиза

Проверить rollout Deployment

Перед применением убедитесь, что команды обращаются к правильному контексту. Для предварительного просмотра используйте kubectl diff, затем применяйте ресурсы в логическом порядке.

kubectl config current-context
kubectl diff -f k8s/ -n production
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml -f k8s/secret.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
kubectl rollout status deployment/web-api -n production --timeout=10m

После rollout сверяйте несколько уровней состояния. Значения desired, current, ready и available должны соответствовать ожидаемому числу реплик.

kubectl get deployment web-api -n production
kubectl get rs -n production -l app.kubernetes.io/name=web-api
kubectl get pods -n production -l app.kubernetes.io/name=web-api -o wide
kubectl get pods -n production -l app.kubernetes.io/name=web-api \
  -o=jsonpath='{range .items[*]}{.metadata.name}{" Ready="}{.status.containerStatuses[0].ready}{" Restarts="}{.status.containerStatuses[0].restartCount}{"\n"}{end}'

Ожидайте завершения rollout, статус 1/1 для контейнера и отсутствие новых рестартов. Принятый YAML и готовый релиз, это разные состояния, поэтому внешнюю проверку выполняйте после проверки Pod и EndpointSlices.

Найти причину проблем через describe, Events и logs

Команда describe показывает условия Pod и события планировщика. Ищите сообщения о нехватке ресурсов, невозможности скачать образ, ошибках монтирования, отказах probes и завершении контейнера.

kubectl describe pod POD_NAME -n production
kubectl get events -n production --sort-by=.lastTimestamp
kubectl logs deployment/web-api -n production --all-containers=true --tail=200
kubectl logs pod/POD_NAME -n production --previous --tail=200

Текущие логи помогают увидеть ошибку работающего процесса. Ключ --previous показывает вывод контейнера перед последним рестартом и часто раскрывает причину CrashLoopBackOff. Не выводите в логах environment variables целиком и не копируйте значения Secret в диагностические сообщения.

Проверить цепочку Service и Ingress

Проверка сетевой цепочки должна идти изнутри наружу. Сначала подтвердите готовые Pod, потом EndpointSlices, затем запрос к ClusterIP или DNS Service, после чего проверьте Ingress и внешний host.

kubectl get pods -n production
kubectl get service web-api -n production
kubectl get endpointslices -n production \
  -l kubernetes.io/service-name=web-api
kubectl get ingress web-api -n production
kubectl run netcheck -n production --rm -it \
  --restart=Never \
  --image=curlimages/curl:8.10.1 \
  -- curl -i http://web-api/ready

Для внешнего запроса задайте APP_URL с нужной схемой и host, затем проверьте HTTP-код, заголовки, время ответа и сертификат. Запрос с другим Host может попасть в default backend и создать ошибочное впечатление, что приложение недоступно.

Разобрать типовые ошибки при запуске

СимптомВероятная причинаПроверкаИсправление
ImagePullBackOff, ErrImagePullНеверное имя образа или тега, закрытый Registry, отсутствует pull-secret.kubectl describe pod POD_NAME -n productionПроверить точный tag, доступ worker-узлов к Registry и imagePullSecrets в том же namespace.
CrashLoopBackOffПроцесс завершается, не хватает конфигурации, недоступна зависимость или probe настроена на неверный endpoint.kubectl logs pod/POD_NAME -n production --previousСверить exit code, команду запуска, ConfigMap, Secret, зависимости и health endpoints.
PendingНе хватает CPU или памяти, не подходят taints, nodeSelector, PVC или политика размещения.kubectl describe pod POD_NAME -n productionИзучить Events, проверить ресурсы узлов, requests, tolerations, PVC и доступность подходящих worker-узлов.
Running, но NotReadyНеверный порт probe, ошибочный путь health endpoint или приложение еще запускается.kubectl describe pod POD_NAME -n productionПроверить URL, порт, задержки, логи и фактическое поведение endpoint изнутри Pod.
Service без endpointsSelector не совпадает с labels Pod или все Pod не прошли readiness.kubectl get endpointslices -n productionСверить labels Deployment и selector Service, затем исправить readiness или состояние Pod.
Ingress возвращает 404Не совпадает host, path или ingressClassName, запрос попал в другой backend.kubectl describe ingress web-api -n productionПроверить Host в запросе, DNS, path, IngressClass и наличие правила для нужного namespace.
Ingress возвращает 502Service не имеет Ready endpoints, неверен порт или контроллер не может подключиться к backend.kubectl get service,endpointslices -n productionСверить port, targetPort, selector и readiness Pod.
Ingress не отвечаетНет внешнего адреса контроллера, DNS указывает не туда или контроллер не запущен.kubectl get service -A и kubectl get pods -AПроверить внешний Service контроллера, DNS-запись, сетевые правила и его логи.

Диагностируйте в порядке зависимости: образ и Pod, затем ресурсы и probes, после этого labels и Service, в конце Ingress и DNS. Такой порядок сокращает число ложных гипотез. Например, проверка DNS не исправит пустой EndpointSlices, а изменение timeout Ingress не устранит падение процесса.

ImagePullBackOff и ErrImagePull

Начните с Events. Kubernetes обычно сообщает, не найден ли tag, отклонены ли credentials или недоступен Registry. Убедитесь, что Secret типа kubernetes.io/dockerconfigjson создан в production, а имя в imagePullSecrets совпадает с его metadata.name.

CrashLoopBackOff и постоянные рестарты

Сравните текущие и предыдущие логи, exit code и настройки запуска. Проверьте обязательные ключи ConfigMap и Secret, DNS-имена зависимостей, миграции и права на файловую систему. Увеличение задержки probe без анализа причины может скрыть проблему и отсрочить ее проявление.

Pending, NotReady и отсутствие endpoints

Для Pending первыми проверяйте Events. Сообщения о Insufficient cpu или Insufficient memory указывают на requests и свободные ресурсы. Сообщения о taint, PVC или node affinity требуют проверки правил размещения.

Для NotReady проверьте путь и порт readinessProbe. Если Pod Ready, но Service пуст, сравните selector Service с labels Pod посимвольно, включая регистр и префиксы.

Ingress возвращает 404, 502 или не отвечает

Разделите проблему на четыре уровня: DNS, внешний Service контроллера, правило Ingress и backend Service. Код 404 от контроллера обычно связан с host или path. Код 502 появляется, когда правило найдено, но контроллер не получает корректный ответ от backend. Отсутствие соединения требует проверки адреса контроллера, сетевых правил и DNS.

Выполнить базовый откат неудачного релиза

Сохранить и посмотреть историю ревизий

Deployment хранит историю изменений, если старые ReplicaSet не удалены из-за малого revisionHistoryLimit. Перед релизом зафиксируйте image tag, номер задачи и изменения конфигурации в системе деплоя или changelog.

kubectl rollout history deployment/web-api -n production
kubectl rollout history deployment/web-api -n production --revision=3
kubectl get rs -n production -l app.kubernetes.io/name=web-api

В описании ревизии проверяйте образ, environment variables и другие поля Pod template. Изменение только ConfigMap или Secret не всегда создает новую ревизию Deployment, поэтому история Deployment не покажет полный набор изменений окружения.

Откатить Deployment и подтвердить восстановление

Для возврата на предыдущую ревизию выполните rollback и дождитесь готовности новых Pod.

kubectl rollout undo deployment/web-api -n production
kubectl rollout status deployment/web-api -n production --timeout=10m
kubectl get pods -n production -l app.kubernetes.io/name=web-api
kubectl get endpointslices -n production \
  -l kubernetes.io/service-name=web-api

Если нужно выбрать конкретную ревизию, используйте ее номер:

kubectl rollout undo deployment/web-api \
  --to-revision=3 \
  -n production

Команда rollout undo меняет Pod template, но сама по себе не подтверждает работу приложения. После нее проверьте Ready-состояние Pod, отсутствие рестартов, EndpointSlices, внутренний запрос и внешний HTTP или HTTPS-запрос с правильным Host.

Учесть ограничения rollback

Откат Deployment не отменяет миграцию базы данных, изменение внешнего API, удаление данных или ротацию Secret. Если новая версия уже изменила схему БД необратимым способом, возврат старого образа может привести к дополнительным ошибкам.

Для безопасного релиза используйте backward-compatible migrations: сначала добавляйте новые поля, сохраняйте совместимость старого кода, переключайте чтение и запись после проверки, а удаление старой схемы выполняйте отдельным этапом. Перед критическим изменением проверьте backup и процедуру восстановления.

Если проблема связана с ConfigMap или Secret, их нужно вернуть отдельно и затем запустить новый rollout. После восстановления зафиксируйте причину сбоя и обновите чек-лист, манифест или pipeline.

Проверить production-готовность перед передачей сервиса пользователям

Контрольный список перед релизом

  • Манифесты и версии: YAML проходит проверку, API-версии поддерживаются кластером, image tag фиксирован и существует в Registry.
  • Deployment: selector совпадает с labels, replicas соответствуют SLA, заданы requests и limits, настроены startup, readiness и liveness probes.
  • Безопасность: реальные пароли отсутствуют в Git и Docker-образе, RBAC ограничен, Secret не выводится в логи, контейнер запускается без root-привилегий.
  • Конфигурация: имена ConfigMap и Secret совпадают со ссылками в Deployment, обязательные ключи присутствуют, после изменения конфигурации выполнен нужный restart.
  • Service: selector совпадает с labels, port и targetPort проверены, EndpointSlices содержат Ready-адреса.
  • Ingress и TLS: установлен нужный Ingress Controller, указан ingressClassName, host и path совпадают с запросом, сертификат действителен.
  • DNS: запись направляет домен на внешний адрес Ingress Controller, а не на ClusterIP приложения.
  • Наблюдаемость: доступны логи, события, метрики и алерты на недоступность, рост рестартов и потерю Ready-реплик.
  • Восстановление: известны команды rollback, сохранена история ревизий, проверен backup и описаны ограничения отката для базы данных.
  • Нагрузка: число реплик, requests, limits, timeout и параметры rolling update подтверждены тестом, а не взяты без изменений из примера.

Минимальный набор команд для дежурной проверки

kubectl config current-context
kubectl get deployment DEPLOYMENT_NAME -n NAMESPACE
kubectl rollout status deployment/DEPLOYMENT_NAME -n NAMESPACE
kubectl get pods -n NAMESPACE -l app.kubernetes.io/name=APP_NAME -o wide
kubectl describe pod POD_NAME -n NAMESPACE
kubectl logs pod/POD_NAME -n NAMESPACE --tail=200
kubectl get events -n NAMESPACE --sort-by=.lastTimestamp
kubectl get service SERVICE_NAME -n NAMESPACE
kubectl get endpointslices -n NAMESPACE \
  -l kubernetes.io/service-name=SERVICE_NAME
kubectl get ingress INGRESS_NAME -n NAMESPACE
kubectl describe ingress INGRESS_NAME -n NAMESPACE
kubectl rollout history deployment/DEPLOYMENT_NAME -n NAMESPACE

Для рабочего релиза замените placeholders конкретными значениями namespace и имен ресурсов. Команды не должны печатать содержимое Secret. Результат проверки фиксируйте в журнале релиза: версия образа, номер ревизии, время rollout, число Ready Pod, HTTP-код внешнего запроса и выявленные события.

Такая последовательность дает воспроизводимый production-деплой: Kubernetes принимает описанные ресурсы, Deployment запускает нужную версию, probes подтверждают готовность, Service формирует endpoints, Ingress публикует маршрут, а rollback возвращает предыдущий Pod template при проблемном обновлении. Каждый этап проверяется отдельной командой, поэтому причину сбоя можно локализовать без перебора случайных настроек.

Поделиться:
Сохранить гайд? В закладки браузера