
Argo CD, Docker Registry и cert-manager — одним аддоном каждый

CI/CD в Kubernetes редко ломается на синтаксисе YAML. Пайплайн может стать зелёным за сорок секунд, а в кластере продолжит работать предыдущая версия приложения. Обычно это обнаруживают уже после обращения в поддержку.
Есть сценарий опаснее: kubeconfig с правами cluster-admin хранится в CI-переменной. Тогда любой, кто может запустить джобу в проекте, потенциально получает права на удаление production-namespace.
В обоих случаях проблема сводится к одному вопросу: где хранятся доступы к production-кластеру. В push-модели доступы находятся в CI-системе, а джоба сама обращается к Kubernetes API. В pull-модели доступы не выходят за пределы кластера: контроллер внутри него читает манифесты из Git и приводит инфраструктуру к описанному состоянию.
GitLab CI и GitHub Actions можно использовать в обеих моделях. Меняется интерфейс пайплайна, но не сама модель доступа.
Разберём путь от коммита до пода: чем собирать образ в 2026 году, как выдать джобе доступ к кластеру в GitLab и GitHub Actions, какие права нужны деплой-аккаунту и почему завершившаяся джоба ещё не означает успешный запуск приложения.
Конвейер обычно состоит из пяти шагов:
Коммит → сборка образа → push в реестр → обновление манифеста или Helm-релиза → приведение кластера к желаемому состоянию
Первые три шага не отличаются от контейнерной сборки для любой другой среды. Особенности Kubernetes начинаются на этапе деплоя. Kubernetes работает с декларативным состоянием. В кластер передают описание того, что должно работать, а контроллеры приводят фактическое состояние к этому описанию.
Состояние кластера хранится в etcd — распределённом key-value-хранилище control plane. Там находятся объекты Kubernetes: Deployment, Service, ConfigMap, Secret и другие ресурсы.
kubectl, Helm и GitOps-контроллеры не управляют подами напрямую. Они создают или обновляют объекты через Kubernetes API, а затем контроллеры создают ReplicaSet, поды, сервисы и другие зависимые ресурсы.
Поэтому успешная запись в Kubernetes API ещё не означает, что приложение уже запустилось.
В push-модели CI-джоба обращается к Kubernetes API и выполняет kubectl apply или helm upgrade. Пайплайн описан в одном файле, шаги идут последовательно, а отладка обычно начинается с логов конкретной джобы.
Главный риск связан с доступами. Kubeconfig, токен сервисного аккаунта или другие учётные данные хранятся в CI-системе. Если они утекут, последствия будут зависеть от прав, выданных деплой-аккаунту.
В pull-модели манифесты забирает контроллер внутри кластера, например Argo CD или Flux. Он следит за Git-репозиторием и применяет описанное там состояние.
Доступы к Kubernetes API не передаются в CI-систему. Контроллер может обнаруживать и исправлять дрейф конфигурации, а история выкатов совпадает с историей изменений в Git.
По данным CNCF Annual Survey 2024, GitOps в той или иной форме используют 77% респондентов. Опрос проходил осенью 2024 года среди 750 участников, а отчёт опубликовали в апреле 2025 года. Среди GitOps-контроллеров лидирует Argo CD: почти 60% кластеров респондентов работают с ним, а 97% опрошенных используют Argo CD в production.
Эти цифры не означают, что GitOps нужен каждому проекту. Они показывают удобное разделение задач: CI собирает, тестирует, подписывает и публикует артефакты, а CD отвечает за состояние кластера.
Push-модель подходит небольшой команде, staging-окружению или проекту, в котором некому сопровождать отдельный контроллер внутри кластера.
В обеих схемах путь до Kubernetes API одинаков. Разница только в том, кто вызывает API: внешняя CI-джоба или контроллер, работающий внутри кластера.
На этом этапе Kubernetes почти не влияет на процесс. Важны два решения: чем собирать образ и как его тегировать.
Совет использовать kaniko, если в CI нельзя запускать privileged Docker, всё ещё встречается в старых гайдах. Но исходный репозиторий GoogleContainerTools/kaniko архивирован, а последняя версия проекта — v1.24.0.
Разработку продолжает форк Chainguard. Он получает security-патчи и сопровождение, хотя в README не заявлены крупные новые возможности. На 12 августа 2026 года последняя версия форка — v1.25.18.
BuildKit продолжает активно развиваться. Последний тег BuildKit — v0.32.2. У Buildx собственная нумерация версий, последняя версия — v0.36.1.
Для новых пайплайнов лучше использовать BuildKit. Если нельзя запускать привилегированный Docker-демон, подойдёт rootless-режим. kaniko тоже остаётся рабочим вариантом, но выбирать стоит форк Chainguard, а не архивированный исходный проект.
Kubernetes не рекомендует использовать тег :latest в production. По нему трудно определить, какая версия работает в кластере и на какой образ нужно откатываться.
Вместо :latest используйте версионный тег, например v1.42.0, SHA коммита или digest образа.
У imagePullPolicy есть важная особенность: Kubernetes определяет эту политику при создании объекта и позже не меняет её автоматически.
Например, Deployment, созданный с тегом v1.2.3, получит imagePullPolicy: IfNotPresent. Если позже заменить образ на :latest, политика останется IfNotPresent, хотя для :latest обычно ожидают Always. Пока imagePullPolicy не изменят вручную, узел может использовать закешированный образ.
В GitLab для тега удобно использовать:
$CI_COMMIT_SHORT_SHA
В GitHub Actions:
${{ github.sha }}
Ещё надёжнее деплоить образ по digest:
image@sha256:...
Такой выкат воспроизводим побайтово, а вопрос с политикой загрузки образа не возникает.
Проще всего использовать реестр того же вендора, что и CI-система:
Аутентификация обычно уже работает через токен джобы, поэтому отдельные доступы создавать не нужно.
Реестр внутри кластера — отдельный сценарий. В VK Cloud Cloud Containers для этого есть аддон Docker Registry. Он разворачивается в отказоустойчивой конфигурации и хранит образы в S3-совместимом объектном хранилище.
При установке создаются стандартный балансировщик нагрузки и Floating IP. Оба ресурса тарифицируются.
Аддону требуется 100m CPU и от 128 до 512 MiB RAM. Документированный способ подключения — добавить адрес реестра в формате
То есть из коробки это HTTP-реестр, доступный по IP-адресу. Для production нужно отдельно настраивать TLS, поэтому такой вариант пока не стоит считать полноценной заменой внешнему registry.
Для GitLab актуальный вариант — GitLab agent for Kubernetes. Агент устанавливается в кластер, после чего CI-джобы получают Kubernetes-контекст.
GitLab описывает работу агента так:
Сертификатная интеграция Kubernetes в GitLab устарела, хотя её всё ещё нередко советуют в старых инструкциях. GitLab объявил её deprecated в версии 14.5, а в GitLab Self-Managed 17.0 и новее она уже отключена по умолчанию.
На GitLab.com интеграция была доступна до версии 15.9 и только тем проектам, в иерархии namespace которых уже существовал хотя бы один сертификатный кластер. Полностью из продукта её пока не удалили: в GitLab 18.0 она всё ещё может быть включена через feature flag certificate_based_clusters. Поэтому инструкции, где предлагают открыть Operations → Kubernetes и добавить CA-сертификат, относятся к прежнему механизму, а не к GitLab agent for Kubernetes.
Kubeconfig уже примонтирован в джобу. После установки kubectl остаётся выбрать контекст агента. Формат имени контекста:
<path/to/agent/project>:<agent-name>
Если точное имя неизвестно, выполните:
kubectl config get-contexts
Пример .gitlab-ci.yml:
# .gitlab-ci.yml — деплой через GitLab agent for Kubernetes deploy: image: debian:13-slim variables: KUBECTL_VERSION: v1.34 DEBIAN_FRONTEND: noninteractive script: - apt-get update - apt-get install -y --no-install-recommends apt-transport-https ca-certificates curl gnupg - curl --fail --silent --show-error --location \ "https://pkgs.k8s.io/core:/stable:/${KUBECTL_VERSION}/deb/Release.key" \ | gpg --dearmor --output /etc/apt/keyrings/kubernetes-apt-keyring.gpg - chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg - echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${KUBECTL_VERSION}/deb/ /" \ | tee /etc/apt/sources.list.d/kubernetes.list - chmod 644 /etc/apt/sources.list.d/kubernetes.list - apt-get update - apt-get install -y --no-install-recommends kubectl - kubectl config get-contexts - kubectl config use-context path/to/agent/project:agent-name - kubectl get pods
Проекты и группы авторизуются в конфигурации агента:
# .gitlab/agents/<agent-name>/config.yaml ci_access: projects: - id: path/to/project groups: - id: path/to/group/subgroup
В Auto DevOps контекст передаётся через переменную KUBE_CONTEXT. Для разных окружений можно создать environment-scoped переменные с одним именем, но разными значениями.
Если в проекте остался сертификатный кластер, его контекст называется gitlab-deploy и выбирается по умолчанию. Контекст агента в таком случае нужно указать явно.
Если GitLab agent не используется, CI-джобе нужен kubeconfig.
Kubeconfig из личного кабинета VK Cloud требует SSO и пароль. Для автоматизации документация рекомендует kubeconfig сервисного аккаунта: токен в нём не имеет срока действия и не требует интерактивного входа.
Готовый kubeconfig консоль не создаёт, его собирают вручную:
kubectl config set-context --current --user=<ИМЯ_СЕРВИСНОГО_АККАУНТА>
После этого kubeconfig содержит сервисный аккаунт и отдельный Kubernetes-контекст. Файл нужно сохранить в GitLab как CI/CD-переменную типа File с флагом Protected. Права сервисного аккаунта лучше ограничить одним namespace. Пример Role приведён ниже. Маскирование для такой переменной не работает: masked-переменная должна быть однострочной и не содержать пробелов, а kubeconfig — многострочный YAML-файл.
Конфигурация ниже собрана из документированных частей: kubeconfig сервисного аккаунта описан в документации VK Cloud, File-переменные и маскирование — в документации GitLab, поведение helm upgrade — в исходном коде Helm. Перед использованием в production проверьте пайплайн на стенде.
# .gitlab-ci.yml — сборка и деплой через kubeconfig сервисного аккаунта stages: [build, deploy] variables: # Тег по SHA коммита, а не :latest IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA build: stage: build image: docker:cli services: [docker:dind] script: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" - docker buildx build --push -t "$IMAGE" . deploy: stage: deploy # Версия Helm, поставляемая в кластерах VK Cloud 1.34.x и 1.33.x image: alpine/helm:3.18.4 environment: name: production rules: # Деплой в production — только из защищённой ветки по умолчанию - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: # KUBECONFIG — CI/CD-переменная типа File с флагом Protected - > helm upgrade --install myapp ./chart --namespace prod --set image.repository=$CI_REGISTRY_IMAGE --set image.tag=$CI_COMMIT_SHORT_SHA --wait --atomic --timeout 5m # Helm --wait проверяет релиз, rollout status — конкретный объект - kubectl rollout status deployment/myapp -n prod --timeout=5m
В примере используется синтаксис Helm 3, потому что эта ветка поставляется в кластерах VK Cloud. В Helm 4 синтаксис отличается.
Официальная документация GitHub по публикации Docker-образов рекомендует три практики, которые стоит использовать и в собственных workflow:
# .github/workflows/deploy.yml — сборка, push в ghcr.io и деплой в кластер name: Build and deploy to Kubernetes on: push: branches: [main] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v6 - uses: docker/setup-buildx-action@<commit-sha> - uses: docker/login-action@<commit-sha> with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@<commit-sha> with: context: . push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} deploy: needs: build-and-push runs-on: ubuntu-latest # Правила защиты environment могут требовать ручного подтверждения выката в production environment: production steps: - uses: azure/setup-kubectl@v5 - name: Записать kubeconfig из секрета репозитория run: | mkdir -p "$HOME/.kube" echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > "$HOME/.kube/config" chmod 600 "$HOME/.kube/config" - name: Выкатить и дождаться готовности run: | kubectl -n prod set image deployment/myapp \ myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} kubectl -n prod rollout status deployment/myapp --timeout=300s - name: Откатить при ошибке выката if: failure() run: kubectl -n prod rollout undo deployment/myapp
У версий actions есть отдельная особенность. Последний мажор в репозитории action и версия в документации вендора часто не совпадают: документация может отставать на одну мажорную версию.
На 12 августа 2026 года стабильная версия actions/checkout — v7.0.1, а docker/build-push-action — v7.3.0. При этом в примерах GitHub всё ещё встречается actions/checkout@v6.
Поэтому лучше фиксировать actions по commit SHA и обновлять их через Dependabot.
GitHub Actions может получать временный доступ к облаку через OIDC без постоянных ключей в секретах репозитория. Во время запуска джоба запрашивает у GitHub короткоживущий JWT. Облачный провайдер проверяет его claims, включая sub, и выдаёт временные учётные данные с заранее заданными правами.
После завершения джобы эти учётные данные перестают действовать. Хранить в GitHub долгоживущий ключ облачного аккаунта не нужно.
Чтобы запросить OIDC-токен, нужно выдать джобе право:
permissions: id-token: write
OIDC требует, чтобы облачный провайдер умел проверять токены GitHub и выдавать временные учётные данные через IAM-федерацию. В документации VK Cloud нет сценария OIDC-аутентификации внешней CI-системы при доступе к Kubernetes-кластеру. Для автоматизации там предлагается kubeconfig сервисного аккаунта, сохранённый в секрете репозитория.
В GitLab можно использовать GitLab agent: kubeconfig выдаётся джобе только на время выполнения и не хранится в переменных проекта. В GitHub Actions для подключения к Kubernetes-кластеру понадобится kubeconfig в секрете репозитория.
Такой доступ стоит ограничить одним namespace через RBAC. Production-деплой лучше запускать только из protected-ветки и через environment с ручным подтверждением. Токен сервисного аккаунта нужно регулярно ротировать: он действует, пока его не отзовут.
kubectl apply завершается с нулевым кодом сразу после записи объекта в Kubernetes API. В этот момент поды могут ещё не создаться, образ — не скачаться, а readiness-проба — не начать отвечать. Поэтому успешное завершение джобы говорит только о том, что кластер принял новую конфигурацию, но не подтверждает запуск приложения.
Готовность проверяют отдельным шагом:
kubectl rollout status deployment/<name> -n <namespace> --timeout=<время>
Команда ждёт завершения выката и возвращает ошибку, если Deployment не достиг нужного состояния за заданное время. При деплое через Helm ту же проверку выполняет helm upgrade --wait --timeout <время>. Параметр --timeout по умолчанию равен 300 секундам и в Helm 3, и в Helm 4.
Со стороны кластера за зависший выкат отвечает progressDeadlineSeconds в спецификации Deployment. По умолчанию он равен 600 секундам. Если за это время Deployment не продвинулся, контроллер выставит состояние ProgressDeadlineExceeded, а kubectl rollout status завершится с ошибкой.
Для stateful-нагрузок таймаут лучше увеличить. PVC привязывает под к постоянному тому, а StatefulSet пересоздаёт поды последовательно, сохраняя за ними те же диски. Пяти минут, которых часто хватает stateless-сервису, базе данных с большим томом может не хватить.
Многие русскоязычные инструкции рассчитаны на Helm 3. В Helm 4 часть синтаксиса изменилась.
| Флаг | Helm 3, ветка release-3.21 | Helm 4, main |
| --atomic | Откатывает изменения при неудачном upgrade, автоматически включает --wait | Помечен как deprecated, вместо него рекомендуют --rollback-on-failure |
| --rollback-on-failure | Нет | Новый флаг, откатывает релиз к предыдущей успешной версии. Для --wait по умолчанию используется стратегия watcher |
| --wait | Булев флаг | Флаг-стратегия |
| --timeout | 300 секунд | 300 секунд |
| --cleanup-on-fail | Есть | Есть |
kubectl apply подтверждает, что Kubernetes API принял новую версию объекта. На этом работа CI-джобы может закончиться, хотя кластер ещё только создаёт поды, скачивает образ и ждёт readiness-пробу. Если образ недоступен, не хватает ресурсов или приложение не проходит проверку готовности, сам apply об этом не сообщит.
После деплоя стоит дождаться результата выката:
kubectl rollout status deployment/<name> -n <namespace> --timeout=<время>
Команда вернёт ошибку, если Deployment не достигнет нужного состояния за отведённое время. При работе через Helm ту же проверку добавляют к helm upgrade флагами --wait и --timeout. По умолчанию Helm ждёт 300 секунд независимо от ветки, Helm 3 или Helm 4.
У Deployment есть и собственный предохранитель — progressDeadlineSeconds. Его значение по умолчанию равно 600 секундам. Если за этот срок выкат не продвинется, контроллер укажет в статусе ProgressDeadlineExceeded, а kubectl rollout status завершится с ошибкой.
Для StatefulSet таймаут обычно нужен больше. Такие поды запускаются по очереди и сохраняют привязку к своим PVC. Базе данных с большим томом может потребоваться больше пяти минут на остановку, подключение диска и запуск, тогда как stateless-сервис за это время уже успеет обновиться.
kubectl apply заканчивает работу, когда Kubernetes API принял обновлённый объект. Дальше кластеру ещё нужно создать новые поды, скачать образ и дождаться успешного прохождения readiness-пробы. Если образ недоступен, на узлах не хватает ресурсов или приложение не проходит проверку готовности, команда apply этого не покажет.
После применения манифеста в пайплайне нужно проверить, завершился ли выкат:
kubectl rollout status deployment/<name> -n <namespace> --timeout=<время>
Команда ждёт, пока Deployment перейдёт в нужное состояние, и завершится с ошибкой, если этого не произойдёт за указанный срок. При деплое через Helm аналогичную проверку включают флагами --wait и --timeout у helm upgrade. По умолчанию Helm ждёт 300 секунд как в Helm 3, так и в Helm 4.
У Deployment есть собственный таймаут — progressDeadlineSeconds. По умолчанию он равен 600 секундам. Если за это время выкат не продвинется, контроллер запишет в статус ProgressDeadlineExceeded, а kubectl rollout status вернёт ошибку.
Для StatefulSet таймаут обычно увеличивают. Подам нужно завершаться и запускаться по очереди, при этом каждый сохраняет привязку к своему PVC. Базе данных с большим томом может потребоваться больше пяти минут на остановку, подключение диска и запуск. Stateless-сервис за это время часто успевает обновиться.
# rbac-deploy.yaml — минимальные права деплой-аккаунта в namespace prod apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ci-deployer namespace: prod rules: - apiGroups: ["apps"] resources: ["deployments", "statefulsets", "daemonsets"] verbs: ["get", "list", "watch", "patch", "update"] - apiGroups: ["apps"] resources: ["deployments/status", "statefulsets/status"] verbs: ["get"] - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ci-deployer namespace: prod subjects: - kind: ServiceAccount name: ci-deployer namespace: prod roleRef: kind: Role name: ci-deployer apiGroup: rbac.authorization.k8s.io
В этой Role нет прав на secrets, создание и удаление namespace, а также create для Deployment.
Утёкший токен не даст прочитать Secret или создать новый namespace. С ним можно только обновить образ в уже существующих workload. Это всё равно инцидент, но доступ ограничен одним namespace и не позволяет менять инфраструктуру кластера.
Набор прав рассчитан на выкат через kubectl set image.
Helm 3 хранит сведения о релизах в Secret целевого namespace. Для helm upgrade --install роли понадобятся права на secrets: get, list, create, update. Также нужны права на создание ресурсов, описанных в Helm-чарте.
В GitLab с версии 18.3 переменные по умолчанию имеют видимость Masked. Раньше использовалась Visible.
Режим Masked and hidden, в котором значение нельзя посмотреть после сохранения, доступен:
Protected-переменные передаются только джобам, запущенным из protected-веток и тегов. Все переменные с чувствительными данными должны маскироваться в логах.
В GitHub Actions аналогичную роль выполняют environments. Правила защиты environment позволяют вручную подтверждать production-деплой. В workflow выше джоба deploy использует:
environment: production
Kubeconfig и values.yaml с паролями не должны попадать в репозиторий. Секреты также не стоит выводить в лог джобы, например включать set -x или выполнять во время отладки kubectl get secret -o yaml.
В 2025 году в публичных коммитах GitHub обнаружили 28 649 024 новых секрета — на 34% больше, чем годом ранее.
Секреты в Kubernetes требуют отдельной настройки. Стандартный объект Secret хранится в etcd в Base64: это кодирование, а не шифрование. Шифрование данных at rest по умолчанию выключено.
В управляемом кластере часть конвейера уже подготовлена, но перед внедрением стоит проверить возможности и ограничения сервиса.
На 12 августа 2026 года в Cloud Containers доступны Kubernetes 1.34.2, 1.33.3, 1.32.1 и 1.31.4.
Новая версия появляется в сервисе примерно через месяц после официального upstream-релиза и поддерживается 14 месяцев с даты добавления. За 30 дней до окончания поддержки приходит уведомление на email и в центр уведомлений.
Версии 1.31 и 1.32 ещё доступны при создании кластера, но их поддержка в сервисе уже закончилась:
Upstream прекратил поддержку раньше: Kubernetes 1.31 — в ноябре 2025 года, Kubernetes 1.32 — в феврале 2026 года.
Если важны актуальные исправления CVE в Kubernetes, переход на 1.33 или 1.34 стоит запланировать до окончания поддержки со стороны вендора.
В кластер можно установить подготовленные аддоны. Для CI/CD пригодятся:
Список аддонов и их параметры приведены в документации VK Cloud.
При планировании учитывайте три ограничения:
Для автоматизации в Cloud Containers используют kubeconfig сервисного аккаунта. В GitLab его сохраняют как CI/CD-переменную типа File, в GitHub Actions — как секрет репозитория.
GitLab agent можно развернуть в кластере как обычную рабочую нагрузку. Перед внедрением в production стоит проверить этот сценарий на тестовом окружении.
Федерация удостоверений в IAM VK Cloud предназначена для SAML 2.0 и входа пользователей в личный кабинет. Сценарий доступа GitHub Actions к Kubernetes-кластеру через OIDC в документации не описан, поэтому для такого деплоя нужен kubeconfig в секрете репозитория.
На одном узле может работать до 110 подов, но для сохранения производительности лучше планировать 30–40 подов на узел. В одном кластере допускается до 50 000 подов, а объём базы etcd ограничен 6 ГБ.
Отдельно тарифицируются диски постоянных томов в кластерах второго поколения, сервисные балансировщики и Floating IP.
Входящий и исходящий трафик, а также мониторинг не тарифицируются. Расходы на master- и worker-узлы отображаются раздельно.
GitLab agent for Kubernetes создаёт отдельный контекст для каждого кластера. Kubeconfig передаётся в джобу автоматически через переменную $KUBECONFIG, а доступ ограничивается списком проектов и групп — до 500 каждого типа.
Поддерживаются impersonation и ограничения по protected-веткам.
Сертификатную интеграцию объявили устаревшей в GitLab 14.5. В GitLab Self-Managed 17.0 и новее она выключена по умолчанию, а на GitLab.com недоступна новым пользователям.
Без внешнего IAM с федерацией удостоверений — никак.
GitHub Actions OIDC выдаёт короткоживущий токен облачному провайдеру, если на стороне провайдера настроено доверие. Для доступа к произвольному Kubernetes-кластеру нужен kubeconfig в секрете репозитория.
Риск снижают минимальным RBAC в одном namespace, environments с ручным подтверждением production-деплоя и регулярной ротацией токена сервисного аккаунта.
kubectl apply сообщает об успехе сразу после записи объекта в Kubernetes API. В этот момент поды могут ещё не запуститься.
Готовность нужно ждать отдельным шагом:
kubectl rollout status
или:
helm upgrade --wait
Дополнительную страховку даёт progressDeadlineSeconds в Deployment. По умолчанию он равен 600 секундам. После его истечения Deployment получает состояние ProgressDeadlineExceeded.
Да, если используется оригинальный kaniko.
Репозиторий GoogleContainerTools/kaniko архивирован, последняя версия — v1.24.0, поэтому уязвимости в нём больше не исправляются.
Рабочих вариантов два:
BuildKit умеет собирать образы в rootless-режиме, поэтому аргумент «kaniko не требует привилегий» больше не уникален.
На 12 августа 2026 года в VK Cloud Cloud Containers доступны Kubernetes 1.34.2, 1.33.3, 1.32.1 и 1.31.4.
Новые версии добавляются примерно через месяц после upstream-релиза. Каждая поддерживается 14 месяцев с даты появления в сервисе. За 30 дней до завершения поддержки VK Cloud отправляет уведомление на email и в центр уведомлений.
При настройке CI/CD для Kubernetes сначала определяют, кто и откуда будет обращаться к Kubernetes API. В push-модели доступы хранятся в CI-системе, в pull-модели остаются у контроллера внутри кластера. От этого выбора зависят схема хранения kubeconfig, права деплой-аккаунта и порядок диагностики проблем.
Образ лучше привязывать к SHA коммита или digest, а не к :latest: так проще понять, какая версия работает в кластере, и откатиться на предыдущую. После kubectl apply пайплайн должен дождаться результата через kubectl rollout status, а у Deployment стоит оставить подходящее progressDeadlineSeconds. Иначе джоба завершится успешно в момент, когда приложение ещё не запустилось или уже не может пройти readiness-пробу.
У сервисного аккаунта должны быть только те права, которые нужны для выката в конкретный namespace. При утечке kubeconfig именно RBAC определит, что сможет сделать тот, кто получит токен. Перед следующим релизом проверьте, ждёт ли пайплайн готовности приложения, умеет ли откатывать неудачный выкат, где хранится kubeconfig и ограничен ли production-деплой protected-веткой или правилами environment.

Argo CD, Docker Registry и cert-manager — одним аддоном каждый
Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

Будем держать в курсе новостей и облачных трендов




