2022年10月12日

GitOps

GitOpsのシークレット管理の基本

Git、GitOpsの管理、およびGitOpsのシークレット管理の基本を学びます。

63482e09b83429491614016c_GitOps Secrets-p-800.png

2005年にLinus Torvalds がGitを作ったとき、ソフトウェア産業はより分散型で宣言的な作業モデルへと移行しました。従来の中央バージョン管理システムとは異なり、Gitは完全に分散されており、開発者が望む場所でローカルにホストすることができました。これによって、ブランチ、マージ、プルリクエストなどの技術が可能になったのです。Gitが世界標準となり、Gitリポジトリーが開発者プロジェクトのための信頼できる唯一の情報源となったため、これらの用語は全て開発者にとっての常識となっています。

 

しかし、新しい世界標準は新たな課題を提示しました。Gitリポジトリーがプロジェクトの信頼できる唯一の情報源として機能する世界で、Git のシークレットをどのように管理するかということです。

 

APIキーや OAuthトークン、証明書、パスワードなどのシークレットは、非常に機密性の高いものです。一般的な考え方では、Git リポジトリーでそれらをホストしないように伝えるでしょう。しかし、便利だから、テキストファイルにハードコードしてあるから、あるいは開発者がリポジトリーは非公開だから安全だと思っているからというのが理由で、シークレットが危険なリポジトリーに入り込んでしまうことがあります。すると、シークレットの安全性が保たれません。実際は、Git リポジトリーはクローンすることができ、一度クローンされると、保存されているもの全てが一緒になってしまうのです。非公開のリポジトリーは、機密情報を盗まれないようにするための十分な保護を提供しません。開発者は、機密漏洩のリスクを減らすために、機密管理プロセスを注意深く監視する必要があります。

 

GitOpsのシークレット管理には、さらなる複雑さが加わります。GitOpsは、開発者がソフトウェアを効率的にデプロイするための直感的な方法であり、プロジェクトの信頼できる唯一の情報源としてGitリポジトリーに大きく依存しています。GitOpsベースのデプロイを成功させるためには、開発者がシークレットにアクセスする必要があります。組織は、複雑なシークレット管理プロセスによって開発者の速度を妨げたくはないでしょうが、同時に、不適切なシークレット管理はビジネスに大きなリスクをもたらす可能性があります。

GitOpsの基礎とベストプラクティス

GitOpsは、Gitのようなリビジョン管理システムに保存されているシステムの望ましい設定を使用して、ソフトウェアのデプロイを管理します。UIやCLIで変更する代わりに、開発者は望ましい状態を表す設定ファイルに変更を加えます。Gitに保存された望ましい状態とシステムの実際の状態を比較すると、全ての変更がデプロイされていないことを示します。これらの変更は、プルリクエスト、コードレビュー、マスターへのマージといった標準的なリビジョン管理プロセスを通じて、レビューと承認を行うことができます。変更が承認され、メイン・ブランチにマージされると、オペレーター・ソフトウェア・プロセスが、Git に格納された構成に基づいて、システムの現在の状態を望ましい状態に変更する責任を負います。

 

GitOpsは、特定のツールセットを必要としませんが、ツールはこれらの標準的な機能を提供する必要があります。

 

  • Gitに格納されたシステムの望ましい状態で操作する。
  • 望ましい状態と実際の状態との差異を検出する。
  • インフラに対して必要な操作を行い、実際の状態を望ましい状態に同期させる。

 

GitOpsの理想的な実装では、システムに対する手動での変更は許可されず、設定の変更は全てGitに保存されたファイルに対して行わなければなりません。極端な例では、システムを変更する権限は、オペレーターのソフトウェア・プロセスのみに与えられます。そして、GitOpsモデルにおけるインフラ&オペレーションエンジニアの役割は、インフラの変更とアプリケーションのデプロイから、GitOpsの自動化を維持し、チームが変更をレビューし承認するのを助けることへと移行します。

KubernetesのGitOpsのシークレットとは?

最も基本的なレベルでは、Kubernetesにおける「シークレット」は、シークレットキー、パスワード、認証トークンなどの機密データや情報を安全に保管するための方法です。情報は簡単にアクセスでき、なおかつセキュリティーを脅かすようなシナリオから保護されます。デフォルトでは、Kubernetesで実行されるコンテナ化されたアプリケーションは、正しく動作し、他のインフラストラクチャーやアプリケーションと対話するために、しばしばクレデンシャルを必要とします。

 

Kubernetesでは、機密情報をアプリケーションコードから見えないように格納するためのオブジェクトとしてSecretsを提供しています。この仕組みにより、Kubernetes自体の運用を管理する際に、機密情報を誤って漏洩するリスクを抑えて利用できます。基礎的なレベルから、Kubernetesのシークレットを作成するプロセスはとても簡単です。

 

  • 信頼できる個人または情報源は、特定の名前を作成し、機密データを入力することによって、Secretを定義します。Kubernetesのオペレーターは実際のデータそのものを見ることはなく、名前だけが表示されます。
  • ワークロードが機密データにアクセスして使用する必要が生じると、以前に作成した特定の名前を参照してデータを取得します。

