Azure Kubernetes Service (AKS) でポッドのセキュリティ ポリシーを使用してクラスターのセキュリティを保護する (プレビュー)

重要

ポッド セキュリティ ポリシー機能は、2023 年 8 月 1 日に非推奨となり、AKS バージョン 1.25 以降から削除されました。

Azure のサポートを維持できるように、ポッド セキュリティ アドミッション コントローラーまたは Azure ポリシーに移行することをお勧めします。 ポッド セキュリティ アドミッションは、単一クラスター実装用の組み込みポリシー ソリューションです。 エンタープライズ レベルのポリシーをお探しの場合は、Azure ポリシー の方が適しています。

開始する前に

  • この記事は、AKS クラスターがすでに存在していることを前提としています。 AKS クラスターが必要な場合は、Azure CLIAzure PowerShell、または Azure portal を使用して作成します。
  • Azure CLI バージョン 2.0.61 以降がインストールされて構成されている必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、「Azure CLI のインストール」を参照してください。

aks-preview Azure CLI 拡張機能をインストールする

重要

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿のまま" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。

  1. az extension add コマンドを使用して aks-preview 拡張機能をインストールします。

    az extension add --name aks-preview
    
  2. az extension update コマンドを使って拡張機能の最新バージョンに更新します。

    az extension update --name aks-preview
    

PodSecurityPolicyPreview 機能フラグを登録する

  1. az feature register コマンドを使用して、PodSecurityPolicyPreview 機能フラグを登録します。

    az feature register --namespace "Microsoft.ContainerService" --name "PodSecurityPolicyPreview"
    

    状態が [登録済み] と表示されるまでに数分かかります。

  2. az feature show コマンドを使用して、登録の状態を確認します。

    az feature show --namespace "Microsoft.ContainerService" --name "PodSecurityPolicyPreview"
    
  3. 状態が Registered と表示されたら、az provider register コマンドを使用して Microsoft.ContainerService リソース プロバイダーの登録を最新の情報に更新します。

    az provider register --namespace Microsoft.ContainerService
    

ポッド セキュリティ ポリシーの概要

Kubernetes クラスターでは、リソースが作成されるときに、アドミッション コントローラーを使用して API サーバーへの要求をインターセプトします。 次にアドミッション コントローラーは、一連のルールに対してリソース要求を検証したり、デプロイ パラメーターを変更するようにリソースを変化させたりすることができます。

PodSecurityPolicy は、ポッド仕様が定義されている要件を満たしていることを検証するアドミッション コント ローラーです。 これらの要件により、特権コンテナーの使用、特定の種類のストレージへのアクセス、またはコンテナーを実行できるユーザーやグループが制限される可能性があります。 ポッド セキュリティ ポリシーに概説されている要件をポッド仕様が満たしていない場合にリソースをデプロイしようとすると、要求は拒否されます。 AKS クラスターにどのポッドをスケジュールできるかを制御するこの機能により、いくつかの潜在的なセキュリティの脆弱性や特権エスカレーションを防ぐことができます。

AKS クラスターでポッド セキュリティ ポリシーを有効にすると、いくつかの既定のポリシーが適用されます。 これらのポリシーには、どのようなポッドをスケジュールできるかを定義するための、すぐに使えるエクスペリエンスが用意されています。 ただし、独自のポリシーを定義するまでは、ポッドのデプロイで問題が発生する可能性があります。 推奨される方法:

  1. AKS クラスターを作成します。
  2. 独自のポッドのセキュリティ ポリシーを定義する。
  3. ポッドのセキュリティ ポリシー機能を有効にする。

ポッドのセキュリティ ポリシーと Azure Policy の動作変更

