Azure Policy を使用して Azure Kubernetes Service (AKS) クラスターをセキュリティで保護する

Azure Policy を使用して、Azure Kubernetes Service (AKS) クラスターに組み込みのセキュリティ ポリシーを適用し実施することができます。 Azure Policy は、組織の標準を適用してコンプライアンスを大規模に評価するのに役立ちます。 AKS 用の Azure Policy アドオンをインストールした後、個々のポリシー定義またはイニシアチブ (policysets と呼ばれることもあります) と呼ばれるポリシー定義のグループをクラスターに適用できます。 AKS ポリシーの完全な一覧とイニシアチブの定義については、AKS 用の Azure Policy 組み込み定義に関するページを参照してください。

この記事では、ポリシー定義をクラスターに適用し、それらの割り当てが適用されていることを確認する方法について説明します。

前提条件

組み込みポリシー定義またはイニシアチブの割り当て

次の手順を使用して、Azure portal でポリシー定義またはイニシアチブを適用できます。

  1. Policy と呼ばれる、Azure portal での Azure Policy サービスに移動します。
  2. Azure Policy ページの左側のウィンドウで、 [定義] を選択します。
  3. [カテゴリ]Kubernetes を選択します。
  4. 適用するポリシー定義またはイニシアチブを選択します。 この例では、[Linux ベースのワークロード用の Kubernetes クラスター ポッド セキュリティ ベースライン標準] イニシアチブを選択します。
  5. [割り当て] を選択します。
  6. [スコープ] には、Azure Policy アドオンが有効な AKS クラスターのリソース グループを設定します。
  7. [パラメーター] ページを選択し、 [効果]audit から deny に更新して、ベースライン イニシアチブに違反している新しいデプロイをブロックします。 評価から除外する名前空間を追加することもできます。 この例では、規定値のままにしておきます。
  8. [確認と作成]>[作成] の順に選択して、ポリシーの割り当てを送信します。

カスタム ポリシー定義を作成して割り当てる

カスタム ポリシーを使用すると、Azure を使用する際の規則を定義することができます。 たとえば、次の種類のルールを適用できます。

  • セキュリティの実行
  • コスト管理
  • 組織固有のルール (名前付けや場所など)

カスタム ポリシーを作成する前に、一般的なパターンとサンプルの一覧を確認して、該当するケースがすでにカバーされていないかどうかを確認してください。

カスタム ポリシー定義は JSON で記述されます。 カスタム ポリシーの作成について詳しくは、「Azure Policy の定義の構造」と「カスタム ポリシー定義の作成」を参照してください。

Note

Azure Policy では、templateInfo と呼ばれる新しいプロパティが利用され、制約テンプレートのソースの種類を定義できるようになっています。 ポリシー定義で templateInfo を定義するときに、constraintTemplateconstraint プロパティを定義する必要はありません。 その場合でも、apiGroupskinds の定義は必要です。 詳細については、Azure Policy の効果についてのページを参照してください。

カスタム ポリシー定義を作成したら、「ポリシー定義の割り当て」に関するページを参照し、Kubernetes クラスターにポリシーを割り当てる手順を確認してください。

Azure Policy が実行されていることを検証する

  • 次の kubectl get コマンドを使用して、ポリシーの割り当てがクラスターに適用されていることを確認します。

    kubectl get constrainttemplates
    

    Note

    ポリシーの割り当てが各クラスターに同期されるまでに最大 20 分かかる場合があります。

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

    NAME                                     AGE
    k8sazureallowedcapabilities              23m
    k8sazureallowedusersgroups               23m
    k8sazureblockhostnamespace               23m
    k8sazurecontainerallowedimages           23m
    k8sazurecontainerallowedports            23m
    k8sazurecontainerlimits                  23m
    k8sazurecontainernoprivilege             23m
    k8sazurecontainernoprivilegeescalation   23m
    k8sazureenforceapparmor                  23m
    k8sazurehostfilesystem                   23m
    k8sazurehostnetworkingports              23m
    k8sazurereadonlyrootfilesystem           23m
    k8sazureserviceallowedports              23m
    

特権のあるポッドの拒否を検証する

まず、privileged: true のセキュリティ コンテキストを持つポッドをスケジュールしたときに何が起こるかをテストしてみましょう。 このセキュリティ コンテキストは、ポッドの特権をエスカレートします。 イニシアチブでは特権のあるポッドが禁止されているため、要求は拒否されます。その結果、デプロイが拒否されます。

  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.15.5-alpine
          securityContext:
            privileged: true
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。

    kubectl apply -f nginx-privileged.yaml
    

    次の出力例に示すように、このポッドは想定どおりスケジュールできません。

    Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}
    

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

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

前の例では、コンテナー イメージは、自動的に root を使用して NGINX をポート 80 にバインドしようとしました。 ポリシー イニシアチブによりこの要求が拒否されるので、ポッドの起動が失敗します。 次に、特権アクセスなしで同じ 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.15.5-alpine
    
  2. kubectl apply コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。

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

    kubectl get pods
    

    出力は次の出力例のようになります。ここには、ポッドが正常にスケジュールされ、状態が [実行中] であることが示されています。

    NAME                 READY   STATUS    RESTARTS   AGE
    nginx-unprivileged   1/1     Running   0          18s
    

    この例は、コレクション内のポリシーに違反するデプロイのみに影響するベースライン イニシアチブを示しています。 許可されたデプロイは引き続き機能します。

  4. kubectl delete コマンドを使用し、YAML マニフェストの名前を指定して、特権のない NGINX ポッドを削除します。

    kubectl delete -f nginx-unprivileged.yaml
    

ポリシーまたはイニシアチブを無効にする

次の手順を使用して、Azure portal でベースライン イニシアチブを削除できます。

  1. Azure portal の [Policy] ペインに移動します。
  2. [割り当て] を選択します。
  3. [Linux ベースのワークロード用の Kubernetes クラスター ポッド セキュリティ ベースライン標準] イニシアチブの横にある [...] ボタンを選択します。
  4. [割り当ての削除] を選択します。

次のステップ

Azure Policy のしくみについて詳しくは、次の記事をご覧ください。