Kubernetesオペレーターがもたらすセキュリティ上の影響
Chris Laux
2022年2月15日
0 分で読めます初期のKubernetesでは、リソースの管理はシンプルでした。YAML形式でリソースを定義し、その定義をクラスターに送信すればよかったのです。しかし、この方法では手作業が多く、しかも低いレベルでの作業が必要になることが分かりました。
Kubernetesの進化における次の段階では、Helmチャートが使われるようになりました。「Kubernetesのパッケージマネージャー」と呼ばれることもあるHelmを使うと、テンプレート言語によってアプリケーション全体の構成を共有できます。これにより設定を簡単に共有でき、コマンド1つでチャートをデプロイできるようになりました。
しかし、Helmは外部アドオンであり、その機能は既存のKubernetes APIを通じて実装できる範囲に限られます。そこで、Kubernetes APIをオペレーターで拡張することが、次の自然なステップとなりました。これにより、クラスター内からカスタム機能を追加できるようになりました。
Kubernetesオペレーターは、人間のオペレーターが担っていたタスクを実行する制御ループを提供します。Kubernetesオペレーターを作成するには、開発者がKubernetes APIと連携し、アプリケーションのライフサイクルを自動的に管理するカスタムコードを定義します。このカスタムコードは通常、クラスター上の1つ以上のPodで実行されますが、適切な認証を行えば、クラスターの外部から連携させることもできます。
この構成には脆弱性が潜む可能性があると思いませんか?そのとおりです。新たな抽象化が生まれるたびに、新たなKubernetesのセキュリティ上の課題も生じます。
この記事では、オペレーターに適切な権限範囲を設定する例、セキュリティ確保におけるオペレーターの作成者とエンドユーザーそれぞれの役割、そしてKubernetesサービスの安全性を高めるためのオペレーターの活用方法をいくつか紹介します。
RBACによるKubernetesのセキュリティ
Kubernetesオペレーターをクラスターにデプロイする場合、オペレーター固有の検討事項の基礎として、一般的なKubernetesセキュリティの慣行を適用する必要があります。まず、こうした一般的な考慮事項を見ていきましょう。
Kubernetesの主な権限管理システムは、ロールベースのアクセス制御(RBAC)認可です。これはクラスターの起動時に有効にする必要があります。RBACでは、追加の権限リソースとしてRolesとRoleBindingsを利用できます。これらは定義された名前空間内でのみ適用されます。また、クラスター全体に適用されるClusterRolesとClusterRoleBindingsもあります(必要な場合に限って使用してください)。
Rolesは、権限を持つ主体がリソースにアクセスする方法を定義し、RoleBindingsは、人やソフトウェアコンポーネントなどの主体をRolesに関連付けます。一般的なOSのセキュリティと同様に、必要最小限の権限のみを付与し、付与済みの権限が引き続き必要かどうか定期的に確認することが重要です。
以下は、指定した名前空間内のPodリソースへの読み取りアクセスを許可するロールの例です。
apiGroupsの空文字列は、コアAPIを示しています。これに対応するロールバインディングを定義し、このロールを特定のユーザーアカウントに割り当てることができます。
オペレーターのデプロイには、独自のロールやバインディングが含まれていることがよくあります。サードパーティーがユーザーのクラスターにどのような権限を付与するのかを正確に把握するため、ユーザーはこれらの設定とドキュメントを確認する必要があります。
スコープと権限
Kubernetesオペレーターのセキュリティには、信頼の連鎖が関わります。この連鎖はオペレーターの作成者とそのリポジトリから始まり、オペレーターをユーザーのクラスターに届ける方法など、さまざまな要素へと続きます。RBACシステムと同様に、オペレーターの権限は可能な限り制限するのが適切です。ただし、多くのKubernetesオペレーターは機能を実行するためにかなり広範な権限を必要とするため、開発者はセキュリティと有用性のバランスを慎重に取る必要があります。
ロールやロールバインディングと同じく、オペレーターのスコープは名前空間内(名前空間スコープ)に限定することも、クラスター全体のすべての名前空間を対象(クラスター スコープ)にすることもできます。Kubernetesアプリケーションは、それぞれを分離し、互いの影響やKubernetesシステムへの影響を防ぐため、専用の名前空間に配置できます。
可能な限り、オペレーター開発者は名前空間スコープの方式を選ぶべきです。これにより、同じクラスター上の他のデプロイに問題が波及するのを防げます。クラスター上のすべてのデプロイにサービスを提供するオペレーターには、クラスター スコープが必要です。よくある例として、アプリケーションに証明書を自動的にプロビジョニングするデプロイがあります。
PodやコンテナによるKubernetesシステムの他の部分の操作を防ぐ方法の1つにsecurityContextsがあります。オペレーターのコンテナにも適用できます。以下は、Podの権限を制限するYAMLの例です。
この例では、コンテナが稼働するKubernetesクラスター上で実行されていることを前提としています。この設定により、プロセスがroot権限を取得したり、ルートファイルシステムを変更したりするのを防ぎます。何らかの理由でオペレーターが侵害された場合でも、攻撃者がホストシステムに対してできることを制限できます。
次のステップは、クラスター全体に適用するPodセキュリティ制限を定義することです。Kubernetes 1.21より前のバージョンでは、PodSecurityPolicy(PSP)オブジェクトを使っていましたが、現在は非推奨です。後継となるPodSecurityAdmission(PSA)は、Kubernetes 1.23でベータ機能として提供されています。
残念ながら、新しいPSAでは、上記のYAML例のようなきめ細かなカスタム制御はできません。その代わりに、privileged、baseline、restrictedという3つの新しいポリシーレベルから選び、各名前空間に適用します。
この例では、中間にあたるbaselineのセキュリティレベルで適用を強制し、名前のとおりrestrictedレベルでは警告を出すように名前空間を設定しています。各ポリシーの正確な定義は、KubernetesドキュメントのPod Security Standardsに記載されています。
オペレーターがもたらすセキュリティ上のメリット
Kubernetesオペレーターにはセキュリティ上の考慮事項が伴いますが、クラスターの安全性を高めることもできます。前述のとおり、Kubernetesオペレーターは、人間のオペレーターに通常任される操作や設定を実行します。人間は間違いを犯すことがあり、実際に頻繁に起こります。プログラムによる設定や制御は、人間が行う操作よりも信頼性と再現性に優れています。
適切に作成されたオペレーターは、過失によるミスや悪意によるミスをなくします。セキュリティでは、対応の速さも欠かせません。問題の検知と解決のどちらにおいても、ソフトウェアのオペレーターは人間より大きな優位性を持っています。
クラスターへのデプロイの多くは、アプリケーションの日々の運用を目的としていますが、専用のセキュリティ管理サービスをクラスター内に直接デプロイすることもできます。こうしたサービスは、オペレーターの制御ループで管理するのが最適です。
Kubernetesを安全にデプロイするためのソリューション
Kubernetesオペレーターの開発により、クラスター内のカスタムロジックでKubernetes APIを拡張できるようになりました。この機能が適切に扱われなければ、悪意のある攻撃者に悪用されるおそれがあります。しかし開発者は、権限ルールなどの制限を設けることで、Kubernetesのデプロイを安全に保つことができます。Kubernetesで権限を管理する主な機能はRBACで、権限の指定に利用できます。
オペレーターは、人為的なミスが起きやすい手作業を置き換えることで、セキュリティ上のメリットももたらします。また、Snykのような専用のセキュリティサービスをクラスター内で実行できます。
Snykは、この記事で取り上げた潜在的な脆弱性をはじめ、さまざまなセキュリティ課題に対応するソリューションを提供します。コーディング中に発生するセキュリティ上の問題を開発者に通知し、迅速な対応を支援します。特に、SnykではクラスターにインストールできるKubernetesオペレーターを提供しています。インストール後は、クラスター上の既存または新規のワークロードに脆弱性が見つかると、Snykが検出して報告します。
ソースコードの段階からインフラを保護
Snykはワークフロー内のIaCセキュリティとコンプライアンスを自動化し、構成ドリフトや不足しているリソースを検出します。