シナリオ ポッドのセキュリティ ポリシー Azure Policy
インストール ポッドのセキュリティ ポリシー機能を有効にします Azure Policy アドオンを有効にします
ポリシーのデプロイ ポッドのセキュリティ ポリシーのリソースをデプロイします サブスクリプションまたはリソース グループのスコープに Azure Policy を割り当てます。 Kubernetes リソース アプリケーションには Azure Policy アドオンが必要です。
既定のポリシー AKS でポッドのセキュリティ ポリシーが有効になっている場合、既定の特権ポリシーおよび無制限のポリシーが適用されます。 Azure Policy アドオンを有効にしても、既定のポリシーは適用されません。 Azure Policy では、ポリシーを明示的に有効にする必要があります。
ポリシーの作成と割り当てが可能なユーザー クラスター管理者がポッドのセキュリティ ポリシー リソースを作成します。 ユーザーには、少なくとも AKS クラスター リソース グループに対する "所有者" または "リソース ポリシーの共同作成者" 権限を含むロールが必要です。 - ユーザーは、API を通じて、AKS クラスター リソース スコープでポリシーを割り当てることができます。 ユーザーには、少なくとも AKS クラスター リソースに対する "所有者" または "リソース ポリシーの共同作成者" 権限が必要です。 - Azure portal では、ポリシーを管理グループ、サブスクリプション、またはリソース グループ レベルで割り当てることができます。
ポリシーの承認 ユーザーおよびサービス アカウントには、ポッドのセキュリティ ポリシーを使用するための明示的な権限が必要です。 ポリシーを承認するために、追加の割り当ては必要ありません。 Azure でポリシーが割り当てられると、すべてのクラスター ユーザーがこれらのポリシーを使用できるようになります。
ポリシーの適用性 管理者ユーザーは、ポッド セキュリティ ポリシーの適用をバイパスします。 すべてのユーザー (管理者と管理者以外) に同じポリシーが表示されます。 ユーザーに基づく特殊な保護はありません。 ポリシーの適用は、名前空間レベルで除外できます。
ポリシーのスコープ ポッドのセキュリティ ポリシーには、名前空間が指定されていません。 Azure Policy によって使用される制約テンプレートには、名前空間が指定されていません。
拒否/監査/変異アクション ポッドのセキュリティ ポリシーでは、拒否アクションのみがサポートされます。 作成要求では、既定値を使用して変異を実行できます。 更新要求中に検証を行うことができます。 Azure Policy では、監査アクションと拒否アクションの両方がサポートされています。 変異はまだサポートされていません。
ポッドのセキュリティ ポリシーへの準拠 ポッドのセキュリティ ポリシーを有効にする前に存在していたポッドのコンプライアンスを可視化することはできません。 ポッドのセキュリティ ポリシーを有効にした後に作成された非準拠ポッドは拒否されます。 Azure ポリシーを適用する前に存在していた非準拠ポッドは、ポリシー違反として表示されます。 ポリシーに deny 効果が設定されている場合、Azure ポリシーを有効にした後に作成された非準拠ポッドは拒否されます。
クラスターでポリシーを表示する方法 kubectl get psp kubectl get constrainttemplate - すべてのポリシーが返されます。
ポッドのセキュリティ ポリシーの標準 - 特権 この機能を有効にすると、特権ポッド セキュリティ ポリシー リソースが既定で作成されます。 特権モードは、制限がないことを意味します。したがって、Azure Policy が割り当てられていないことと同じです。
ポッドのセキュリティ ポリシーの標準 - ベースライン/既定 ユーザーは、ポッドのセキュリティ ポリシーのベースライン リソースをインストールします。 Azure Policy には、ベースライン ポッド セキュリティ ポリシーにマップされる組み込みベースライン イニシアチブが用意されています。
ポッドのセキュリティ ポリシーの標準 - 制限付き ユーザーは、ポッドのセキュリティ ポリシーの制限付きリソースをインストールします。 Azure Policy には、制限付きポッド セキュリティ ポリシーにマップされる組み込みの制限付きイニシアチブが用意されています。

AKS クラスターでポッド セキュリティ ポリシーを有効にする

Note

実際の使用では、独自のカスタム ポリシーを定義するまではポッドのセキュリティ ポリシーを有効にしないでください。 この記事では、既定のポリシーでポッドのデプロイがどのように制限されるかを示すために、最初の手順としてポッドのセキュリティ ポリシーを有効にしています。

  • az aks update コマンドを使用してポッドのセキュリティ ポリシーを有効にします。

    az aks update \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --enable-pod-security-policy
    

既定の AKS ポリシー

