ArgoCD

Overview

What Is Argo CD?

Argo CD это декларативная, GitOps CD утилита для Kubernetes

argocd-ui.gif

Why Argo CD?

Описания приложений, конфигурации и окружения должны быть декларативными и находиться под версионным контролем. Деплой приложений и управление их жизненным циклом должны быть автоматизированны, проверяемы и легкими для понимания

Getting Started

Quick Start

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Следуй getting started guide
В дополнение есть user guide
Для обновления есть upgrade guide
И документация для разработчиков, если захочешь сделать какие-то интергации

How it works

Argo CD следует принципам GitOps используя Git как источник истины для определения желаемого состояния приложений. Kubernetes манифесты могут быть описаны следующими образами:

Argo CD автоматизирует деплой до желаемого состояния приложения в указанном окружении. Деплойменты могут отслеживать обновления манифестов в ветках, тэгах или в конкретных коммитах (см. tracking strategies для подробностей)

Architecture

argocd_architecture.png

Argo CD выполнен как Kubernetes контроллер который постоянно отслеживает приложения и сравнивает их текущее состояние с желаемым (которое описано в Git repo). Задеплоенное приложение, состояние которого отличается от желаемого, помечается как OutOfSync. Argo CD показывает различия в состояниях и предоставляет средства для автоматической и ручной синхронизации. Любые изменения в желаемом состоянии (в Git) могут быть автоматически применены

Дополнительные детали можно узнать из architecture overview

Features

Core Concepts

Подразумеваем что ты знаком с концепциями Git, Docker, Kubernetes, CD и GitOps. Ниже концепции специфичные для Argo CD:

Getting Started

1. Install Argo CD

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Эти команды создают новый неймспейс argocd где будет жить Argo CD

Установочный манифест включает ClusterRoleBinding который ссылается на неймспейс argocd. Поэтому если используешь другой неймспейс, то нужно указать его в манифесте

Screenshot_2021_02_02-12_49_03-2022-09-08-at-15crb.png

Если тебе не нужны UI, SSO, multi-cluster, то можно установить только core-компоненты:

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml

Такая дефолтная инсталяция будет иметь самоподписанный сертификат (а не LE) и не будет доступна сразу, нужно сделать одно из дополнительных действий:

При использовании core версии используй argocd login --core для настройки CLI и скипай шаги 3-5

2. Download Argo CD CLI

Скачай нужный бинарь с https://github.com/argoproj/argo-cd/releases/latest
Более детализированные инструкции по установке можно найти в https://argo-cd.readthedocs.io/en/stable/cli_installation/

Под Mac, Linux и WSL можно использовать Homebrew:

brew install argocd

3. Access The Argo CD API Server

По умолчанию Argo CD API сервер не экспозится наружу через какой-либо внешний адрес. Чтобы получить доступ к нему используй одну из следующих техник:

Service Type Load Balancer

Измени тип сервиса argocd-server с ClusterIP на LoadBalancer:

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

(yc-test:default) vandud@macbook: ~ [0] ? kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
service/argocd-server patched

(yc-test:default) vandud@macbook: ~ [0] ? yc load-balancer network-load-balancer list
+----------------------+----------------------------------------------+-------------+----------+----------------+------------------------+--------+
|          ID          |                     NAME                     |  REGION ID  |   TYPE   | LISTENER COUNT | ATTACHED TARGET GROUPS | STATUS |
+----------------------+----------------------------------------------+-------------+----------+----------------+------------------------+--------+
| enpdlstm2kb4dsan9c07 | k8s-92249e6140a0fea320a9088fd76c933dc6cac2f4 | ru-central1 | EXTERNAL |              2 | enpfj6q1vkpcbp8qcdto   | ACTIVE |
+----------------------+----------------------------------------------+-------------+----------+----------------+------------------------+--------+

(yc-test:default) vandud@macbook: ~ [0] ? yc load-balancer network-load-balancer get --id enpdlstm2kb4dsan9c07 --format json | jq '.listeners'
[
  {
    "name": "http",
    "address": "158.160.5.94",
    "port": "80",
    "protocol": "TCP",
    "target_port": "32749",
    "ip_version": "IPV4"
  },
  {
    "name": "https",
    "address": "158.160.5.94",
    "port": "443",
    "protocol": "TCP",
    "target_port": "30809",
    "ip_version": "IPV4"
  }
]

