Print this page

CI/CD и Secret Management через Vault

08 October 2025

GitLab CI/CD + Kubernetes + Vault = Автоматизация

Когда у тебя уже есть Docker/Kubernetes инфраструктура, следующий шаг — автоматизировать всё это. GitLab CI/CD позволяет:

  • Автоматически собирать образы при каждом коммите
  • Публиковать их в GitLab Container Registry
  • Деплоить в Kubernetes без ручных команд
  • Получать секреты из Vault на этапе сборки и деплоя

1. Подготовка GitLab проекта

У тебя должен быть проект в GitLab с подключённым Container Registry (включается в Settings → Packages & Registries → Container Registry).

# Локальная аутентификация
docker login registry.gitlab.com

# Пример тега и пуша образа
docker build -t registry.gitlab.com/<group>/<project>/php-app:latest .
docker push registry.gitlab.com/<group>/<project>/php-app:latest

Далее все сборки и пуши будут выполняться автоматически через .gitlab-ci.yml.


2. Настройка GitLab Runner

Для выполнения CI/CD pipeline нужен GitLab Runner. Его можно:

  • Развернуть как контейнер в k8s (рекомендуется)
  • Установить на отдельный сервер
# Установка runner в Kubernetes
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm upgrade --install gitlab-runner gitlab/gitlab-runner \
  --namespace gitlab-runner --create-namespace \
  --set gitlabUrl="https://gitlab.com/" \
  --set runnerRegistrationToken="<YOUR_TOKEN>" \
  --set rbac.create=true

После этого Runner автоматически появится в разделе CI/CD → Runners в GitLab.


3. Пример .gitlab-ci.yml

Файл .gitlab-ci.yml лежит в корне репозитория и описывает pipeline.

stages:
  - build
  - push
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

before_script:
  - echo $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY

build:
  stage: build
  script:
    - docker build -t $IMAGE_TAG .
  only:
    - main

push:
  stage: push
  script:
    - docker push $IMAGE_TAG
  only:
    - main

deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl config set-cluster k8s --server=$KUBE_SERVER --certificate-authority=/tmp/ca.crt
    - kubectl config set-credentials gitlab --token=$KUBE_TOKEN
    - kubectl config set-context gitlab --cluster=k8s --user=gitlab --namespace=$KUBE_NAMESPACE
    - kubectl config use-context gitlab
    - kubectl set image deployment/php-fpm php-fpm=$IMAGE_TAG
  environment:
    name: production
    url: https://devopz.tech
  only:
    - main

Здесь:

  • Сборка и пуш образа выполняются автоматически при пуше в main
  • Развёртывание выполняется через kubectl set image
  • Доступ к кластеру обеспечивается через переменные окружения GitLab CI (KUBE_SERVER, KUBE_TOKEN, KUBE_NAMESPACE)

4. HashiCorp Vault Integration

Хранить токены и пароли в GitLab переменных — можно, но не идеально. Гораздо круче — интегрировать Vault, чтобы GitLab получал секреты на лету.

Принцип:

  1. Vault хранит все чувствительные данные (пароли БД, API ключи и т.д.)
  2. GitLab Runner аутентифицируется в Vault по токену или JWT
  3. Pipeline получает секреты через vault kv get и экспортирует в переменные

Пример Vault Secret

vault kv put secret/prod/mysql ROOT_PASSWORD=supersecret
vault kv put secret/prod/k8s TOKEN=<KUBE_TOKEN>

Пример использования Vault в pipeline

vault:
  stage: deploy
  image: hashicorp/vault:latest
  script:
    - export VAULT_ADDR=$VAULT_ADDR
    - vault login $VAULT_TOKEN
    - export MYSQL_ROOT_PASSWORD=$(vault kv get -field=ROOT_PASSWORD secret/prod/mysql)
    - export KUBE_TOKEN=$(vault kv get -field=TOKEN secret/prod/k8s)
    - kubectl config set-credentials gitlab --token=$KUBE_TOKEN
    - kubectl set secret generic mysql-secret --from-literal=root-password=$MYSQL_ROOT_PASSWORD --dry-run=client -o yaml | kubectl apply -f -
    - kubectl set image deployment/php-fpm php-fpm=$IMAGE_TAG
  only:
    - main

Таким образом:

  • Секреты живут только в Vault, не в Git
  • GitLab получает их динамически на этапе деплоя
  • Всё логируется и можно применять политики доступа

5. Best Practices для CI/CD + Vault

  • Используй отдельные токены для каждого проекта GitLab
  • Не храни секреты в .gitlab-ci.yml — только переменные или Vault
  • Разделяй среды: dev / stage / prod → отдельные пути в Vault
  • Включи аудит в Vault → следи, кто запрашивает секреты
  • ⏰ Настрой TTL и автоматическую ротацию ключей

Результат

Теперь у тебя:

  • GitLab CI/CD автоматически собирает и пушит образы
  • Kubernetes деплоит их без ручного вмешательства
  • Vault надёжно управляет секретами

Это уже полноценный продакшн-процесс — от коммита до выката в кластер с безопасным хранением секретов.


Бонус: типовые переменные в GitLab CI для деплоя в Kubernetes

Переменная Описание
KUBE_SERVER URL API Kubernetes кластера
KUBE_TOKEN Service Account Token с правами деплоя
KUBE_NAMESPACE Namespace, куда деплоится приложение
VAULT_ADDR Адрес HashiCorp Vault
VAULT_TOKEN Token для аутентификации GitLab Runner в Vault

Вывод

GitLab CI/CD + Kubernetes + Vault — это не просто модно. Это устойчивый, безопасный и масштабируемый pipeline, который позволяет выкатывать фичи в прод за минуты, не раскрывая секретов и не трогая кластер руками.

Следующий шаг автоматизация миграций БД, Blue-Green / Canary деплой, Helm Charts и ArgoCD