Приветствую! Меня зовут Ксения, и я — DevOps инженер компании Smartex. 

Я люблю создавать инфраструктуру и процессы, которые помогают разработчикам и операционной команде быть более эффективными и продуктивными. 

Если ваша повседневная рутина связана с множеством однотипных микросервисов и разнообразными средами, данная информация может быть для вас полезна. Материал рассчитан на Junior+ и Middle DevOps специалистов.

Кейс

К нам обратился клиент, проект которого связан с работой кассовых систем сети супермаркетов, управлением списком товаров, ценами и другими данными. Перед нашей DevOps-командой была поставлена задача — помочь в миграции монолитного приложения из собственной инфраструктуры без контейнеризации в Kubernetes в публичном облаке, с созданием трех окружений — для разработки, для тестирования и для production. Приложение переписывалось на микросервисную архитектуру. Для экономии ресурсов клиента и максимального облегчения жизни разработчиков, мы должны были создать инфраструктуру, в которой разработчики могут сами, используя документацию, развернуть любое количество микросервисов, и в production, и в development-окружении. То есть, по сути создание новых приложений должно происходить с минимальным участием DevOps. 

К моменту старта проекта уже было подготовлено несколько микросервисов. Используя Terraform, мы успешно настроили всю необходимую инфраструктуру, включая виртуальную сеть, подсеть, управляемый кластер Kubernetes, управляемую базу данных PostgreSQL и управляемый инструмент для хранения секретов. Также при помощи Terraform мы развернули веб-сервер Nginx Ingress и  Argo CD. Все сервисы и микросервисы нашего приложения, включая служебные Helm-чарты, разворачиваются через Argo CD. Но мы столкнулись с рядом недочетов, которые хотелось устранить до запуска production окружения.

Вот какой технический стек мы использовали

  1. Сетап микросервисов выполнен через Argo CD с применением подхода "App of Apps". Концепция "App of Apps" (приложение приложений) в Argo CD — это способ организации и управления несколькими приложениями Kubernetes через одно приложение, которое называется "App of Apps".

    "App of Apps" в Argo CD
    "App of Apps" в Argo CD
  1. Мы создали 3 App of Apps, по одному для каждого окружения. Для каждого Application в Argo CD настроили Automated Sync Policy.

    Данный механизм позволяет автоматически синхронизировать состояние приложений с их желаемым состоянием в Git-репозитории. Таким образом триггером для запуска синхронизации является коммит в Git-репозиторий Helm-чартов, который указан в качестве source для приложения.

  1. Для каждого микросервиса создали отдельный Helm-чарт с одинаковыми шаблонами. Для Helm-чартов добавили values для 3 окружений — development, preproduction (тестовый) и production. При этом на все 3 окружения — одна ветка. Вот как на этом шаге выглядит структура Git-репозитория с шаблонами Helm-чартов:

    Структура Git-репозитория с  Helm-чартами
    Структура Git-репозитория с Helm-чартами

Запустив development-окружение, мы столкнулись со следующими проблемами:

  1. Неудобство администрирования. Без централизованного управления одинаковыми шаблонами для Helm-чартов возрастает риск возникновения ошибок. Мы копировали с места на место шаблоны, делали множество правок в каждой копии. Это вело к ошибкам. 

  2. Приходилось создавать branch для каждого окружения, так как Automated Sync Policy в Argo CD для production может привести к выкатке некорректного темплейта. Либо же требовалось создавать отдельные директории для каждого окружения. Такой объем работы не соответствовал изначально выбранной концепции.

  3. Не соблюдается версионирование чартов, вернее версия указывалась вручную, а значит никто этого толком не делал. Работающее разделение чартов по версиям упрощает управление жизненным циклом.

Инфраструктура соответствовала требованиям разработчиков, но администрирование Helm- чартов — тяжелая ручная задача. Поэтому мы решили, что на проекте необходим чарт-репозиторий. Специализированные чарт-репозитории предназначены для решения проблем с версионированием. Наш выбор пал на ChartMuseum.

ChartMuseum — хранилище Helm-чартов, использование которого дает ряд значительных преимуществ в управлении и развертывании приложений с использованием Helm-чартов. Ключевыми преимуществами для нас были:

  • ChartMuseum обеспечивает локальное хранение Helm-чартов, что дает командам полный контроль над репозиториями чартов и возможность управлять ими в пределах собственной инфраструктуры. Репозиторий хранится прямо внутри кластера, администрируется вместе с его инфраструктурой и всегда под рукой.

  • ChartMuseum позволяет гибко управлять версиями, обновлениями и релизами Helm-чартов. 

  • Гибкие механизмы аутентификации и авторизации дают контролировать доступ к репозиториям и чартам, поддерживая безопасность работы с ними.

Для такого решения выполнили следующие шаги:

  1. Развернули ChartMuseum.

  2. Создали директорию с новым Helm-чартом,  который будет служить источником для всех микросервисов. Мы назвали его library-chart.

  3. Запушили library-chart в ChartMuseum.

    helm package library-chart -d library-chart/
    cd library-chart && curl --data-binary "@library-1.0.11.tgz"  https:/my-chart-museum/api/charts
  4. Далее корректируем версию в Chart.yaml для микросервисов, которые переводим на новую версию чарта. После каждого изменения обновляем для них dependency:

    apiVersion: v2
    appVersion: 1.0.11
    description: Chart for publishing microservice1 to Kubernetes
    name: microservice1
    type: application
    version: 1.0.11
    dependencies:
    - name: library
      version: "1.0.11"
      repository: https://my-chart-museum
    helm dependency update

    Данное решение относительно распространено, но для нас закрывает исключительно проблему отсутствия версионирования. У темплейтов теперь есть централизованный источник, но появляются дополнительные шаги при администрировании.

    Структура Git-репозитория при применении ChartMuseum
    Структура Git-репозитория при применении ChartMuseum