Screenshot_2021_02_02-12_49_03-2022-09-08-at-17service-type-ld.png

Ingress

Следуй инструкции по ингрессу чтобы настроить его

Port Forwarding

port-forwarding может быть использован для коннекта к api серверу без экспозинга его наружу

kubectl port-forward svc/argocd-server -n argocd 8080:443

API сервер будет доступен на https://localhost:8080


(yc-test:default) vandud@macbook: ~ [0] ? kubectl port-forward svc/argocd-server -n argocd 8080:443
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

(yc-test:default) vandud@macbook: ~ [0] ? argocd login localhost:8080
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context 'localhost:8080' updated

(yc-test:default) vandud@macbook: ~ [0] ? argocd cluster list
SERVER                          NAME        VERSION  STATUS   MESSAGE                                                  PROJECT
https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitored.

4. Login Using The CLI

Пароль для пользователя admin генерируется автоматически и хранится в секрете argocd-initial-admin-secret

(yc-test:default) vandud@macbook: ~ [0] ? kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath={.data.password} | base64 -d
LjOCyPoDNuZ0j6Ry

Можно удалить этот секрет после того как изменишь админский пароль. Секрет нужен только для того чтобы ты мог получить автосгенерированный начальный пароль (этот секрет нужен только для отображения автосгенерированного пароля, хэш этого пароля хранится в argocd-secret)


Изменил админский пароль через вебню и argocd-cli отвалился:

(yc-test:default) vandud@macbook: ~ [0] ? argocd cluster list
FATA[0000] Failed to establish connection to localhost:8080: dial tcp [::1]:8080: connect: connection refused

Логинимся с новым паролем:

(yc-test:default) vandud@macbook: ~ [0] ? argocd login localhost:8080
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context 'localhost:8080' updated

О том как сбросить пароль - https://github.com/argoproj/argo-cd/blob/master/docs/faq.md#i-forgot-the-admin-password-how-do-i-reset-it

(yc-test:default) vandud@macbook: ~ [0] ? python3 -c "import bcrypt; print(bcrypt.hashpw(b'newpassword', bcrypt.gensalt()).decode())"
$2b$12$nDQh4.w6Xrn5gKMt1O/AnuKCELoHwj.89TmeWc2ODWcIbYD7m2qbm

(yc-test:default) vandud@macbook: ~ [0] ? kubectl -n argocd patch secret argocd-secret   -p '{"stringData": {
    "admin.password": "$2b$12$nDQh4.w6Xrn5gKMt1O/AnuKCELoHwj.89TmeWc2ODWcIbYD7m2qbm",
    "admin.passwordMtime": "'$(date +%FT%T%Z)'"
  }}'
secret/argocd-secret patched

Еще более простой вариант сброса пароля: удалить из секрета argocd-secret поля admin.password и admin.passwordMtime и рестартануть argocd-server
Он сгенерит новый пароль и положит его в argocd-initial-admin-secret


Далее можно залогиниться в CLI

(yc-test:default) vandud@macbook: ~ [0] ? argocd login 158.160.5.94
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context '158.160.5.94' updated

Если API сервер не доступен напрямую (через Ingress или LB) то можно использовать PortForward. Можно передавать ключ --port-forward-namespace argocd каждой argocd команде или засунуть этот ключ в переменную окружения ARGOCD_OPTS

(yc-test:default) vandud@macbook: ~ [0] ? argocd --port-forward --port-forward-namespace argocd login --username admin --password "$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath={.data.password} | base64 -d)"
'admin:login' logged in successfully
Context 'port-forward' updated

Подкоманда login требует еще и флаг --port-forward, если его не указывать то она будет требовать хостнейм api сервера

(yc-test:default) vandud@macbook: ~ [0] ? export ARGOCD_OPTS='--port-forward-namespace argocd'

