Trending keywords: security, cloud, container,

アドミッションコントローラを使用して Kubernetes のセキュリティを強化する

SHARE:

すでに Kubernetes を使用しているのであれば、RBAC やネットワークポリシーなど、Kubernetes の基本的なセキュリティ機能についてはよくご存じでしょう。これらのツールは、クラスター内のさまざまなユーザーやサービスが実行できるアクションについての基本的なルールを適用できます。

しかし、場合によっては、RBAC やネットワークポリシーがサポートする以上の細かい設定やポリシー機能が必要になることもあります。あるいは、クラスターへの参加を許可する前に、追加のチェックを実行してリソースを検証しなければならない場合もあります。

このような場合に使用できるのが Kubernetes アドミッションコントローラです。アドミッションコントローラは、他の種類の Kubernetes ポリシーフレームワークを介して適用する認証、承認、ネットワークセキュリティのルールよりもはるかに高度なセキュリティチェックを実行するために、拡張性に優れたソリューションを提供します。また、さらに高度な分析機能やコンプライアンス機能を提供する外部のセキュリティツールと Kubernetes を接続する際にも中心的な役割を果たします。

アドミッションコントローラはオプション機能であり、基本的な RBAC やネットワークポリシーで十分にセキュリティを確保できるシンプルな構成であれば必要ないかもしれません。しかし、複雑で大規模なクラスターを保護するのであれば、アドミッションコントローラが非常に有効なリソースとなります。

この記事では、Kubernetes アドミッションコントローラの役割と仕組みについて説明し、アドミッションコントローラを使用してセキュリティを強化する場合の一般的な手順をご紹介します。

Kubernetes アドミッションコントローラとは

Kubernetes アドミッションコントローラとは、Kubernetes API サーバーへのリクエストを評価し、そのリクエストを許可するかどうかを決定するコードです。

この評価は、API サーバーがリクエストを認証して権限を付与したあと、リクエストが許可され、実行される前に行われます。

つまり、API サーバーが有効なリクエストであると判断した場合でも(API サーバーは設定した RBAC Role や ClusterRole に基づいて判断します)、アドミッションコントローラはそのリクエストを評価し、独自のルールに基づいて受け入れるかどうかを決定します。

アドミッションコントローラのメリット

アドミッションコントローラは、Kubernetes のセキュリティ戦略の一環として、いくつかの重要なメリットをもたらします。

  • リクエストのダブルチェック: アドミッションコントローラは、RBAC ポリシーの設定ミスなどのために RBAC の制御をすり抜ける可能性のある無効なリクエストに対して、第 2 の防御線として機能します。
  • ルールの柔軟性: アドミッションコントローラは、RBAC では構成できない(少なくとも簡単にはできない)パラメータに基づいてリクエストを評価し、ルールを適用できます。RBAC は ID とアクションのみに基づいてルールを定義するため、この点は重要です。アドミッションコントローラは、リソースのリクエストを制限したり、特権コンテナでコマンドを実行できないようにしたりするなど、さらに細かい設定が可能です。
  • サードパーティの統合: アドミッションコントローラの中には、Webhook を使用できるものがあります。Webhook を使用すると、サードパーティのセキュリティシステムでアクションをトリガできます。つまり、アドミッションコントローラは外部のセキュリティツールを Kubernetes API で直接実行することなく、これらのツールを Kubernetes に統合する手段を提供します。これはおそらく、アドミッションコントローラの最も強力な機能と言えるでしょう。

アドミッションコントローラの使用

ここでは、Kubernetes でアドミッションコントローラを使用する手順を説明します。

クラスターでのアドミッションコントローラの有効化

Kubernetes でアドミッションコントローラを使用するには、最初にクラスターの kube-apiserver.yaml ファイル(ほとんどの場合、Kubernetes のマスターまたはマスターノードの /etc/kubernetes/manifests/ ディレクトリに格納されます)で、アドミッションコントローラ機能が有効になっていることを確認する必要があります。

–enable-admission-plugins フラグが存在する場合、アドミッションコントローラはそのクラスターに対して有効になっています。

特定のアドミッションコントローラの選択

–enable-admission-plugins フラグのあとに、次のようにコンマ区切りリストが続いていることがあります。

--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,TaintNodesByCondition
,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection
,PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,RuntimeClass
,ResourceQuota

このリストは、クラスターに対して有効になっている具体的なアドミッションコントローラを示しています。Kubernetes のドキュメントでは、利用できるすべてのアドミッションコントローラについて詳しく説明しています。

–enable-admission-plugins フラグが存在し、あとに続くリストがない場合、Kubernetes はアドミッションコントローラのデフォルトのセットを有効にします。Kubernetes の現在のバージョンでは次のようになります。

  • NamespaceLifecycle
  • LimitRanger
  • ServiceAccount
  • TaintNodesByCondition
  • Priority
  • DefaultTolerationSeconds
  • DefaultStorageClass
  • StorageObjectInUseProtection
  • PersistentVolumeClaimResize
  • RuntimeClass
  • CertificateApproval
  • CertificateSigning
  • CertificateSubjectRestriction
  • DefaultIngressClass
  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook
  • ResourceQuota

