Azure Policy

Admission Controllerについて整理できたところで、Azure Policyを説明しましょう。Azure Policy は、AKS 固有の機能ではなく、Azure のリソースに対してガバナンスを提供するためのマネージドサービスです。AKS においては、Azure Policy と組み合わせることができ、Azure ポータル上からポリシーの監査を有効にできます。

AKS で Azure Policy による監査を有効にする手順は以下の通りです。それぞれ具体的な手順はドキュメントを参照してください。

  1. Azure Policy アドオンのインストール
  2. Azure Policy の割り当て

Azure Policy アドオンのインストール

Azure Policy アドオンをインストールすると、gatekeeper-system 名前空間が AKS 上に作成され、その中に Gatekeeper に関するリソースが展開されます。Gatekeeper は冒頭にも記載したように、オープンソースの汎用ポリシーエンジンである OPA を Kubernetes で利用できるようにしたプロダクトです。Gatekeeperについては、以下のブログを参照してください。

OPA Gatekeeper: Policy and Governance for Kubernetes

以下は、リソースの一覧です。


NAME                           STATUS   AGE
namespace/default              Active   29h
namespace/gatekeeper-system    Active   14m <-- gatekeeper に関するリソースが展開されている名前空間
namespace/kube-node-lease      Active   29h
namespace/kube-public          Active   29h
namespace/kube-system          Active   29h

NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gatekeeper-audit        1/1     1            1           14m
deployment.apps/gatekeeper-controller   2/2     2            2           14m

NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/gatekeeper-webhook-service   ClusterIP   192.168.24.24   <none>        443/TCP   14m

service/gatekeeper-webhook-service が、Admission Controller の ValidatingWebhook で呼び出される API のエンドポイントです。

続いて、ValidatingWebhookConfiguration を見てみましょう。


# kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io
NAME                                            WEBHOOKS   AGE
aks-node-validating-webhook                     1          29h
azure-policy-validating-webhook-configuration   1          34m
gatekeeper-validating-webhook-configuration     2          33m

3つありますが、gatekeeper-validating-webhook-configuration が通常のワークロードリソースが展開される際の設定です。describe してみましょう。


# kubectl describe validatingwebhookconfigurations.admissionregistration.k8s.io gatekeeper-validating-webhook-configuration
Webhooks:
  Admission Review Versions:
    v1
    v1beta1
  Client Config:
    Ca Bundle: ... (省略) ...
    Service:
      Name:        gatekeeper-webhook-service
... (省略) ...
  Rules:
    API Groups:
      *
    API Versions:
      *
    Operations:
      CREATE
      UPDATE
    Resources:
      *
      pods/ephemeralcontainers
... (省略) ...

この設定を見ると、Service に先ほどの一覧で確認した Service が指定されていることから、この Webhook により service/gatekeeper-webhook-service が呼び出されることが分かります。さらに、API Group、リソースはすべてを対象としており、CREATE と UPDATE 操作が行われる際にフックされるルールとなっています。

実際のポリシーのテンプレートは、以下で取得できます。


# kubectl get constrainttemplate
NAME                                     AGE
k8sazureallowedcapabilities              2d9h
k8sazureallowedseccomp                   2d4h
k8sazureallowedusersgroups               2d9h
k8sazureblockautomounttokenv2            2d9h
k8sazureblockdefault                     2d9h
k8sazureblockhostnamespacev2             2d9h
k8sazurecontainerallowedimages           2d9h
k8sazurecontainerlimits                  2d9h
k8sazurecontainernoprivilege             2d9h
k8sazurecontainernoprivilegeescalation   2d9h
k8sazuredisallowedcapabilities           2d9h
k8sazureenforceapparmor                  2d9h
k8sazurehostfilesystem                   2d9h
k8sazurehostnetworkingports              2d9h
k8sazureingresshttpsonly                 2d9h
k8sazurereadonlyrootfilesystem           2d9h
k8sazureserviceallowedports              2d9h
k8sazurevolumetypes                      2d4h

上記はテンプレートであり、ポリシーの一致を評価するための具体的な値は別のリソースで定義されています。値を定義しているリソースは、カスタムリソースとして展開されている constraints.gatekeeper.sh/v1beta1 のリソース群です。


