ApplicationSet controller とは
ApplicationSet controller は ArgoCD の Application リソースをまとめて生成・管理するためのコントローラです。ApplicationSet controller は ArgoCD のサブプロジェクトとして、複数のクラスタ間やモノレポにある Application リソースの自動化や柔軟な管理を目的に開発が進められたようです。
ApplicationSet controller を利用することで冗長になりやすかった複数ある Application リソースを ApplicationSet リソースとして一つにまとめられメンテナンスコストの削減に繋がります。
この記事では現時点(2021/07/27)で最新版である v0.1.0 (2021/04/07 released) を対象とします。
インストール方法
すでに ArgoCD を動作させているクラスタがある前提でインストール手順を紹介します
手順は簡単で公式マニュアルに書いてあるとおりの手順でインストールすれば動作しました。
ArgoCD がすでに動作しているクラスタ(argocd namespace に存在する前提)であれば以下の手順を実行するだけでインストールすることができます。
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/applicationset/v0.1.0/manifests/install.yaml
公式マニュアルには ArgoCD とまとめてインストールできる YAML ファイルも用意されているのでもし未インストールのクラスタで試したい場合はそちらを利用すると良いかもしれません。
インストールできると以下のように Application controller pod が起動すると思います。
$ kubectl -n argocd get pod
...
argocd-applicationset-controller-76fc4dc766-8ndzp 1/1 Running 0 20h
...
Podが正常に Running になっていたら無事インストール完了です。
使い方
ApplicationSet controller の Pod が正常に起動したら ApplicationSet を使って実際に Application リソースを作ってみます。
使い方は名前からなんとなくイメージができると思いますが、Kubernetes の RepliacaSet と Pod の関係と似ていて ApplicationSet に以下の2点を記述し、その2点を ApplicationSet controller が見て Application リソースを生成してくれるというものになります。
- generator
- 生成する単位とtemplatesを使ってどのように生成するかを指定するフィールド
- templates
- Application リソースのテンプレート
- generator 毎に用意された変数をテンプレートに利用できる
実際にやってみましょう。公式にあるサンプルをデプロイしてみます。(一部古いのか誤っている部分があるので修正しています)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook
spec:
generators:
- list:
elements:
- cluster: engineering-dev
url: https://1.2.3.4
- cluster: engineering-prod
url: https://2.4.6.8
- cluster: finance-preprod
url: https://9.8.7.6
template:
metadata:
name: '{{cluster}}-guestbook'
spec:
source:
repoURL: https://github.com/infra-team/cluster-deployments.git
targetRevision: HEAD
path: 'guestbook/{{cluster}}'
destination:
server: '{{url}}'
namespace: guestbook
project: default
$ kubectl -n argocd apply -f guestbook.yaml
applicationset.argoproj.io/guestbook created
デプロイしたので見てみます。
$ kubectl -n argocd get applicationset
NAME AGE
guestbook 95s
$ kubectl -n argocd get application
No resources found in argocd namespace.
Application リソースは生成されていませんでした。
コントローラのログや ApplicationSet リソースの status を見てみましたが、特にエラーなども出ていません。
登録されていないクラスタが指定してあるのが原因なのかもしれません。クラスタを正しい値にして試してみます。
spec:
generators:
- list:
elements:
- cluster: engineering-dev
- url: https://1.2.3.4
+ url: ここを正しいクラスタのURLに変更する
$ kubectl -n argocd get apps engineering-dev-guestbook -o yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
creationTimestamp: "2021-07-27T02:58:16Z"
finalizers:
- resources-finalizer.argocd.argoproj.io
generation: 5
name: engineering-dev-guestbook
namespace: argocd
ownerReferences:
- apiVersion: argoproj.io/v1alpha1
blockOwnerDeletion: true
controller: true
kind: ApplicationSet
name: guestbook
uid: 06dd86e8-2890-43b0-b7a0-bf588f6cde4d
resourceVersion: "378942533"
uid: 72928e11-556c-4af9-b922-575c3be48db3
spec:
destination:
namespace: guestbook
server: https://xxxxxxxxxxxxxxx.git
project: default
source:
path: guestbook/
repoURL: https://github.com/infra-team/cluster-deployments.git
targetRevision: HEAD
無事生成されました。Health が Unknown になっていますが上記のリポジトリが存在しないため同期ができないためです。正しいリポジトリを設定すれば動作します。
上記のように templates の変数が展開され Application が作られています。
このように生成できるので上記であれば複数の element を list に記述すれば一つのリソースで複数の Application リソースを管理できるようになります。
また、上記のように finalizers も自動的に設定されるので ApplicationSet リソースの変更などで Application リソースが削除されるときはその Application によってデプロイされたリソースも削除されます。
https://argocd-applicationset.readthedocs.io/en/stable/Application-Deletion/
ApplicationSet リソースを削除しても ownerReferences に指定してあるので Application リソースも削除されます。
その為不要になったら以下のように ApplicationSet リソースを削除すればデプロイされたすべてのリソースが削除されます。
$ kubectl -n argocd delete -f guestbook.yaml
Generator
上記のサンプルでは list generator を利用していましたが、 v0.1.0 時点では以下の3つの generator が用意されています。
それぞれ軽く紹介していきます。
list generator
list generator は先程のサンプルのようにクラスタ名とそのクラスタのURLからなる固定のリストをパラメータとして生成するジェネレータです。
細かい部分は先ほど紹介したので省きますが、一点注意点としてパラメータとして定義できるのは cluster と url のみ となっています。
他のパラメータは定義できないので注意してください。
自分も他のパラメータが定義できると思って試してみましたがエラーになるようでした😅
cluster generator
cluster generator は ArgoCD に登録されているクラスタのリストを使って各クラスタ毎に Application リソースを生成するジェネレータです。
ArgoCDの複数クラスタのセットアップを行ったことがある人ならわかると思いますが、ArgoCD に登録されているクラスタのリストというのは実際には cluster にアクセスするための情報を保存している secret リソースになります。
具体的には https://argoproj.github.io/argo-cd/operator-manual/declarative-setup/#clusters で作成する Secret リソースです。
勘の良い人はお気づきだと思いますが、cluster generator は上記の Secret リソースを用意しなくても良いローカルクラスタ(つまり ArgoCD が動作しているクラスタ)は Secret がないので、そのままでは clsuter generator の対象になりません。
対処法としては本来は必要がないローカルクラスタように Secret を作成するという方法がドキュメントでは紹介されています。
https://argocd-applicationset.readthedocs.io/en/stable/Generators/#deploying-to-the-local-cluster
他のジェネレータと違う点として label selector が以下のように指定でき、Secret リソースに適応させたいクラスタなどにラベルを付与して、それを label selector で指定すれば特定のクラスタのみに適応する ApplicationSet なども作ることが可能です。指定の例は以下のとおりです。
kind: ApplicationSet
metadata:
name: guestbook
spec:
generators:
- clusters:
selector:
matchLabels:
staging: true
template:
# (...)
テンプレートして利用できるパラメータはドキュメントにも書いてありますが以下の4つです。
-
name
: Secret に指定してあるクラスタ名 -
server
: Secret に指定してあるクラスタURL -
metadata.labels.<key>
: Secret に指定してあるラベル -
metadata.annotations.<key>
: Secret に指定してあるアノテーション
ラベルやアノテーションも指定ができるのでかなり自由にパラメータを設定することが可能なジェネレータとなっています。
git generator
git generator は git リポジトリのファイルやディレクトリを使って生成するジェネレータです。ファイルとディレクトリの両タイプに対応していて、それぞれ使い方が異なります。
ディレクトリ
ディレクトリのほうはリポジトリのディレクトリ構造を利用して生成します。
例えば以下のようなディレクトリ構造だったとすると、
├── argo-workflows
│ ├── kustomization.yaml
│ └── namespace-install.yaml
└── prometheus-operator
├── Chart.yaml
├── README.md
├── requirements.yaml
└── values.yaml
以下のように指定することで
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
spec:
generators:
- git:
repoURL: https://github.com/argoproj-labs/applicationset.git
revision: HEAD
directories:
- path: examples/git-generator-directory/cluster-addons/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/argoproj-labs/applicationset.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
argo-workflows と prometheus-operator の2つの Application が生成されるというものです。
こちらについてはあまりカスタマイズ性は高くなく、以下のパラメータのみが利用できます。
-
path
: path ワイルドカードと一致する Git リポジトリ内のディレクトリパス -
path.basename
: path ワイルドカードと一致する Git リポジトリ内のディレクトリパスについて、右端のパス名が抽出されます(たとえば、/directory/directory2
なら directory2)
ファイル
ファイルは指定されたリポジトリ内で見つかった JSON ファイルのコンテンツを使用して生成するジェネレータです。
例えば以下のようなファイル構成だったとすると
├── apps
│ └── guestbook
│ ├── guestbook-ui-deployment.yaml
│ ├── guestbook-ui-svc.yaml
│ └── kustomization.yaml
├── cluster-config
│ └── engineering
│ ├── dev
│ │ └── config.json
│ └── prod
│ └── config.json
└── git-generator-files.yaml
以下のように path を指定したとします。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook
spec:
generators:
- git:
repoURL: https://github.com/argoproj-labs/applicationset.git
revision: HEAD
files:
- path: "examples/git-generator-files-discovery/cluster-config/**/config.json"
template:
metadata:
name: '{{cluster.name}}-guestbook'
spec:
project: default
source:
repoURL: https://github.com/argoproj-labs/applicationset.git
targetRevision: HEAD
path: "examples/git-generator-files-discovery/apps/guestbook"
destination:
server: '{{cluster.address}}'
namespace: guestbook
そうすると examples/git-generator-files-discovery/cluster-config/**/config.json
に一致する JSON ファイルの中身を見て JSON ファイルに記載されたパラメータを使って template から Application リソースを生成します。
この JSON ファイルでは自由にパラメータを定義できるため、かなり柔軟に Application リソースを生成することができます。
その他
v0.1.0 では以上の3つの generator のみですが、次のバージョンではつぎのいくつかのジェネレータが追加されそうでいくつか PR がマージされていました。少し紹介します。
- Matrix generator: https://github.com/argoproj-labs/applicationset/pull/205
- 複数の generator を組み合わせることができるようでした
- Github generator: https://github.com/argoproj-labs/applicationset/pull/209
- Github の API のレスポンスをパラメータにできるようです
- ブランチをパラメータとして生成するなどができるようでした
仕組み
仕組みは Kubernetes をご存じの方なら書くまでもないですが、CRDといわゆるカスタムコントローラ(Operator)として実装されています。
詳しくは https://argocd-applicationset.readthedocs.io/en/stable/Argo-CD-Integration/ にまとまっているのでそちらを参照するとよいかと思います。
まとめ
この記事では ArgoCD ApplicationSet controller の概要と簡単な機能を紹介しました。
自分のチームでも同じような Application リソースが大量にあって整理できていなかった部分がありましたが、ApplicationSet を導入することでかなり整理され、見やすくまた管理しやすい状態になりました。
参考文献
- Generating Applications with ApplicationSet: https://argoproj.github.io/argo-cd/user-guide/application-set/
- 公式リポジトリ: https://github.com/argoproj-labs/applicationset
- 公式ドキュメント: https://argocd-applicationset.readthedocs.io/en/stable/