TT Lab
はじめる
学ぶ 学習パス コース

GitOpsとArgo CD

ApplicationとAppProjectを自分で書く

TT Labで続きを見る

目標

Argo CDのApplicationとAppProjectを自分で書いて、「何をどこから読み、どこにどんな順序とポリシーで適用するか」を宣言として表現できるようになります。

なぜ重要なのか

デプロイをスクリプトではなくオブジェクトにすると、3つのことが付いてきます。クラスターに「今何をデプロイされているか」を尋ねられ、RBACと監査ログがただで付き、その宣言自体をまたgitにコミットできます。このラボで埋めるフィールドは、すべて実際の事故と対になっています。pruneは、リポジトリのパスの打ち間違い1回を大量削除に変えうるスイッチであり、retry.backoffがないと、失敗した同期がAPIサーバーを同じ間隔で叩く負荷装置になり、ignoreDifferencesがないと、HPAとArgo CDが互いにreplicasを元に戻し合う無限ループが生まれます。ただし、この環境ではArgo CDコントローラーが実行されません。CRDを登録してカスタムリソースを作ることはできますが、それがひとりでSynced/Healthyに変わることはありません。そのため、採点するのは状態ではなく宣言の正確さであり、その宣言が実際のコントローラーに何をさせるかは、前の読み物と最後のモジュールで扱います。

