Azure Key Vault で AKS の secret を管理する

Kubernetes の secret リソースの保管先として、Azure Key Vault を使用してみたので手順を残しておきます。

# 前提

事前準備として、AKS 上に Kubernetes クラスタを作成しておきます。

```bash
$ kubectl get node
NAME                     STATUS   ROLES   AGE   VERSION
aks-default-09796230-0   Ready    agent   23h   v1.12.8
aks-default-09796230-1   Ready    agent   23h   v1.12.8

```

# 手順

1. Azure Key Vault にデータを追加
2. Key Vault FlexVolume を有効化
3. secret を使用する Pod をデプロイ

## 1. Azure Key Vault にデータを追加

Azure ポータル上で操作します。
https://docs.microsoft.com/en-us/azure/key-vault/quick-create-portal

``Key vaults``リソースを検索し、左上の「追加」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111157/8d907525-4a35-1945-6990-6a0c82945dbc.png)

必要項目を入力して Key Vault を作成。
名前はユニークなものにしないといけないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111157/6971c8dc-565f-fade-9473-a59c5f45e571.png)

作成が完了したらデータを登録します。
左の項目の中から``Secrets``を選択し、「作成」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111157/663b255c-7d73-517a-bd74-dc874344d743.png)

以下の内容で secret を作成します。

- Name:test
- Value：secretdata

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111157/02cf4526-6a47-6772-1d42-7399a0ca12c3.png)

このデータを Pod 上にマウントします。

## 2. Key Vault FlexVolume を有効化

GitHub の README に沿ってコマンド操作していきます。
https://github.com/Azure/kubernetes-keyvault-flexvol

### Key Vault FlexVolume をインストール

作成済みの Kubernetes クラスタに Key Vault FlexVolume をデプロイします。

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

作成が完了すると、クラスタ上の各ノードに Pod が配置されます。

```bash
$ kubectl get po -n kv
NAME                        READY   STATUS    RESTARTS   AGE
keyvault-flexvolume-nsn6s   1/1     Running   0          23h
keyvault-flexvolume-xh64w   1/1     Running   0          23h
```

### サービスプリンシパルを設定

サービスプリンシパルの情報を、secret としてクラスタに追加します。

※サービスプリンシパルの追加については以下のリンクを参照
https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli

```bash
$ kubectl create secret generic kvcreds --from-literal clientid=<CLIENTID> --from-literal clientsecret=<CLIENTSECRET> --type=azure/kv
```

Key Vault にアクセスするため、サービスプリンシパルにロールの割り当てを行います。
``<principalid>``と``<YOUR SPN CLIENT ID>``は、上の``<CLIENTID>``と同じ値で大丈夫でした。
``<resourcegroup>``、``<keyvaultname>``には Key Vault 作成時の値を入力します。

```bash
az role assignment create --role Reader --assignee <principalid> --scope /subscriptions/<subscriptionid>/resourcegroups/<resourcegroup>/providers/Microsoft.KeyVault/vaults/<keyvaultname>

az keyvault set-policy -n $KV_NAME --key-permissions get --spn <YOUR SPN CLIENT ID>
az keyvault set-policy -n $KV_NAME --secret-permissions get --spn <YOUR SPN CLIENT ID>
az keyvault set-policy -n $KV_NAME --certificate-permissions get --spn <YOUR SPN CLIENT ID>
```

## 3. secret を使用する Pod をデプロイ

GitHub のサンプルコードを修正してマニフェストを作成します。

```yaml:test-pod.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
      options:
        usepodidentity: "false"
        keyvaultname: "testkeyvault-aks"
        keyvaultobjectnames: test
        keyvaultobjecttypes: secret
        resourcegroup: "testresourcegroup"
        subscriptionid: ""
        tenantid: ""
```

``subscriptionid``と``tenantid``を環境に合わせて設定します。
``tenantid``はリンクを参考に取得してください。
https://stackoverflow.com/questions/26384034/how-to-get-the-azure-account-tenant-id

マニフェストを使用して Pod をデプロイします。

```bash
$ kubectl apply -f test-pod.yaml

$ kubectl get po
NAME                                                  READY   STATUS    RESTARTS   AGE
nginx-flex-kv                                         1/1     Running   0         5h25m
```

# secret を確認

Pod 上で secret を取得してみます。
マウント先は``/kvmnt/test``になります。

```bash
$ kubectl exec -it nginx-flex-kv cat /kvmnt/test
secretdata
```

# おまけ

マウント先のファイル名は、``flexVolume`` のオプションに``keyvaultobjectaliases:``をつけることで変更できます。

```yaml:test-pod.yaml(一部)
    flexVolume:
      
      options:
        keyvaultobjectnames: test
        keyvaultobjectaliases: "secret.json"
```

上のようにエイリアスを設定すると、``secret.json``ファイルにマウントされます。

```bash
$ kubectl exec -it nginx-flex-kv cat /kvmnt/secret.json
secretdata
```