ポッド セキュリティ ポリシーを有効にすると、AKS によって、privileged という名前の既定ポリシーが 1 つ作成されます。 既定のポリシーを編集または削除しないでください。 代わりに、自分が制御したい設定を定義する、独自のポリシーを作成します。 最初に、これらの既定のポリシーがどのようなものか、そしてそれらがどのようにポッドのデプロイに影響を与えるかについて見てみましょう。

  1. kubectl get psp コマンドを使用して、使用可能なポリシーを表示します。

    kubectl get psp
    

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

    NAME         PRIV    CAPS   SELINUX    RUNASUSER          FSGROUP     SUPGROUP    READONLYROOTFS   VOLUMES
    privileged   true    *      RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *     configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
    

    privileged ポッド セキュリティ ポリシーは、AKS クラスター内のすべての認証済みユーザーに適用されます。 この割り当ては、ClusterRolesClusterRoleBindings によって制御されます。

  2. kubectl get rolebindings コマンドを使用して、kube-system 名前空間で default:privileged: バインディングを検索します。

    kubectl get rolebindings default:privileged -n kube-system -o yaml
    

    次に示す縮約された出力例では、psp:privilegedClusterRole が、すべての system:authenticated ユーザーに割り当てられています。 この機能により、独自のポリシーが定義されていなくても基本レベルの特権が提供されます。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      [...]
      name: default:privileged
      [...]
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: psp:privileged
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:masters
    

独自のセキュリティ ポリシーの作成を開始する前に、これらの既定のポリシーがポッドをスケジュールするためにどのようにユーザー要求に作用するかを理解することが重要です。 次のいくつかのセクションでは、いくつかポッドをスケジュールして既定のポリシーの動作を確認してみます。

AKS クラスターでテスト ユーザーを作成する

az aks get-credentials コマンドを使用すると、既定では、AKS クラスターの "管理者" 資格情報が kubectl config に追加されます。 管理者ユーザーは、ポッド セキュリティ ポリシーの適用をバイパスします。 AKS クラスターに Microsoft Entra 統合を使う場合は、管理者以外のユーザーの資格情報でサインインして、ポリシー適用の動作を確認できます。

  1. kubectl create namespace コマンドを使用して、テスト リソース用に psp-aks という名前のサンプル名前空間を作成します。

    kubectl create namespace psp-aks
    
  2. kubectl create serviceaccount コマンドを使用して、nonadmin-user という名前のサービス アカウントを作成します。

    kubectl create serviceaccount --namespace psp-aks nonadmin-user
    
  3. kubectl create rolebinding コマンドを使用して、名前空間で基本的な操作を行うために nonadmin-user の RoleBinding を作成します。

    kubectl create rolebinding \
        --namespace psp-aks \
        psp-aks-editor \
        --clusterrole=edit \
        --serviceaccount=psp-aks:nonadmin-user
    

管理者と管理者以外のユーザーのエイリアス コマンドを作成する

kubectl を使用する場合は、2 つのコマンド ライン エイリアスを作成することで、通常の管理者ユーザーと管理者以外のユーザーの違いを明確にすることができます。

  1. 通常の管理者ユーザー用の kubectl-admin エイリアス。スコープは psp-aks 名前空間です。
  2. 前の手順で作成した nonadmin-user 用の kubectl-nonadminuser エイリアス。スコープは psp-aks 名前空間です。
  • 次のコマンドを使用して、2 つのエイリアスを作成します。

    alias kubectl-admin='kubectl --namespace psp-aks'
    alias kubectl-nonadminuser='kubectl --as=system:serviceaccount:psp-aks:nonadmin-user --namespace psp-aks'
    

特権のあるポッドの作成をテストする

privileged: true のセキュリティ コンテキストを持つポッドをスケジュールすると何が起こるかをテストしてみましょう。 このセキュリティ コンテキストは、ポッドの特権をエスカレートします。 既定の privilege AKS セキュリティ ポリシーでは、この要求を拒否する必要があります。

  1. nginx-privileged.yaml という名前のファイルを作成し、次の YAML マニフェストの内容を貼り付けます。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-privileged
    spec:
      containers:
        - name: nginx-privileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
          securityContext:
            privileged: true
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。

    kubectl-nonadminuser apply -f nginx-privileged.yaml
    

    次の出力例は、ポッドをスケジュールできなかったことを示しています。

    Error from server (Forbidden): error when creating "nginx-privileged.yaml": pods "nginx-privileged" is forbidden: unable to validate against any pod security policy: []
    

    ポッドがスケジューリング段階に達していないため、続行する前に削除すべきリソースはありません。

