Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2022年7月26日にEduardo Mínguezが投稿したブログ(https://sysdig.com/blog/gitops-iac-security-source/)を元に日本語に翻訳・再構成した内容となっております。
GitOpsデプロイメントモデルにセキュリティの問題がある場合(たとえば、タイプミスによる権限の設定ミス)、これは、ランタイムで検出されるまで伝播されてしまうかもしれません。ほとんどの場合においてランタイムでセキュリティイベントがスキャンまたは検出されてしまうのです。
インフラストラクチャーに潜在するセキュリティ問題を発生源で修正できるとしたらどうでしょうか。
基本的なことから始めていきましょう。
Gitは、オープンソースの分散型バージョン管理システムです。ファイル(通常はソースコードのようなテキスト・ファイル)に加えられた変更を追跡し、共同作業モデルを可能にし、促進します。現在では、バージョン管理システムのデファクト・スタンダードとなっています。
自分のノートパソコンに自分のgitリポジトリを持つことも、自分のサーバーにホストすることも、GitLabやGitHubのようなプロバイダーを利用することも可能です。
リポジトリを管理する方法にはさまざまな「フロー」(git-flow、github-flowなど)がありますが、gitの使い方の基本例は次のようなものです。ファイルの変更は、ユーザーがリポジトリを「フォーク」し、「ブランチ」で適切な変更を行うことで「コミット」されます。
次に、ユーザーはそれらの変更をリポジトリに含めるためのリクエスト(「プルリクエスト」、「マージリクエスト」、または単に「パッチを送る」のいずれか)を作成します。
その後、通常「オーナー」とリクエストを作成したユーザーとの間で議論が行われ、すべてがうまくいけば変更が受け入れられ、リポジトリに追加されます。
注:もっと詳しく知りたい方は、git pull request の仕組みについてもっと詳しく知りたい方は、こちらをご覧ください。
実際の例を見るには、お気に入りのオープンソースの GitLab や GitHub リポジトリをブラウズして Pull Request (あるいは Merge Request) タブを表示します (面白い例としてはこちらも参照ください)。提案された変更点、コメント、ラベル、誰が変更を提案したか、提案された変更点に対して検証を行うツール、リポジトリを見ている人に送られる通知などを見ることができます。
簡単に言うと、GitOps はソフトウェア資産の単一の真実の源として git リポジトリを使用し、ソフトウェアに git デプロイメントモデル(プルリクエスト、ロールバック、承認など)を活用できるようにする方法論にすぎません。
書籍(The Path to GitOps、GitOps and Kubernetes、GitOps Cloud-native Continuous Deployment)やホワイトペーパー、数え切れないほどのブログ記事がありますが、ここ数年の進化を簡単に見て、GitOpsという目的について詳しく説明しましょう。
クラウド以前は、アプリケーションをホストする新しいサーバーを追加するのに何週間もかかりました。許可を得て、購入し、多くの手動タスクを実行しなければなりませんでした。その後、仮想化によって、事態はより簡単になりました。あるスペックの仮想マシンを要求すると、数分後にはアクセスできるようになります。
そして、クラウド、サーバー、ネットワーク、ストレージ、そしてデータベース、メッセージングキュー、コンテナ、機械学習、サーバーレス...といったものをAPIコールでリクエストすることができるようになりました。リクエストして、数秒後にはそれが手に入る、そんな感じです。使った分だけお金を払えばいいのです。これは、インフラストラクチャーがAPIコールを実行するコードとして管理できることも意味します...そして、あなたのコードはどこに保存されるのでしょうか?git リポジトリ(または他のコンテンツバージョンシステム)です。
GitOpsという用語は2017年にウィーブワークスによって作られたもので、OpenGitOpsを言い換えると、GitOpsシステムは以下の原則に基づいています。
GitOps手法の本質は、基本的にクラスター上で動作するKubernetesコントローラーまたはコントローラー(またはエージェント)が、その上で動作するKubernetesオブジェクト(CustomResourceで定義)を監視して、現在の状態とGitリポジトリで指定された状態とを比較することです。一致しない場合、リポジトリで見つかったマニフェストを適用することでアプリケーションを修正します。
注:GitOpsには、例えばプッシュとプルの違いや、構成管理の扱い方など、若干異なるアプローチが存在します。これらは高度なトピックですが、今は基本に忠実でありましょう。
次の図は、GitOps システムを簡略化したものです。開発者が変更を送信し、GitOpsのプロセスとKubernetesにデプロイされたエージェントが変更を監視しているGitOpsのダイアグラム
Gitをベースにしているということは、開発者にとっては摩擦がないことを意味します。新しいツールに悩まされることなく、Gitリポジトリでコードを管理するのと同じプラクティスを適用することができるのです。
GitOpsツールについては、CNCFのインキュベート・プロジェクトであるFluxやArgoCDのようなオープンソースのツールを含め、すでにいくつかのツールが利用可能になっています。
GitOpsによるアプリケーションの定義がどのようなものかを知るために、簡単なアプリケーション(GitHubのリポジトリに格納されている)をFluxやArgoCDで管理する例を挙げてみます。
Fluxの場合:
--- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: GitRepository metadata: name: my-example-app namespace: hello-world spec: interval: 30s ref: branch: master url: https://github.com/xxx/my-example-apps.git --- apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: my-example-app namespace: hello-world spec: interval: 5m0s path: ./myapp prune: true sourceRef: kind: GitRepository name: my-example-app targetNamespace: hello-world
ArgoCD を使う場合:
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-example-app namespace: hello-world spec: destination: namespace: my-example-app server: https://kubernetes.default.svc project: default source: path: myapp/ repoURL: https://github.com/xxx/my-example-apps.git targetRevision: HEAD syncPolicy: automated: {} syncOptions: - CreateNamespace=true
どちらもアプリケーションマニフェストを格納する Git リポジトリ (デプロイメント)、ネームスペース、その他いくつかの詳細を参照しています。
Infrastructure as Code は、インフラストラクチャーのビルドブロックを、さまざまなテクニックやツールを使ってコードとして扱う方法論です。つまり、VM、コンテナ、ネットワーク、ストレージなどのインフラストラクチャーを、お気に入りのインフラストラクチャープロバイダーのウェブインターフェースを使って手動で作成する代わりに、それらをコードとして定義し、terraform、 crossplane pulumi, など、選んだツールで作成/更新/管理します。
そのメリットは非常に大きいです。インフラストラクチャーをコードであるかのように管理でき(今はコードです)、開発のベストプラクティス(自動化、テスト、トレーサビリティ、バージョン管理など)をインフラストラクチャー資産に活用することができるのです。実際、インフラストラクチャーは単なるコード以上のものであるため、代わりに「Infrastructure as Software」という言葉を使おうという動きがあります。
このトピックに関する情報はたくさんありますが、次のリソースが良い出発点となるでしょう。
おそらくお分かりのように、GitOpsはインフラストラクチャーを定義するための宣言型モデルとしてInfrastructure as Codeを活用しています。実際、IaCはGitOpsの基礎の1つです。しかし、IaCはGitOpsの他の原則を義務づけているわけではないので、それ以上のものなのです。
「DevOps」という言葉には、さまざまな定義があります。誰に尋ねるかにもよりますが、簡単に言うと、「DevOpsとは、摩擦を減らし、高速にソフトウェアをビルドして提供するためのプラクティスとツールの組み合わせである」です。
GitOpsはDevOpsのプラクティスにマッチしたフレームワークを提供するため、DevOpsの方法論はGitOpsを活用できますが、厳密には必要ではありません。
NoOpsは2021年にForresterによって作られた造語で、IT環境を抽象化し、手動で管理する必要がないほど自動化する、運用を扱うためのラディカルなアプローチです。
GitOpsは、Gitリポジトリにある望ましい状態のものをリメディエーションすることで、手動による変更を減らすのに役立ちますが、IT環境全体に本当の意味でのNoOpsを適用することは、今日時点では現実の目標ではなく、憧れ的なゴールと言えます。
いいえ。Kubernetes、コントローラーパターン、Kubernetesオブジェクトを定義する宣言型モデルは、GitOpsの方法論に完全にマッチしていますが、KubernetesなしではGitOpsの方法論が適用できないというわけではありません。Kubernetes以外でGitOpsを使う場合、冪等性の処理、アセットの削除/作成、秘密管理など、いくつかの課題があります。しかし、GitOpsの原則はKubernetesなしでも(そして少し創造性を働かせれば)適用可能です。
ここで、セキュリティの側面についてお話ししましょう。ほとんどのセキュリティツールは、潜在的な脆弱性や問題をランタイムで(遅すぎるくらい)検出します。それらを修正するためには、リアクティブな手動プロセスを実行する必要があるか(例えば、k8sオブジェクトのパラメーターをkubectl editで直接修正する)、理想的には、修正がソースで行われ、サプライチェーン全体に伝搬されるようにすることです。これが「Shift Security Left」と呼ばれるものです。手遅れになる前に問題を修正することから、問題が発生する前に修正することへ。
これは、すべてのセキュリティ問題をソースで修正できるということではありませんが、ソースに直接セキュリティレイヤーを追加することで、いくつかの問題を防ぐことができます。
まず、一般的なセキュリティの推奨事項が適用されます。
GitOps の方法論が一般的なセキュリティを向上させるシナリオをいくつか見てみましょう。
これらの利点は、GitOps の手法を使用してセキュリティ体制を改善することを正当化するのに十分なものであり、アウトオブザボックスのものです。私たちは、もっと多くのことを行うことができます。GitHubやGitLab、その他のGitリポジトリプロバイダーでは、プルリクエストによるものも含めて、Gitリポジトリで行った変更に基づいてアクションやパイプラインを実行できるので、可能性は無限大です。いくつか例を挙げます。
GitOpsの方法論は、他のツールを追加することなく、デプロイメントモデルとセキュリティの利点にいくつかの改良をもたらします。
ソースコードに直接「シフトレフト」レイヤーを追加することでセキュリティ姿勢を改善し、プルリクエストモデルの柔軟性のおかげで、ランタイムに影響を与えたり、変更したりせずに、簡単に追加のセキュリティチェックを追加することができます。