- 01. はじめに
- 02. 概要
- 03. repo-server
- 04. application-controller、redis-server
- 05. dex-server
- 06. argocd-server (argocd-apiserver)
- 07. アーキテクチャのまとめ
- 08. おわりに
- 謝辞
01. はじめに
ロケットに乗るArgoくんのツラが腹立つわー。
さて最近の業務で、全プロダクトが共通基盤として使用するArgoCDとAWS EKS Clusterのアーキテクチャをリプレイスしています。
採用した設計プラクティスの紹介も兼ねて、ArgoCDのアーキテクチャと自動デプロイの仕組みを記事で解説しました🚀
ArgoCDは、kubectl
コマンドによるマニフェストのデプロイを自動化するツールです。
現在に至るまでArgoCDのアーキテクチャには変遷があり、今回紹介するのは執筆時点 (2023/05/02) 時点で最新の 2.6
系のアーキテクチャです。
アーキテクチャや仕組みはもちろん、個々のマニフェストの実装にもちょっとだけ言及します。
それでは、もりもり布教していきます😗
02. 概要
アーキテクチャ
▼ レイヤー
まずは、ArgoCDのアーキテクチャのレイヤーがどのようになっているかを見ていきましょう。
ArgoCD公式から、コンポーネント図が公開されています。
図から、次のようなことがわかります👇
- 下位レイヤー向きにしか依存方向がなく、例えばコアドメインとインフラのレイヤー間で依存性は逆転させていない。
- レイヤーの種類 (UI、アプリケーション、コアドメイン、インフラ) とそれらの依存方向から、レイヤードアーキテクチャのような構成になっている。
- 特にコアドメインレイヤーが独立したコンポーネントに分割されており、マイクロサービスアーキテクチャを採用している。
↪️:argo-cd/components.md at master · argoproj/argo-cd · GitHub
本記事では詳しく言及しませんが、マイクロサービスアーキテクチャの分割方法には大小いくつかの種類があり、境界付けられたコンテキストで分割することがベタープラクティスと言われています😎
(境界付けられたコンテキストについても、ちゃんと記事を投稿したい...)
機能単位による分割は、境界付けられたコンテキストのそれよりも粒度が小さくなります。
↪️:モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド | Sam Newman, 島田 浩二 |本 | 通販 | Amazon
コンポーネント図では、依存方向 (そのコンポーネントがいずれのコンポーネントを使用するのか) に着目できます。
そのため、これはマイクロサービス間の依存方向を視覚化するために有効なUML図です🙆🏻
↪️:Component Diagrams - Code With Engineering Playbook
▼ コンポーネント
次に、コンポーネントの種類を紹介します。
ArgoCDの各コンポーネントが組み合わさり、マニフェストの自動的なデプロイを実現します。
ArgoCD (2.6
系) のコンポーネントはいくつかあり、主要なコンポーネントの種類とレイヤーは以下の通りです👇
コンポーネント | レイヤー | 機能 |
---|---|---|
argocd-server (argocd-apiserver) | UI / アプリケーション | みんながよく知るArgoCDのダッシュボードです。 また、ArgoCDのAPIとしても機能します。 現在、複数のレイヤーの責務を持っており、将来的にUIとアプリケーションは異なるコンポーネントに分割されるかもしれません。 |
application-controller | コアドメイン | Clusterにマニフェストをデプロイします。 また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。 |
repo-server | コアドメイン | マニフェスト/チャートリポジトリからクローンを取得します。 また、クローンからマニフェストを作成します。 |
redis-server | インフラ | application-controllerの処理結果のキャッシュを保管します。 |
dex-server | インフラ | SSOを採用する場合に、argocd-serverの代わりに認可リクエストを作成し、IDプロバイダーにこれを送信します。 これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。 |
仕組み
それでは、ArgoCDは、どのようにコンポーネントを組み合わせて、マニフェストをデプロイするのでしょうか?
ここではデプロイ先Cluster管理者 (デプロイ先Clusterを管理するエンジニア) は、ArgoCDのダッシュボードを介してマニフェストをデプロイするとしましょう。
まずは、概要を説明していきます。
【1】
ArgoCDのCluster上で、repo-serverがマニフェスト/チャートリポジトリのクローンを取得します。
【2】
application-controllerは、repo-serverからマニフェストを取得します。
【3】
application-controllerは、デプロイ先Clusterの現状を確認します。
【4】
application-controllerは、処理結果をredis-serverに保管します。
【5】
argocd-serverは、redis-serverからキャッシュを取得します。
【6】
デプロイ先Cluster管理者は、argocd-serverにログインしようとします。
【7】
argocd-serverは、ログイン時にIDプロバイダーに認可フェーズを委譲するために、dex-serverをコールします。
今回の記事では、SSOを採用した場合の仕組みを紹介しています🙇🏻
【8】
dex-serverは、IDプロバイダーに認可リクエストを作成し、これをIDプロバイダーに送信します。
【9】
argocd-serverで認可フェーズを実施します。
ログインが完了し、デプロイ先Cluster管理者は認可スコープに応じてダッシュボードを操作できます。
今回の記事では、ArgoCD用Clusterを採用した場合の仕組みを紹介しています🙇🏻
【10】
application-controllerは、Clusterにマニフェストをデプロイします。
マニフェストのデプロイの仕組みをざっくり紹介しました。
ただこれだと全く面白くないので、各コンポーネントの具体的な処理と、各々がどのように通信しているのかを説明します✌️
03. repo-server
repo-serverとは
まずは、コアドメインレイヤーにあるrepo-serverです。
マニフェスト/チャートリポジトリ (例:GiHub、GitHub Pages、Artifact Hub、AWS ECR、Artifact Registry、など) からクローンを取得します。
repo-serverを持つPodには、他に軽量コンテナイメージからなるInitContainerとサイドカー (cmp-server) がおり、それぞれ機能が切り分けられています👍
仕組み
【1】
repo-serverの起動時に、InitContainerでお好きなマニフェスト管理ツール (Helm、Kustomize、など) やプラグイン (helm-secrets、KSOPS、SOPS、argocd-vault-plugin、など) をインストールします。
また、サイドカーのcmp-serverでは起動時に/var/run/argocd/argocd-cmp-server
コマンドを実行する必要があり、InitContainer (ここではcopyutil
コンテナ) を使用して、ArgoCDのコンテナイメージからargocd-cli
のバイナリファイルをコピーします。
repo-serverのざっくりした実装例は以下の通りです👇
ここでは、ArgoCDで使いたいツール (Helm、SOPS、helm-secrets) をInitContainerでインストールしています。
apiVersion: v1 kind: Pod metadata: name: argocd-repo-server namespace: argocd spec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest initContainers: # HelmをインストールするInitContainer - name: helm-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # SOPSをインストールするInitContainer - name: sops-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /custom-tools name: custom-tools # helm-secretsをインストールするInitContainer - name: helm-secrets-installer image: alpine:latest command: - /bin/sh - -c args: - | # インストール処理 volumeMounts: - mountPath: /helm-working-dir/plugins name: helm-working-dir ... # cmp-serverにargocd-cliのバイナリをコピーするInitContainer - name: copyutil image: quay.io/argoproj/argocd:latest command: - cp - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server volumeMounts: - name: var-files mountPath: /var/run/argocd # Podの共有ボリューム volumes: - name: custom-tools emptyDir: {} - name: var-files emptyDir: {}
↪️:Custom Tooling - Argo CD - Declarative GitOps CD for Kubernetes
quay.io/argoproj/argocd
) には、いくつかのツール (例:Helm、Kustomize、Ks、Jsonnet、など) の推奨バージョンがあらかじめインストールされています。
そのため、サイドカーのcmp-serverを採用しない場合は、これらのツールをインストールする必要はありません。
反対に、cmp-serverを採用する場合はインストールが必要になります🙇🏻
公式が、推奨バージョンを含むサイドカー用イメージを公開してくれるのを待ちたいところなのですが、リポジトリからバージョンを取得することもできなくはないです🙆🏻
# ArgoCDのコンテナイメージに内蔵されたHelmの推奨バージョンを取得する $ curl -s https://raw.githubusercontent.com/argoproj/argo-cd/<バージョンタグ>/hack/tool-versions.sh \ | grep helm3_version | sed -e 's/^[^=]*=//'
↪️:argo-cd/tool-versions.sh at master · argoproj/argo-cd · GitHub
執筆時点 (2023/05/02) では、ArgoCDとKustomizeが密に結合しています。
例えば、ArgoCD上のKustomize系オプションはrepo-serverでマニフェストを作成することを想定して設計されています。
無理やりサイドカーでKustomizeを実行しようとすると、ArgoCDの既存のオプションを無視した実装になってしまうため、Kustomizeだけはrepo-serverで実行することをお勧めします😢
【2】
repo-serverは、Secret (argocd-repo-creds) からリポジトリの認証情報を取得します。
argocd-repo-credsではリポジトリの認証情報のテンプレートを管理しています。
指定した文字列から始まる (最長一致) URLを持つリポジトリに接続する場合に、それらの接続で認証情報を一括して適用できます。
argocd-repo-credsのざっくりした実装例は以下の通りです👇
ここでは、リポジトリのSSH公開鍵認証を採用し、argocd-repo-credsに共通の秘密鍵を設定しています。
apiVersion: v1 kind: Secret metadata: name: argocd-repo-creds-github namespace: argocd labels: argocd.argoproj.io/secret-type: repo-creds type: Opaque data: type: git url: https://github.com/hiroki-hasegawa # 秘密鍵 sshPrivateKey: | MIIC2 ...
あとは、各リポジトリのSecret (argocd-repo) にURLを設定しておきます。
すると、先ほどのargocd-repo-credsのURLに最長一致するURLを持つSecretには、一括して秘密鍵が適用されます。
# foo-repositoryをポーリングするためのargocd-repo apiVersion: v1 kind: Secret metadata: namespace: argocd name: foo-argocd-repo labels: argocd.argoproj.io/secret-type: repository type: Opaque data: # 認証情報は設定しない。 # チャートリポジトリ名 name: bar-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/bar-chart.git --- # baz-repositoryをポーリングするためのargocd-repo apiVersion: v1 kind: Secret metadata: namespace: foo name: baz-argocd-repo labels: argocd.argoproj.io/secret-type: repository type: Opaque data: # 認証情報は設定しない。 # チャートリポジトリ名 name: baz-repository # https://github.com/hiroki-hasegawa に最長一致する。 url: https://github.com/hiroki-hasegawa/baz-chart.git
↪️:Declarative Setup - Argo CD - Declarative GitOps CD for Kubernetes
【3】
repo-serverは、認証情報を使用して、リポジトリにgit clone
コマンドを実行します。
取得したクローンを、/tmp/_argocd-repo
ディレクトリ配下にUUIDの名前で保管します。
また、リポジトリの変更をポーリングし、変更を検知した場合はgit fetch
コマンドを実行します。
# クローンが保管されていることを確認できる $ kubectl -it exec argocd-repo-server \ -c repo-server \ -n foo \ -- bash -c "ls /tmp/_argocd-repo/<URLに基づくUUID>" # リポジトリ内のファイル Chart.yaml README.md templates values.yaml
↪️:custom repo-server - where is the local cache kept? · argoproj/argo-cd · Discussion #9889 · GitHub
2.3
以前では、repo-serverは/tmp
ディレクトリ配下にURLに基づく名前でクローンを保管します。
$ kubectl -it exec argocd-repo-server \ -c repo-server \ -n foo \ -- bash -c "ls /tmp/https___github.com_hiroki-hasegawa_foo-repository" # リポジトリ内のファイル Chart.yaml README.md templates values.yaml
【4】
repo-serverは、Volume上のUnixドメインソケットを介して、サイドカー (cmp-server) によるプラグインの実行をコールします。
Unixドメインソケットのエンドポイントの実体は.sock
ファイルです。
$ kubectl exec -it argocd-repo-server -c foo-plugin-cmp-server\ -- bash -c "ls /home/argocd/cmp-server/plugins/" foo-plugin.sock
Unixソケットドメインを使用すると、同じVolumeがマウントされたコンテナのプロセス間で、データを送受信できます👍
↪️:ASCII.jp:Unixドメインソケット (1/2)
【5】
cmp-serverは、暗号化キー (例:AWS KMS、Google CKM、など) を使用してSecretストア (AWS SecretManager、Google SecretManager、SOPS、Vault、など) の暗号化変数を復号化します。
cmp-serverに軽量なコンテナイメージを使用していると、
/etc/ssl
ディレクトリ (OSによる) にSSL証明書が無く、cmp-serverがHTTPSプロトコルを使用できない可能性があります。
その場合は、お好きな方法で証明書をインストールし、コンテナにマウントするようにしてください👍
apiVersion: v1 kind: Pod metadata: name: argocd-repo-server namespace: foo spec: containers: - name: repo-server image: quay.io/argoproj/argocd:latest ... # サイドカーのcmp-server - name: helm-secrets-cmp-server image: ubuntu:latest ... volumeMounts: # サイドカーがAWS KMSを使用する時にHTTPSリクエストを送信する必要があるため、SSL証明書をマウントする - name: certificate mountPath: /etc/ssl ... initContainers: - name: certificate-installer image: ubuntu:latest command: - /bin/sh - -c args: - | apt-get update -y # ルート証明書をインストールする apt-get install -y ca-certificates # 証明書を更新する update-ca-certificates volumeMounts: - mountPath: /etc/ssl name: certificate volumes: - name: certificate emptyDir: {}
【6】
cmp-serverがマニフェスト管理ツール (例:Helm、Kustomize) でマニフェストを作成する時に、これのプラグイン (helm-secrets、argocd-vault-plugin、など) を使用したいようなユースケースがあるかと思います。
マニフェストの作成時の追加処理として、ConfigMap配下のConfigManagementPluginでプラグインの処理を定義します。
ざっくりした実装例は以下の通りです👇
ここでは、プラグインとしてhelm-secretsを採用し、helm secrets template
コマンドの実行を定義します。
apiVersion: v1 kind: ConfigMap metadata: name: argocd-cmp-cm namespace: foo data: helm-secrets-plugin.yaml: | apiVersion: argoproj.io/v1alpha1 kind: ConfigManagementPlugin metadata: namespace: foo name: helm-secrets spec: generate: command: - /bin/bash - -c args: - | set -o pipefail helm secrets template -f $ARGOCD_ENV_SECRETS -f $ARGOCD_ENV_VALUES -n $ARGOCD_APP_NAMESPACE $ARGOCD_APP_NAME . foo-plugin.yaml: | ...
【7】
cmp-serverは、を実行し、Secretを含むマニフェストを作成します。
ConfigMap配下のファイルをplugin.yaml
の名前でサイドカーにマウントする必要があります。
また、先ほどのUnixドメインソケットの.sock
ファイルや、 cmp-serverがプラグインを実行するための各種バイナリファイルもマウントが必要です。
ざっくりした実装例は以下の通りです👇
ここでは、helm-secrets
プラグインを実行するサイドカー (helm-secrets-cmp-server) を作成します。
apiVersion: v1 kind: Pod metadata: name: argocd-repo-server spec: containers: # repo-server - name: repo-server image: quay.io/argoproj/argocd:latest ... # helm-secretsのcmp-server - name: helm-secrets-cmp-server # コンテナイメージは軽量にする image: ubuntu:latest command: - /var/run/argocd/argocd-cmp-server env: # helmプラグインの場所を設定する - name: HELM_PLUGINS value: /helm-working-dir/plugins securityContext: runAsNonRoot: true runAsUser: 999 volumeMounts: # リポジトリのクローンをコンテナにマウントする - name: tmp mountPath: /tmp # ConfigManagementPluginのマニフェスト (helm-secrets.yaml) を "plugin.yaml" の名前でコンテナにマウントする - name: argocd-cmp-cm mountPath: /home/argocd/cmp-server/config/plugin.yaml subPath: helm-secrets.yaml # コンテナ間で通信するためのUnixドメインソケットファイルをコンテナにマウントする - name: plugins mountPath: /home/argocd/cmp-server/plugins # 任意のツールのバイナリファイルをコンテナにマウントする - name: custom-tools mountPath: /usr/local/bin # helmプラグインのバイナリをコンテナにマウントする - name: helm-working-dir mountPath: /helm-working-dir/plugins ... # Podの共有ボリューム volumes: # リポジトリのクローンを含む - name: tmp emptyDir: {} # Helmなどの任意のツールを含む - name: custom-tools emptyDir: {} # helmプラグインを含む - name: helm-working-dir emptyDir: {}
v2.6
では、ConfigManagementPluginのマニフェストを/home/argocd/cmp-server/config
ディレクトリに、plugin.yaml
の名前でマウントしないといけません。
これは、cmp-serverの起動コマンド (
/var/run/argocd/argocd-cmp-server
) がplugin.yaml
の名前しか扱えないためです。
今後のアップグレードで改善される可能性がありますが、
v2.6
では、ConfigManagementPluginの数だけcmp-serverが必要になってしまいます🙇🏻
この場合、代わりにSecretsストアCSIドライバーやExternalSecretsOperatorを使用できます。
これらは、クラウドプロバイダーから変数を取得し、これをSecretにデータとして注入してくれます🙇🏻
↪️:How to manage Kubernetes secrets with GitOps? | Akuity
04. application-controller、redis-server
application-controllerとは
コアドメインレイヤーにあるapplication-controllerです。
Clusterにマニフェストをデプロイします。
また、ArgoCD系カスタムリソースのカスタムコントローラーとしても機能します。
redis-serverとは
インフラレイヤーにあるredis-serverです。
application-controllerの処理結果のキャッシュを保管します。
仕組み
【1】
ArgoCD用Clusterの管理者は、ClusterにArgoCD系のカスタムリソース (例:Application、AppProject、など) をデプロイします。
この時、argo-helmを使用すると簡単にArgoCDのマニフェストを作成できます。
️↪️:GitHub - argoproj/argo-helm: ArgoProj Helm Charts
ただしHelmの重要な仕様として、チャートの更新時に使用する
helm upgrade
コマンドは、CRDを作成できる一方でこれを変更できません。
HelmでCRDを作成するとHelmの管理ラベルが挿入されてしまうため、作成の時点からCRDがHelmの管理外となるように、
kubectl
コマンドでCRDを作成した方がよいです👍
$ kubectl diff -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>" $ kubectl apply -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=<バージョンタグ>"ArgoCD上でHelmを使用してデプロイする場合はこの仕様を気にしなくて良いのかな、と思った方がいるかもしれないです。
ですが本記事で解説した通り、ArgoCDはcmp-serverの
helm template
コマンド (この時、--include-crds
オプションが有効になっている) や、application-controllerのkubectl apply
コマンドを組み合わせてマニフェストをデプロイしているため、CRDもちゃんと更新してくれます👍🏻
️↪️:Helm | Custom Resource Definitions
【2】
kube-controller-managerは、application-controllerを操作し、Reconciliationを実施します。
application-controllerは、Etcd上に永続化されたマニフェストと同じ状態のArgoCD系カスタムリソースを作成/変更します。
本記事では詳しく言及しませんが、カスタムコントローラーの仕組みやCRDとの関係については、以下の記事が非常に参考になりました🙇🏻
️↪️:How Operators work in Kubernetes | Red Hat Developer
【3】
application-controllerは、repo-serverからリポジトリのマニフェストを取得します。
取得したマニフェストは、repo-serverのサイドカーであるcmp-serverが作成したものです。
【4】
application-controllerは、デプロイ先Clusterをヘルスチェックします。
application-controllerには、gitops-engineパッケージが内蔵されており、これはヘルスチェックからデプロイまでの基本的な処理を実行します。
執筆時点 (2023/05/02) では以下のディレクトリからなります👇
gitops-engine/ ├── pkg │ ├── cache │ ├── diff # リポジトリとClusterの間のマニフェストの差分を検出する。ArgoCDのDiff機能に相当する。 │ ├── engine # 他のパッケージを使い、GitOpsの一連の処理を実行する。 │ ├── health # Clusterのステータスをチェックする。ArgoCDのヘルスチェック機能に相当する。 │ ├── sync # Clusterにマニフェストをデプロイする。ArgoCDのSync機能に相当する。 │ └── utils # 他のパッケージに汎用的な関数を提供する。 │ ...
↪️:gitops-engine/design-top-down.md at master · argoproj/gitops-engine · GitHub
【5】
application-controllerは、デプロイ先Clusterのマニフェストと、repo-serverから取得したマニフェストの差分を検出します。
ここで、kubectl diff
コマンドの実行が自動化されています。
【6】
application-controllerは、処理結果をredis-serverに保管します。
redis-serverは、Applicationやリポジトリのコミットの単位で、application-controllerの処理結果を保管しています。
$ kubectl exec -it argocd-redis-server \ -n foo \ -- sh -c "redis-cli --raw" 127.0.0.1:6379> keys * ... app|resources-tree|<Application名>|<キャッシュバージョン> cluster|info|<デプロイ先ClusterのURL>|<キャッシュバージョン> git-refs|<マニフェスト/チャートリポジトリのURL>|<キャッシュバージョン> mfst|app.kubernetes.io/instance|<Application名>|<最新のコミットハッシュ値>|<デプロイ先Namespace>|*****|<キャッシュバージョン> ...
【7】
application-controllerは、Applicationの操作に応じて、Clusterにマニフェストをデプロイします。
ここで、kubectl apply
コマンドの実行が自動化されています。
metadata.managedFields
キーがあり、何がそのマニフェストを作成/変更したのかを確認できます。
実際にマニフェストを確認してみると、確かにapplication-controllerがマニフェストを作成/変更してくれたことを確認できます。
apiVersion: apps/v1 kind: Deployment metadata: managedFields: # ArgoCDのapplication-controllerによる管理 - manager: argocd-application-controller apiVersion: apps/v1 # kube-apiserverに対するリクエスト内容 operation: Update time: "2022-01-01T16:00:00.000Z" # ArgoCDのapplication-controllerが管理するマニフェストのキー部分 fields: ...
️↪️:Server-Side Apply | Kubernetes
05. dex-server
dex-serverとは
インフラレイヤーにあるdex-serverです。
SSO (例:OAuth 2.0
、SAML、OIDC) を採用する場合に、argocd-serverの代わりに認可リクエストを作成し、IDプロバイダー (例:GitHub、Keycloak、AWS Cognito、Google Auth、など) にこれを送信します。
これにより、argocd-server上の認証フェーズをIDプロバイダーに委譲できます。
↪️:GitHub - dexidp/dex: OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
執筆時点 (2023/05/02) で、argocd-serverは特にOIDCの認可リクエストを作成できるため、ログイン要件がOIDCの場合は、dex-serverを必ずしも採用してなくもよいです。
言い換えれば、その他のSSO (例:OAuth
2.0
、SAML) を使用する場合は、dex-serverを採用する必要があります👍
️↪️:Overview - Argo CD - Declarative GitOps CD for Kubernetes
仕組み
【1】
デプロイ先Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。
【2】
argocd-serverは、認証フェーズをIDプロバイダーに委譲するために、dex-serverをコールします。
認証フェーズを委譲しない場合、このAuthNにて、ArgoCD上で定義したユーザーやグループを認証することになります👍