特権のないポッドの作成をテストする

前の例で、ポッド仕様は特権のエスカレーションを要求しました。 この要求は既定の privilege ポッド セキュリティ ポリシーによって拒否されるため、ポッドはスケジュールできません。 同じ NGINX ポッドを特権エスカレーション要求なしで実行してみましょう。

  1. nginx-unprivileged.yaml という名前のファイルを作成し、次の YAML マニフェストの内容を貼り付けます。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。

    kubectl-nonadminuser apply -f nginx-unprivileged.yaml
    

    次の出力例は、ポッドをスケジュールできなかったことを示しています。

    Error from server (Forbidden): error when creating "nginx-unprivileged.yaml": pods "nginx-unprivileged" is forbidden: unable to validate against any pod security policy: []
    

    ポッドがスケジューリング段階に達していないため、続行する前に削除すべきリソースはありません。

特定のユーザー コンテキストでのポッドの作成をテストする

前の例では、コンテナー イメージは、自動的に root を使用して NGINX をポート 80 にバインドしようとしました。 この要求は既定の privilege ポッド セキュリティ ポリシーによって拒否されたため、ポッドは開始できません。 runAsUser: 2000 などの特定のユーザー コンテキストを使用して、同じ NGINX ポッドを実行してみましょう。

  1. nginx-unprivileged-nonroot.yaml という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged-nonroot
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
          securityContext:
            runAsUser: 2000
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。

    kubectl-nonadminuser apply -f nginx-unprivileged-nonroot.yaml
    

    次の出力例は、ポッドをスケジュールできなかったことを示しています。

    Error from server (Forbidden): error when creating "nginx-unprivileged-nonroot.yaml": pods "nginx-unprivileged-nonroot" is forbidden: unable to validate against any pod security policy: []
    

    ポッドがスケジューリング段階に達していないため、続行する前に削除すべきリソースはありません。

カスタム ポッド セキュリティ ポリシーを作成する

既定のポッド セキュリティ ポリシーのビヘイビアーを確認したので、管理者以外のユーザーが正常にポッドをスケジュールする方法を提供しましょう。

特権アクセスを要求するポッドを拒否するポリシーを作成します。 runAsUser や許可されるボリュームなどのその他のオプションは、明示的に制限されません。 この種類のポリシーは特権アクセスの要求を拒否しますが、要求されたポッドの実行をクラスターに許可します。

  1. psp-deny-privileged.yaml という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。

    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: psp-deny-privileged
    spec:
      privileged: false
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      runAsUser:
        rule: RunAsAny
      fsGroup:
        rule: RunAsAny
      volumes:
     - '*'
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポリシーを作成します。

    kubectl apply -f psp-deny-privileged.yaml
    
  3. kubectl get psp コマンドを使用して、使用可能なポリシーを表示します。

    kubectl get psp
    

    次の出力例で、psp-deny-privileged ポリシーを、前述のポッドを作成する例で適用されていた既定の privilege ポリシーと比較します。 PRIV エスカレーションの使用のみがポリシーによって拒否されます。 psp-deny-privileged ポリシーには、ユーザーまたはグループの制限はありません。

    NAME                  PRIV    CAPS   SELINUX    RUNASUSER          FSGROUP     SUPGROUP    READONLYROOTFS   VOLUMES
    privileged            true    *      RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *
    psp-deny-privileged   false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *          
    

ユーザー アカウントでのカスタム ポッド ポリシーの使用を許可する