(yc-test:default) vandud@macbook: ~ [0] ? argocd --port-forward login --username admin --password "$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath={.data.password} | base64 -d)"
'admin:login' logged in successfully
Context 'port-forward' updated

(yc-test:default) vandud@macbook: ~ [0] ? argocd cluster list
SERVER                          NAME        VERSION  STATUS   MESSAGE                                                  PROJECT
https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitored.

Изменить пароль через CLI можно так:

(yc-test:default) vandud@macbook: ~ [0] ? argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context 'port-forward' updated

5. Register A Cluster To Deploy Apps To (Optional)

Этот шаг позволяет зарегистрировать внешний кластер в Argo CD (когда нужно деплоить во внешние кластеры)
При внутреннем деплое (когда Argo CD задеплоен в тот же кластер в который нужно деплоить приложения) используется https://kubernetes.default.svc как K8s Api server

Следующей командой можно просмотреть текущие контексты из твоего kubeconfig:

kubectl config get-contexts -o name

Выбери нужный и подставь в argocd cluster add CONTEXTNAME:

(yc-test:default) vandud@macbook: ~ [0] ? argocd cluster add ifree-test-k8s
WARNING: This will create a service account `argocd-manager` on the cluster referenced by context `ifree-test-k8s` with full cluster level privileges. Do you want to continue [y/N]? y
INFO[0001] ServiceAccount "argocd-manager" already exists in namespace "kube-system"
INFO[0001] ClusterRole "argocd-manager-role" updated
INFO[0001] ClusterRoleBinding "argocd-manager-role-binding" updated
FATA[0002] Failed to establish connection to port-forward:443: dial tcp: lookup port-forward on 172.27.192.2:53: server misbehaving

У меня возникла ошибка с резолвингом имени port-forward потому что у меня выбран контекст port-forward

(yc-test:default) vandud@macbook: ~ [0] ? argocd context
CURRENT  NAME            SERVER
         localhost:8080  localhost:8080
         158.160.5.94    158.160.5.94
*        port-forward    port-forward

Переключаем контекст на кластер с Argo CD сервером
И подключаем к этому Argo CD серверу внешний кластер K8s

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd cluster add yc-demo-main-cluster
WARNING: This will create a service account `argocd-manager` on the cluster referenced by context `yc-demo-main-cluster` with full cluster level privileges. Do you want to continue [y/N]? y
INFO[0002] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0002] ClusterRole "argocd-manager-role" created
INFO[0002] ClusterRoleBinding "argocd-manager-role-binding" created
Cluster 'https://51.250.94.51' added

После этого в интерфейсе Argo CD появляется дополнительный кластер
Screenshot_2021_02_02-12_49_03-2022-09-08-at-19extcluster.png

Команда argocd cluster add CONTEXT создает ServiceAccount (argocd-manager) в указанном внешнем кластере в неймспейсе kube-system и биндит этот service account на admin-level ClusterRole
Argo CD будет использовать токен этого сервис аккаунта для управления кластером

6. Create An Application From A Git Repository

Репозиторий https://github.com/argoproj/argocd-example-apps содержит приложение guestbook (папка guestbook) с помощью которого будет продемонстрирована работа Argo CD

Creating Apps Via CLI

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace guestbook
application 'guestbook' created

Creating Apps Via UI

Screenshot_2021_02_02-12_49_03-2022-09-08-at-19appviaui.png

7. Sync (Deploy) The Application

Syncing via CLI

Создаем приложение, видим его в общем списке и видим статус - OutOfSync:

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd app create guestbook-2 --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace guestbook
application 'guestbook-2' created

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd app list
NAME         CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS                REPO                                                 PATH       TARGET
guestbook    https://kubernetes.default.svc  guestbook  default  Synced     Healthy  <none>      <none>                    https://github.com/argoproj/argocd-example-apps.git  guestbook
guestbook-2  https://kubernetes.default.svc  guestbook  default  OutOfSync  Healthy  <none>      SharedResourceWarning(2)  https://github.com/argoproj/argocd-example-apps.git  guestbook

