FlexVolumeを用いたKeyVaultとAKSの連携（１）

[FlexVolume](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md)はKubernetesでボリュームのプラグインを書けるようにしたもので、それを利用して、[Key Vault FlexVolume](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md)と言うものがあります。認証の方式として、Service Principalを使う方法と、Pod identity と言うADと連携させる方法がサポートされています。今回は、まずは簡単なように、ServicePrincipal から初めてみたいと思います。

# KeyVault の作成

KeyVault を作成して適当なシークレットを作成しておきます。とりあえず、hello/world としておきました。ちなみに、以降の例では、センシティブな内容は全て`$ResourceGroupName` などのSubstitute表現にしています。

```bash
az keyvault create --location westus2 --name $KeyVaultName --resource-group $ResourceGroupName
az keyvault secret set -n hello --vault-name $KeyVaultName --value world
```

# KeyVault FlexVolume のインストール

ワンライナーで行けて良い感じです。中身はDaemonSetを作っていて、そこで、プラグインを各ノードにインストールしています。

```bash
kubectl create -f https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-installer.yaml
```


# Service Principal の作成とロールの割り当て

```bash
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を使うサンプルをみてみます。

```yaml
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するとマウントされているのがわかります。

```bash
$ 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あげてみました。

* [Subscription Id and Tenant Id into Secret](https://github.com/Azure/kubernetes-keyvault-flexvol/issues/111)