В Сети довольно мало хороших рабочих примеров, на которые можно опираться и строить собственные решения. Данная статья основана на статье из блога компании Nortal, и предназначена для небольших проектов и команд, т.к основной акцент сделан на Application.
Теоретическая часть
Общая концепция
В документации ArgoCD предлагается использовать декларативную установку, что позволяет в явном виде определять необходимые настройки. В данную установку можно также включить создание Application, посредством которых реализовать подход app of app. Концепция получаются следующей: при установке ArgoCD, создаётся несколько ресурсов Application, которые опираются на Git-репозиторий. В свою очередь, Git-репозиторий содержит: чарт генерирующий Application для кастомных приложений, исходный чарт для кастомных приложений, и чарт для развёртывания инфраструктурных приложений.
Концепция развёртывания инфраструктурных приложений
Здесь используется infra chart, который будет:
Автоматически генерировать Application из общего шаблона
В шаблон подставлять значения из свойств applications, в котором вложенный массив объектов
Концепция развёртывания кастомных приложений
Здесь используются common и apps чарты. В apps чарте будет:
Автоматическая генерация Application из общего шаблона
В шаблон подставляться значения из свойств applications, в котором вложенный массив объектов
Основной шаблон ссылается на common чарт
В common чарте будут общие шаблоны для ресурсов: Deploymen, Ingress, Service, etc. А также будут директории с файлами, содержащие параметры под каждое приложение и его отдельное окружение.
Практическая часть
Настройка argocd-server
В параметры официального чарта в секции server, необходимо добавить приложение apps, которое будет являться родительским app of app, и будет создавать дочерние Application для кастомных приложений. Для удобства и логического разделения, также будет добавлено приложение с назваием infra, из которого будет развёртывание инфраструктурных приложений. Пример необходимых настроек:
# -- Deploy ArgoCD Applications within this helm release
# @default -- `[]` (See [values.yaml])
## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/
additionalApplications:
- name: apps
namespace: argocd
additionalLabels: {}
additionalAnnotations: {}
project: default
source:
repoURL: https://github.com/dmitrii-dmnk/argocd-working-example.git
targetRevision: master
path: apps
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
- name: infra
namespace: argocd
additionalLabels: {}
additionalAnnotations: {}
project: default
source:
repoURL: https://github.com/dmitrii-dmnk/argocd-working-example.git
targetRevision: master
path: infra
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Вышеописанные настройки собраны в одном файле argrocd.yaml, и доступны на github.
Решения для развёртывания кастомных приложений
Для развёртывания кастомных приложений, требуются чарты apps и common. В чарте apps идёт генерация Application из общего шаблона. Отдельно стоит отметить, что в блоге компании Nortal, предлагается вариант параметризировать приложение непосредственно в чарте apps. В текущих рабочих условиях данный подход оказался избыточным, и проще было вынести все настраиваемые параметры в одноимённые values-файлы в common чарте.
Пример шаблона из чарта apps
Шаблон для кастомных Application выглядит следующим образом:
{{ $targetRevision := .Values.targetRevision }}
{{ $repoURL := .Values.repoURL }}
{{ $project_name := .Values.project_name }}
{{- range $application := .Values.applications }}
{{- range $namespace := $application.namespaces }}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ $application.name }}-{{ $namespace }}
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: {{ $namespace }}
server: https://kubernetes.default.svc
project: {{ $project_name }}
source:
path: common
repoURL: {{ $repoURL }}
targetRevision: {{ $targetRevision }}
helm:
valueFiles:
- values.yaml
- values/{{ $application.name }}.yaml
- values/{{ $namespace }}/{{ $application.name }}.yaml
syncPolicy:
automated:
prune: true
selfHeal: true
---
{{- end }}
{{- end }}
В values.yaml в свойствах applications находится вложенный массив объектов, который выглядит следующим образом:
applications:
- name: guestbook
namespaces: [develop,test]
- name: hello-kubernetes
namespaces: [develop,test]
- name: static
namespaces: [develop,test]
В разных рабочих кейсах нужны разные подходы, поэтому в common чарте для демонстрации будет показан практически без изменений дефолтный генерируемый helm чарт. Отдельно был добавлен параметр с установкой порта контейнера.
Решения для развёртывания инфраструктурных приложений
Существует несколько вариантов параметризации развёртываемого приложения из сторонних и официальных чартов, а именно:
Поместить настройки через мультилайн
spec.source.helm.values: |
все необходимые настройки
Минусы данного подхода: нет возможности шаблонизировать Application, некоторые параметры могут содержать двойные фигурные скобки, которые будут вызывать подобные ошибки:
Error: template: infra/templates/argocd.yaml:2304:63: executing "infra/templates/argocd.yaml" at <.app.metadata.name>: nil pointer evaluating interface {}.metadata
Загружать целиком содержимое из отдельного файла в переменную
spec.source.helm.values: |
{{ $valueFileContent }}
При таком подходе не будет ошибок при наличии двойных фигурных скобок. Также будет проще редактировать параметры приложения, т.к не будет ломаться подсветка синтаксиса в редакторе, не будет лишних отступов, появляется возможность шаблонизировать.
Пример шаблона из чарта infra
Шаблон для инфраструктурных Application выглядит следующим образом:
{{- range $application := .Values.applications }}
{{ $valueFilePath := print "values/" $application.name ".yaml" }}
{{ $valueFileContent := $.Files.Get $valueFilePath | nindent 8 }}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ $application.name }}
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
server: https://kubernetes.default.svc
namespace: {{ $application.namespace }}
project: {{ $application.project | default "default" }}
syncPolicy:
automated:
prune: true
selfHeal: true
source:
path: ''
repoURL: {{ $application.repoURL }}
targetRevision: {{ $application.targetRevision }}
chart: {{ $application.chart }}
helm:
values: |
{{ $valueFileContent }}
---
{{- end }}
В values.yaml в свойствах applications находится вложенный массив объектов, выглядит следующим образом:
applications:
- name: argocd
namespace: argocd
chart: argo-cd
targetRevision: 3.33.6
repoURL: https://argoproj.github.io/argo-helm
- name: cert-manager
namespace: infra
chart: cert-manager
targetRevision: v1.8.0
repoURL: https://charts.jetstack.io
- name: tomcat
namespace: infra
chart: tomcat
targetRevision: 10.3.9
repoURL: https://charts.bitnami.com/bitnami
Применение вышеописанных настроек
В демонстративных целях можно воспользоваться готовой конфигурацией argocd.yaml, и выполнить развертывание ArgoCD, в minikube.
Клонируем репозиторий с настройками, и запускаем установочный скрипт:
git clone git@github.com:dmitrii-dmnk/argocd-working-example.git;
cd argocd-working-example/helpers;
sh setup.sh
На этом этапе необходимые настройки завершены. Все приложения автоматически развернутся, т.к они были описаны заранее.
Заключение
Возможности Helm хорошо сочетаются с развёртыванием приложений через создание Application. Гибкость шаблонизации позволяет решать рабочие задачи достаточно практично. Рекомендации и описания решений выше были получены в ходе практического использования ArgoCD. Приветствуются: критика, пожелания, предложения.