Подробнее приложение можно просмотреть через get:

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd app get guestbook-2
Name:               guestbook-2
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          guestbook
URL:                https://158.160.5.94/applications/guestbook-2
Repo:               https://github.com/argoproj/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from  (53e28ff)
Health Status:      Healthy

CONDITION              MESSAGE                                                                    LAST TRANSITION
SharedResourceWarning  Deployment/guestbook-ui is part of applications guestbook-2 and guestbook  2022-09-08 20:03:34 +0300 MSK
SharedResourceWarning  Service/guestbook-ui is part of applications guestbook-2 and guestbook     2022-09-08 20:03:34 +0300 MSK


GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     guestbook  guestbook-ui  OutOfSync  Healthy
apps   Deployment  guestbook  guestbook-ui  OutOfSync  Healthy

Чтобы синхронизировать нужно использовать команду sync:

(yc-demo-main-cluster:default) vandud@macbook: ~ [0] ? argocd app sync guestbook-2
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
2022-09-08T20:07:40+03:00   apps  Deployment   guestbook          guestbook-ui  OutOfSync  Healthy
2022-09-08T20:07:40+03:00            Service   guestbook          guestbook-ui  OutOfSync  Healthy
2022-09-08T20:07:40+03:00            Service   guestbook          guestbook-ui    Synced  Healthy
2022-09-08T20:07:40+03:00            Service   guestbook          guestbook-ui    Synced   Healthy              service/guestbook-ui configured
2022-09-08T20:07:40+03:00   apps  Deployment   guestbook          guestbook-ui  OutOfSync  Healthy              deployment.apps/guestbook-ui configured
2022-09-08T20:07:40+03:00   apps  Deployment   guestbook          guestbook-ui    Synced  Healthy              deployment.apps/guestbook-ui configured

Name:               guestbook-2
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          guestbook
URL:                https://158.160.5.94/applications/guestbook-2
Repo:               https://github.com/argoproj/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        Synced to  (53e28ff)
Health Status:      Healthy

Operation:          Sync
Sync Revision:      53e28ff20cc530b9ada2173fbbd64d48338583ba
Phase:              Succeeded
Start:              2022-09-08 20:07:40 +0300 MSK
Finished:           2022-09-08 20:07:40 +0300 MSK
Duration:           0s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH   HOOK  MESSAGE
       Service     guestbook  guestbook-ui  Synced  Healthy        service/guestbook-ui configured
apps   Deployment  guestbook  guestbook-ui  Synced  Healthy        deployment.apps/guestbook-ui configured

Команда sync получает манифесты из репозитория и делает для них kubectl apply


Что интересно, у нас два одинаковых приложения в одном и том же неймспейсе, это приводит к вот таким интересным моментам:

(yc-test:default) vandud@macbook: ~ [0] ? kubectl -n argocd get applications
NAME          SYNC STATUS   HEALTH STATUS
guestbook     Synced        Healthy
guestbook-2   OutOfSync     Healthy
(yc-test:default) vandud@macbook: ~ [0] ? argocd app sync guestbook-2 --async
(yc-test:default) vandud@macbook: ~ [0] ? kubectl -n argocd get applications
NAME          SYNC STATUS   HEALTH STATUS
guestbook     OutOfSync     Healthy
guestbook-2   Synced        Healthy
(yc-test:default) vandud@macbook: ~ [0] ? argocd app sync guestbook --async
(yc-test:default) vandud@macbook: ~ [0] ? kubectl -n argocd get applications
NAME          SYNC STATUS   HEALTH STATUS
guestbook     Synced        Healthy
guestbook-2   OutOfSync     Healthy

Syncing via UI

Для синхронизации через UI нужно просто нажать кнопку

Operator Manual

Overview

Этот гайд для администраторов и операторов желающих установить и настроить Argo CD для других разработчиков

Architectural Overview

argocd_architecture.png

Components

API Server

API Server это gRPC/REST сервер который предоставляет API используемый Web UI, CLI и CI/CD системами. Он отвечает за:

Repository Server

Repository server это внутренний сервис который поддерживает локальный кэш Git репозитория хранящего манифесты. Он отвечает за генерацию и отдачу манифестов когда даны следующие вводные:

