kubell Creator's Note

ビジネスチャット「Chatwork」のエンジニアのブログです。

ビジネスチャット「Chatwork」のエンジニアのブログです。

読者になる

いろいろなAWSアカウントのArgo CDを統合した話(3)

いろいろな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を採用しました。

argo-cd.readthedocs.io

採用した理由としては、(何か勘違いしているかもしれませんが)これ以外のオプションでは、Applicaiton側を手動で修正(TargetRevisionの変更など)しても、ApplicationSetの内容で上書きされてしまうためです。 create-deleteなら、とも思いましたが、これはあくまでApplicationSet -> Applicaitonのupdateがされないだけで、Applicationを修正した場合には、上書きされてしまいました。

本来であればprodなど、Applicationを触る可能性が低いものは、sync(あくまでApplicationSet経由でコントロールする)、テスト環境など触りがちなものはcreate-onlyにする、などができるとよかったのですが、、と思っていたら、なんと2.8からできるようになるようです🎊

Argo CD v2.8 Release Candidate. We are pleased to announce that the… | by Keith Chong | Jun, 2023 | Argo Project

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のリソースまですべて消したい、というパターンはあまりない気がするので、preserveResourcesOnDeletiontrueにすることをおすすめします。

ApplicationSetの管理

Application単体のときは、app of appsスタイルで管理していましたが、AutoSyncを導入したりすると、テスト環境でのTarget Revisionの変更などがやりにくく、管理が難しいと感じていました。

そのため、ApplicationSetではapp of appsはやめて、ApplcationSetのみhelmで管理しています。 何度も記載していますが、Chatworkではhelmfileを多用しており、ApplcationSetもhelmfileを利用して、helmで管理してます。

ApplicationSetのChartはないので、helmfileのmanifest template機能を利用しています。

github.com

下記のように./manifests/mgmt配下に*.yaml.gotmplのtemplateをおいておくと、それをtemplateとして利用して、manfiestを生成することが可能になります。

releases:
  - name: argocd-applicationsets
    chart: "./manifests"
    namespace: argocd

ということで、Argo CDのApplicaiotn Setの導入に関して記載しました。 (4)では(4で終わりです)、Argo CDを統合したことによるリソース問題への対応とまとめに関して記載したいと思います。