この記事は、DevOps および理解したい方々に向けて書かれています。
前言#
始める前に、従来の GitOps プロセスについて少し説明します。git リポジトリを使用して ci/cd のパイプラインを構成し、git push の後、現在の git sha に基づいてイメージを構築し、それを kubernetes に適用します。Deployment は自動的に更新されます。
これは非常にシンプルで、非常に便利です。kubernetes は自動的にイメージをローリングアップデートしますが、私たちはもっと多くの問題や要求を持っています。
-
どのようにリソースを変更するか
例えば、レプリカ数を増やしたり、リソースを追加したりするような編成の変更を行った場合、新しい git コミットが作成されます。プロセス上、これは新しいコードをコミットするのと同じで、依然として[ci]->build->deploy
のプロセスを経る必要があります。もちろん、deploy ファイルが変更されたときに build プロセスをトリガーしないようにパイプラインを構成することもできます。src / や app / のようなディレクトリ内でファイルが変更された場合のみ、イメージを一度構築する必要があります。そうすると、新たな問題が生じます。先ほど述べたように、私たちは git コミット sha をイメージタグとしてデプロイに適用しています。例えば、a1b2c3
のコミットを一度コミットしたが、ビルドをスキップした場合、デプロイの段階でエラーが発生します。なぜなら、a1b2c3
というタグのイメージが見つからないからです。 -
どのように機密情報を保存するか
通常、アプリケーションにはDATABASE_URL
やACCESS_TOKEN
のような機密情報が伴います。これらは git リポジトリに保存すべきではなく、プライベートまたはプライベートドメインのリポジトリであっても同様です。これらは通常、kubernetes secret の形式で存在し、secret は単純な base64 暗号化であり、平文ストレージに相当します。もちろん、secret を別に保存することも、直接手動でクラスターに適用することもできます。しかし、これを行うと、一方ではアプリケーションのリリースと secret が切り離され、他方では効果的に管理できなくなります。
ArgoCD#
Argocdは CD ツールで、公式の紹介は以下の通りです。
Argo CD とは?
Argo CD は、Kubernetes 用の宣言型 GitOps 継続的デリバリーツールです。
ArgoCD は Application(以下、app と略します)レベルの単位で管理します。一般的に、1 つの app は単一のクラスター内の単一のアプリケーションに対応します。
ArgoCD は git リポジトリリソースを監視する形式で app を管理し、Helm/Kustomize/Directoryなど、kubernetes リソースを管理するさまざまな方法をサポートしています。簡単に言えば、デプロイする必要があるファイルを git リポジトリに置き、app を正しく構成すれば、argocd はデプロイの変更を監視します。
例えば
さて、ここまでで、私たちは 1 つの問題を解決しました ——《イメージを再構築せずにリソースを変更する方法》
Secret management#
https://argo-cd.readthedocs.io/en/stable/operator-manual/secret-management/
ArgoCD には secret を管理する強制的な方法はありません。上記のリンクでは、推奨される一部の secret 管理方法が言及されています。この記事では、Hashicorp Vault と argocd-vault-plugin をツールとして使用して管理します。
Vault#
Vault は Hashicorp が提供する KV キーと値のペアをサポートする secret ベースのエンジンです。サーバーバージョンの 1password と理解できます。ここでは、Vault のインストールと構成方法については詳しく説明しません。
現在、私たちは secret を vault のkv/<namespace>/<app>
パスに保存すると仮定します。例えば、DATABASE_URL などです。
vault に付属の pod inject は使用要件を満たさないため、ここでは詳しく説明しません。私たちは vault secret を kubernetes secret に同期する方法を望んでいます。
argocd-vault-plugin#
argocd-vault-plugin は argocd が vault にアクセスするためのプラグインで、以下、avp と呼びます。
avp の主な役割は、対応するテンプレートを vault secret に変換することです。
例えば、私が持っている yaml は次のようになります。
kind: Secret
apiVersion: v1
metadata:
name: example-secret
annotations:
avp.kubernetes.io/path: "path/to/secret"
type: Opaque
data:
password: <password-vault-key>
avp で処理された後にクラスターに適用すると、実際のデータになります。具体的には:https://argocd-vault-plugin.readthedocs.io/en/stable/howitworks/
しかし、上記で述べたように、argocd はさまざまなリソース編成ツールをサポートしていますが、デフォルトでは avp は有効になっていません。avp を使用するには、プラグインをカスタマイズする必要があります。つまり、pluginの方法で使用します。
plugin 自体は単なる前処理スクリプトで、AVP Installにある github yaml ファイルの例の一部です。
discover:
find:
command:
- find
- "."
- -name
- kustomization.yaml
generate:
command:
- sh
- "-c"
- "kustomize build . | argocd-vault-plugin generate -"
ここでは、kustomization.yaml を発見するための discover があり、ビルド後に avp プラグインを使用して生成しています。
特に注意 helm と kustomize で使用されるプラグインは異なるため、公式のプラグインの例に従って使用する際には plugin の名前を指定する必要があります。
例えば、plugin = avp-helm および plugin = avp-kustomize としなければなりません。そうしないとエラーが発生します。
kustomize は 4.x バージョンで kustomization 内で helm-charts の構文をサポートしていますが、手動で --enable-helm フラグを使用する必要があります。そのため、私たちはプラグインをカスタマイズしました。部分的なコードは以下の通りです。
avp-kustomize:
allowConcurrency: true
discover:
find:
command:
- sh
- "-c"
- "find . -name kustomization.yaml"
generate:
command:
- sh
- "-c"
- "kustomize edit set annotation \"github.com/url:${ARGOCD_ENV_APP_REPO}\"; kustomize edit set image ${ARGOCD_ENV_IMAGE_NAME}:${ARGOCD_ENV_IMAGE_TAG}; kustomize build --enable-helm . | argocd-vault-plugin -s ${ARGOCD_ENV_AVP_SECRET} generate -"
lockRepo: false
https://argo-cd.readthedocs.io/en/latest/operator-manual/upgrading/2.3-2.4/#update-plugins-to-use-newly-prefixed-environment-variables
記事に示されているように、plugin の env に ARGO_ENV のプレフィックスを追加する必要があります。
ここでは、4 つの環境変数を追加しました。
- IMAGE_NAME イメージ名
- IMAGE_TAG イメージタグ
- AVP_SECRET vault の資格情報を設定
- APP_REPO git リポジトリのアドレス
git リポジトリのアドレスは、クラスター内で特定のリソースがどのリポジトリに属するかを確認するための global annotations に使用されます。
ここまでで、私たちは大部分を完了しました。
Git CI#
github action/gitlab ci/drone などの任意のパイプラインを使用して、対応する構成方法を実現できます。
CI では、2 つのステージ、build と deploy を設定する必要があります。
build ステージは docker イメージをビルドし、イメージリポジトリにプッシュするために使用されます。deploy ステージは argocd app を更新または作成するプロセスです。
主に deploy ステージを紹介します。これは argocd の cli を使用してイメージのタグを更新または作成します。
例:
argocd app create {your_app} \
--repo https://github.com/{git_url} \
--path {your_repo_pass} \
--project {your_project} \
--dest-name {deploy_cluster} \
--dest-namespace {cluster_ns} \
--config-management-plugin=avp-kustomize \
--revision {revision} \
--plugin-env AVP_SECRET={secret_name} \
--plugin-env APP_REPO={git_url} \
--plugin-env IMAGE_NAME={image.name} \
--plugin-env IMAGE_TAG={image.tag} \
--sync-policy automated \
--sync-option ApplyOutOfSyncOnly=true,ServerSideApply=true \
--upsert
これにより、argocd app が作成されます。こうすることで、argocd は自動的に git リポジトリを監視し、deploy ファイルが変更されると、app に適用されるイメージ名とタグが変更されていないため、以前のイメージから新しいデプロイを生成できます。
したがって、git パイプラインでいくつかのトリガー条件を設定し、deploy ファイルを除外するか、コードファイルのみを含めることができます。
まとめ#
この記事では、argocd、vault、argocd-vault-plugin、ci を連携させて使用し、比較的整った gitops エコシステムを構築する方法について説明しました。成熟した商業ソリューションには及ばないかもしれませんが、オープンソースのコンポーネントを自由に組み合わせることで、最適な実践形式を見つけることができます。
例えば、CI と Git リポジトリには何の制限もなく、vault と avp を使用するのも私の提案に過ぎません。argocd で言及されている secret を管理する方法は、プラグインの形式で使用することができます。