GitOpsでKubernetes Secretsを扱う

Gitは、更新が行われたときにリポジトリー内の設定を本番環境と同期させるために、Gitワークフローと自動化に依存しています。しかし、機密データをどのような形であれGitに保持することは、たとえリポジトリーが厳格なアクセス制御を行う非公開のものであっても、セキュリティーリスクをもたらします。もしシークレットがプレーンテキストの形でGitリポジトリーにコミットされたら、それを取り消し、もう使用しないようにしなければなりません。しかし、GitOpsでシークレットを扱うには、セキュリティーリスクを軽減する方法がまだあります。

 

GitOpsのアプローチをとりつつ、機密情報をリスクにさらすことなくアプリケーションにシークレットを提供したい人のために、GitOpsでシークレットを管理するための一般的な方法論を2つ紹介しましょう。

 

  1. 暗号化されたシークレットをGitリポジトリーに格納し、自動化を活用して復号化し、Kubernetes Secretsとしてレンダリングする。
  2. 暗号化されたシークレットを直接Gitに格納する代わりに、Gitリポジトリーにシークレットへの参照を格納する。次に自動化を活用して、Kubernetes Secretsとしてレンダリングする前に、その参照に基づいて実際のシークレットをフェッチします。

方法1:暗号化されたシークレット

Bitnami の Sealed Secrets と Mozilla の SOPS (Secrets OPerationS) は、Git リポジトリーに暗号化したシークレットを保存するための最も人気のあるオープンソースのオプションで、同じようなアプローチをとっています。

 

どちらのツールにもそれぞれ長所・短所・制限がありますが、ここではそれを説明します。

 

Bitnami Sealed Secrets

 

使いやすさで知られるBitnami Sealed Secretsは、公開鍵暗号方式を活用して、ソースコントロールを使用してシークレットを保存し、Kubernetesクラスター内で復号化キーを使用してシークレットを復号化するという2つのコアステップでシークレットを暗号化します。暗号化はユーザーのコンピューター上で行われ、復号はコントローラーによってKubernetesクラスター上で行われます。CLIツールであるKubesealは、クラスターにアクセスして暗号化キーを取得できるため、シークレットの暗号化を簡単に行うことができます。

 

また、カスタムリソース、あるいはKubernetes APIの拡張機能であるSealedSecretがあり、コントローラーが復号してKubernetes Secretを作成できるように暗号化された情報を保持しています。この封印されたシークレットのコントローラーは、「監視員」として機能し、全てのネームスペースでクラスター内の封印されたシークレットを探します。つまり、新しく封印されたシークレットが作成されるたびに、コントローラーは自動的にそれらを検出するのです。

 

Bitnami Sealed Secretsの主な利点は、使いやすさと、Hashicorp Vaultのような別のSecrets Managerを使用する必要がないことです。とはいえ、各シークレットを手動で暗号化する必要があることに変わりはありません。主な制限事項としては、このソリューションはKubernetesでのみ動作することと、多数のクラスターがある大規模な管理が難しくなることです。

 

Mozilla SOPs

 

SOPS(Secrets OPerationS)は、Kubernetesを使ったユースケースに限らず、より柔軟に暗号化・復号化できるCLIツールです。このツールは以前からあり、キーストアが標準だった時代に人気になりました。CLIツールであることを考えると、ネイティブなKubernetes環境で積極的に使うことはあまり有用ではなく、追加のツールを必要とします。これらのツールには、Helmなどのツールのプラグインの使用、SOPSでカスタムコンテナイメージを構築するための追加機能、Argo CDのような使用をサポートする拡張機能などがあります。

 

SOPSは、YAML、ENV、INI、BINARY、JSONなどの複数の入力形式をサポートしています。Hashicorp Vault、Azure Key Vault、GCP KMS、AWS KMSなどのKey Management Systems(KMS)との統合をサポートし、KMS内に直接シークレットを保存するのではなく、シークレットを守るための暗号化キーを提供します。KMSが利用できない場合、代わりにコマンドラインからPGP(Pretty Good Privacy)キーペアを使用するオプションがあります。これは、異なる開発環境に対して柔軟性を提供するユニークなアプローチです。例えば、サンドボックス環境ではPGPキーペアを使用し、本番環境ではその下のツールのレイヤーを変更する必要なくKMSを使用することができます。

 

SealedSecretsの仕組みと同様、シークレットは開発者が手動で暗号化します。SealedSecretsのワークフローを使用しますが、暗号化にはSOPSを使用します。キーストアから復号化キーを読み込み、Argo CDのようなツールがSOPSプラグインで実行できるSOPSバイナリを使用して、シークレットを復号化します。

 

