Pod Security Policy の制約を使用する

Policy Controller には制約テンプレートのデフォルト ライブラリが付属しており、Pod Security Policy バンドルとともに使用することで、Kubernetes Pod Security Policy(PSP)と同様の保護機能の多くを実現できます。さらに、ポリシーを適用する前にテストを行い、特定のリソースの適用範囲を除外する機能も追加されています。

バンドルには次の制約が含まれています。これらの制約は、次の Kubernetes Pod Security Policy(PSP)フィールド名(コントロール ID)にマッピングするパラメータを提供します。

制約名 制約の説明 コントロール ID
psp-v2022-psp-allow-privilege-escalation root 権限への昇格の制限 allowPrivilegeEscalation
psp-v2022-psp-apparmor コンテナで使用される AppArmor プロファイル アノテーション
psp-v2022-psp-capabilities Linux 機能 allowedCapabilities, requiredDropCapabilities
psp-v2022-flexvolume-drivers 特定の FlexVolume ドライバを許可する allowedFlexVolumes
psp-v2022-psp-forbidden-sysctls コンテナで使用される sysctl プロファイル forbiddenSysctls
psp-v2022-psp-fsgroup Pod のボリュームを所有している FSGroup の割り当て fsGroup
psp-v2022-psp-host-filesystem ホスト ファイル システムの使用 allowedHostPaths
psp-v2022-psp-host-namespace ホスト Namespace の使用 hostPID、hostIPC
psp-v2022-psp-host-network-ports ホスト ネットワーキングとホストポートの使用 hostNetwork、hostPorts
psp-v2022-psp-privileged-container 特権コンテナの実行 privileged
psp-v2022-psp-proc-mount コンテナで許可される Proc マウントタイプ allowedProcMountTypes
psp-v2022-psp-readonlyrootfilesystem 読み取り専用ルート ファイル システムの使用の必須化 readOnlyRootFilesystem
psp-v2022-psp-seccomp コンテナで使用される seccomp プロファイル アノテーション
psp-v2022-psp-selinux-v2 コンテナの SELinux コンテキスト seLinux
psp-v2022-psp-pods-allowed-user-ranges コンテナのユーザーとグループ ID runAsUser、runAsGroup、supplementalGroups、fsGroup
psp-v2022-psp-volume-types ボリューム タイプの使用 volumes

準備

  1. この手順で使用する gcloud コマンドと kubectl コマンドを含む Google Cloud CLI をインストールして初期化します。Cloud Shell を使用する場合、Google Cloud CLI がプリインストールされています。
  2. 制約テンプレートのデフォルト ライブラリを使用して、クラスタに Policy Controller をインストールします。

Pod Security Policy のポリシー バンドルの監査

Policy Controller を使用すると、Kubernetes クラスタにポリシーを適用できます。前の表に概要を記載している、Google 推奨のベスト プラクティスに関するワークロードとそのコンプライアンスをテストする場合は、これらの制約を「監査」モードでデプロイできます。これにより、違反が明確になり、Kubernetes クラスタに適用する前に修正できます。

kubectl、kpt、または Config Sync を使用して spec.enforcementActiondryrun に設定し、これらのポリシーを適用できます。

