AKS でのデプロイセーフガードを試してみた
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