暗号化されたシークレットに対するデメリット

 

ざっくりというと、開発者はプレーンテキスト形式で手作業でシークレットを取得し、暗号化し、Gitに保存する必要があります。しかし、この方法では、Gitのログに残された情報からコミッターを簡単に突き止めることができるため、コードをコミットした人のアイデンティティーが危険にさらされる可能性があります。この方法のもう一つの欠点は、暗号化されたキーが漏洩した場合、全てのキーを遡って見つけ、取り消すことが難しいという点です。

 

SOPSとSealed Secretsは、手動による暗号化プロセスと人間の介入を必要とするレベルのため、スケーリングに問題があることを忘れてはいけません。可能な限りKMSを使用することで、鍵の管理がより簡単になり、シークレット管理の新たなオプションへの扉を開くことができます。

方法2:GitOpsシークレットリファレンス

シークレットの参照方式は、Kubernetesのシークレットを管理するために外部のシークレット管理システムを使用し、シークレットをクラスターへデプロイするにはGitOpsオペレーターが必要です。マニフェストはGitに格納され、前述のシークレット管理システムに格納されているシークレットへの参照を表します。その後、GitOpsオペレーターがマニフェストをKubernetesクラスターにデプロイします。それからシークレットマネージャーからシークレットをフェッチし、Kubernetesのシークレットとしてクラスターに適用することができます。

 

このアプローチは効果的なように聞こえますが、どのようにマネージャーからシークレットを取得し、クラスターに取り込むのでしょうか?シークレットマネージャーと対話するためには、クラスターにインストールされたオペレーターが必要です。市場で最も人気のあるこのためのツールは、ExternalSecretsKubernetes Secrets Store CSI Driverの2つです。

 

ExternalSecrets

 

ExternalSecretsプロジェクトは、外部のシークレット管理ソリューションに保存されたシークレットをKubernetesクラスターに安全に接続するためにGoDaddyによって作成されました。ExternalSecretsコミュニティーは、追加のシークレットマネージャーのサポートを追加し続け、異なるツールセットに対して非常に汎用性の高いツールになっています。

 

実際には、開発者はシークレットへの参照を含むExternalSecretカスタムリソースを自身のGitリポジトリーにコミットするでしょう。GitOpsオペレーターは、ExternalSecretをクラスターにデプロイし、ExternalSecret Operatorがその参照を使用して外部の鍵管理システムからシークレットを取得します。オペレーターはシークレットを取り込み、Kubernetesシークレットを作成します。ExternalSecretリソースは、実際には機密情報を含まないため、Gitリポジトリに保存しても安全です。

 

Kubernetes Secrets Store CSI Driver

 

ExternalSecretsと同様に、Secret Store CSI Driverは、外部のシークレット管理ツールからシークレットを取り出し、Kubernetesクラスターに持ち込むためのソリューションです。このツールは複数のシークレットマネージャーをネイティブにサポートしていますが、ExternalSecretsに比べるとサポートが手薄です。このギャップを埋めるため、Secrets Store CSI Driverでは、サードパーティーがシークレットの保管場所への接続を独自に開発できるようにしています。このアプローチにより、より柔軟な対応が可能になりますが、自社で使用しているシークレット管理ツールがネイティブでサポートされていない場合、手作業が必要になることもあります。

 

CSI Driver は ExternalSecrets よりも複雑です。このソリューションでは、外部のシークレットを取得してシークレットリソースを作成する代わりに、ポッドに接続された別のボリュームを使用してシークレットを保存します。開発者は、シークレットを参照できるSecretProviderClassをコミットします。GitOpsオペレーターはその変更をデプロイし、CSI Secret Store Operator Pluginはシークレット管理システムからシークレットを取得します。オペレータープラグインは次に、指定されたPodに接続されたシークレットを持つボリュームを作成します。

シークレット管理のための代替ツール

ここでは、GitOpsアプローチでシークレットを管理するための、注目すべき追加ソリューションを紹介します。

 

GitOpsのシークレット管理を簡単にするHarness

GitOps のデプロイモデルに切り替えることを決定する前に、シークレット管理戦略について熟考する必要があります。戦略を決定した後、安全なGitOpsのプラクティスを設定することは困難です。Harness GitOps-as-a-Service は、高度な RBAC、監査証跡、ガバナンスルールなどのエンタープライズコントロールを提供し、デプロイの安全性とコンプライアンスを維持します。

 

Harness GitOps GitOps-as-a-Serviceは、実装と利用がシンプルで、メンテナンスやトラブルシューティングのためのエンジニアリングの労力はほぼ不要です。Harness GitOpsの試用にご興味がある方は、フルデモをリクエストしてください


この記事はHarness社のウェブサイトで公開されているものをDigital Stacksが日本語に訳したものです。無断複製を禁じます。原文はこちらです。

Harnessに関するお問い合わせはお気軽にお寄せください。

お問い合わせ