FlexVolumeはKubernetesでボリュームのプラグインを書けるようにしたもので、それを利用して、Key Vault FlexVolumeと言うものがあります。認証の方式として、Service Principalを使う方法と、Pod identity と言うADと連携させる方法がサポートされています。今回は、まずは簡単なように、ServicePrincipal から初めてみたいと思います。
KeyVault の作成
KeyVault を作成して適当なシークレットを作成しておきます。とりあえず、hello/world としておきました。ちなみに、以降の例では、センシティブな内容は全て$ResourceGroupName
などのSubstitute表現にしています。
az keyvault create --location westus2 --name $KeyVaultName --resource-group $ResourceGroupName
az keyvault secret set -n hello --vault-name $KeyVaultName --value world
KeyVault FlexVolume のインストール
ワンライナーで行けて良い感じです。中身はDaemonSetを作っていて、そこで、プラグインを各ノードにインストールしています。
kubectl create -f https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-installer.yaml
Service Principal の作成とロールの割り当て
az ad sp create-for-rbac -n "KeyVaultSpike"
kubectl create secret generic kvcreds --from-literal clientid=$appId --from-literal clientsecret=$secret --type=azure/kv
az role assignment create --role Reader --assignee $appId --scope /subscriptions/$subscriptionId/resourcegroups/$ResourceGroupName/providers/Microsoft.KeyVault/vaults/tsushikeyvault
az keyvault set-policy -n $KeyVaultName --secret-permissions get --spn $appId
FlexVolume のマウント
FlexVolumeを使うサンプルをみてみます。
apiVersion: v1
kind: Pod
metadata:
name: nginx-flex-kv
spec:
containers:
- name: nginx-flex-kv
image: nginx
volumeMounts:
- name: test
mountPath: /kvmnt
readOnly: true
volumes:
- name: test
flexVolume:
driver: "azure/kv"
secretRef:
name: kvcreds # [OPTIONAL] not required if using Pod Identity
options:
usepodidentity: "false" # [OPTIONAL] if not provided, will default to "false"
keyvaultname: "tsushikeyvault" # [REQUIRED] the name of the KeyVault
keyvaultobjectnames: "hello" # [REQUIRED] list of KeyVault object names (semi-colon separated)
keyvaultobjectaliases: "secret.json" # [OPTIONAL] list of KeyVault object aliases
keyvaultobjecttypes: secret # [REQUIRED] list of KeyVault object types: secret, key, cert
resourcegroup: "FlexVolume" # [REQUIRED] the resource group of the KeyVault
subscriptionid: "<<subscriptionId>>" # [REQUIRED] the subscription ID of the KeyVault
tenantid: "<<tenantId>>" # [REQUIRED] the tenant ID of the KeyVault
これを applyするとマウントされているのがわかります。
$ kubectl apply -f flexkeyvault.yaml
pod/nginx-flex-kv created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-flex-kv 0/1 ContainerCreating 0 7s
$ kubectl exec -it nginx-flex-kv -- bash
root@nginx-flex-kv:/# ls
bin dev home lib media opt root sbin sys usr
boot etc kvmnt lib64 mnt proc run srv tmp var
root@nginx-flex-kv:/# cd /kvmnt
root@nginx-flex-kv:/kvmnt# ls
secret.json
root@nginx-flex-kv:/kvmnt# cat secret.json
world
課題
少なくとも、Service Principal の方式での課題は、yamlに、subscriptionId と tenantId が入っていることだと思います。Secretか何かに入れたらええのにと思ったので、Issueあげてみました。