ADG Оставить заявку
Блог DevOps 5 мин чтения

GitOps на отечественных рельсах: Argo CD с GitFlic Registry без GitHub

Переносим GitOps-пайплайн Argo CD на GitFlic Registry в изолированном контуре: настраиваем image updater и webhook-интеграцию без привязки к внешним сервисам.

Контекст момента

GitFlic и Сфера Репозиторий наращивают функциональность CI/CD для изолированных контуров в 2025

GitFlic в этом году добавил container registry как полноценную составляющую платформы, а не просто прикрученный сбоку сервис. Сфера Репозиторий движется в похожем направлении - оба продукта наращивают CI/CD-функциональность для контуров без выхода в интернет. У нас как раз был повод проверить это в деле: клиент с кластером Kubernetes в изолированном сегменте захотел построить нормальный GitOps-пайплайн через Argo CD, не завязанный на GitHub или Docker Hub.

Задача звучала просто: сборка образа в GitFlic CI, пуш в GitFlic Registry, автоматическое обновление манифестов Argo CD и деплой в кластер. Без единого обращения во внешний интернет. На практике - несколько неожиданностей, о которых ниже.

Как вообще устроен image updater в Argo CD

Argo CD Image Updater - отдельный контроллер, который следит за новыми тегами образов в реестре и автоматически обновляет манифесты в Git (или прямо в кластере, если работать без Git-write-back). Классическая схема: пайплайн собрал и запушил новый образ, image updater это заметил, обновил values.yaml или аннотацию в ArgoCD Application, Argo CD синхронизировал кластер.

Штука рабочая, когда реестр - Docker Hub или GHCR. С отечественными реестрами надо чуть больше поковыряться.

Настройка GitFlic Registry как источника образов

GitFlic Registry поддерживает Docker Registry HTTP API v2 - это хорошая новость, потому что image updater работает именно с этим протоколом. Достаточно добавить реестр в конфигурацию контроллера:

registries:
  - name: gitflic-registry
    prefix: registry.gitflic.space
    api_url: https://registry.gitflic.space
    credentials: pullsecret:argocd/gitflic-registry-creds
    defaultns: your-org
    insecure: false

Credentials - это обычный Kubernetes Secret с .dockerconfigjson. GitFlic использует стандартные токены доступа (deploy tokens или personal access tokens), механика та же что у GitLab.

Первый сюрприз: image updater по умолчанию использует latest-стратегию или semver. Если тег формируется по схеме branch-commitsha (а GitFlic CI так делает из коробки), нужно прописать явную стратегию в аннотациях Application:

annotations:
  argocd-image-updater.argoproj.io/image-list: app=registry.gitflic.space/your-org/your-app
  argocd-image-updater.argoproj.io/app.update-strategy: newest-build
  argocd-image-updater.argoproj.io/app.tag-match: ^main-[a-f0-9]{8}$

newest-build смотрит на дату создания тега, tag-match фильтрует по регулярке. Без фильтра image updater может подхватить тег из другой ветки.

Webhook вместо polling

По умолчанию image updater ходит в реестр каждые 2 минуты и проверяет новые теги. Для изолированного контура это нормально, но задержка в 2 минуты может раздражать. GitFlic Registry поддерживает webhook при пуше образа - можно сделать почти мгновенное обновление.

Webhook в GitFlic настраивается через настройки репозитория (не организации), что немного неочевидно. Endpoint у image updater стандартный: /api/v1/webhook. Нужен соответствующий Ingress или Service типа LoadBalancer - в изолированном контуре обычно достаточно ClusterIP с проксированием через ingress внутри кластера.

# argocd-image-updater-config ConfigMap
data:
  webhook.enable: "true"
# argocd-image-updater-secret Secret
stringData:
  webhook.gitflic-secret: "<random-token>"

Webhook-секрет генерируем случайно, прописываем и в GitFlic, и в секрет. Проверка подписи работает стандартно через HMAC-SHA256.

Второй сюрприз: GitFlic отправляет webhook-payload в формате, близком к GitLab, но не идентичном ему. Image updater умеет парсить Docker Hub и GHCR webhook-форматы, а для GitFlic пришлось посмотреть в логи и убедиться, что payload всё-таки разбирается корректно. В нашем случае разобрался - image updater увидел repository.full_name и правильно сопоставил с конфигом. Но без проверки логов мы бы не были уверены.

Write-back: обновление манифестов в GitFlic

Image updater умеет писать изменения обратно в Git (write-back mode). Это означает, что при появлении нового тега он создаёт коммит в репозитории манифестов с обновлённым тегом образа. Argo CD затем видит коммит и синхронизирует.

Для write-back нужен SSH-ключ или токен с правом на push в репозиторий манифестов в GitFlic. Мы использовали deploy token с правом write_repository:

apiVersion: v1
kind: Secret
metadata:
  name: argocd-image-updater-gitcreds
  namespace: argocd
stringData:
  username: "image-updater-bot"
  password: "<gitflic-deploy-token>"

Аннотация в Application:

argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/argocd-image-updater-gitcreds
argocd-image-updater.argoproj.io/git-branch: main

Write-back работает через .argocd-source-<appname>.yaml - image updater создаёт или обновляет этот файл рядом с основным Application-манифестом. Argo CD подхватывает его автоматически. Подход немного магический с первого взгляда, но логичный: все изменения трекаются в Git, история образов не теряется.

Что в итоге получилось

Схема полностью работает в изолированном контуре:

  • GitFlic CI собирает образ и пушит в GitFlic Registry с тегом main-{sha8}
  • Webhook уведомляет image updater в течение нескольких секунд
  • Image updater обновляет манифест в репозитории GitFlic и делает коммит
  • Argo CD видит новый коммит, синхронизирует кластер

Полный цикл от пуша кода до обновления в кластере - около 2-3 минут, из которых большую часть занимает сама сборка. Это нормально.

Что не заработало сразу: image updater иногда теряет связь с webhook-эндпоинтом при рестарте пода и не переподписывается автоматически. Пришлось добавить liveness-проверку с принудительным рестартом, если webhook-соединение не восстанавливается за 5 минут. Это похоже на известный issue в upstream, который ещё не закрыт.

Сфера Репозиторий мы в этом проекте не трогали - клиент уже сидит на GitFlic и менять реестр смысла нет. Но по документации Сферы webhook-интеграция устроена похоже, и проблем с Docker Registry v2 совместимостью там тоже не должно быть.

Весь этот пайплайн живёт в рамках managed-сопровождения инфраструктуры - там же разбираемся с обновлением самого Argo CD и image updater между версиями, что тоже иногда требует внимания при смене API аннотаций.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.