🎼

AKS でのデプロイセーフガードを試してみた

2024/04/20に公開

AKS にて、デプロイセーフガード (Deployment Safeguards) の機能がプレビュー提供されました。

早速動作確認してみましたので、残しておこうと思います。

実装前の準備

aks-preview CLI 拡張機能のインストール

プレビュー機能を試す際は「あるある」ですね。下記を参考にインストールしておきます。

Azure Policy に関する Azure RBAC アクセス許可の設定

以降でデプロイ等のコマンドを実行するユーザーに、明示的に "Microsoft.Authorization/policyAssignments/write" および "Microsoft.Authorization/policyAssignments/read" のアクセス許可が必要になります。

簡単な方法としては、サブスクリプションの IAM にて「リソース ポリシーの共同作成者ロール」を付与することで可能です。手順等は下記を参考にしてください。

デプロイセーフガードが有効な AKS クラスターの作成

公式の手順を参考に、下記のようなコマンドで作成ができます。

az aks create --name <aks-cluster-name> --resource-group <resource-group-name> --enable-addons azure-policy --safeguards-level Warning

クラスターの作成後、機能が有効になるには最大で 35 分間かかるとのことですので、ひとまず待ちましょう☕

なお、もし下記のようなエラーが発生する場合は、前述の「Azure Policy に関する Azure RBAC アクセス許可の設定」の手順が上手くできていないと思われるので、再確認してみてください。

(SafeguardsBadRequest) Need permissions: "Microsoft.Authorization/policyAssignments/write","Microsoft.Authorization/policyAssignments/read" over scope: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/<resource-group-name>/providers/Microsoft.ContainerService/managedClusters/<aks-cluster-name> in order to use guardrails
Code: SafeguardsBadRequest
Message: Need permissions: "Microsoft.Authorization/policyAssignments/write","Microsoft.Authorization/policyAssignments/read" over scope: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/<resource-group-name>/providers/Microsoft.ContainerService/managedClusters/<aks-cluster-name> in order to use guardrails

試してみる

サンプルは界隈ではおなじみ、Azure Voting App を利用します。

Warning モードでのデプロイ

$ kubectl apply -f azure-vote.yaml
Warning: [azurepolicy-k8sazurev1containerenforcepres-a5d568f46b7ac61d84fb] Container: azure-vote-back does not include a Pre-stop hook. Neglecting to use Pre-stop hooks can lead to abrupt termination of processes, potentially causing data corruption, lost transactions, or degraded user experiences during pod shutdowns. Please use Pre-stop hooks in your manifests
deployment.apps/azure-vote-back created
service/azure-vote-back created
Warning: [azurepolicy-k8sazurev1containerenforcepres-a5d568f46b7ac61d84fb] Container: azure-vote-front does not include a Pre-stop hook. Neglecting to use Pre-stop hooks can lead to abrupt termination of processes, potentially causing data corruption, lost transactions, or degraded user experiences during pod shutdowns. Please use Pre-stop hooks in your manifests
Warning: [azurepolicy-k8sazurev1antiaffinityrules-86242ed41f02c6dbf1c8] Deployment with 3 replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing
deployment.apps/azure-vote-front created
service/azure-vote-front created

おー。Warning が出力されました。とはいえ "Warning" モードでデプロイしているため、Pod 自体はちゃんと作成されていることが確認できます。

$ kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
azure-vote-back-65d6c7cb84-sdzj5   1/1     Running   0          33s
azure-vote-front-dff68bb65-2zjs5   1/1     Running   0          33s
azure-vote-front-dff68bb65-csng5   1/1     Running   0          33s
azure-vote-front-dff68bb65-vz6l2   1/1     Running   0          33s

次の手順のために、一度デプロイを削除しておきます。

kubectl delete -f azure-vote.yaml

Enforcement モードに変更しつつ、特定の名前空間を除外する

では、準拠していない場合はデプロイも抑止する "Enforcement" モードに変更しつつ、テスト用の名前空間は除外するようにしてみます。

