いろいろな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を統合したことによるリソース問題への対応とまとめに関して記載したいと思います。