Поэтому мы пришли к решению — применить Multiple Sources for an Application + ChartMuseum, при котором данные для настройки Argo CD-приложения получаются из нескольких источников. Argo CD напрямую обращается к ChartMuseum, директория charts исчезает из Git-репозитория. 

Такая «фича» появилась в Argo CD 2.6. На момент написания статьи этот функционал все еще помечен как Beta Feature.

Примеры использования «фичи» Multiple sources for an Application:

  • Объединение ресурсов из разных репозиториев для приложений на основе микросервисов.

  • Управление общими библиотеками или общими ресурсами между несколькими командами или репозиториями.

  • Объединение ресурсов из разных веток Git-репозитория для тестирования или экспериментов.

  • Управление ресурсами для разных сред (например, development, preproduction и production) в отдельных Git-репозиториях.

  •  Указание файлов значений Helm из внешнего Git-репозитория — в ChartMuseum находится Helm, а в git-репозитории — values*.yaml.

Манифест для приложения в Argo CD выглядит следующим образом:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: microcervice1
  namespace: argocd
spec:
  project: default
  sources:
    - repoURL: 'https://my-chart-museum/'
      chart: library
      targetRevision: 1.0.11
      helm:
        valueFiles:
          - $values/myproject/helm/microservice1/values.yaml
          - $values/myproject/helm/microservice2/values-production.yaml
    - repoURL: 'https://my-gitlab.com/active/my_repo.git'
      targetRevision: master
      ref: values
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: mynamespace
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
    automated:
      selfHeal: true

$values тег ссылается на корневую директорию репозитория my_repo, на который указывает ключ ref в списке источников. Переменная $values может быть указана только в начале пути к файлу значений. Соответственно, my_repo выступает в роли источника values-файлов для микросервисов. 

Структура становится чище и понятней, править нужно только library-chart, появляется единая точка входа конфигураций:

Структура Git-репозитория при применении Multiple Sources for an Application + ChartMuseum
Структура Git-репозитория при применении Multiple Sources for an Application + ChartMuseum

Вот как происходит изменение версии Helm-чарта в нашей текущей реализации:

  1. После изменения темплейтов фиксируем новую версию в Chart.yaml и пушим в ChartMuseum:

    helm package library-chart -d library-chart/
    cd library-chart && curl --data-binary "@library-1.0.12.tgz"  https:/my-chart-museum/api/charts

    Мы выполняли этот шаг вручную, так как после запуска инфраструктуры такие изменения сразу же стали крайне редки. Но этот шаг легко автоматизировать через CI/CD по коммиту.

  2. Корректируем версию в манифесте приложения:

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: microcervice1
      namespace: argocd
    spec:
      project: default
      sources:
        - repoURL: 'https://my-chart-museum/'
          chart: library
          targetRevision: 1.0.12
    
  3. После выполнения Auto-sync в Argo CD происходит деплой новой версии чарта.

На какие особенности стоит обратить внимание

  1. Параметры приложения не получится проверить и поправить через Argo CD. Для кого-то отсутствие такой возможности является большим минусом. Для нас это скорей плюс, так как даже если руки чешутся поправить параметры через Argo CD, сделать это не получится. Для концепции GitOps такая особенность — большое преимущество, так как единственным источником параметров будет служить Git-репозиторий.

    Отображение параметров приложения в Argo CD
    Отображение параметров приложения в Argo CD
  2. Нет возможности сделать Rollback через UI Argo CD - “Rollback is not supported for apps with multiple sources”. В нашем случае это не проблема, так как мы применяем Argo Rollout c blue-green deployment. Трафик переключается на под только после прохождения анализа. Но для многих отсутствие данной возможности может быть критично. На исправление данного ограничения открыт pull request.

Итак. Какие преимущества мы получили

  1. Ускорился процесс добавления нового микросервиса. Со стороны Git-репозитория добавляется директория микросервиса и values файлы для 3 окружений, а также добавляется манифест приложения Argo CD для каждого окружения. Для всех окружений в качестве источника выступает master branch. 

  2. Значительно упрощается процесс администрирования Helm-чартов. При этом нет необходимости в разнесении Helm-для различных окружений по отдельным веткам либо директориям.

  3. Снизилась вероятность возникновения ошибки при изменениях в Helm-чартах.

Применение решения Multiple sources Argo CD + ChartMuseum для управления микросервисами на нашем проекте помогло оптимизировать процессы разработки, снизить расходы времени и риски возникновения ошибок в конфигурации.

Разработчики получили возможность добавлять новые микросервисы, не привлекая DevOps и с низкими шансами на ошибку, что соответствует основному требованию проекта.

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


  1. vasyakrg
    15.04.2024 15:39

    К слову, в аппликациях где ресурсом выступает чарт, не обязательно указывать /values.yaml, достаточно только овверрайдов. Дефолтные переменные читаются первыми и автоматом.


    1. kuksepa Автор
      15.04.2024 15:39

      Спасибо за комментарий! Решение сработает, если рядом с чартом лежит файл с переменными, но в нашем случае это не так, поскольку переменные не шарятся. В values.yaml мы указываем общие параметры для всех окружений, которые при этом отличаются для разных микросервисов.