️↪️:argo-cd/authz-authn.md at master · argoproj/argo-cd · GitHub
【3】
dex-serverは、認可リクエストを作成します。
認可リクエストに必要な情報は、ConfigMap (argocd-cm) で設定しておく必要があります。
argocd-cmのざっくりした実装例は以下の通りです👇
ここでは、IDプロバイダーをGitHubとし、認可リクエストに必要なクライアントIDとクライアントシークレットを設定しています。
apiVersion: v1 kind: ConfigMap metadata: namespace: foo name: argocd-cm data: dex.config: | connectors: - type: github id: github name: GitHub SSO config: clientID: ***** clientSecret: ***** # dex-serverが認可レスポンスを受信するURLを設定する redirectURI: https://example.com/api/dex/callback
dex.config
キー配下の設定方法に関しては、dexのドキュメントをみると良いです👍
↪️:Dex
【4】
dex-serverは、前の手順で作成した認可リクエストをIDプロバイダーに送信します。
【5】
IDプロバイダー側でSSOの認証フェーズを実施します。
IDプロバイダーは、コールバックURL (<ArgoCDのドメイン名>/api/dex/callback
) を指定して、認可レスポンスを送信します。
認可レスポンスは、argocd-serverを介して、dex-serverに届きます。
例えばGitHubをIDプロバイダーとする場合、 Developer settingsタブ でSSOを設定する必要があり、この時に
Authorization callback URL
という設定箇所があるはずです👍🏻
【6】
argocd-serverは、AuthZで認可フェーズを実施します。
ConfigMap (argocd-rbac-cm) を参照し、IDプロバイダーから取得したユーザーやグループに、ArgoCD系リソースに関する認可スコープを付与します。
ざっくりした実装例は以下の通りです👇
ここでは、developerロールにはdev
というAppProjectに属するArgoCD系リソースにのみ、またmaintainerロールには全てのAppProjectの操作を許可しています。
またこれらのロールを、IDプロバイダーで認証されたグループに紐づけています。
特定のArgoCD系リソースのみへのアクセスを許可すれば、結果として特定のClusterへのデプロイのみを許可したことになります👍
apiVersion: v1 kind: ConfigMap metadata: name: argocd-rbac-cm namespace: foo data: # デフォルトのロール policy.default: role:developer policy.csv: | # ロールと認可スコープを定義する。 p, role:developer, *, *, dev/*, allow p, role:maintainer, *, *, *, allow # IDプロバイダーで認証されたグループにロールを紐付ける。 g, developers, role:developer g, maintainers, role:maintainer scopes: "[groups]"
今回の実装例で使用した
p
とg
では、以下を定義できます。
記号 | 説明 | 記法 |
---|---|---|
p (パーミッション) |
ロールと認可スコープを定義する。 | p, <ロール名> <Kubernetesリソースの種類> <アクション名> <AppProject名>/<Kubernetesリソースの識別名> |
g (グループ) |
グループにロールを紐付ける。 | g, <グループ名> <ロール名> |
↪️:RBAC Configuration - Argo CD - Declarative GitOps CD for Kubernetes
06. argocd-server (argocd-apiserver)
argocd-serverとは
最後に、インフラレイヤーにあるargocd-serverです。
『argocd-apiserver』とも呼ばれます。
みんながよく知るArgoCDのダッシュボードです。
また、ArgoCDのAPIとしても機能し、他のコンポーネントと通信します🦄
仕組み
【1】
application-controllerは、デプロイ先Clusterをヘルスチェックします。
【2】
application-controllerは、デプロイ先Clusterのマニフェストと、ポーリング対象のリポジトリのマニフェストの差分を検出します。
【3】
application-controllerは、処理結果をredis-serverに保管します。
【4】
argocd-serverは、redis-serverから処理結果を取得します。
【5】
デプロイ先Cluster管理者がダッシュボード (argocd-server) にSSOを使用してログインしようとします。
【6】
Ingressコントローラーは、Ingressのルーティングルールを参照し、argocd-serverにルーティングします。
【7】
argocd-serverは、ログイン時にIDプロバイダーに認可フェーズを委譲するために、dex-serverをコールします。
【8】
IDプロバイダー上で認証フェーズが完了します。
argocd-serverは、ConfigMap (argocd-rbac-cm) を参照し、デプロイ先Cluster管理者に認可スコープを付与します。
【9】
argocd-serverは、認可スコープに応じて、デプロイ先Cluster管理者がApplicationを操作できるようにします。
その場合、ArgoCD本体をNamespacedスコープモードに設定する必要があります。
Namespacedスコープモードの場合、
apiVersion: v1 kind: ConfigMap metadata: name: argocd-cmd-params-cm namespace: foo data: # 設定してはダメ # application.namespaces: "*" # 全てのNamespaceを許可する。
apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: dev-foo-project namespace: foo spec: # 設定してはダメ # sourceNamespaces: # - "foo"これらにより、`foo`に属するArgoCDは、他のNamespaceにはアクセスできなくなります👍
↪️:Installation - Argo CD - Declarative GitOps CD for Kubernetes
【10】
デプロイ先Cluster管理者は、ダッシュボード (argocd-server) を使用して、ClusterにマニフェストをSyncします。
この時、Applicationを介してapplication-controllerを操作し、マニフェストをデプロイします。
図では、App-Of-Appsパターンを採用したと仮定しています👨👩👧👦
これは、Applicationを階層上に作成するものであり、最下層のApplication配下のマニフェストをより疎結合に管理できます✌️
例えば以下の画像の通り、最上位のApplication配下に、チーム別の親Applicationを配置します (アプリチームの親Application、インフラチームのそれ) 。
その後、両方のApplication配下にさらにチャート別に最下層の子Applicationを配置し、チャートのデプロイを管理します。
アプリチーム最下層の子Applicationではアプリコンテナのチャート、インフラチームの子Applicationでは監視/ネットワーク/ハードウェアリソース管理系のチャートを管理します👍

07. アーキテクチャのまとめ
今までの全ての情報をざっくり整理して簡略化すると、ArgoCDは以下の仕組みでマニフェストをデプロイすることになります👇
08. おわりに
ArgoCDによるデプロイの仕組みの仕組みをもりもり布教しました。
ArgoCDは、UIが使いやすく、仕組みの詳細を知らずとも比較的簡単に運用できるため、ユーザーフレンドリーなツールだと思っています。
もしArgoCDを使わずにマニフェストをデプロイしている方は、ArgoCDの採用をハイパー・ウルトラ・アルティメットおすすめします👍
なお、登場した設計プラクティスのいくつかは、以下の書籍にも記載されていますので、ぜひご一読いただけると🙇🏻
↪️:
謝辞
ArgoCDの設計にあたり、@yaml_villager
さんに有益なプラクティスをご教授いただきました。
この場で感謝申し上げます🙇🏻