Kubernetesクラスタのセキュリティを強化するには?コンポーネント別に解説
Kubernetesは単一のツールではなく、APIサーバー、ノードエージェント、コンテナランタイムなど、多数の異なるタイプのサービスとリソースで構成されています。クラスタ内の各コンポーネントは、それぞれ異なるタイプのセキュリティ脅威に直面しており、異なるセキュリティ設定が必要です。
場合によっては、同じセキュリティ手法を複数のコンポーネントに適用することもできます。例えば、役割ベースのアクセス制御を使用して、Kubernetesのさまざまなタイプのリソースの権限を管理可能です。
それでも、一部のコンポーネントには固有のセキュリティ要件があり、固有のセキュリティソリューションが必要となります。例えば、APIサーバーのセキュリティ確保は、Kubernetesノードのセキュリティ確保とは異なります。Kubernetesクラスタのセキュリティは、各コンポーネントに起こりうるセキュリティ上の脅威を理解し、対処することが重要です。
ここではKubernetesクラスタの各コンポーネントを保護することで、Kubernetesクラスタ全体の安全性を高めるための方法を解説します。
関 連 記 事
Kubernetesとは? | Kubernetesセキュリティ の基礎 | Kubernetesアーキテクチャの 設計方法 |
AWSのEKS (Elastic Kubernetes Service) | Kubernetesの クラスターとは? | Kubernetes のノードとは? |
KubernetesのPodとは? | KubernetesのHelmとは? | クラウドセキュリティと ランタイムインサイト |
Kubernetesクラスタを保護する方法
まずは、Kubernetesクラスタ全体を保護するための対策を紹介します。
Kubernetes APIサーバーのセキュリティ確保
Kubernetes APIサーバであるkube-apiserverは、Kubernetesクラスタの心臓部です。APIサーバーは、アクセスリクエストを許可したり、ワークロードを実行し続けたりするものです。
KubernetesでAPIサーバーを保護するための主なツールは、Kubernetes Role-Based Access Control(RBAC)フレームワークです。RBACポリシーを使用すると、ユーザーとサービスアカウントを定義し、Kubernetes APIを使用して特定のアクションを実行できる権限を割り当てることができます。
例えば、リソースがデフォルトのKubernetes名前空間内のポッドを取得、監視、リストできるようにするRBAC Roleを作成できます。Roleは次のようになります:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
Code language: PHP (php)
そして、RoleBindingやClusterRoleBindingを以下のようなコマンドで作成することで、KubernetesのユーザーやサービスグループにRoleを関連付けます。
kubectl create rolebinding podreader-binding --user=john
このRoleBindingは、ユーザ “john “に、上記のRoleで定義されたポッドを取得、監視、リストする権限を与えます。
アドミッションコントローラとKubernetes APIセキュリティ
アドミッションコントローラを使うことで、Kubernetes APIやKubernetesクラスタ全体に第二の防御層を構築することができます。つまり、APIがすでにリクエストを認証・許可した後、APIがリクエストを完了する前に、Kubernetes APIへのリクエストをインターセプトするコードです。
例えば、アドミッションコントローラにより、オブジェクトがAPIからリクエストできるリソースの量を制限できます。RBACポリシーやセキュリティコンテキストで許可されていても特定のコマンドの実行を阻止することも可能です。
セキュリティ強化のための監査ログの活用
Kubernetes APIのセキュリティ強化に役立つセキュリティリソースとして、監査ログがあります。監査ログはKubernetesのオプション機能で、APIサーバーがリクエストを処理する際に、リクエストの記録・追跡が可能です。
監査ログを作成し、Falcoのようなツールで継続的に分析します。これにより、「ユーザーやサービスがアクセス権限のないリソースに繰り返しアクセスしようとする」など、不審なリクエストを行った場合に自動的にアラートを受け取ることができます。
Etcdの保護とバックアップ
デフォルトでは、Kubernetesはetcdというキーバリューストアを使用してクラスタのすべての設定データを保存します。
Kubernetesはetcdを保護するためのネイティブツールを提供していませんが、トランスポートセキュリティを有効にしておく必要があります。詳細についてはetcdのドキュメントを参照してください。
クラスタセキュリティのベストプラクティスとして、etcdctl snapshot saveコマンドを使用してetcdを確実にバックアップする必要もあります。たとえ、しっかりと安全性が確保されたはずの場所でKubernetesを実行している場合でも、何が起こるかわかりません。etcdをバックアップしておくことで、「etcdに保存されている重要な設定データへのアクセスを無効にしようとする」といったランサムウェアの攻撃などから環境を守ることができます。
作業する際のポイントは、パスワードやアクセスキーのような機密性の高いシークレットデータをetcdに保存しないことです。ほとんどのKubernetesディストリビューションはデフォルトでetcdにシークレットを保存します。そのかわりに外部のシークレットマネージャーを使用することで、安全性を高めやすくなります。
マスターノードの保護
Kubernetesにおけるマスターノードとは、Kubernetes APIサーバ、スケジューラ、コントローラ、etcdをホストするノードのことです。Kubernetesクラスタを束ねて管理する重要なサービスすべてをホストするノードと考えることもできます。
Kubernetesクラスタによっては、可用性を高めるために複数のマスターノードを実行することがあり、この場合、各マスターはKubernetesのコアサービスの冗長インスタンスを実行します。
マスターノードがクラスタで中心的な役割を果たすことを考えると、そのセキュリティ確保はクラスタ全体の安全性を高めるうえで不可欠です。マスターノードを保護するために押さえたいポイントは以下となります。
- Alpine Linuxのような最小限のLinuxディストリビューションでマスターノードをプロビジョニングします。ノードに余分なアプリケーションやライブラリをインストールしないようにします。
- RBACポリシーを使用して、ノード上で実行できるアクションを制限します。攻撃者によるノードへのアクセスやノードに関する情報が少ないほど、ノードの安全性は高まります。
- SELinux、AppArmor、seccomp などのエンフォースメント・フレームワークを使用して、マスター上のカーネル・レベルでのアクセス制御を制限します。これらのフレームワークは、悪意のあるプロセスがカーネルリソースにアクセスしたり、他のプロセスに干渉したりすることをより困難にすることで、セキュリティイベントの拡大を防ぐのに役立ちます。
- 不審な活動の兆候がないか、ノードのログファイルを継続的に監視します。
ワーカーノードの保護と、KubeletとKube-Proxyの権限制限
ワーカーノードの主な役割は、実行中のコンテナやポッドをホストすることです。各ワーカーノードは、ローカルに実行されるエージェントであるkubeletを介してクラスタの残りの部分と通信します。また、kube-proxyと呼ばれるサービスを使用して、ワーカーノード上でホストされているPodのネットワーク通信の管理も担当します。
設計上、Kubernetesのワーカーノードは交換可能です。ノードに障害が発生した場合、Kubernetesは自動的にそのノードのPodを他のノードに割り当て直します。この意味で、ワーカーノードのセキュリティ確保の重要性は、マスターノードのセキュリティ確保よりも高いとはいえません。セキュリティ関連の問題で少数のワーカーノードに障害が発生しても、クラスタ全体にとっては重大な脅威にはならないからです。
とはいえ、ワーカーノードを侵害した攻撃者は、そのノードでホストされているすべてのポッドにアクセスできる可能性があります。クラスタ全体のセキュリティプロセスの一環として、ワーカーノードのセキュリティ対策を講じましょう。
なお、マスターノードを保護するためのポイントは、すべてワーカーノードにも当てはまります。さらに、攻撃者がコンテナからコンテナをホストするワーカーノードへの侵入に成功した場合の潜在的な被害を減らすために、kubeletとkube-proxyに付与される権限の制限も検討しましょう。
コンテナイメージの継続的なスキャン
コンテナイメージは、コンテナの実行に必要なリソースを定義するものです。それ自体はKubernetesに含まれませんが、ほとんどのKubernetesクラスタにとって不可欠な部分であり、クラスタのセキュリティを確保する上で欠かせない要素となります。
コンテナイメージのセキュリティを確保するポイントは、コンテナイメージを継続的にスキャンすることです。さらに、以下の方法でリスクを最小限に抑えることができます。
- 信頼できるソースからのイメージのみを使用します。便利だからといって、適当なレジストリからイメージを引っ張ってくるような誘惑は避けましょう。
- コンテナをプルするときに「latest」タグを使用しないようにします。代わりにバージョンを指定することで、実行しているコンテナのバージョンと、そのコンテナに影響を及ぼす可能性のあるセキュリティ脆弱性を正確に把握することができます。
- コンテナイメージの設計に最小主義的なアプローチを取ります。複数のリソースを1つのイメージに詰め込もうとするのではなく、実装が必要な機能ごとに異なるイメージを作成します。
コンテナランタイムのセキュリティ
コンテナランタイムは、コンテナを実際に実行するサービスです。Kubernetesはさまざまなランタイムをサポートしています。ランタイムはほとんどのコンテナを実行できるため、一般的にはランタイム間の違いは重要ではない傾向があります。
コンテナランタイムソフトウェアにセキュリティ上の欠陥があると、攻撃者はいくらでもエクスプロイトを実行できる可能性があります。たとえば2019年、開発者はDockerランタイムに重大な脆弱性を発見し、コンテナがホスト全体へのルートレベルのアクセスを事実上可能にしました。
Kubernetes自体は、コンテナランタイムの脆弱性を監視したり、それらの脆弱性から発生する可能性のある侵害を警告したりすることはありません。そのため、ランタイムのセキュリティを確保するには、以下のような外部ツールを活用しましょう。
- SELinux や AppArmor のような強制フレームワークは、悪意のあるコンテナが実行できるアクションを制限するために使用できます。これらのフレームワークは、適切に構成されていれば、攻撃者がコンテナランタイムセキュリティの脆弱性を悪用して、許可されるべきではないアクションを実行した場合に、防御の第二のレイヤーを提供します。
- Falco のような監査ツールは、私たちのコンテナランタイム環境からの監査ログやその他のデータストリームを継続的に監視し、侵害の兆候となりうる振る舞いを検出したときに警告を発することができます。監査ツールは、コンテナランタイムに関連するものだけでなく、様々なセキュリティ脅威を検知することができますが、ランタイムレベルの脆弱性に起因する侵害を特定するための主要な手段です。
- 厳密に必要な場合を除き、Kubernetesのセキュリティコンテキストを使用して、コンテナが特権モードで実行されるのを防ぎ、コンテナがアクセスできるリソースを制限します。セキュリティコンテキストはコンテナランタイムの脆弱性を直接的に防止するものではありませんが、ランタイム侵害の影響を緩和できる追加の防御レイヤーを提供します。
まとめ
Kubernetesのすべてのコンポーネントを常にセキュアに保てる万能の解決策は、はっきり言って存在しません。Kubernetesのセキュリティは、アーキテクチャそのものと同じくらい複雑です。
監査やモニタリングのような特定のクラスタレベルのプラクティスは、ある種の脅威に対するセキュリティならある程度高めることができます。あわせて、APIサーバーからワーカーノード、マスターノード、etcd、そしてそれ以上に至るまで、Kubernetesクラスタを形成するさまざまな個々のコンポーネントを保護可能なセキュリティリソースを配備するのがおすすめです。