前の手順では、特権アクセスを要求するポッドを拒否するポッド セキュリティ ポリシーを作成しました。 このポリシーの使用を許可するには、Role または ClusterRole を作成します。 次に、RoleBinding または ClusterRoleBinding を使用してこれらのロールのいずれかを関連付けます。 この例では、前の手順で作成した psp-deny-privileged ポリシーの use を許可する ClusterRole を作成します。

  1. psp-deny-privileged-clusterrole.yaml という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: psp-deny-privileged-clusterrole
    rules:
    - apiGroups:
      - extensions
       resources:
      - podsecuritypolicies
       resourceNames:
      - psp-deny-privileged
       verbs:
      - use
    
  2. kubectl apply コマンドを使用し、YAML マニフェストのファイル名を指定して ClusterRole を作成します。

    kubectl apply -f psp-deny-privileged-clusterrole.yaml
    
  3. psp-deny-privileged-clusterrolebinding.yaml という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: psp-deny-privileged-clusterrolebinding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: psp-deny-privileged-clusterrole
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:serviceaccounts
    
  4. kubectl apply コマンドを使用し、YAML マニフェストのファイル名を指定して ClusterRoleBinding を作成します。

    kubectl apply -f psp-deny-privileged-clusterrolebinding.yaml
    

注意

この記事の最初の手順で、ポッド セキュリティ ポリシー機能が AKS クラスターで有効にされました。 推奨プラクティスは、独自のポリシーを定義した後でのみポッド セキュリティ ポリシーを有効にするというものでした。 これが、ポッド セキュリティ ポリシー機能を有効にする段階です。 1 つ以上のカスタム ポリシーが定義されており、ユーザー アカウントがそれらのポリシーに関連付けられています。 これで、ポッドのセキュリティ ポリシー機能を安全に有効にして、既定のポリシーによって引き起こされる問題を最小限に抑えることができます。

特権のないポッドの作成をもう一度テストする

カスタム ポッド セキュリティ ポリシーが適用され、そのポリシーを使用するためのユーザー アカウントのバインディングが作成されたので、特権のないポッドをもう一度作成してみましょう。

この例は、カスタム ポッド セキュリティ ポリシーを作成して、さまざまなユーザーまたはグループのための AKS クラスターへのアクセス権を定義する方法を示しています。 既定の AKS ポリシーでは、ポッドが実行できることに対して厳格な管理が提供されているので、独自のカスタム ポリシーを作成して、自分に必要な制限を正しく定義します。

  1. nginx-privileged.yaml マニフェスト使って、kubectl apply コマンドを使用してポッドを作成します。

    kubectl-nonadminuser apply -f nginx-unprivileged.yaml
    
  2. kubectl get pods コマンドを使用して、ポッドの状態を確認します。

    kubectl-nonadminuser get pods
    

    次の出力例は、ポッドが正常にスケジュールされ、Running であることを示しています。

    NAME                 READY   STATUS    RESTARTS   AGE
    nginx-unprivileged   1/1     Running   0          7m14s
    
  3. kubectl delete コマンドを使用し、YAML マニフェストの名前を指定して、特権のない NGINX ポッドを削除します。

    kubectl-nonadminuser delete -f nginx-unprivileged.yaml
    

リソースをクリーンアップする

  1. az aks update コマンドを使用してポッドのセキュリティ ポリシーを無効にします。

    az aks update \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --disable-pod-security-policy
    
  2. kubectl delete コマンドを使用して、ClusterRole と ClusterRoleBinding を削除します。

    kubectl delete -f psp-deny-privileged-clusterrole.yaml
    
  3. kubectl delete コマンドを使用して、ClusterRoleBinding を削除します。

    kubectl delete -f psp-deny-privileged-clusterrolebinding.yaml
    
  4. kubectl delete コマンドを使用し、YAML マニフェストの名前を指定して、セキュリティ ポリシーを削除します。

    kubectl delete -f psp-deny-privileged.yaml
    
  5. kubectl delete コマンドを使用して psp-aks 名前空間を削除します。

    kubectl delete namespace psp-aks
    

次のステップ

この記事では、特権アクセスの使用を防止するためのポッド セキュリティ ポリシーを作成する方法を示しました。 ポリシーでは、ボリュームの種類や RunAs ユーザーなど、多くの機能を適用できます。 利用可能なオプションの詳細については、Kubernetes ポッド セキュリティ ポリシーの参照ドキュメントに関するページを参照してください。

ポッド ネットワーク トラフィックの制限の詳細については、「Azure Kubernetes Service (AKS) のネットワーク ポリシーを使用したポッド間のトラフィックの保護」を参照してください。