いろいろなAWSアカウントのArgo CDを統合した話(2)では主にAWSのクロスアカウントに関して記載しましたが、(3)ではApplicationSetへの対応に関して記載したいと思います。
ApplicationSetの導入
(1)で記載しましたが、Chatworkでは、Argo CDを各EKSクラスタに個別で構築していたために、ApplicationSetを利用する場面がなく(ApplicationSetを作る手間とApplicationを作る手間が変わらない)、Argo CD統合前には導入していませんでした。
しかし、1つのArgo CDで、複数のクラスタを管理するため、今回ApplicationSetを導入して、Cluster Credentialの追加に反応して、Applicationが作成されるようにしました。
ApplicationSetの作成の種類
今回の統合では、EKSクラスタの追加(Argo CDへの登録)を起因として、Applcationを作成したかったため、Cluster Generatorを採用しました。 argocd-applicationset.readthedocs.io
Generatorにはいくつか種類があり、Generatorによって、使えるパラメータが微妙に違うので、やや注意が必要です。
ApplicationSetの具体例
(2)で記載したように、ChatworkではAWSアカウントごとに使用するRoleをCluster Generatorのvaluesに記載し、それをApplicationのtemplateに記載して、利用しています。
具体的には下記のようになります。
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: annotations: meta.helm.sh/release-name: **** meta.helm.sh/release-namespace: argocd labels: app.kubernetes.io/managed-by: Helm name: **** namespace: argocd spec: generators: - clusters: selector: matchLabels: eks/cluster-kind: eks eks/cluster-role: test values: repoServerIamRoleArn: arn:aws:iam::XXXX:role/XXXX - clusters: selector: matchLabels: eks/cluster-kind: eks eks/cluster-role: stg values: repoServerIamRoleArn: arn:aws:iam::YYYY:role/YYYY syncPolicy: preserveResourcesOnDeletion: true template: metadata: labels: group: sre name: '{{ name }}-****' spec: destination: namespace: kube-system server: '{{ server }}' ignoreDifferences: [] project: mgmt source: path: ****/**** plugin: env: - name: HELMFILE_ENV value: '{{ name }}' - name: REPO_SERVER_IAM_ROLE_ARN value: '{{ values.repoServerIamRoleArn }}' repoURL: https://github.com/chatwork/****.git targetRevision: master syncPolicy: syncOptions: - CreateNamespace=true
ところで、Cluster Credentialのlabelでvaluesを振り分ける際に地味に困ったのがin-clusterの扱いでしたが、in-clusterもCluster Credentialを作成することで他のEKSクラスタを同じように扱うことが可能になりました。
ApplicationSetの挙動
ApplicationSetはApplicationのテンプレートですが、微妙にApplcation単体での利用と挙動が異なり、こちらも少し対応に時間がかかりました。
applicationsetcontroller.policyの挙動
Chatworkでは、一時的にtargetRevisionを変えて、デプロイすることがあります。特にテスト環境で、manifest(というかhelmfile)を修正しているときは、main branchに入れる前に確認したいことが多いと思います。 しかしApplicationSet経由でApplicationを作成する場合、基本的にはApplicationSetをテンプレートとして作成するので、ApplcationSetに設定したTarget Revisionの値が採用されます。
そうすると、特定のEKSクラスタでのみ、あるTarget Revisionで確認したい、というパターンに対応しにくくなります。
ApplicationSet -> Applicationを作成する際の挙動は下記のドキュメントのとおりですが、いろいろと試した結果、create-only
を採用しました。
採用した理由としては、(何か勘違いしているかもしれませんが)これ以外のオプションでは、Applicaiton側を手動で修正(TargetRevisionの変更など)しても、ApplicationSetの内容で上書きされてしまうためです。
create-delete
なら、とも思いましたが、これはあくまでApplicationSet -> Applicaitonのupdateがされないだけで、Applicationを修正した場合には、上書きされてしまいました。
本来であればprodなど、Applicationを触る可能性が低いものは、sync(あくまでApplicationSet経由でコントロールする)、テスト環境など触りがちなものはcreate-only
にする、などができるとよかったのですが、、と思っていたら、なんと2.8からできるようになるようです🎊
create-only
だと、ApplicationSetの内容が反映されないので、ApplicationSet修正後に対象のApplicationを消して、再作成させる必要があり、そのあたりはCI(self hosted runnerを利用して、Argo CDが動いているEKSクラスタ内部のPodから)で実行しています。
preserveResourcesOnDeletionの挙動
Applicationだけを作り直したいことがあり、Applicaitonを消すことがあるので、Chatworkではcascadeしないように消していましたが、ApplicationSetから作成されたApplicationではその挙動が変えられず、さらに最初にcreate-deleteなどで試していたときは、ApplcaitonSetを消す -> Applicationが消える -> Kubernetesのリソースがすべて消える、という状況になり、少々困っていました。
ドキュメントはCRDを見ると、実はpreserveResourcesOnDeletion
というパラメータがあり、これをtrue
にすることで、Appicaitonが消えても、リソースが消えることがなくなりました。
お試しで作成したApplicationSet以外ではKuberentesのリソースまですべて消したい、というパターンはあまりない気がするので、preserveResourcesOnDeletion
をtrue
にすることをおすすめします。
ApplicationSetの管理
Application単体のときは、app of appsスタイルで管理していましたが、AutoSyncを導入したりすると、テスト環境でのTarget Revisionの変更などがやりにくく、管理が難しいと感じていました。
そのため、ApplicationSetではapp of appsはやめて、ApplcationSetのみhelmで管理しています。 何度も記載していますが、Chatworkではhelmfileを多用しており、ApplcationSetもhelmfileを利用して、helmで管理してます。
ApplicationSetのChartはないので、helmfileのmanifest template機能を利用しています。
下記のように./manifests/mgmt
配下に*.yaml.gotmplのtemplateをおいておくと、それをtemplateとして利用して、manfiestを生成することが可能になります。
releases: - name: argocd-applicationsets chart: "./manifests" namespace: argocd
ということで、Argo CDのApplicaiotn Setの導入に関して記載しました。 (4)では(4で終わりです)、Argo CDを統合したことによるリソース問題への対応とまとめに関して記載したいと思います。