Application Controller

Application controller это Kubernetes контроллер который постоянно отслеживает запущенные приложения и сравнивает их текущее состояние с желаемым (из репы). Он обнаруживает OutOfSync приложения и, если указано, предпринимает корректирующие действия. Также он отвечает за выполнение настроенных пользователем хуков (PreSync, Sync, PostSync)

Installation

Argo CD имеет два варианта установки: мультитенантный и core

Multi-Tenant

Multi-tenant инсталяция это самый частый вариант установки. Этот вариант обычно используется для обслуживания множества команд разработчиков приложений в организации и поддерживается командой платформы

Конечные пользователи могут использовать Argo CD через API используя Web UI или argocd CLI

Есть два варианта такой инсталяции

Non High Availability

Не рекомендуется для использования в проде. Обычно этот вариант используется на время тестов или для демонстраций

High Availability

HA инсталяция рекомендована для продакшена. Следующие два набора манифестов содержат те же самые компоненты, но подтюненные для HA

Core

Core инсталяция подходят для кластер администраторов использующих Argo CD независимо от остальных и кому не нужна мультитенантность. Она содержит меньшее число компонентов и легче в установке. В нее не включен UI и устанавливается легковесная версия каждого компонента (non-HA)

Конечным пользователям необходим доступ к Kubernetes для управления Argo CD. argocd CLI должен быть сконфигурирован следующими командами:

kubectl config set-context --current --namespace=argocd # change current kube context to argocd namespace
argocd login --core

Web UI доступен локально через argocd admin dashboard:

(yc-test:argocd) vandud@macbook: ~ [0] ? argocd admin dashboard
Argo CD UI is available at http://localhost:8080

Screenshot_2021_02_02-12_49_03-2022-09-09-at-04coreui.png


Команда argocd app create у меня завелась только когда в переменной KUBECONFIG оказался один файл:

(yc-test:argocd) vandud@macbook: ~ [0] ? export KUBECONFIG=/tmp/yc-test.kubeconfig.yaml
(yc-test:argocd) vandud@macbook: ~ [0] ? argocd --core app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default --upsert
application 'guestbook' created

Когда их там много - не работает:
2022-09-09-0multikubeconferr.jpg

Kustomize

Argo CD манифесты могут быть установлены через Kustomize и пропатчены по ходу

Helm

Argo CD может быть установлен через Helm
Community maintained chart - https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd

Supported versions

Как и у Kubernetes, поддерживаемая версия Argo CD в любой момент времени это последний патч-релиз для N и N-1 минорной версии

Declarative Setup

Argo CD applications, projects и настройки могут быть описаны декларативно в Kubernetes манифестах
И могут обновляться через kubectl apply без использования argocd cli

Quick Reference

Все ресурсы, включая Application и AppProject должны устанавливаться в неймспейс с Argo CD (by default argocd)

Atomic configuration

Sample File Resource Name Kind Description
argocd-cm.yaml argocd-cm ConfigMap General Argo CD configuration
argocd-repositories.yaml my-private-repo / istio-helm-repo / private-helm-repo / private-repo Secrets Sample repository connection details
argocd-repo-creds.yaml argoproj-https-creds / argoproj-ssh-creds / github-creds / github-enterprise-creds Secrets Sample repository credential templates
argocd-cmd-params-cm.yaml argocd-cmd-params-cm ConfigMap Argo CD env variables configuration
argocd-secret.yaml argocd-secret Secret User Passwords, Certificates (deprecated), Signing Key, Dex secrets, Webhook secrets
argocd-rbac-cm.yaml argocd-rbac-cm ConfigMap RBAC Configuration
argocd-tls-certs-cm.yaml argocd-tls-certs-cm ConfigMap Custom TLS certificates for connecting Git repositories via HTTPS (v1.2 and later)
argocd-ssh-known-hosts-cm.yaml argocd-ssh-known-hosts-cm ConfigMap SSH known hosts data for connecting Git repositories via SSH (v1.2 and later)

Для каждого ConfigMap или Secret возможно только определенное имя ресурса (в таблице)
Каждая ConfigMap должна иметь лейбл app.kubernetes.io/part-of: argocd, иначе Argo CD их не увидит