つまり、デフォルトのアドミッションコントローラを使用することも、有効にするアドミッションコントローラを明示的に定義することもできます。

アドミッションコントローラの無効化

必要に応じて、kube-apiserver.yaml ファイル内の –disable-admission-plugins=… フラグを使用してアドミッションコントローラを明示的に無効にすることができます。

このフラグはコントローラのデフォルトのセットを使用しており、そのセット内の特定のコントローラを無効にしたい場合に便利です。

アクティブなアドミッションコントローラの確認

クラスター内で有効になっているアドミッションコントローラがわからない場合は、以下のコマンドを実行すると一覧表示できます。

kube-apiserver -h | grep enable-admission-plugins

Kubernetes は、クラスター内で有効にしたアドミッションコントローラを自動的に適用します。(RBAC などのように)追加のポリシーファイルを作成する必要はありません。

ただし、アドミッションコントローラによっては、構成の詳細を指定する必要があります。たとえば、API サーバーで受け入れるリクエストの数を制限する EventRateLimit コントローラを使用するには、YAML 形式の構成ファイルを作成し、–admission-control-config-file フラグを使用して API サーバーにそれを指示する必要があります。

構成ファイルは次のようになります。

apiVersion: eventratelimit.admission.k8s.io/v1alpha1
kind: Configuration
limits:
- type: Namespace
  qps: 50
  burst: 100
  cacheSize: 2000
- type: User
  qps: 10
  burst: 50Code language: PHP (php)

このファイルでは、qps は 1 秒あたりのクエリ数(queries per second)を表し、burst は qps で設定した制限を適用する前に API サーバーが受け入れるクエリ数を定義するものです。つまり、qps が 50 で burst が 100 の場合、サーバーは 50 の qps 制限を適用し始める前に、クエリを 100 個まで受け入れることを意味します。この制限は、特定の種類のリソース(上記の例では namespace とユーザー)に対して定義されます。

具体的なアドミッションコントローラの構成に関する詳細は、Kubernetes のドキュメントを参照してください。

Webhook を使用する場合のカスタムアドミッションコントローラの作成

さまざまな組み込みアドミッションコントローラを適切に構成すれば、クラスターセキュリティのさまざまな面を大幅に強化できます。

しかし、前述のとおり、アドミッションコントローラの最も強力な機能は、Webhook を使用して外部のセキュリティツールと統合できることです。

たとえば、ImagePolicyWebhook コントローラを使用すれば、リモートサーバーに接続できます。そのためには、最初に kube-apiserver.yaml で ImagePolicyWebhook が有効になっていることを確認する必要があります。

次に、リモートサーバーへの接続に使用する ImagePolicyWebhook の構成の詳細を記載したファイル(admission-config.yaml)を作成します。次のコマンドで API サーバーにこのファイルを指定します。

kube-apiserver --admission-control-config-file=admission-config.yaml

admission-config.yaml ファイル自体には、次のような記述が含まれています。

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  configuration:
    imagePolicy:
      kubeConfigFile: <path-to-kubeconfig-file>
      allowTTL: 50
      denyTTL: 50
      retryBackoff: 500
      defaultAllow: trueCode language: HTML, XML (xml)

また、リモートサーバーを構成する、次のような別の kubeconfig ファイルも必要です。

# clusters refers to the remote service.
clusters:
- name: name-of-remote-imagepolicy-service
  cluster:
    certificate-authority: /path/to/ca.pem    # CA for verifying the remote service.
    server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
  user:
    client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use
    client-key: /path/to/key.pem          # key matching the certCode language: PHP (php)

正しく構成すれば、Kubernetes API サーバーが許可の判断を行う際に、(上記で定義したリモートサーバーのような)リモートサービスに接続できるようになります。繰り返しますが、このアプローチの利点は、使用したいポリシーエンジンを Kubernetes API サーバー自体に組み込むことなく、アドミッションルールを外部で定義できることです(率直に言えば、API サーバーの構成はそれ自体で十分複雑であるためです)。

つまり、少なくとも現在の Kubernetes の基準では、Kubernetes アドミッションコントローラは、クラスターに他のセキュリティ層を追加するための強力かつ比較的使いやすいリソースと言えます。どのアドミッションコントローラを有効にするかはワークロードによって異なり、Webhook を使用してカスタムコントローラを定義する必要があるかどうかも、アドミッションコントローラによって異なります。

しかし、少なくとも、どの種類の本番ワークロードにも使用する Kubernetes クラスターについては、最低限デフォルトのアドミッションコントローラを有効にしておく必要があるでしょう。