Trending keywords: security, cloud, container,

Kubernetesクラスタのセキュリティ、コンポーネント別

SHARE:

Kubernetesを知っている人は、Kubernetesが単一のツールではなく、APIサーバー、ノードエージェント、コンテナランタイムなど、多数の異なるタイプのサービスとリソースで構成されていることをご存じでしょう。

Kubernetesクラスタ内の各コンポーネントは、それぞれ異なるタイプのセキュリティ脅威に直面しており、異なるセキュリティ設定が必要です。場合によっては、同じセキュリティ手法を複数のコンポーネントに適用することもできます。例えば、役割ベースのアクセス制御を使用して、Kubernetesのさまざまなタイプのリソースの権限を管理できます。

それでも、一部のコンポーネントには固有のセキュリティ要件があり、固有のセキュリティソリューションが必要です。例えば、APIサーバーのセキュリティ確保は、Kubernetesノードのセキュリティ確保とは異なります。Kubernetesクラスタのセキュリティは、各コンポーネントに起こりうるセキュリティ上の脅威を理解し、対処することが重要です。

このような現実を念頭に置いて、ここではKubernetesクラスタの各コンポーネントを保護することで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に関連するセキュリティ問題を防ぐのに役立つ3つ目のセキュリティリソースは、監査ログです。監査ログはKubernetesのオプション機能で、APIサーバーがリクエストを処理する際に、リクエストを記録・追跡することができます。

監査ログを作成し、Falcoのようなツールで継続的に分析することで、ユーザーやサービスがアクセス権限のないリソースに繰り返しアクセスしようとするなど、不審なリクエストを行った場合に自動的にアラートを受け取ることができます。

Etcdの保護とバックアップ

デフォルトでは、Kubernetesはetcdというキーバリューストアを使用してクラスタのすべての設定データを保存します。

Kubernetesはetcdを保護するためのネイティブツールを提供していませんが、トランスポートセキュリティを有効にしておく必要があります。詳細についてはetcdのドキュメントを参照してください。

クラスタセキュリティのベストプラクティスとして、etcdctl snapshot saveコマンドを使用してetcdを確実にバックアップする必要もあります。etcdの信頼性に強い自信を持っている場所でKubernetesを実行している場合でも、etcdのバックアップは、誰かが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のすべてのコンポーネントを常にセキュアにするために使える「1つの馬鹿げたトリック」があればいいのですが。しかし、それはありません。Kubernetesのセキュリティは、Kubernetesのアーキテクチャそのものと同じくらい複雑です。監査やモニタリングのような特定のクラスタレベルのプラクティスは、ある種の脅威に対する広範な保護を提供することができますが、APIサーバーからワーカーノード、マスターノード、etcd、そしてそれ以上に至るまで、Kubernetesクラスタを形成するさまざまな個々のコンポーネントを保護できるセキュリティリソースを配備する必要もあります。