Multiple configuration objects

Sample File Kind Description
application.yaml Application Example application spec
project.yaml AppProject Example project spec
- Secret Repository credentials

Для Application и AppProject имя ресурса равно объекта в Argo CD
Это значит что имена для Application и AppProject должны быть уникальными в рамках Argo CD и не может быть двух приложений с одинаковыми именами

Applications

Application CRD это ресурс Kubernetes отображающий задеплоенный инстанс приложения в каком-то окружении. Он определяется двуми ключевыми частями:

Минимальный Application выглядит так:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook

Дополнительные поля можно посмотреть в https://argo-cd.readthedocs.io/en/stable/operator-manual/application.yaml

Namespace должен совпадать с неймспейсом где находится Argo CD, обычно это argocd

Когда приложение берется из Helm репозитория, аттрибут chart должен быть указан вместо path

spec:
  source:
    repoURL: https://argoproj.github.io/argo-helm
    chart: argo

По умолчанию при удалении application не происходит каскадного удаления ресурсов. Для такого нужно указывать finalizer

metadata:
  finalizers:
    - resources-finalizer.argocd.argoproj.io

App of Apps

Можно создать app который будет создавать другие app, которые могут создавать другие app (и так до бесконечности)
Это позволяет декларативно управлять группами приложений которые будут соответственно задеплоены и сконфигурированы

Смотри cluster bootstrapping

Projects

AppProject CRD это ресурс Kubernetes представляющий логическую группу приложений. Он определяется следующими ключевыми частями:

Если у проекта в destinations разрешено деплоиться в неймспейс где установлен Argo CD, тогда аппликейшены из этого проекта будут иметь админские права

