AKS の Secrets Store CSI driver 経由で Key Vault を使う
AKS (Azure Kubernetes Service) にて、Secrets Store CSI driver 経由での Key Vault へのアクセスがプレビュー公開されています。
Key Vault を利用することで、シークレット情報をセキュアな方法で格納・取得できることが期待できます。
チュートリアル手順は下記の公式ドキュメントが参考になります。
やってみたのですが、一部詰まる箇所が出てきたこともあり、記事として残しておこうと思います。
環境
- AKS (1.19.11)
- Windows 10
考慮が必要な箇所
kubectl の資格情報を保存しておく
『シークレット ストア CSI ドライバーのインストールの確認』にて、手順ではサラっと kubectl get pods
を叩いていますが、環境によっては前の接続情報を持っている等の理由で接続できない場合があります。
kubectl get pods -n kube-system -l 'app in (secrets-store-csi-driver, secrets-store-provider-azure)'
Unable to connect to the server: dial tcp: lookup xxx: no such host
下記のコマンドで kubectl での接続先を設定しておきましょう。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
そのうえで kubectl get pods
を実行すれば、問題なく通るはずです。
> kubectl get pods -n kube-system -l 'app in (secrets-store-csi-driver, secrets-store-provider-azure)'
NAME READY STATUS RESTARTS AGE
aks-secrets-store-csi-driver-j9gjh 3/3 Running 1 4m20s
aks-secrets-store-csi-driver-nmzjs 3/3 Running 2 4m31s
aks-secrets-store-csi-driver-wkhwd 3/3 Running 1 4m20s
aks-secrets-store-provider-azure-54vp5 1/1 Running 0 4m20s
aks-secrets-store-provider-azure-pztzs 1/1 Running 0 4m31s
aks-secrets-store-provider-azure-vms2g 1/1 Running 0 4m20s
シークレットとキーを作成しておく
チュートリアルの yaml ファイルを (ほぼ) そのまま使うのであれば、『Azure Key Vault を作成するか既存のものを使用する』あたりで、対象の Key Vault に secret1
というシークレットと key1
というキーを作成しておく必要があります。
サービスプリンシパルの作成とアクセス許可が必要
『Azure Key Vault にアクセスするために ID を提供する』に手順の記載無くサラっと書いてありますが、サービスプリンシパルの作成と Key Vault へのアクセス許可が必要になります。
この手順を実施しないと、後の busybox-secrets-store-inline
Pod の作成において ContainerCreating
のままとなります。その際、kubectl describe pod
で状況を確認すると下記のエラーが発生していることが確認できます。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4s default-scheduler Successfully assigned default/busybox-secrets-store-inline to aks-nodepool1-42592859-vmss000001
Warning FailedMount 1s (x2 over 2s) kubelet <下記参照>
MountVolume.SetUp failed for volume "secrets-store-inline" : fetching NodePublishSecretRef default/secrets-store-creds failed: kubernetes.io/csi: failed to find the secret secrets-store-creds in the namespace default with error: secrets "secrets-store-creds" not found
「secrets-store-creds
というシークレットが無い」と怒られていますが、これを作成する手順が下記のドキュメントに記載されています。
Service Principal | Azure Key Vault Provider for Secrets Store CSI Driver
まずはサービスプリンシパルを作成し、
az ad sp create-for-rbac --skip-assignment --name myAKSClusterServicePrincipal
{
"appId": "06634dda-f18b-4688-b941-ff71d363ca10",
"displayName": "myAKSClusterServicePrincipal",
"name": "http://myAKSClusterServicePrincipal",
"password": "TAy5g~0d-NPskcesNsS9DhFNbxNnFQGYjw",
"tenant": "xxxxxx"
}
Key Vault 上のアクセスポリシーにて、上記のサービスプリンシパルに少なくともシークレットとキーへのアクセス許可を付与します。
参考 : Azure Key Vault アクセス ポリシーを割り当てる (ポータル) | Microsoft Docs
下記のような感じになれば OK かと。
そして、secrets-store-creds
というシークレットを作成しておきます。
kubectl create secret generic secrets-store-creds --from-literal clientid="06634dda-f18b-4688-b941-ff71d363ca10" --from-literal clientsecret="TAy5g~0d-NPskcesNsS9DhFNbxNnFQGYjw"
再度 Pod を作成して、Pod が Running
になり、kubectl describe pod
で下記のようにエラーが無くなれば無事 OK です。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4s default-scheduler Successfully assigned default/busybox-secrets-store-inline to aks-nodepool1-42592859-vmss000001
Normal Pulling 4s kubelet Pulling image "k8s.gcr.io/e2e-test-images/busybox:1.29"
Normal Pulled 2s kubelet Successfully pulled image "k8s.gcr.io/e2e-test-images/busybox:1.29" in 2.198869156s
Normal Created 1s kubelet Created container busybox
Normal Started 1s kubelet Started container busybox
なお、アクセス付与のミスなどの場合は、先ほどのエラーメッセージの箇所に下記のようなアクセス拒否 (403 Forbidden) のエラーが出ますので、これが出たらアクセスポリシーが間違っていないか確認すると良いと思います。
MountVolume.SetUp failed for volume "secrets-store-inline" : rpc error: code = Unknown desc = failed to mount secrets store objects for pod default/busybox-secrets-store-inline, err: rpc error: code = Unknown desc = failed to mount objects, error: failed to get objectType:secret, objectName:secret1, objectVersion:: keyvault.BaseClient#GetSecret: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="Forbidden" Message="The user, group or application 'appid=06634dda-f18b-4688-b941-ff71d363ca10;oid=xxxxxx;iss=https://sts.windows.net/xxxxxx/' does not have secrets get permission on key vault 'ndsouMyKeyVault3;location=japaneast'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287" InnerError={"code":"AccessDenied"}
ここまでできれば、チュートリアルの手順が最後まで実行できると思います。
> kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/
key1
secret1
> kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/secret1
P@ssw0rd!!
その他の考慮事項
冒頭の通り、Azure Key Vault を利用することでシークレット情報をセキュアな方法で格納・取得できることが期待できます。
一方で、依存するサービスが増えてしまうことは事実です。サービス全体の可用性の計算式などにおいて、Key Vault の可用性も掛け算しなければならなくなってくることには若干の注意が必要と思われます。便利ですけどね。
Discussion