Kubernetesアドミッションコントローラーが必要な理由
Chris Laux
2022年4月25日
0 分で読めますKubernetesのオペレーターや管理者としての経験がなければ、アドミッションコントローラーは初めて耳にする機能かもしれません。これらのコントローラーは主にバックグラウンドで動作し、コンパイル済みプラグインとして利用できるものも多数ありますが、デプロイのセキュリティを大きく高めることができます。
アドミッションコントローラーは、APIリクエストがAPIサーバーに届く前に介入し、拒否または変更できます。コントローラーを経由しない純粋な読み取りリクエストを除き、ほとんどの種類のKubernetesリクエストに適用されます。アドミッションコントローラーがリクエストを処理するのは、認証と認可が適切に行われた後です。
この記事では、Kubernetesにアドミッションコントローラーを導入する理由を解説します。また、その機能をより深く理解することのメリットについても説明します。
通常のKubernetes操作の多くは複数のアドミッションコントローラーに依存しているため、いくつかはデフォルトで有効になっています。これらのコントローラーの大半はKubernetesのソースツリーに含まれ、プラグインとしてコンパイルされます。一方、サードパーティ製のアドミッションコントローラーを開発してデプロイすることも可能です。後ほど、いくつかの例を紹介します。アドミッションコントローラーの実装方法について詳しくは、Kubernetesのドキュメントを参照してください。
デフォルトのアドミッションコントローラー
Kubernetesには複数の組み込みアドミッションコントローラーがあります。たとえば、DefaultIngressClassは、クラスがまだ指定されていないIngressオブジェクトにデフォルトのIngressクラスを適用します。同様に、DefaultStorageClassは、ストレージクラスがまだ指定されていないPersistentVolumeClaimsにデフォルトのストレージクラスを適用します。ストレージクラスに基づく動的なストレージプロビジョニングを有効にするには、このコントローラーが必要です。
アドミッションコントローラーは、セキュリティの維持にも非常に役立ちます。たとえば、マルチテナントクラスターに対するサービス拒否(DoS)攻撃の影響を軽減できます。LimitRangerプラグインを見てみましょう。名前のとおり、リソースの制限範囲を適用します。制限範囲では、名前空間ごとにリソース消費量の必須範囲を定義します。これにより、あるテナントが他のテナントのリソースを使い果たすのを防げます。
もう一つの懸念は、いわゆるイベントフラッディングです。クラスターにイベントが大量に押し寄せ、ほかの正当なリクエストを適切に処理できなくなる状態を指します。このような状況では、EventRateLimitコントローラーが強力な緩和策となります。名前空間ごと、またはユーザーごとにイベントの発生率を制限できるよう設計されています。
さらに、アドミッションプラグインを、実行時に設定可能なWebhookとして開発者が実行できる重要なコントローラーが2つあります。MutatingAdmissionWebhookはWebhookによる送信リソースの変更を可能にし、通常はカスタムのデフォルト値を適用するために使われます。一方、ValidatingAdmissionWebhookコントローラーでは、登録済みWebhookが、APIによる検証後の最終状態のリソースを処理のチェーンに進めるか、完全に破棄するかを判断できます。
コントローラーの目的
物理マシン上で複数のサービスを実行する従来の方法は、ハイパーバイザーでOSを分離しながら、同じホスト上で仮想マシンを稼働させることでした。AWSが定義するような複雑なクラウド設定によってシステムを分離し、テナント同士が意図せず、あるいは意図的に互いに害を及ぼせないようにしていました。
Kubernetesは当初、単一の組織やユーザーが利用する協調型システムとして設計されました。また、他のクラウドシステムと比べて、相互配慮に大きく依存していました。しかし、利用可能なデプロイ方法の多様化や、より大規模なクラスターへの対応が進むにつれ、単一のユーザーがシステムの運用を妨げないようにするポリシーの適用がますます重要になっています。
このプロセスを自動化するには、組織にポリシーシステムが必要です。Kubernetesには基本的な組み込みサポートがありますが、専用の高機能なポリシーエンジンに匹敵する機能は備えていません。
外部ポリシーエンジン
Kubernetes向けの主要なオープンソースポリシーエンジンは、Open Policy Agent(OPA)GatekeeperとKyvernoの2つです。
どちらのエンジンも、クラウドネイティブ技術の標準化と普及を目指すCloud Native Computing Foundation(CNCF)に寄贈されています。CNCFは親組織であるLinux Foundationの下で運営されています。KubernetesもCNCFのプロジェクトです。
Kyvernoの主な利点は、新たな言語を習得する必要がないことです。ポリシーはすべてKubernetesリソースとして定義されます。一方、GatekeeperはOPAの宣言型言語であるRegoを活用します。Gatekeeperはより大きなOPAシステムの一部ですが、KyvernoはKubernetes向けの独立したプロジェクトです。まとめると、Gatekeeperはより成熟したプロジェクトであり、Kyvernoは学習のハードルが低いという特徴があります。
独自のアドミッションコントローラー
HTTPリクエストを処理し、JavaScript Object Notation(JSON)を返せる任意の言語を使って、Webhookで独自のアドミッションコントローラーのロジックを実装できます。たとえば、Go、Python、Rubyはいずれも使用できます。
以下の例では、独自のアドミッションコントローラー用Webhookの設定方法を示します。前述のLimitRangerと同様に、名前空間のリソース上限を超えるPodのリクエストを拒否します。この例にはコントローラーのソースコード全体は含まれていませんが、詳しい手順についてはKubernetesのアドミッションWebhookサーバーに関するドキュメントを参照してください。
まず、設定オブジェクトを使ってWebhookを登録します。
これにより、ValidatingWebhookControllerにWebhookの情報が伝えられます。また、アクセスするサービスと、サーバーを実行しているコンテナで確認するパスを指定します。Webhookを呼び出すかどうかの判断に適用するルールも特定します。この例では、新しいPodの作成に焦点を当てています。
実際には、このリソースのクラスターへの作成は最後に行います。Webhookサーバーのデプロイを作成した後です。デプロイには、上記ファイルの定義に一致するサービスが含まれます。
以下はWebhookのデプロイ例です。通常のアプリと変わりません。トランスポート層セキュリティ(TLS)による通信の保護については説明しませんが、強く推奨します。
新しいPodのリクエストがKubernetesに送信され、ValidatingWebhookを通過すると、関連情報がPOSTリクエストとして設定済みのURLパスに送信されます。Webhookが処理するJSONオブジェクトが含まれています。リクエストを承認するには、次のようなレスポンスと200 OKステータスコードを返します。
uidフィールドはリクエストから取得され、リクエストとレスポンスを照合するために使われます。Podの作成を防ぐには、allowedフィールドをfalseに設定し、HTTPエラーコードを返す必要があります。
独自のアドミッションコントローラーは、この例のようにシンプルにも、さらに複雑にもできます。詳しくは、アドミッションWebhookのドキュメントを参照してください。
まとめ
Kubernetesのアドミッションコントローラーは、オブジェクトが永続化される前にAPIサーバーへのリクエストを変更または拒否できます。Kubernetesには、事前コンパイル済みプラグインや2種類のアドミッションコントロールWebhookなど、多用途に使える組み込みコントローラーが数多くあります。一方、独自のWebhookやコントローラーを実装すれば、柔軟性を高め、細かな制御が可能になります。
アドミッションコントローラーとWebhookを利用すれば、OPA GatekeeperやKyvernoのようなポリシーエンジンをプロジェクトに導入できます。さらに、HTTPに対応したWebhookを使って独自のアドミッションシステムを定義するのは簡単です。HTTPレスポンスとJSONペイロードを返せる任意の言語で実装できます。
アドミッションコントローラーは、包括的なKubernetesセキュリティ戦略を構成する要素の一つにすぎません。ソフトウェア開発ライフサイクルの各段階にはリスクや脆弱性が存在しますが、こうしたリスクの軽減によってワークフロー全体を妨げる必要はありません。適切な専門知識を求める際には、セキュリティを重視する組織が貴重な知見を提供してくれます。
開発者のために設計されたIaCセキュリティ
Snykは、統合されたポリシー・アズ・コードエンジンにより、SDLCからクラウドでの実行時までInfrastructure as Codeを保護します。すべてのチームが安全に開発、デプロイ、運用できるよう支援します。
Chris Laux は、さまざまなプログラミング言語を使い、20年以上にわたってソフトウェア開発に携わってきました。



