|
GitOpsの基本原則は、すべてがコードであるということです。つまり、ユーザー名、パスワード、証明書、トークンなどの機密情報もGitリポジトリに保存する必要があります。これは明らかに非常に安全ではありません。しかし、Vault、Keycloak、SOPSなどのシークレット管理ツールを使用することで、この問題は解決できます。最も簡単な方法はSOPSを使用することです。SOPSはPGPキーを使用してコンテンツを暗号化できるためです。kustomizeを使用すれば、同じPGPキーを使用してクラスター内のシークレットを復号化することもできます。ArgoCDにはシークレット管理機能が組み込まれていませんが、任意のシークレット管理ツールと統合できます。 sopsは、YAML、JSON、ENV、INI、BINARY形式をサポートするオープンソースの暗号化ファイルエディタです。AWS KMS、GCP KMS、Azure Key Vault、age、PGPを使用して暗号化することもできます。公式推奨では暗号化と復号にageを使用することが推奨されているため、ここではageを使用します。age[1]は、シンプルでモダンかつ安全な暗号化ツール(およびGoライブラリ)です。 SOPSとAGEまず、ageツールをインストールする必要があります。対応するインストールパッケージはリリースページ[2]から直接ダウンロードできます。 $ wget $ tar - xvf age - v1.0.0 - linux - amd64 。 タール。 ガズ $ mv age / age / usr / local / bin $ mv age / age - keygen / usr / local / bin $ 年齢-- バージョン v1.0.0 次に、リリースページ[3]から対応するインストールパッケージを直接ダウンロードして、sopsをインストールします。 $ wget $ mv sops - v3 .7 .3 . linux . amd64 sops && chmod + x sops $ mv sops / usr / ローカル/ bin インストールが成功したかどうかを確認するには、次のコマンドを使用します。 $ sops -- バージョン sops 3.7.3 (最新) まず、SOP を使用して暗号化をテストするための簡単な Secret を作成しましょう。 $ kubectl シークレット汎用アプリを作成- シークレット\ -- from - リテラル= トークン= SOPS - AGE - TOKEN - TEST \ -- ドライラン= クライアント\ - o yaml > シークレット. yaml 生成されたシークレット リソース マニフェスト ファイルを以下に示します。 apiバージョン: v1 データ: トークン: U09QUy1BR0UtVE9LRU4tVEVTVA == 種類: 秘密 メタデータ 名前: アプリ- シークレット 次に、`age-keygen`コマンドを使用して、暗号化用の公開鍵と秘密鍵を生成します。秘密鍵は、以下のコマンドで`key.txt`ファイルに保存できます。 $ age -keygen -o key . txt 公開鍵: age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt 次に、上記の秘密鍵を使用して、生成された secret.yaml ファイルを暗号化します。 $ age -o シークレット. enc . yaml - r age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt シークレット. yaml 暗号化された secret.enc.yaml ファイルの内容を以下に示します。文字化けした文字が表示されています。 age-encryption.org/v1 -> X25519 x8bynJlv6Sz03ks71Jvn92RZQ6IlTj9B8zgU3lJsOFQ sqrP + zq9nw93mafbBjuc5F6GWIjjzdYtQV6DtV9KiTw --- 6 W1cpc ��NY0Y��� ^ � / A��i�� . �N��� = �ԦPb�ļ���҈v ?-< t�t� / $ �Zs�۸�gKz�U���Kf�aϛ�� � + YjgIDP > > g2m9RaqfCqn @ O'gP6 同様に、暗号化されたファイルを復号化することもできます。 $ age -- decrypt -i key . txt secret . enc . yaml apiバージョン: v1 データ: トークン: U09QUy1BR0UtVE9LRU4tVEVTVA == 種類: 秘密 メタデータ 作成タイムスタンプ: null 名前: アプリ- シークレット 同様に、sops は age との統合もサポートしています。次の sops コマンドを使用して secret.yaml ファイルを暗号化できます。 $ sops -- 暗号化-- age age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt secret . yaml > secret . enc . yaml 暗号化されたファイルの内容を以下に示します。 apiバージョン: ENC [ AES256_GCM 、 データ: e7E = 、 iv : Pfwj3 / 74 CygAHtWlt9tsnexrH74nfa0teNZzknzfGwA = 、 タグ: U2yJjnalFOuGe8rQK + c7Ng == 、 タイプ: str ] データ: トークン: ENC [ AES256_GCM 、 データ: 8 kwq4GqETBJjHbrtS5S3AqJIPcq3Nmf8Gg1muQ == 、 iv : l7O1UnjzcXOkc48EVvbqGPVv0RQxxNX3aIzCU5B / 7 / o = 、 タグ: XuNw / N7XDLU17BOQkjn5Rg == 、 タイプ: str ] 種類: ENC [ AES256_GCM 、 データ: U4hGrF9C 、 iv : CloG5 / RgWHXN / lNGKHGNxeZJXj8kfjw8OmFAxQblUgY = 、 タグ: gq0wKDUa50odvRNcak + Vig == 、 タイプ: str ] メタデータ 作成タイムスタンプ: null 名前: ENC [ AES256_GCM 、 データ: PEhXQdE3 / vj + bA == 、 iv : dkWCj5cAqc4IeB2lXdxC7otmCmFn3vGe5s2Ij3uh8ag = 、 タグ: bbUaA1dqXnrLaTnCPVnxpQ == 、 タイプ: str ] ソップス: km : [] gcp_kms : [] azure_kv : [] hc_vault : [] 年: - 受取人: age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt 暗号化: | ----- 開始年齢暗号化ファイル----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0 + IFgyNTUxOSBwY3JKdmxVM2lFb0NpTjVj cGdyc3d1QXBvN3RVdzAwMVNVMXZrS3pLYm1zCnZqTGZ5TzVBL2VSay80RkFFTlBC R1NtZmxoYVlTd2RyWUl1c24wME83K00KLS0tIENlczRGb1QzRCtCeWxpMU9PTXN5 QnpyckI1bmZSSFliMUgyUDlkd0tWalUKK4vKJwcGLsZn5wT9WHh5tvNOEGScOlAb Fx118rutRK4nVpfIhAvhfS9TDqvhaQ2wFVv3N / a / BhkYpwTrE / cjmQ == ----- END AGE 暗号化ファイル----- 最終更新日時: "2022-08-18T08:04:35Z" mac : ENC [ AES256_GCM 、 データ: / ujRqRKFR / 5u qRBGAZzVIsdVR95In18zUrKuHFuJnHrrfRAt4WXzSUTBovIqOaGPQxXvY4jqkWnd7kqlO629CjK3SA6 selEb8N6ytN5kGquGUqSYlOAjsnk575VtpMKXIr8jeaGkzJRmU6aEnbPa18kekw0FCX1aP6yubD8Ce2Y = 、 iv : / bRn1tk7iXplz4OGxqkUGD4UQRRtb5jUnICQyFnT4fg = 、 タグ: kt9CzFye1OXsq + MKXTZeXA == 、 タイプ: str ] pgp : - 作成日時: "2022-08-18T08:04:35Z" 暗号化: |- ----- PGP メッセージ開始----- wcFMA0Eva10jiAHJAQ /+ LgUsrJKoo95yCIxbMT1OPjnJhAK / LkIwY9EdHbJewphI CKwpDwvsrbdpjcmBkCt4sL4S30bPR3qdAjLxJCnGTJPZQzxjOEIzvJNAG5nC3zk / UVPAWj7nV26CCPMc +/ j / GHGwMphoLviMr9et0adtaWILSP0yhMuH8LVzGa04WVEz AihT849sF /+ WrUy4f7axI4Z2IH2mEepSqNZDQR9mmiu + nA9e + QZqsfazLJXRPsNd 2 hQn7qSGPZ10bzy9ccA5nO5r1oU2J + GEEMYujur / RL8y5oi3BCSvWc0udfuU0dka Nn77OA73zS8aziA9pj3D46wgeGYFfX7h2XKytSI15GGTAT7RmM6D2cB9xWzeQncy 4 TN0LDvcw / 7 SRjxY55iDyYHPLTNlMfajKwXoKfeQX5nd0rnZRCovYDoj2OrqZDff 1 N25EEWN6MSztZML0eE / k / p7RDBG9bJ6lntXNAXQJRjzhUYeHMnXLc9NCN5P3WdW Ny155SsGK6n9Ok1SdAolqlOFRKiO8AA + 2 jPVS7aDUrWktqPCa8hzf / Bm1ttBoYjw D5Xc5x3IcyZDIISqz / 9 cQYfiPusZohpGnfwoea5qhvXEY / wM5IwfLdTm8u78djho HMLFdFUzuprkHZlZlP3HfPbZi5wGpmiqAuYX + i40teOEaQNGhE7HKCJZkAVS0J3S UQHmBMxL1SL / JGAdSsuddB0liIIriENIxr14W04zeJ + pClxvnzxNYigOYM3Jk8wF w7zmhD3IvEpSLG0f4a / c486LpNryBBz6qzBZRYqnJ87PQQ == = K5dC ----- PGP メッセージ終了----- fp : CCC4D0692165A88405EF1F579CC5737D5CCB9760 暗号化されていないサフィックス: _unencrypted バージョン: 3.7.3 ご覧の通り、主要なフィールドは暗号化されています。ただし、「kind」などの他のフィールドも暗号化されます。暗号化が必要なフィールドは、以下に示すように.sops.yamlファイルを作成することで指定できます。 # .sops .yaml 作成ルール: - 暗号化正規表現: "^(ユーザー名|パスワード|)$" 年齢: "CCC4D0692165A88405EF1F579CC5737D5CCB9760" この場合、ユーザー名とパスワードのフィールドのみが暗号化されます。 ArgoCDはSOPSを統合これで、SOPSを使ってプライベートファイルを暗号化・復号化できるようになりました。前の例では、ArgoCDのHelm Chart方式を使ってアプリケーションを同期しました。例えば、valuesファイルにプライベート情報を提供します。これをプレーンテキストで提供し、Gitリポジトリに保存するのは明らかに非常に危険です。このとき、SOPSを使ってこれらのvaluesファイルを暗号化できます。もちろん、アプリケーションを同期する際には、ArgoCDが相手のSOPSによる復号化をサポートしている必要があります。ここでもHelmプラグインhelm-secrets[4]を使用する必要があります。 次に、Argo CDでSOPSサポートを有効にする必要があります。一般的に、主に2つの方法があります。 helm と sops を使用してカスタム ArgoCD Docker イメージを作成し、そのカスタム Docker イメージを使用しますが、ArgoCD の新しいバージョンごとにこのイメージを更新する必要があります。 こちらの説明に従って、SOP付きのHelmプラグインを取得し、Podで使用するには、Argo CDリポジトリサーバーのデプロイメントに初期化コンテナを追加してください。Argo CDのバージョンを更新しても、プラグインのバージョンとArgo CDのバージョンの間に互換性の問題がない限り、プラグインを更新する必要はありません。 簡潔にするために、以下のDockerfileに示すように、カスタムイメージ作成の最初の方法を使用します。これにより、SOPとhelm-secretsがArgo CDイメージに統合されます。 ARG ARGOCD_VERSION = "v2.4.9" argoproj / argocd から: $ARGOCD_VERSION ARG SOPS_VERSION = "3.7.3" 引数VALS_VERSION = "0.18.0" ARG HELM_SECRETS_VERSION = "3.15.0" ARG KUBECTL_VERSION = "1.24.3" # ラッパースクリプトを使用する場合、 HELM_SECRETS_HELM_PATH は実際のhelm バイナリのパスである必要があります ENV HELM_SECRETS_HELM_PATH =/ usr / local / bin / helm \ HELM_PLUGINS = "/home/argocd/.local/share/helm/plugins/" \ HELM_SECRETS_VALUES_ALLOW_SYMLINKS = false \ HELM_SECRETS_VALUES_ALLOW_ABSOLUTE_PATH = false \ HELM_SECRETS_VALUES_ALLOW_PATH_TRAVERSAL = false ユーザールート apt を実行してアップデートを取得&& \ apt - get install -y カール&& \ apt - クリーンアップ&& \ rm -rf / var / lib / apt / リスト *
上記のDockerfileを使用してイメージ(cnych/argocd:v2.4.9)を再構築した後、 argocd-repo-serverアプリケーションのイメージを置き換えます。その他のコンポーネントは置き換える必要はありません。 ArgoCD はデフォルトでリモート値プロトコルとして http:// と https:// のみをサポートしているため、 argocd-cm ConfigMap にも helm-secrets プロトコルを追加する必要があります。 apiバージョン: v1 種類: ConfigMap メタデータ ラベル: app.kubernetes.io / 名前: argocd - cm app.kubernetes.io/ 一部: argocd 名前: argocd - cm データ: helm.valuesFileSchemes : > - シークレット+ gpg - インポート、 シークレット+ gpg - インポート- kubernetes 、 シークレット+ 年齢- インポート、 シークレット+ 年齢- インポート- kubernetes 、 秘密 https 次に、Argo CDリポジトリサーバーが秘密鍵にアクセスして暗号化されたファイルを復号できるように設定する必要があります。ここでは、先ほどのage-keygenコマンドで生成された秘密鍵ファイルkey.txtを使用して、Kubernetes Secretオブジェクトを作成します。 $ kubectl create secret generic helm - secrets - private - keys --from - file = key . txt - n argocd ここで、このシークレットをボリュームとして argocd-repo-server にマウントする必要があります。 巻数: - 名前: helm - シークレット- プライベート- キー 秘密: secretName : helm - シークレット- プライベート- キー # …… ボリュームマウント: -mountPath : / helm - secrets - private - keys / 名前: helm - シークレット- プライベート- キー …… 次に、argocd-repo-serverコンポーネントを更新します。更新が完了したら、以下のようにArgo CDアプリケーションを作成し、暗号化されたファイルを復号化できます。 apiバージョン: argoproj .io / v1alpha1 種類: アプリケーション メタデータ 名前: アプリ 仕様: ソース: ヘルム: 値ファイル: # 方法1 : Kubernetes シークレットからgpg キーをボリュームとしてマウントする # secrets + gpg - import : # secrets + age - import : # 方法例1 : ( 前提: key - volume - mount =/ helm - secrets - private - keys 、 key - name = app 、 secret.yaml がルートフォルダーにある) - シークレット+ 年齢- インポート: ここで、以前の devops-demo アプリケーションの例を使用して再度テストします。 DevOpsデモをデプロイする これからデプロイする my-values.yaml ファイルを SOP を使用して暗号化します。 $ sops -- encrypt -- age age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt my - values . yaml > my - values . enc . yaml 暗号化されたファイルの内容を以下に示します。 画像: リポジトリ: ENC [ AES256_GCM 、 データ: ZDnA7yTAe2B + TbcQYhcs4yufLgXJWHzX7IUnYdOXtsqzfEo = 、 iv : 4 yn + RkQoTHNVW8Y5yDzHsY2hhpMo8yw6j / uj9g6AvMA = 、 タグ: IPwFo2AfLT7yBwoKrvCLCg == 、 タイプ: str ] タグ: ENC [ AES256_GCM 、 データ: koDRtD5NfWn03JJLAZnYYWLgwsJr / kSKtw8WHJoeSLD8Zco4M0Doqw == 、 iv : DbxefZ03J7dGRviRq2DQHhRkcBiBY5FgSh1lJwjwzEg = 、 タグ: zc6ZL5ObSymSVH + caxUzpA == 、 タイプ: str ] プルポリシー: ENC [ AES256_GCM 、 データ: dJ + xl6llTN2NcEKL 、 iv : 入口: 有効: ENC [ AES256_GCM 、 データ: eZB9GA == 、 iv : p12fWs14ATWke0IiMz0SpAb2rW + ViYcEpGRbOoNt9Uk = 、 タグ: w371uI / KRESNP30eD9rrTQ == 、 タイプ: bool ] ingressClassName : ENC [ AES256_GCM 、 データ: WviAhbo = 、 iv : Vqx0R8RVWkGipZkR2HZfyOYyZdkc + 1f hFEV7AdpI4t0 = 、 タグ: fv2hf94svXOQeqfjqXN4gg == 、 タイプ: str ] パス: ENC [ AES256_GCM 、 データ: jg == 、 iv : cRm / OXlGEbNEHhAAm / JpPx5sP9GRmW1fyEAi + SZhfjY = 、 タグ: QAJmQSQ5qWfjnzrm + MWLbQ == 、 タイプ: str ] ホスト: - ENC [ AES256_GCM 、 データ: tb32cnmE1d2qnzzsmG2NzMVOPxkW 、 iv : RH57dgs0gIS28mB83YX + SQNFNjwoTfPa28YvZsCAJW4 = 、 タグ: J7SJXkZKPyydx8NvvCh22w == 、 タイプ: str ] リソース: 制限: cpu : ENC [ AES256_GCM 、 データ: uys2 、 iv : UfAl2lP2wLzc0GkLcBs33vl4dQqLiXWmoyyucqovuVM = 、 タグ: yXRpMIS11s0iqVZQpJ / Bdw == 、 タイプ: str ] メモリ: ENC [ AES256_GCM 、 データ: fBHSfog = 、 iv : lf6fTZfOPlhQVspm2BAl56ps8Q5W6Qz4tMT7A8Au9tA = 、 タグ: XZqHEWEb2qBjWms / qTsAOQ == 、 タイプ: str ] リクエスト: cpu : ENC [ AES256_GCM 、 データ: MDYW 、 iv : / j6A3oVQ4HILXFLVAr8Rjcq2CDdHrtPa70uySxQQeBI = 、 タグ: EyWwWl0hFkTWzHFBXndFeA == 、 タイプ: str ] メモリ: ENC [ AES256_GCM 、 データ: qiwPiRI = 、 iv : m / oFxJrcdysf26ry7LEcL6IQRRqi5B8Zsjc / YJOkO7c = 、 タグ: 3 brvdx + dFUN0VyJ6KO8biQ == 、 タイプ: str ] ソップス: km : [] gcp_kms : [] azure_kv : [] hc_vault : [] 年: - 受取人: age1wvdahagxfgqc53awmmgz52njdk2zm6vkw760tc368gstsypgvusqy7zvtt 暗号化: | ----- 開始年齢暗号化ファイル----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0 + IFgyNTUxOSAyeHNNTWJhWHZHZERJNnlh L1FpMkdibERFM2ZtU2FFZ1VhMnYxVG90dUNBCmpTVEk3ODg4aWlhOEY3cDdMSWFW ZmdoaGtQT3NDU0E0bEZPQlJqNXNuamsKLS0tIHhEcm5memczQTNaVGZzUGNGQmsw cW1QSDd4dDdwZnI2ZzloM2tGRFJxTW8KMPU93lWiNMMaCfOUANmsv + kfi4R7NAzP nV2H2EyCTQGsNTeKCS / HkmiSD4 / 4 RLui4Z6TbPf8ALpeGHDH8rVSoA == ----- END AGE 暗号化ファイル----- 最終更新日: "2022-08-18T08:18:05Z" mac : ENC [ AES256_GCM 、 データ: Z + KJTZRP6L2QEcSG6S43fvqWsROAwEVnQcVkpN / yU1Kk8x0PUXXZkdyJiykQ + 7 HRBNWJp1wKF1TAlqnrZyUSXx7zl5fZGbalgK8kRKzzTzdSsB + Cp4Km5uYNqWUh + RFtzRVOYwOU7fOsAxiHLFMjzaqLAE6 + WsCY9xjfj67NymA = , iv : Kyckp64XCkmpbeSEiampXp47Qr9ZIJRZUWsLDhHIw / 4 = 、 タグ: / eH5d5e9anLRoiCxdWPS / w == 、 タイプ: str ] pgp : - 作成日時: "2022-08-18T08:18:05Z" 暗号化: |- ----- PGP メッセージ開始----- wcFMA0Eva10jiAHJAQ / 9 HZJck5xCbIB43fYrmnrMokwQB5HPMMCpl8gw / U4Cz / RD zs6nlIXhO1U29rQT3s2G9IjfCS0ehfwA6lKGXAuK10jY9HJ7dVthWnKlNsCq35d / 5 ZKzKIT2mvK1h6 + qYai86FwGyG436nAw198oNvC4d9E46PfBcx7PXP1lRFoOJI7V St81HwFTWOd88tkPyIfv2XW1bcvWo7Qz8YunNqGriD3SREwgkSlcyIL4neumWAru YGzTmwEXFjwcTIzel57fI42Qd61wq1p7CKw8njs1pOGucC3uX1b99f1BaeLdQl3C lJvYrP0SYKJ / JA2kPRkeJHDd39ywI8A / iNOW4nRFxbMoAHdEiwAUg2DOCfMwDgVu WQiQqTF + 7 AycdqjpXYjYZ7SI3al6jhcDA2KxvNsPNjT8F5yl3c9MIwMdo / NRoc6G XNGXqbR + 8 kChFQiVKCUopbCqHtFaVVV6Ldhk3fB76ht3vgXXS9XFR8 + KYFLHAezIO VdzzWqVPv72lO3CkyqHfoL8FwxjNI9KAQkU1T3ETv5YJw7mUWWvdMVee9SVf8Qa1 m3JJGqcRd9kyH / u8tMKsrgfG1 / KVeyx1gStlO3ioHlCyjsNBAUZ2QIsFa7gxUmQL HqgCIqGC / SjFv1 + 5 sHF807sYBBWfARQZRTum / Pg3FHpRiVhNPcvEUPIZjQhT79fS UQHw1EvK5Wj4Ea3 / 3 jNt9bim + pJrxCoUAKByU8lyjL7vOsogiM7sgp50t54oI / 3 V G0hvOZNvWV / V0YLqXoTVeru / rqLUKzHunl9psutAXlUOkA == = 4l 27 ----- PGP メッセージ終了----- fp : CCC4D0692165A88405EF1F579CC5737D5CCB9760 暗号化されていないサフィックス: _unencrypted バージョン: 3.7.3 このファイルをGitリポジトリに再送信し、アプリケーションを再作成する必要があります。対応するマニフェストファイルは以下の通りです。 apiバージョン: argoproj .io / v1alpha1 種類: アプリケーション メタデータ 名前: DevOps - デモ 名前空間argocd 仕様: 行き先: 名前空間: デフォルト サーバー: "https://kubernetes.default.svc" プロジェクト: デモ ソース: path : helm # Helmリポジトリからアプリケーションを作成する場合、チャートはパスを指定する必要があります。 リポジトリ URL : "http://git.k8s.local/course/devops-demo-deploy.git" ターゲットリビジョン: HEAD ヘルム: パラメータ: - 名前: レプリカ数 値: "2" 値ファイル: - シークレット+ 年齢- インポート: その中心となるのは、`valuesFiles` の `secrets+age-import:///helm-secrets-private-keys/key.txt?my-values.enc.yaml` 構成です。これは、`/helm-secrets-private-keys/key.txt` ファイルから秘密鍵をインポートして、`my-values.enc.yaml` ファイルを復号化することを意味します。 上記のオブジェクトを再作成すると、アプリケーションの同期が成功するはずです。 参考文献[1]年齢: https://github.com/FiloSottile/age/. [2]年齢解放ページ: https://github.com/FiloSottile/age/releases. [3] SOPSリリースページ: https://github.com/mozilla/sops/releases/download/v3.7.3/sops-v3.7.3.linux.amd64. [4] helm-secrets: https://github.com/jkroepke/helm-secrets. |