PodSecurityPolicy の使用

このページでは、Google Kubernetes Engine の PodSecurityPolicy を使用する方法について説明します。

概要

PodSecurityPolicy は、クラスタ上で Pod を作成および更新するリクエストを検証するために作成するアドミッション コントローラ リソースです。PodSecurityPolicy は、クラスタに受け入れられるために Pod が満たす必要がある一連の条件を定義します。Pod の作成または更新のリクエストが PodSecurityPolicy の条件を満たさない場合、そのリクエストは拒否され、エラーが返されます。

PodSecurityPolicy を使用するには、新規 Pod および更新された Pod が満たさなければならないポリシーをまず作成して定義する必要があります。次に、定義されたポリシーに従ってポッドの作成リクエストおよび更新リクエストを検証する PodSecurityPolicy アドミッション コントローラを有効にする必要があります。

複数の PodSecurityPolicy が使用可能な場合、アドミッション コントローラは、検証に成功した最初のポリシーを使用します。ポリシーはアルファベット順に並べられ、コントローラは、変更ポリシーよりも非変更ポリシー(ポッドを変更しないポリシー)を優先します。

PodSecurityPolicy は、Kubernetes バージョン 1.8.6 以降を実行する GKE クラスタで使用できます。

始める前に

作業を始める前に、次のことを確認してください。

次のいずれかの方法で gcloud のデフォルトの設定を指定します。

  • gcloud init。デフォルトの設定全般を確認する場合に使用します。
  • gcloud config。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。

gcloud init の使用

エラー One of [--zone, --region] must be supplied: Please specify location を受信した場合は、このセクションの内容を実施します。

  1. gcloud init を実行して、次の操作を行います。

    gcloud init

    リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

    gcloud init --console-only
  2. 手順に従って gcloud を承認し、Google Cloud アカウントを使用します。
  3. 新しい構成を作成するか、既存の構成を選択します。
  4. Google Cloud プロジェクトを選択します。
  5. デフォルトの Compute Engine ゾーンを選択します。

gcloud config の使用

  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project project-id
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone compute-zone
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region compute-region
  • gcloud を最新バージョンに更新します。
    gcloud components update

PodSecurityPolicy の定義

PodSecurityPolicy コントローラがポッドを検証してクラスタ内に受け入れるには、その前に PodSecurityPolicy リソースをクラスタ内で定義する必要があります。

PodSecurityPolicy は、そのポリシー下で作成される Pod の制限、要件、およびデフォルト値のリストを指定します。例として、特権コンテナ、hostPath Volume、およびホスト ネットワーキングの使用を制限すること、または、すべてのコンテナをデフォルトで seccomp プロファイルにより実行することが挙げられます。PodSecurityPolicy アドミッション コントローラは、利用可能な PodSecurityPolicy に従って、リクエストを検証します。

次の PodSecurityPolicy の my-psp.yaml の例では、単に特権 Pod が作成されないようにします。また、このポリシーは、使用可能なすべての Volume へのアクセスを許可するなど、制御に関して他のいくつかの側面にも影響します。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: my-psp
spec:
  privileged: false  # Prevents creation of privileged Pods
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

PodSecurityPolicy 仕様により、制御の多くの側面のセキュリティを確保できます。制御のさまざまな側面のうちこの例で指定されているもの(seLinuxsupplementalGroupsrunAsUser、および fsGroup)はすべて RunAsAny に設定されており、それは、これらのフィールドの有効な任意の値をこのポリシーで使用できることを示しています。

PodSecurityPolicy とその制御の側面については、PodSecurityPolicy とはおよび Kubernetes のドキュメントの中のポリシーのリファレンスを参照してください。

このリソースは、kubectl コマンドライン ツールを使用して作成します。

kubectl apply -f my-psp.yaml

PodSecurityPolicy の構成例については、Kubernetes ドキュメントの PodSecurityPolicy のページにあるを参照してください。

ポリシーの承認

cluster-admin ロールを持つアカウントは、ロールベースのアクセス制御を使用して、目的のサービス アカウントに PodSecurityPolicy へのアクセス権を付与する Role または ClusterRole を作成できます。ClusterRole はクラスタ全体にわたる権限を付与し、ロールは自分が定義する Namespace 内で権限を付与します。

たとえば、以下の ClusterRole my-clusterrole.yaml は、verb: use で示されているように、my-psp という PodSecurityPolicy へのアクセスを付与します。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: my-clusterrole
rules:
- apiGroups:
  - policy
  resources:
  - podsecuritypolicies
  verbs:
  - use
  resourceNames:
  - my-psp

次のコマンドを実行して ClusterRole を作成します。

kubectl apply -f my-clusterrole.yaml

Role(または ClusterRole)を作成した後、RoleBinding(または ClusterRoleBinding)リソースを作成することにより、目的のサービス アカウントに関連付けます。

次の RoleBinding、my-rolebinding.yaml は、ClusterRole my-clusterrole を、特定の Namespace my-namespace のサービス アカウントにバインドします。

# Bind the ClusterRole to the desired set of service accounts.
# Policies should typically be bound to service accounts in a namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-rolebinding
  namespace: my-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: my-clusterrole
subjects:
# Example: All service accounts in my-namespace
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:serviceaccounts
# Example: A specific service account in my-namespace
- kind: ServiceAccount # Omit apiGroup
  name: default
  namespace: my-namespace

この RoleBinding において、

  • subjects フィールドは、ClusterRole がどのアカウントにバインドされるかを指定します。
  • 最初のサブジェクトは Group である system:serviceaccounts です。これは、クラスタ内のすべてのサービス アカウントを含むものです。
  • 2 番目のサブジェクトは個別の ServiceAccount である default です。これは、Namespace 内のデフォルトのサービス アカウントを指定するものです。

次のコマンドを実行して RoleBinding を作成します。

kubectl apply -f my-rolebinding.yaml

RBAC の詳細については、RBAC 認可の使用を参照してください。

PodSecurityPolicy コントローラを有効にする

PodSecurityPolicy アドミッション コントローラを使用するには、新しいクラスタを作成するか、--enable-pod-security-policy フラグを使用して既存のクラスタを更新する必要があります。

PodSecurityPolicy を使用して新しいクラスタを作成するには、次のコマンドを実行します。

gcloud beta container clusters create cluster-name --enable-pod-security-policy

既存のクラスタを更新するには、次のコマンドを実行します。

gcloud beta container clusters update cluster-name --enable-pod-security-policy

PodSecurityPolicy コントローラを無効にする

PodSecurityPolicy コントローラを無効にするには、次のコマンドを実行します。

gcloud beta container clusters update cluster-name --no-enable-pod-security-policy

コントローラを無効にすると、クラスタは既存のポリシーの検証とデフォルト設定を停止しますが、削除するわけではありません。バインディングも削除されません。

NetworkPolicy に関する処理

NetworkPolicy を使用していて、PodSecurityPolicy の対象となる Pod がある場合は、PodSecurityPolicy を使用する権限を持つ RBAC Role または ClusterRole を作成します。その後、役割または ClusterRole をポッドのサービス アカウントにバインドします。この場合、ユーザー アカウントに権限を付与するだけでは不十分です。詳細については、ポリシーの承認をご覧ください。

次のステップ