# kubectl api-resources  | grep constraints.gatekeeper.sh/v1beta1
k8sazureallowedcapabilities                            constraints.gatekeeper.sh/v1beta1      false        K8sAzureAllowedCapabilities
k8sazureallowedseccomp                                 constraints.gatekeeper.sh/v1beta1      false        K8sAzureAllowedSeccomp
k8sazureallowedusersgroups                             constraints.gatekeeper.sh/v1beta1      false        K8sAzureAllowedUsersGroups
k8sazureblockautomounttokenv2                          constraints.gatekeeper.sh/v1beta1      false        K8sAzureBlockAutomountTokenV2
k8sazureblockdefault                                   constraints.gatekeeper.sh/v1beta1      false        K8sAzureBlockDefault
k8sazureblockhostnamespacev2                           constraints.gatekeeper.sh/v1beta1      false        K8sAzureBlockHostNamespaceV2
k8sazurecontainerallowedimages                         constraints.gatekeeper.sh/v1beta1      false        K8sAzureContainerAllowedImages
k8sazurecontainerlimits                                constraints.gatekeeper.sh/v1beta1      false        K8sAzureContainerLimits
k8sazurecontainernoprivilege                           constraints.gatekeeper.sh/v1beta1      false        K8sAzureContainerNoPrivilege
k8sazurecontainernoprivilegeescalation                 constraints.gatekeeper.sh/v1beta1      false        K8sAzureContainerNoPrivilegeEscalation
k8sazuredisallowedcapabilities                         constraints.gatekeeper.sh/v1beta1      false        K8sAzureDisallowedCapabilities
k8sazureenforceapparmor                                constraints.gatekeeper.sh/v1beta1      false        K8sAzureEnforceAppArmor
k8sazurehostfilesystem                                 constraints.gatekeeper.sh/v1beta1      false        K8sAzureHostFilesystem
k8sazurehostnetworkingports                            constraints.gatekeeper.sh/v1beta1      false        K8sAzureHostNetworkingPorts
k8sazureingresshttpsonly                               constraints.gatekeeper.sh/v1beta1      false        K8sAzureIngressHttpsOnly
k8sazurereadonlyrootfilesystem                         constraints.gatekeeper.sh/v1beta1      false        K8sAzureReadOnlyRootFilesystem
k8sazureserviceallowedports                            constraints.gatekeeper.sh/v1beta1      false        K8sAzureServiceAllowedPorts
k8sazurevolumetypes                                    constraints.gatekeeper.sh/v1beta1      false        K8sAzureVolumeTypes

試しに 1 つのリソース(許可する Capability のポリシー)を見てみましょう。


# kubectl get k8sazureallowedcapabilities  azurepolicy-k8sazureallowedcapabilities-4450e9205b0507570535 -o yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAzureAllowedCapabilities
metadata:
  annotations:
    azure-policy-assignment-id: /subscriptions/... (省略) .../resourceGroups/rg-simpleaks0717a/providers/Microsoft.Authorization/policyAssignments/55af52e40d0d4ca1ac46df01
    azure-policy-definition-id: /providers/Microsoft.Authorization/policyDefinitions/c26596ff-4d70-4e6a-9a30-c2506bd2f80c
    azure-policy-definition-reference-id: ContainerCapabilities
    azure-policy-setdefinition-id: /providers/Microsoft.Authorization/policySetDefinitions/42b8ef37-b724-4e24-bbc8-7a7708edfe00
    constraint-installed-by: azure-policy-addon
... (省略) ...
spec:
  enforcementAction: deny
  match:
    excludedNamespaces:
    - kube-system
    - gatekeeper-system
    - azure-arc
    kinds:
    - apiGroups:
      - ""
      kinds:
      - Pod
  parameters:
    allowedCapabilities:
    - CHOWN
    - DAC_OVERRIDE
    - FSETID
    - FOWNER
    - MKNOD
    - NET_RAW
    - SETGID
    - SETUID
    - SETFCAP
    - SETPCAP
    - NET_BIND_SERVICE
    - SYS_CHROOT
    - KILL
    - AUDIT_WRITE

parameters.allowedCapabilities には、指定可能な Capability の記述が含まれています。つまり、この一覧にない Capability を記述したコンテナは展開ができないということになります。allowedCapabilities の値は、Azure ポータルでは、「追加が許可されている機能」に該当し、このパラメーターを変更すると、上記の parameters の値も変更されます。