kubectl

  1. (省略可)kubectl でポリシーの制約をプレビューします。

    kubectl kustomize https://github.com/GoogleCloudPlatform/gke-policy-library.git/bundles/psp-v2022
    
  2. kubectl でポリシーの制約を適用します。

    kubectl apply -k https://github.com/GoogleCloudPlatform/gke-policy-library.git/bundles/psp-v2022
    

    次のような出力が表示されます。

    k8spspallowprivilegeescalationcontainer.constraints.gatekeeper.sh/psp-v2022-psp-allow-privilege-escalation created
    k8spspallowedusers.constraints.gatekeeper.sh/psp-v2022-psp-pods-allowed-user-ranges created
    k8spspapparmor.constraints.gatekeeper.sh/psp-v2022-psp-apparmor created
    k8spspcapabilities.constraints.gatekeeper.sh/psp-v2022-psp-capabilities created
    k8spspfsgroup.constraints.gatekeeper.sh/psp-v2022-psp-fsgroup created
    k8spspflexvolumes.constraints.gatekeeper.sh/psp-v2022-psp-flexvolume-drivers created
    k8spspforbiddensysctls.constraints.gatekeeper.sh/psp-v2022-psp-forbidden-sysctls created
    k8spsphostfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-host-filesystem created
    k8spsphostnamespace.constraints.gatekeeper.sh/psp-v2022-psp-host-namespace created
    k8spsphostnetworkingports.constraints.gatekeeper.sh/psp-v2022-psp-host-network-ports created
    k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-v2022-psp-privileged-container created
    k8spspprocmount.constraints.gatekeeper.sh/psp-v2022-psp-proc-mount created
    k8spspreadonlyrootfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-readonlyrootfilesystem created
    k8spspselinuxv2.constraints.gatekeeper.sh/psp-v2022-psp-selinux-v2 created
    k8spspseccomp.constraints.gatekeeper.sh/psp-v2022-psp-seccomp created
    k8spspvolumetypes.constraints.gatekeeper.sh/psp-v2022-psp-volume-types created
    
  3. ポリシーの制約がインストールされていることを確認し、クラスタ全体で違反の存在を確認します。

    kubectl get -k https://github.com/GoogleCloudPlatform/gke-policy-library.git/bundles/psp-v2022
    

    出力は次のようになります。

    NAME                                                                                                         ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspallowprivilegeescalationcontainer.constraints.gatekeeper.sh/psp-v2022-psp-allow-privilege-escalation   dryrun               0
    
    NAME                                                                                  ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspallowedusers.constraints.gatekeeper.sh/psp-v2022-psp-pods-allowed-user-ranges   dryrun               0
    
    NAME                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspapparmor.constraints.gatekeeper.sh/psp-v2022-psp-apparmor                        0
    
    NAME                                                                      ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspcapabilities.constraints.gatekeeper.sh/psp-v2022-psp-capabilities   dryrun               0
    
    NAME                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspfsgroup.constraints.gatekeeper.sh/psp-v2022-psp-fsgroup                        0
    
    NAME                                                                           ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspflexvolumes.constraints.gatekeeper.sh/psp-v2022-psp-flexvolume-drivers                        0
    
    NAME                                                                               ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspforbiddensysctls.constraints.gatekeeper.sh/psp-v2022-psp-forbidden-sysctls                        0
    
    NAME                                                                           ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spsphostfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-host-filesystem                        0
    
    NAME                                                                         ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spsphostnamespace.constraints.gatekeeper.sh/psp-v2022-psp-host-namespace   dryrun               0
    
    NAME                                                                                   ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spsphostnetworkingports.constraints.gatekeeper.sh/psp-v2022-psp-host-network-ports   dryrun               0
    
    NAME                                                                                     ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-v2022-psp-privileged-container   dryrun               0
    
    NAME                                                                 ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspprocmount.constraints.gatekeeper.sh/psp-v2022-psp-proc-mount                        0
    
    NAME                                                                                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspreadonlyrootfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-readonlyrootfilesystem                        0
    
    NAME                                                                 ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspselinuxv2.constraints.gatekeeper.sh/psp-v2022-psp-selinux-v2                        0
    
    NAME                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspseccomp.constraints.gatekeeper.sh/psp-v2022-psp-seccomp   dryrun               0
    
    NAME                                                                     ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
    k8spspvolumetypes.constraints.gatekeeper.sh/psp-v2022-psp-volume-types                        0
    
  4. (省略可)クラスタ環境に応じて、制約ファイルの PSP フィールド名 parameters を調整します。 詳しくは、上の表にある特定の PSP フィールド名のリンクをご覧ください。 たとえば、psp-host-network-ports では次のようになります。

    parameters:
      hostNetwork: true
      min: 80
      max: 9000
    

kpt

  1. kpt をインストールして設定します。これらの手順では、kpt を使用して Kubernetes リソースのカスタマイズとデプロイを行います。

  2. kpt を使用して GitHub から Pod Security Policy(PSP)v2022 ポリシー バンドルをダウンロードします。

    kpt pkg get https://github.com/GoogleCloudPlatform/gke-policy-library.git/bundles/psp-v2022
    
  3. set-enforcement-action kpt 関数を実行して、ポリシーの適用アクションを dryrun に設定します。

    kpt fn eval psp-v2022 -i gcr.io/kpt-fn/set-enforcement-action:v0.1 \
      -- enforcementAction=dryrun
    
  4. kpt を使用して作業ディレクトリを初期化します。これにより、変更を追跡するためのリソースが作成されます。

    cd psp-v2022
    kpt live init
    
  5. (省略可)クラスタ環境に応じて、制約ファイルの PSP フィールド名 parameters を調整します。 詳しくは、上の表にある特定の PSP フィールド名のリンクをご覧ください。 たとえば、psp-host-network-ports では次のようになります。

    parameters:
      hostNetwork: true
      min: 80
      max: 9000
    
  6. kpt を使用してポリシーの制約を適用します。

    kpt live apply
    
  7. ポリシーの制約がインストールされていることを確認し、クラスタ全体で違反の存在を確認します。

    kpt live status --output table --poll-until current
    

    ステータスが CURRENT の場合、制約が正常にインストールされています。

Config Sync

  1. kpt をインストールして設定します。これらの手順では、kpt を使用して Kubernetes リソースのカスタマイズとデプロイを行います。