kubectl create ns excludens
az aks update --name <aks-cluster-name> --resource-group <resource-group-name> --safeguards-level Enforcement --safeguards-excluded-ns excludens

"--safeguards-level Enforcement" で Enforcement モードに変更し、"--safeguards-excluded-ns excludens" で excludens という名前空間は本機能の対象外とするように変更しています。

モードの変更には最大で 15 分間かかるとのことですので、ひとまず待ちましょう☕

Enforcement モードでのデプロイ

$ kubectl apply -f azure-vote.yaml
service/azure-vote-back created
service/azure-vote-front created
Error from server (Forbidden): error when creating "azure-vote.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [azurepolicy-k8sazurev1containerenforcepres-a5d568f46b7ac61d84fb] Container: azure-vote-back does not include a Pre-stop hook. Neglecting to use Pre-stop hooks can lead to abrupt termination of processes, potentially causing data corruption, lost transactions, or degraded user experiences during pod shutdowns. Please use Pre-stop hooks in your manifests
Error from server (Forbidden): error when creating "azure-vote.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [azurepolicy-k8sazurev1containerenforcepres-a5d568f46b7ac61d84fb] Container: azure-vote-front does not include a Pre-stop hook. Neglecting to use Pre-stop hooks can lead to abrupt termination of processes, potentially causing data corruption, lost transactions, or degraded user experiences during pod shutdowns. Please use Pre-stop hooks in your manifests
[azurepolicy-k8sazurev1antiaffinityrules-86242ed41f02c6dbf1c8] Deployment with 3 replicas should have pod anti-affinity rules set to avoid disruptions due to nodes crashing

エラーが出ましたね。「deployment.apps/azure-vote-back created」といった出力も無いため、Pod は作成されていなさそうです。

$ kubectl get pods
No resources found in default namespace.

$ kubectl get svc
NAME               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
azure-vote-back    ClusterIP      10.0.2.93     <none>        6379/TCP       6s
azure-vote-front   LoadBalancer   10.0.83.106   4.189.1.48    80:31777/TCP   66s
kubernetes         ClusterIP      10.0.0.1      <none>        443/TCP        24h

上記の通り & 想定通り、Pod は作成されていませんでした。なお、Service は作成されており IP アドレスも付与されていますが、割り振られるべき Pod が存在しないので、当然アクセスはできません。

次の手順のために、一度デプロイを削除しておきます。

kubectl delete -f azure-vote.yaml

除外した名前空間へのデプロイ

kubectl apply -f azure-vote.yaml -n excludens

$ kubectl apply -f azure-vote.yaml -n excludens
deployment.apps/azure-vote-back created
service/azure-vote-back created
deployment.apps/azure-vote-front created
service/azure-vote-front created

この通り、Error も Warning も出力されず、デプロイできました。こちらも想定通り🤗

$ kubectl get pods -n excludens
NAME                               READY   STATUS    RESTARTS   AGE
azure-vote-back-65d6c7cb84-fqlj4   1/1     Running   0          44s
azure-vote-front-dff68bb65-fsrsj   1/1     Running   0          44s
azure-vote-front-dff68bb65-k8dlc   1/1     Running   0          44s
azure-vote-front-dff68bb65-qmcqs   1/1     Running   0          44s

$ kubectl get svc -n excludens
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
azure-vote-back    ClusterIP      10.0.112.210   <none>        6379/TCP       28s
azure-vote-front   LoadBalancer   10.0.43.0      4.189.1.141   80:30554/TCP   28s

Pod も Service も作成されており、もちろんアクセスも可能です。

おわりに

以上、Deployment Safeguards 機能の検証でした。

コンテナー運用目線でのポリシーの網羅性はまだまだ感はありますし、特定のポリシーを (簡単に) 除外したりとかは難しそうです。ただ、設定は楽で動きも直感的ではあるので、今後充実していくとかなり使い勝手が良くなる機能ではないかな、と思いました。

適用されるポリシーの定義・種類については下記のドキュメントに記載がありますので、気になる方は参照してみてください。

Discussion