ステップ

  1. /opt/crds/の下のオフラインCRDバンドルから、Argo CDのCRDが入ったファイルを探し(grep -l applications.argoproj.io /opt/crds/*.yaml)、kubectl apply -fで適用してください。applications.argoproj.ioとappprojects.argoproj.ioの2つのCRDができて、Established条件がTrueであり、ネームスペースargocdがある必要があります。登録された型の一覧を/root/gitops/app/out/crds.txtに保存してください(applicationsという文字列が入っている必要があります)。
  2. argocdネームスペースに、kind: Application、metadata.name: webのオブジェクトを作ってください。spec.source.repoURLはfile:///root/gitops/repo、spec.source.pathはapps/web、spec.source.targetRevisionはmain、spec.destination.serverはhttps://kubernetes.default.svc、spec.destination.namespaceはgitops-lab、spec.projectはplatformです。
  3. webのspec.syncPolicy.automatedを追加して、prune: true、selfHeal: trueにしてください。そして/root/gitops/app/out/prune-note.txtに、pruneを有効にしたときのリスク(パスを誤って指したコミット1つが、大量削除につながる)を、韓国語で2、3行書いてください。
  4. webのspec.syncPolicy.syncOptionsにCreateNamespace=trueとServerSideApply=trueを入れ、spec.syncPolicy.retryにlimit: 3、backoff.duration: 10s、backoff.factor: 2、backoff.maxDuration: 5mを入れてください。
  5. リポジトリ/root/gitops/repoがまだなければ、先に作ってください。/opt/lab/fixtures/gitops/seed/のdeployment.yamlとservice.yamlを/root/gitops/repo/apps/web/にコピーして、git initしたあとコミットすれば済みます。そのあと、リポジトリ/root/gitops/repo/apps/web/のservice.yamlにargocd.argoproj.io/sync-wave: "-1"アノテーションを、deployment.yamlにargocd.argoproj.io/sync-wave: "0"アノテーションを追加してください。値は必ず二重引用符で囲んだ文字列でなければなりません。そして/root/gitops/app/out/wave-note.txtに、同じウェーブの中ではリソースの種類(kind)ごとのデフォルトの順序で適用されるという点を書いてください。
  6. /root/gitops/repo/apps/web/presync-job.yamlに、kind: Jobのフックリソースを作ってください。アノテーションとしてargocd.argoproj.io/hook: PreSyncとargocd.argoproj.io/hook-delete-policy: BeforeHookCreationを入れ、コンテナ名はmigrate、spec.backoffLimitは1、PodのrestartPolicyはNeverにしてください。このディレクトリで、フックのアノテーションが付いたファイルはこの1つだけである必要があります。
  7. argocdネームスペースに、kind: AppProject、metadata.name: platformを作ってください。spec.sourceReposにはfile:///root/gitops/repoだけを(*は禁止)、spec.destinations[0]にはserverhttps://kubernetes.default.svcとnamespacegitops-lab(*は禁止)、spec.clusterResourceWhitelistにはgroup""/kindNamespace、spec.namespaceResourceBlacklistにはgroup""/kindResourceQuotaとgroup""/kindLimitRangeを入れてください。Applicationwebのspec.projectはplatformである必要があります。
  8. webにspec.ignoreDifferencesを追加してください。groupapps、kindDeployment、jsonPointersに/spec/replicas(HPAが所有するフィールド)です。そしてspec.revisionHistoryLimitを5にしてください。最後に、/root/gitops/app/out/gitops-report.jsonを作ってください。applicationsは、argocdネームスペースのすべてのApplicationを{"name": "..."}の形で入れた配列で、projectは"platform"、self_healはtrueです。

参考

Argo CDのAPI型を登録する

/opt/crds/の下のオフラインCRDバンドルから、Argo CDのCRDが入ったファイルを探し(grep -l applications.argoproj.io /opt/crds/*.yaml)、kubectl apply -fで適用してください。applications.argoproj.ioとappprojects.argoproj.ioの2つのCRDができて、Established条件がTrueであり、ネームスペースargocdがある必要があります。登録された型の一覧を/root/gitops/app/out/crds.txtに保存してください(applicationsという文字列が入っている必要があります)。

インターネットがないので、オフラインのCRDバンドルを使います。ファイル名を覚える代わりに、中身で探してください。どのファイルにapplications.argoproj.ioが入っているかは、grepで探せます。

Applicationのソースと対象を定義する

argocdネームスペースに、kind: Application、metadata.name: webのオブジェクトを作ってください。spec.source.repoURLはfile:///root/gitops/repo、spec.source.pathはapps/web、spec.source.targetRevisionはmain、spec.destination.serverはhttps://kubernetes.default.svc、spec.destination.namespaceはgitops-lab、spec.projectはplatformです。

Applicationオブジェクト自身がある場所と、デプロイ先のネームスペースは別です。sourceには、どこから・どこを・どのリビジョンで読むかの3つがすべて必要です。

自動同期・整理・自己修復を有効にする

webのspec.syncPolicy.automatedを追加して、prune: true、selfHeal: trueにしてください。そして/root/gitops/app/out/prune-note.txtに、pruneを有効にしたときのリスク(パスを誤って指したコミット1つが、大量削除につながる)を、韓国語で2、3行書いてください。

automatedの下のスイッチ2つは、別々の仕事をします。1つはリポジトリから消したものを処理し、もう1つはクラスターで変わったものを処理します。危険なほうが何かも書く必要があります。

同期オプションとリトライのバックオフを入れる

webのspec.syncPolicy.syncOptionsにCreateNamespace=trueとServerSideApply=trueを入れ、spec.syncPolicy.retryにlimit: 3、backoff.duration: 10s、backoff.factor: 2、backoff.maxDuration: 5mを入れてください。

syncOptionsは、키=값の形の文字列の配列です(プレースホルダーは、順にキーと値です)。リトライは回数だけでは足りず、間隔がだんだん開くようにする値が3つ必要です。

sync waveでデプロイの順序を作る

リポジトリ/root/gitops/repoがまだなければ、先に作ってください。/opt/lab/fixtures/gitops/seed/のdeployment.yamlとservice.yamlを/root/gitops/repo/apps/web/にコピーして、git initしたあとコミットすれば済みます。そのあと、リポジトリ/root/gitops/repo/apps/web/のservice.yamlにargocd.argoproj.io/sync-wave: "-1"アノテーションを、deployment.yamlにargocd.argoproj.io/sync-wave: "0"アノテーションを追加してください。値は必ず二重引用符で囲んだ文字列でなければなりません。そして/root/gitops/app/out/wave-note.txtに、同じウェーブの中ではリソースの種類(kind)ごとのデフォルトの順序で適用されるという点を書いてください。

ウェーブの値はアノテーションで、数値ではなく二重引用符で囲んだ文字列で書きます。先に作るべきものにより小さい値を、必要なら負の数を与えます。順序を作るには、ファイルが2つ以上必要です。

PreSyncフックのJobを書く

/root/gitops/repo/apps/web/presync-job.yamlに、kind: Jobのフックリソースを作ってください。アノテーションとしてargocd.argoproj.io/hook: PreSyncとargocd.argoproj.io/hook-delete-policy: BeforeHookCreationを入れ、コンテナ名はmigrate、spec.backoffLimitは1、PodのrestartPolicyはNeverにしてください。このディレクトリで、フックのアノテーションが付いたファイルはこの1つだけである必要があります。

フックは、たいていJobです。アノテーションが2つ必要で、1つはどの段階か、もう1つはいつ片付けるかを決めます。削除ポリシーを抜くと、フックのリソースが積み上がり続けます。

AppProjectで境界を引く

argocdネームスペースに、kind: AppProject、metadata.name: platformを作ってください。spec.sourceReposにはfile:///root/gitops/repoだけを(*は禁止)、spec.destinations[0]にはserverhttps://kubernetes.default.svcとnamespacegitops-lab(*は禁止)、spec.clusterResourceWhitelistにはgroup""/kindNamespace、spec.namespaceResourceBlacklistにはgroup""/kindResourceQuotaとgroup""/kindLimitRangeを入れてください。Applicationwebのspec.projectはplatformである必要があります。

許可リストは「書かれたものだけを許可」、拒否リストは「書かれたものだけを禁止」です。リポジトリとネームスペースに*を使うと、プロジェクトを分けた意味がなくなります。アプリをそのプロジェクトに所属させることも、忘れないでください。

無視するフィールドを指定して構成レポートを作る

webにspec.ignoreDifferencesを追加してください。groupapps、kindDeployment、jsonPointersに/spec/replicas(HPAが所有するフィールド)です。そしてspec.revisionHistoryLimitを5にしてください。最後に、/root/gitops/app/out/gitops-report.jsonを作ってください。applicationsは、argocdネームスペースのすべてのApplicationを{"name": "..."}の形で入れた配列で、projectは"platform"、self_healはtrueです。

ほかのコントローラーが所有するフィールドまで元に戻すと、無限同期になります。レポートのアプリの個数は、手で数えず、クラスターに尋ねた結果で作ってください。そうすれば、常に実際と一致します。