Пример:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: my-project
  namespace: argocd
  # Finalizer that ensures that project is not deleted until it is not referenced by any application
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  description: Example Project
  # Allow manifests to deploy from any Git repos
  sourceRepos:
  - '*'
  # Only permit applications to deploy to the guestbook namespace in the same cluster
  destinations:
  - namespace: guestbook
    server: https://kubernetes.default.svc
  # Deny all cluster-scoped resources from being created, except for Namespace
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace
  # Allow all namespaced-scoped resources to be created, except for ResourceQuota, LimitRange, NetworkPolicy
  namespaceResourceBlacklist:
  - group: ''
    kind: ResourceQuota
  - group: ''
    kind: LimitRange
  - group: ''
    kind: NetworkPolicy
  # Deny all namespaced-scoped resources from being created, except for Deployment and StatefulSet
  namespaceResourceWhitelist:
  - group: 'apps'
    kind: Deployment
  - group: 'apps'
    kind: StatefulSet
  roles:
  # A role which provides read-only access to all applications in the project
  - name: read-only
    description: Read-only privileges to my-project
    policies:
    - p, proj:my-project:read-only, applications, get, my-project/*, allow
    groups:
    - my-oidc-group
  # A role which provides sync privileges to only the guestbook-dev application, e.g. to provide
  # sync privileges to a CI system
  - name: ci-role
    description: Sync privileges for guestbook-dev
    policies:
    - p, proj:my-project:ci-role, applications, sync, my-project/guestbook-dev, allow
    # NOTE: JWT tokens can only be generated by the API server and the token is not persisted
    # anywhere by Argo CD. It can be prematurely revoked by removing the entry from this list.
    jwtTokens:
    - iat: 1535390316

Repositories

Некоторые Git хостеры, в особенности GitLab, требуют указывать на конце урла репозитория суффикс .git, иначе они возвращают 301 редирект на урл с суффиксом. Argo CD не следует за редиректами, поэтому надо указывать сразу нормальные урлы

Детали о репозитории хранятся в секрете. Чтобы сконфигурировать репозиторий нужно создать секрет содержащий нужную инфу о нем
Описание каждого репозитория должно иметь поле url и в зависимости от того происходит коннект по https, ssh или github app, требуются поля username, password, sshPrivateKey или githubAppPrivateKey

Example for HTTPS:

apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/argoproj/private-repo
  password: my-password
  username: my-username

Example for SSH:

apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: git@github.com:argoproj/my-private-repository
  sshPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----

Example for GitHub App:

apiVersion: v1
kind: Secret
metadata:
  name: github-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/argoproj/my-private-repository
  githubAppID: 1
  githubAppInstallationID: 2
  githubAppPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----
---
apiVersion: v1
kind: Secret
metadata:
  name: github-enterprise-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://ghe.example.com/argoproj/my-private-repository
  githubAppID: 1
  githubAppInstallationID: 2
  githubAppEnterpriseBaseUrl: https://ghe.example.com/api/v3
  githubAppPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----

Repository Credentials

Если ты хочешь использовать одни и те же креды для многих репозиториев, то можно наладить шаблон. Credential template может нести в себе ту же инфу которую может секрет с репозиторием:

apiVersion: v1
kind: Secret
metadata:
  name: first-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/argoproj/private-repo
---
apiVersion: v1
kind: Secret
metadata:
  name: second-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/argoproj/other-private-repo
---
apiVersion: v1
kind: Secret
metadata:
  name: private-repo-creds
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repo-creds
stringData:
  type: git
  url: https://github.com/argoproj
  password: my-password
  username: my-username

В примере выше каждый репозиторий доступный через https и чей url начинается на https://github.com/argoproj будет использовать username и password из секрета private-repo-creds

Для того чтобы Argo CD могу использовать credential template нужно чтобы совпали следующие условия:

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

Следующие ключи (поля) валидны для темплейтирования:

SSH repositories
HTTPS repositories
GitHub App repositories

Repositories using self-signed TLS certificates (or are signed by custom CA)

https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories-using-self-signed-tls-certificates-or-are-signed-by-custom-ca

v1.2 or later

Можно заложить самоподписанный серт от гитрепозитория в конфигмапу и подложить ее argocd-server'у и argocd-repo-server'у чтобы они могли работать с таким репозиторием

SSH known host public keys

Если ты коннектишься к репам через ssh, то Argo CD нужно знать SSH known hosts public keys git серверов
Это можно менеджить в ConfigMap argocd-ssh-known-hosts-cm, этот ConfigMap содержит простую key value пару, где ssh_known_hosts указан в качестве ключа и список public keys как значение
В отличие варианту с TLS, публичный ключ каждого Git сервера, куда будет коннектиться Argo CD, должен быть сконфигурирован, иначе подключение зафейлится (без вариантов)
Контент может быть скопирован из .ssh/known_hosts или из вывода утилиты ssh-keyscan
Формат - <servername> <keydata>, по одному на строку
Пример:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-ssh-known-hosts-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  ssh_known_hosts: |
    bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
    github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
    gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
    gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
    gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
    ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
    vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
    github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
    github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl

Конфигмапа argocd-ssh-known-hosts-cm должна быть примаунчена в /app/config/ssh к argocd-server и argocd-repo-server

Configure repositories with proxy

Прокси для репозитория должна быть указана в поле proxy в секрете репозитория наравне с другуми параметрами. Argo CD будет использовать указанную прокси для доступа к репозиторию. Argo CD будет использовать переменные окружения конфигурирующие прокси на repository server'e если прокси не указана для конкретного репозитория

apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/argoproj/private-repo
  proxy: https://proxy-server-url:8888
  password: my-password
  username: my-username

Legacy behaviour

В ранних версиях Argo CD можно было конфигурировать репозитории в argocd-cm

apiVersion: v1
kind: ConfigMap
data:
  repositories: |
    - url: https://github.com/argoproj/my-private-repository
      passwordSecret:
        name: my-secret
        key: password
      usernameSecret:
        name: my-secret
        key: username
  repository.credentials: |
    - url: https://github.com/argoproj
      passwordSecret:
        name: my-secret
        key: password
      usernameSecret:
        name: my-secret
        key: username
---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
  namespace: argocd
stringData:
  password: my-password
  username: my-username

Для обратной совместимости это продолжает работать, но скоро будет выпилено

Clusters

Креды от кластеров хранятся так же как креды от репозиторием или сами репозитории. Каждый секрет должен иметь лейбл argocd.argoproj.io/secret-type: cluster
Секрет должен иметь следующие поля:

Helm Chart Repositories

Нестандартные Helm Chart репозитории должны быть зарегистрированы явно. Каждый репозиторий должен иметь url, type и name. Для приватных репозиториев можно указать креды через поля username, password, tlsClientCertData и tlsClientCertKey
Так же должен быть лейбл argocd.argoproj.io/secret-type: repository

apiVersion: v1
kind: Secret
metadata:
  name: istio
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  name: istio.io
  url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts
  type: helm
---
apiVersion: v1
kind: Secret
metadata:
  name: argo-helm
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  name: argo
  url: https://argoproj.github.io/argo-helm
  type: helm
  username: my-username
  password: my-password
  tlsClientCertData: ...
  tlsClientCertKey: ...

Resource Exclusion/Inclusion

Ресурсы можно исключать из дискавери и синхронизации так что Argo CD не будет о них знать
Например events.k8s.io и metrics.k8s.io всегда исключены
Юзкейсы:

Чтобы это настроить нужно добавить в argocd-cm конфигмапу секцию resource.exclusions:

apiVersion: v1
data:
  resource.exclusions: |
    - apiGroups:
      - "*"
      kinds:
      - "*"
      clusters:
      - https://192.168.0.20
kind: ConfigMap

resource.exclusions это список объектов, каждый объект имеет:

Если все три совпадают то ресурс будет игнорироваться

В дополнение к исключениям можно настроить включения параметром resource.inclusions
По умолчанию включены все groups/kinds. С помощью resource.inclusions можно изменить список включенных groups/kinds

apiVersion: v1
data:
  resource.inclusions: |
    - apiGroups:
      - "*"
      kinds:
      - Deployment
      clusters:
      - https://192.168.0.20
kind: ConfigMap

resource.inclusions и resource.exclusions могут использоваться одновременно. Итоговый список включенных groups/kinds будет получен из resource.inclusions минус resource.exclusions

SSO & RBAC

Manage Argo CD Using Argo CD

Argo CD может управлять самим собой потому что все настройки это Kubernetes манифесты
Предлагается создать Kustomization с базовыми манифестами отсюда - https://github.com/argoproj/argo-cd/tree/stable/manifests
Поверх которых будут накладываться нужные изменения

bases:
- github.com/argoproj/argo-cd/manifests/cluster-install?ref=v1.0.1

# additional resources like ingress rules, cluster and repository secrets.
resources:
- clusters-secrets.yaml
- repos-secrets.yaml

# changes to config maps
patchesStrategicMerge:
- overlays/argo-cd-cm.yaml

Пример самоуправляемого Argo CD https://cd.apps.argoproj.io/
У которого конфигурация хранится в https://github.com/argoproj/argoproj-deployments/tree/master/argocd

Ingress Configuration

Ambassador

Option 1: Mapping CRD for Host-based Routing

Option 2: Mapping CRD for Path-based Routing

Contour

Private Argo CD UI with Multiple Ingress Objects and BYO Certificate

kubernetes/ingress-nginx

Option 1: SSL-Passthrough

SSL-Passthrough with cert-manager and Let's Encrypt

Option 2: Multiple Ingress Objects And Hosts

Traefik (v2.2)

IngressRoute CRD

AWS Application Load Balancers (ALBs) And Classic ELB (HTTP Mode)

Google Cloud load balancers with Kubernetes Ingress

Disable internal TLS

Creating a service

Creating a BackendConfig

Creating a FrontendConfig

Creating a certificate secret

Creating an Ingress

Authenticating through multiple layers of authenticating reverse proxies

ArgoCD Server and UI Root Path (v1.5.3)

UI Base Path

User Management

Security

TLS configuration

Cluster Bootstrapping

Secret Management

High Availability

Disaster Recovery

Git Webhook Configuration

Resource Health

Resource Actions

Custom Tooling

Custom Styles

Metrics

Web-based Terminal

Notification

Troubleshooting Tools

ApplicationSet

Server Configuration Parameters

Upgrading