GitOpsリポジトリの骨格を作る
目標
GitOps設定リポジトリの標準的なレイアウトを自分で作り、同じbaseが環境ごとに異なる最終マニフェストへレンダリングされることを目で確認します。最後に、そのリポジトリをArgo CDにつなぐApplication・AppProject・app-of-appsのルートまでを、ファイルとして仕上げます。
なぜ重要なのか
GitOpsでは、リポジトリ構造は好みの問題ではなく、運用コストを決める設計です。baseとオーバーレイが正しく分かれていれば、stageからprodへ上げるPRのdiffはイメージタグ1行になり、レビュアーは「設定はそのままで、バージョンだけが上がる」ことを目で確認できます。逆に、環境ごとにYAMLを丸ごとコピーしていると、プロモーションのPRのたびに数十行が変わり、どの行が意図した差なのか誰にもわからなくなります。このラボで作るApplicationとAppProjectは、ラボ環境にArgo CDのCRDがないためファイルとしてのみ作成し、採点はそのファイルを読んで行います。実際の運用でもこれらのファイルはGitにコミットされる成果物なので、形式を正確に身につけることがそのまま実務になります。
ステップ
/root/cgoa-repo/apps/checkout/base、/root/cgoa-repo/apps/checkout/overlays/dev、/root/cgoa-repo/apps/checkout/overlays/stage、/root/cgoa-repo/apps/checkout/overlays/prod、/root/cgoa-repo/bootstrapディレクトリを作成してください。base/deployment.yamlにDeploymentcheckoutを作成してください(spec.replicas: 1、セレクターとPodラベルはどちらもapp: checkout、コンテナ名app、イメージghcr.io/labhub/checkout:1.4.0、containerPort8080)。base/service.yamlにServicecheckoutを作成してください(spec.ports[0].port: 80、targetPort: 8080、セレクターapp: checkout)。base/kustomization.yamlのresourcesに2つのファイルを列挙してください。overlays/dev/kustomization.yamlにresources: [../../base]、namespace: cgoa-dev、namePrefix: dev-を書いてください。overlays/stage/kustomization.yamlにはresources: [../../base]、namespace: cgoa-stage、namePrefix: stage-を書き、さらにreplicasでcheckoutを2に指定してください。overlays/prod/kustomization.yamlにresources: [../../base]、namespace: cgoa-prod、namePrefix: prod-を書き、replicasでcheckoutを3に、imagesでghcr.io/labhub/checkoutのnewTagを1.5.0に指定してください。kubectl kustomize /root/cgoa-repo/apps/checkout/overlays/prodの出力を/root/cgoa-repo/render-prod.yamlに保存してください。/root/cgoa-repo/bootstrap/app-checkout-prod.yamlにArgo CDのApplicationを作成してください(apiVersion: argoproj.io/v1alpha1、kind: Application、metadata.name: checkout-prod、metadata.namespace: argocd、spec.project: checkout、spec.source.repoURL: http://10.0.0.200/labhub/gitops.git、spec.source.path: apps/checkout/overlays/prod、spec.source.targetRevision: main、spec.destination.server: https://kubernetes.default.svc、spec.destination.namespace: cgoa-prod、spec.syncPolicy.automated.prune: true、spec.syncPolicy.automated.selfHeal: true、spec.syncPolicy.syncOptionsの最初の項目CreateNamespace=true)。/root/cgoa-repo/bootstrap/root-app.yamlにapp-of-appsのルートApplicationを作成してください(名前root、ネームスペースargocd、spec.project: checkout、spec.source.path: bootstrap、spec.source.directory.recurse: true、spec.destination.namespace: argocd、自動同期はpruneとselfHealをどちらもtrue)。/root/cgoa-repo/bootstrap/project-checkout.yamlにAppProjectcheckoutを作成してください(metadata.namespace: argocd、spec.sourceReposの最初の項目http://10.0.0.200/labhub/gitops.git、spec.destinations[0].server: https://kubernetes.default.svc、spec.destinations[0].namespace: cgoa-*、spec.clusterResourceWhitelist[0]はgroup""にkindNamespace)。
参考
- レンダリングの確認は
kubectl kustomize <경로>で行います(プレースホルダーはパスです)。kubectl apply -kと違い、クラスターには触れません。 - kustomization.yamlの
replicasは- name: checkout/count: 3の形で、imagesは- name: <이미지>/newTag: "1.5.0"の形です(プレースホルダーはイメージ名です)。 - よくある間違い1: オーバーレイの
resourcesに../../baseではなくファイル名を並べ直して、baseをコピーしてしまうことです。そうするとプロモーションのPRが1行では済まなくなります。 - よくある間違い2:
namePrefixをbaseに置くことです。baseは環境に依存してはならないので、プレフィックスはオーバーレイの役割です。
リポジトリのディレクトリ骨組み
/root/cgoa-repo/apps/checkout/base、/root/cgoa-repo/apps/checkout/overlays/dev、/root/cgoa-repo/apps/checkout/overlays/stage、/root/cgoa-repo/apps/checkout/overlays/prod、/root/cgoa-repo/bootstrapディレクトリを作成してください。
ベース1つに環境オーバーレイ3つ、そしてApplicationマニフェストをまとめて置くbootstrapディレクトリが必要です。上位のパスまで一度に作るmkdirのオプションを使ってください。
baseマニフェストとkustomization
base/deployment.yamlにDeployment checkoutを作成してください(spec.replicas: 1、セレクターとPodラベルはどちらもapp: checkout、コンテナ名app、イメージghcr.io/labhub/checkout:1.4.0、containerPort 8080)。base/service.yamlにService checkoutを作成してください(spec.ports[0].port: 80、targetPort: 8080、セレクターapp: checkout)。base/kustomization.yamlのresourcesに2つのファイルを列挙してください。
baseには、環境に依存しない共通部分だけを入れます。ネームスペースもreplicasも、ここでは決めないほうがよいです。kustomization.yamlのresourcesにファイル名を列挙してください。
devとstageのオーバーレイ
overlays/dev/kustomization.yamlにresources: [../../base]、namespace: cgoa-dev、namePrefix: dev-を書いてください。overlays/stage/kustomization.yamlにはresources: [../../base]、namespace: cgoa-stage、namePrefix: stage-を書き、さらにreplicasでcheckoutを2に指定してください。
オーバーレイのresourcesは、相対パスでbaseを指します。名前の衝突を防ぐプレフィックスのフィールドとネームスペースのフィールドを、kustomization.yamlで指定できます。
prodオーバーレイ(replicasとイメージタグ)
overlays/prod/kustomization.yamlにresources: [../../base]、namespace: cgoa-prod、namePrefix: prod-を書き、replicasでcheckoutを3に、imagesでghcr.io/labhub/checkoutのnewTagを1.5.0に指定してください。
kustomizeには、replicasを名前で指定して変えるフィールドと、イメージ名を探してタグだけを変えるフィールドが別々にあります。パッチファイルなしで、kustomization.yamlの中だけで完結できます。
kubectl kustomizeのレンダリング結果を保存
kubectl kustomize /root/cgoa-repo/apps/checkout/overlays/prodの出力を/root/cgoa-repo/render-prod.yamlに保存してください。
kubectl kustomize <디렉터리>は、オーバーレイを適用した最終マニフェストを標準出力に出します(プレースホルダーはディレクトリです)。クラスターに適用しなくても、望ましい状態を目で確認できます。
Argo CDのApplicationマニフェスト
/root/cgoa-repo/bootstrap/app-checkout-prod.yamlにArgo CDのApplicationを作成してください(apiVersion: argoproj.io/v1alpha1、kind: Application、metadata.name: checkout-prod、metadata.namespace: argocd、spec.project: checkout、spec.source.repoURL: http://10.0.0.200/labhub/gitops.git、spec.source.path: apps/checkout/overlays/prod、spec.source.targetRevision: main、spec.destination.server: https://kubernetes.default.svc、spec.destination.namespace: cgoa-prod、spec.syncPolicy.automated.prune: true、spec.syncPolicy.automated.selfHeal: true、spec.syncPolicy.syncOptionsの最初の項目CreateNamespace=true)。
Applicationは、source(どこから)、destination(どこへ)、syncPolicy(どのように)の3つのまとまりです。自動同期と自己修復、そしてネームスペースの自動作成オプションがどこに入るかを確認してください。
app-of-appsのルートApplication
/root/cgoa-repo/bootstrap/root-app.yamlにapp-of-appsのルートApplicationを作成してください(名前root、ネームスペースargocd、spec.project: checkout、spec.source.path: bootstrap、spec.source.directory.recurse: true、spec.destination.namespace: argocd、自動同期はpruneとselfHealをどちらもtrue)。
ルートは、子のApplicationファイルが入ったディレクトリをsource.pathで指し、そのディレクトリを再帰的に読むように設定します。destinationはArgo CD自身が動いているネームスペースです。
AppProjectで境界を引く
/root/cgoa-repo/bootstrap/project-checkout.yamlにAppProject checkoutを作成してください(metadata.namespace: argocd、spec.sourceReposの最初の項目http://10.0.0.200/labhub/gitops.git、spec.destinations[0].server: https://kubernetes.default.svc、spec.destinations[0].namespace: cgoa-*、spec.clusterResourceWhitelist[0]はgroup ""にkind Namespace)。
AppProjectは、そのプロジェクトのApplicationが、どのリポジトリから、どのクラスター・ネームスペースへ、どのクラスタースコープのリソースを作れるかを制限します。ステップ6で作成したApplicationのprojectの値と、名前が一致している必要があります。