Config Sync を使用してクラスタにポリシーをデプロイするオペレータは、次の手順を使用できます。

  1. Config Sync の同期ディレクトリに移動します。

    cd SYNC_ROOT_DIR
    

    resourcegroup.yaml を使用して .gitignore を作成または追加するには:

    echo resourcegroup.yaml >> .gitignore
    

  2. 専用の policies ディレクトリを作成します。

    mkdir -p policies
    
  3. kpt を使用して GitHub から Pod Security Policy(PSP)v2022 ポリシー バンドルをダウンロードします。

    kpt pkg get https://github.com/GoogleCloudPlatform/gke-policy-library.git/bundles/psp-v2022 policies/psp-v2022
    
  4. set-enforcement-action kpt 関数を実行して、ポリシーの適用アクションを dryrun に設定します。

    kpt fn eval policies/psp-v2022 -i gcr.io/kpt-fn/set-enforcement-action:v0.1 -- enforcementAction=dryrun
    
  5. (省略可)クラスタ環境に応じて、制約ファイルの PSP フィールド名 parameters を調整します。 詳しくは、上の表にある特定の PSP フィールド名のリンクをご覧ください。 たとえば、psp-host-network-ports では次のようになります。

    parameters:
      hostNetwork: true
      min: 80
      max: 9000
    
  6. (省略可)作成されるポリシー制約をプレビューします。

    kpt live init policies/psp-v2022
    kpt live apply --dry-run policies/psp-v2022
    

    次のような出力が表示されます。

    Dry-run strategy: client
    inventory update started
    inventory update finished
    apply phase started
    k8spspallowprivilegeescalationcontainer.constraints.gatekeeper.sh/psp-v2022-psp-allow-privilege-escalation apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspallowedusers.constraints.gatekeeper.sh/psp-v2022-psp-pods-allowed-user-ranges apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspapparmor.constraints.gatekeeper.sh/psp-v2022-psp-apparmor apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspcapabilities.constraints.gatekeeper.sh/psp-v2022-psp-capabilities apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspfsgroup.constraints.gatekeeper.sh/psp-v2022-psp-fsgroup apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspflexvolumes.constraints.gatekeeper.sh/psp-v2022-psp-flexvolume-drivers apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspforbiddensysctls.constraints.gatekeeper.sh/psp-v2022-psp-forbidden-sysctls apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spsphostfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-host-filesystem apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spsphostnamespace.constraints.gatekeeper.sh/psp-v2022-psp-host-namespace apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spsphostnetworkingports.constraints.gatekeeper.sh/psp-v2022-psp-host-network-ports apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-v2022-psp-privileged-container apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspprocmount.constraints.gatekeeper.sh/psp-v2022-psp-proc-mount apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspreadonlyrootfilesystem.constraints.gatekeeper.sh/psp-v2022-psp-readonlyrootfilesystem apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspselinuxv2.constraints.gatekeeper.sh/psp-v2022-psp-selinux-v2 apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspseccomp.constraints.gatekeeper.sh/psp-v2022-psp-seccomp apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    k8spspvolumetypes.constraints.gatekeeper.sh/psp-v2022-psp-volume-types apply skipped: inventory policy prevented actuation (strategy: Apply, status: Empty, policy: MustMatch)
    apply phase finished
    inventory update started
    inventory update finished
    apply result: 16 attempted, 0 successful, 16 skipped, 0 failed
    
  7. Config Sync の同期ディレクトリで Kustomize を使用している場合は、ルート kustomization.yamlpolicies/psp-v2022 を追加します。 それ以外の場合は、policies/psp-v2022/kustomization.yaml ファイルを削除します。

    rm SYNC_ROOT_DIR/policies/psp-v2022/kustomization.yaml
    
  8. 変更を Config Sync リポジトリに push します。

    git add SYNC_ROOT_DIR/policies/psp-v2022
    git commit -m 'Adding Pod Security Policy audit enforcement'
    git push
    
  9. インストールのステータスを確認します。

    watch gcloud beta container fleet config-management status --project PROJECT_ID
    

    ステータスが SYNCED の場合、ポリシーがインストールされています。

ポリシー違反を確認する

ポリシーの制約が監査モードでインストールされると、UI の Policy Controller ダッシュボードにクラスタに対する違反を表示できます。

また、次のコマンドを実行すると、kubectl を使用してクラスタに対する違反を表示できます。

kubectl get constraint -l policycontroller.gke.io/bundleName=psp-v2022 -o json | jq -cC '.items[]| [.metadata.name,.status.totalViolations]'

違反がある場合は、次のコマンドを実行すると、制約ごとに違反メッセージのリストが表示されます。

kubectl get constraint -l policycontroller.gke.io/bundleName=psp-v2022 -o json | jq -C '.items[]| select(.status.totalViolations>0)| [.metadata.name,.status.violations[]?]'

