virtual-nodeアドオンは、Azure Container InstancesをAKS(Azure Kubernetes Service)の仮想ノードとして利用できる便利な機能です。
Azureのウィザードで作成している分には問題無く動いていたのですが、環境構築をTerraform化した際に理解不足から動かない部分が出てきたので、その対応のメモです。(Terraformに問題があったわけではありません)
- virtual-node-aci-linuxが機能していない
- サブネット設定を確認
- Service Principalの権限の確認
- TerraformでService Principalに権限設定する
- AzureマネージドID(MSI)の場合
virtual-node-aci-linuxが機能していない
Terraformの定義を作ってデプロイ。デプロイが通ったので内容を確認していたら、nodeとしてアサインされているはずの virtual-node-aci-linux
が無いことに気付きました。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION aks-default-12077424-vmss000000 Ready agent 78m v1.16.7
サブネット設定を確認
ググって見ると同じような事象が発生している人もいて、その対応メモから、最初はSubnetNameのところにサブネット名でなくリソースのID(例: /subscriptions/.../aci-virtualnode-subnet
)を入れてしまうミスを見つけたので、そこを直しました。
$ az aks show -g ${rg} -n ${akscluster} #--- 省略 "aciConnectorLinux": { "config": { "SubnetName": "my-vnode-snet" }, "enabled": true, "identity": null }, #--- 省略
Service Principalの権限の確認
それでも起動しない。virtual-nodeの機能のログを確認してみることにしました。
aci-connector-linux-xxx
という名前のpodでkube-systemにデプロイされています。
見てみるとステータスが CrashLoopBackOff
となっていました。
$ kubectl get po -n kube-system NAMESPACE NAME READY STATUS RESTARTS AGE kube-system aci-connector-linux-6d84cd8f4d-cb8nr 0/1 CrashLoopBackOff 5 5m40s kube-system addon-http-application-routing-default-http-backend-7fc6fcfbjcz 1/1 Running 0 79m #--- 省略
ログを確認してみるとネットワーク読み込み権限が足りないようです。
$ kubectl logs -n kube-system aci-connector-linux-6d84cd8f4d-cb8nr Error: error initializing provider azure: error setting up network profile: error while looking up subnet: api call to https://management.azure.com/subscriptions/xxxx-xxxx-xxx/resourcegroups/rg/providers/Microsoft.Network/virtualNetworks/network/subnets/virtual-node-subnet?api-version=2018-08-01: got HTTP response status code 403 error code "AuthorizationFailed": The client 'xxxx-xxxx-xxx' with object id 'xxxx-xxxx-xxx' does not have authorization to perform action 'Microsoft.Network/virtualNetworks/subnets/read' over scope '/subscriptions/xxxx-xxxx-xxx/resourcegroups/rg/providers/Microsoft.Network/virtualNetworks/network/subnets/virtual-node-subnet' or the scope is invalid. If access was recently granted, please refresh your credentials. #--- 省略
AKSにアサインしているService Principalに仮想ネットワークの読み込み権限を付与します。
後は以下のようにAddonを無効化⇒有効化するか、クラスタを再構築します。
az aks disable-addons -g ${rg} -n ${akscluster} --addons virtual-node az aks enable-addons -g ${rg} -n ${akscluster} --addons virtual-node --subnet virtual-node-subnet
これでvirtual-nodeが使えるようになりました。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION aks-default-12077424-vmss000000 Ready agent 93m v1.16.7 virtual-node-aci-linux Ready agent 108s v1.14.3-vk-azure-aci-v1.2.1
TerraformでService Principalに権限設定する
TerraformでのService Principalへの権限設定例も書いておきます。
まず、Service PrincipalのオブジェクトIDを取得します。(Application IDではないので注意)
Azure ADのエンタープライズアプリケーションの部分でオブジェクトIDとして確認することが可能です。
または、azure cliでも以下のように取得できます。
az ad sp show --id http://${YOUR_SP_NAME} --query 'objectId' "d3edxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
後はtfファイルに以下のように設定入れます。
resource "azurerm_role_assignment" "sp_network_role_assignment" { scope = azurerm_virtual_network.your_cluster_network.id role_definition_name = "Reader" principal_id = "d3edxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" }
AzureマネージドID(MSI)の場合
MSIが有効化されているクラスタでvirtual-nodeを有効化すると、 MC_
始まりのリソースグループ内にある aciconnectorlinux-<clustername>
が対象のIDになりますので、こちらに権限を付与します。
ただ、 az aks enable-addons --addons virtual-node
で有効化した直後はMSIに権限が無いのでエラーになってしまいます。
$ kubectl get po -n kube-system NAME READY STATUS RESTARTS AGE aci-connector-linux-659864bcc7-6nb69 0/1 CrashLoopBackOff 1 12s
その場合は以下のコマンドで aci-connector-linux
を再起動してあげます。
$ kubectl rollout restart deployment -n kube-system aci-connector-linux
後はこちらを参考にPodをデプロイすれば、以下のように確認できます。
$ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES aci-helloworld-5c6bf56994-dl69z 1/1 Running 0 14m 10.240.2.4 virtual-node-aci-linux <none> <none>