Pod Security Policy のポリシー バンドル適用アクションを変更する

クラスタのポリシー違反を確認したら、アドミッション コントローラが warn または deny のいずれかでクラスタへの非遵守リソースの適用をブロックするように、強制適用モードを変更することを検討できます。

kubectl

  1. kubectl を使用して、ポリシーの適用アクションを warn に設定します。

    kubectl get constraint -l policycontroller.gke.io/bundleName=psp-v2022 -o name | xargs -I {} kubectl patch {} --type='json' -p='[{"op":"replace","path":"/spec/enforcementAction","value":"warn"}]'
    
  2. ポリシー制約の適用アクションが更新されていることを確認します。

    kubectl get constraint -l policycontroller.gke.io/bundleName=psp-v2022
    

kpt

  1. set-enforcement-action kpt 関数を実行して、ポリシーの適用アクションを warn に設定します。

    kpt fn eval -i gcr.io/kpt-fn/set-enforcement-action:v0.1 -- enforcementAction=warn
    
  2. ポリシー制約を適用します。

    kpt live apply
    

Config Sync

Config Sync を使用してクラスタにポリシーをデプロイするオペレータは、次の手順を使用できます。

  1. Config Sync の同期ディレクトリに移動します。

    cd SYNC_ROOT_DIR
    
  2. set-enforcement-action kpt 関数を実行して、ポリシーの適用アクションを warn に設定します。

    kpt fn eval policies/psp-v2022 -i gcr.io/kpt-fn/set-enforcement-action:v0.1 -- enforcementAction=warn
    
  3. 変更を Config Sync リポジトリに push します。

    git add SYNC_ROOT_DIR/policies/psp-v2022
    git commit -m 'Adding Pod Security Policy policy bundle warn enforcement'
    git push
    
  4. インストールのステータスを確認します。

    gcloud alpha anthos config sync repo list --project PROJECT_ID
    

    SYNCED 列に表示されたリポジトリには、ポリシーがインストールされています。

ポリシーの適用をテストする

次のコマンドを使用して、クラスタに非遵守リソースを作成します。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: wp-non-compliant
  labels:
    app: wordpress
spec:
  containers:
    - image: wordpress
      name: wordpress
      ports:
      - containerPort: 80
        name: wordpress
EOF

次の例のように、アドミッション コントローラにより、このリソースが違反しているポリシー違反の警告の一覧が生成されるはずです。

Warning: [psp-v2022-psp-pods-allowed-user-ranges] Container wordpress is attempting to run without a required securityContext/fsGroup. Allowed fsGroup: {"ranges": [{"max": 200, "min": 100}], "rule": "MustRunAs"}
Warning: [psp-v2022-psp-pods-allowed-user-ranges] Container wordpress is attempting to run without a required securityContext/runAsGroup. Allowed runAsGroup: {"ranges": [{"max": 200, "min": 100}], "rule": "MustRunAs"}
Warning: [psp-v2022-psp-pods-allowed-user-ranges] Container wordpress is attempting to run without a required securityContext/runAsUser
Warning: [psp-v2022-psp-pods-allowed-user-ranges] Container wordpress is attempting to run without a required securityContext/supplementalGroups. Allowed supplementalGroups: {"ranges": [{"max": 200, "min": 100}], "rule": "MustRunAs"}
Warning: [psp-v2022-psp-allow-privilege-escalation] Privilege escalation container is not allowed: wordpress
Warning: [psp-v2022-psp-seccomp] Seccomp profile 'not configured' is not allowed for container 'wordpress'. Found at: no explicit profile found. Allowed profiles: {"RuntimeDefault", "docker/default", "runtime/default"}
Warning: [psp-v2022-psp-capabilities] container <wordpress> is not dropping all required capabilities. Container must drop all of ["must_drop"] or "ALL"
Warning: [psp-v2022-psp-readonlyrootfilesystem] only read-only root filesystem container is allowed: wordpress
pod/wp-non-compliant created

Pod Security Policy のポリシー バンドルを削除する

必要に応じて、Pod Security Policy のポリシー バンドルをクラスタから削除できます。

kubectl

  • kubectl を使用してポリシーを削除します。

    kubectl delete constraint -l policycontroller.gke.io/bundleName=psp-v2022
    

kpt

  • ポリシーを削除します。

    kpt live destroy
    

Config Sync

Config Sync を使用してクラスタにポリシーをデプロイするオペレータは、次の手順を使用できます。

  1. 変更を Config Sync リポジトリに push します。

    git rm -r SYNC_ROOT_DIR/policies/psp-v2022
    git commit -m 'Removing PSP policies'
    git push
    
  2. ステータスを確認します。

    gcloud alpha anthos config sync repo list --project PROJECT_ID
    

    SYNCED 列に表示されたリポジトリで、ポリシーが削除されていることを確認します。