LoginSignup
1
0

More than 1 year has passed since last update.

[Kubernetes/Vault]PodへのSecret注入をkv-v1でもやってみた

Last updated at Posted at 2022-03-21

はじめに

以下のWebセミナーに参加してKubernetesとValutの連携について方法を色々試しているところ。
https://www.youtube.com/watch?v=b2iiZ16eI7A

まずはVaultに登録した認証情報(ユーザー/パスワード情報)をKubernetesのPodに注入する、といったチュートリアルを実施してみた。その中で自分が疑問に思ったことの検証メモ。
※Vaultは触り始めたばかりなので、用語などよくわかってないですが

pathの間に"/data"が入るのはなぜ

チュートリアルを実施するうえで少し疑問だったのが、

vault kv put internal/database/config username="db-readonly-username" password="db-secret-password"

上記ではinternal/database/configにユーザー名/パスワードなどの情報を登録していたのに、

vault policy write internal-app - <<EOF
path "internal/data/database/config" {
  capabilities = ["read"]
}
EOF

ポリシーの作成や、

      annotations:
        vault.hashicorp.com/agent-inject: 'true'
        vault.hashicorp.com/role: 'internal-app'
        vault.hashicorp.com/agent-inject-secret-database-config.txt: 'internal/data/database/config'

Podのyaml定義に記載するアノテーションに記載されているpathがinternal/data/database/configとなっている。さて/dataはどこから出てきたのか?

kvのv1とv2の違い

どうやら、この/dataはkvのversion1とversion2でのAPI利用方法の違いが影響しているみたい。
チュートリアルではversion2のKVで実施している。

version1では/secret/:pathだったのが、version2では/secret/data/:path?version=:version-numberに変更になっている。

検証①:v1でチュートリアルをやってみる

実際の動作を確認するために、以下のチュートリアルをkv-v1で実施してみる。基本的な流れは同じだが一部のコマンドを修正して実施する。
https://learn.hashicorp.com/tutorials/vault/kubernetes-sidecar

internalというpathでsecretを有効化する箇所は以下のコマンドに置き換える。

/ $ vault secrets enable -path=internal kv-v1
Success! Enabled the kv-v1 secrets engine at: internal/

念のため、以下コマンドでinternal/がversion1で有効化されていることを確認しておく。

/ $ vault secrets list -detailed | grep internal
internal/     kv           kv_7122e2b5           system         system     false             replicated     false        false
       map[version:1]    n/a                                                        da1cd7bd-bd8c-97a5-97b8-07f8500abf2b

policyは、/dataが含まれていないpathに置き換えて登録する。

/ $ vault policy write internal-app - <<EOF
> path "internal/database/config" {
>   capabilities = ["read"]
> }
> EOF
Success! Uploaded policy: internal-app

Kubernetes側としては、yamlファイルのannotaionのうち、vault.hashicorp.com/agent-inject-secret-database-config.txtの値も同様に修正しておく。
チュートリアルの手順ではgit上から取得した検証用のyamlファイルを利用しているが、今回は以下の定義ファイルで実施してみる。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: alpine-test
  name: alpine-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alpine-test
  template:
    metadata:
      labels:
        app: alpine-test
      annotations:
        vault.hashicorp.com/agent-inject: 'true'
        vault.hashicorp.com/role: 'internal-app'
        vault.hashicorp.com/agent-inject-secret-database-config.txt: 'internal/database/config'
    spec:
      containers:
      - image: alpine
        name: alpine
        command:
        - "sleep"
        - "3600"
      serviceAccountName: internal-app

kubectl applyでPodを起動させてから、kubectl execコマンドで/vault/secrets/database-config.txtの中身を確認してみる。

$ kubectl get pod alpine-test-59b7456c6d-vsbqt
NAME                           READY   STATUS    RESTARTS   AGE
alpine-test-59b7456c6d-vsbqt   2/2     Running   0          19s
$
$ kubectl exec alpine-test-59b7456c6d-vsbqt -c alpine  -- cat /vault/secrets/database-config.txt
password: db-secret-password
username: db-readonly-username

internal/database/configに登録されているユーザー/パスワードが出力されていることが確認できた。

検証②:v1のまま、pathに"/date"を追加してみる

kv-v1の状態のまま、pathに/dataを付ける形にするとどうなるか試してみる。
vault-0のコンソールにログインした状態で以下コマンドを実施してinternal-appをアップデートする

vault policy write internal-app - <<EOF
path "internal/data/database/config" {
  capabilities = ["read"]
}
EOF

またyamlファイルも修正する。以下コマンドでannotaitonを更新する。

kubectl patch deployment alpine-test -p metadata":{"annotations":{"vault.hashicorp.com/agent-inject-secret-database-config.txt": "internal/data/database/config"}}}}}'

annotationを更新すると新しくPodが作成されるが、新規作成されたPodの状態を確認してもInitが完了せず、Runステータスにはならない。

$ kubectl get pod -w
NAME                           READY   STATUS     RESTARTS   AGE
alpine-test-59b7456c6d-vsbqt   2/2     Running    0          3m24s
alpine-test-6554846995-tpb9v   0/2     Init:0/1   0          5s

kubectl logsコマンドでInitコンテナのログを確認してみると、internal/data/database/configというpathのシークレットは無いといったメッセージが出力されている。
どうやら、version1では/dataはpathの一部として認識されているみたい。

$ kubectl logs alpine-test-6554846995-tpb9v -c vault-agent-init
==> Vault agent started! Log data will stream in below:

==> Vault agent configuration:

                     Cgo: disabled
               Log Level: info
                 Version: Vault v1.9.2
             Version Sha: f4c6d873e2767c0d6853b5d9ffc77b0d297bfbdf

2022-03-21T05:38:03.105Z [INFO]  sink.file: creating file sink
2022-03-21T05:38:03.105Z [INFO]  sink.file: file sink configured: path=/home/vault/.vault-token mode=-rw-r-----
2022-03-21T05:38:03.105Z [INFO]  template.server: starting template server
2022-03-21T05:38:03.105Z [INFO]  auth.handler: starting auth handler
2022-03-21T05:38:03.105Z [INFO]  sink.server: starting sink server
2022-03-21T05:38:03.105Z [INFO] (runner) creating new runner (dry: false, once: false)
2022-03-21T05:38:03.105Z [INFO]  auth.handler: authenticating
2022-03-21T05:38:03.106Z [INFO] (runner) creating watcher
2022-03-21T05:38:03.118Z [INFO]  auth.handler: authentication successful, sending token to sinks
2022-03-21T05:38:03.118Z [INFO]  auth.handler: starting renewal process
2022-03-21T05:38:03.118Z [INFO]  template.server: template server received new token
2022-03-21T05:38:03.118Z [INFO] (runner) stopping
2022-03-21T05:38:03.118Z [INFO] (runner) creating new runner (dry: false, once: false)
2022-03-21T05:38:03.118Z [INFO]  sink.file: token written: path=/home/vault/.vault-token
2022-03-21T05:38:03.119Z [INFO]  sink.server: sink server stopped
2022-03-21T05:38:03.119Z [INFO]  sinks finished, exiting
2022-03-21T05:38:03.119Z [INFO] (runner) creating watcher
2022-03-21T05:38:03.119Z [INFO] (runner) starting
2022-03-21T05:38:03.121Z [INFO]  auth.handler: renewed auth token
2022-03-21T05:38:03.124Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 1 after "250ms")
2022-03-21T05:38:03.377Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 2 after "500ms")
2022-03-21T05:38:03.879Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 3 after "1s")
2022-03-21T05:38:04.881Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 4 after "2s")
2022-03-21T05:38:06.884Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 5 after "4s")
2022-03-21T05:38:10.888Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 6 after "8s")
2022-03-21T05:38:18.892Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 7 after "16s")
2022-03-21T05:38:34.895Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 8 after "32s")
2022-03-21T05:39:06.897Z [WARN] (view) vault.read(internal/data/database/config): no secret exists at internal/data/database/config (retry at
tempt 9 after "1m0s")

検証③:kvをバージョンアップしてみる

これまでkv-v1だったものをkv-v2にアップデートしてみる。
vault-0コンテナへログインして、以下コマンドでkv-v2へアップデートする。

/ $ vault kv enable-versioning internal
Success! Tuned the secrets engine at: internal/

internal/がversion2になっていることを確認しておく。

/ $ vault secrets list -detailed | grep internal
internal/     kv           kv_7122e2b5           system         system     false             replicated     false        false
       map[version:2]    n/a        

先ほどのPodが"Running"ステータスになっており、internal/database/configに登録されているユーザー/パスワードが出力されていることが確認できた。

$ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
alpine-test-6554846995-tpb9v   2/2     Running   0          2m58s
$
$ kubectl exec alpine-test-6554846995-tpb9v -c alpine -- cat /vault/secrets/database-config.txt
data: map[password:db-secret-password username:db-readonly-username]
metadata: map[created_time:2022-03-21T05:39:57.3716551Z custom_metadata:<nil> deletion_time: destroyed:false version:1]

v2だとバージョン管理が可能

kv-v1とkv-v2の違いについては、kv-v2ではバージョン管理されており過去バージョンの値も参照可能らしい。

確かにAPIの説明でも末尾に/secret/data/:path?version=:version-numberとバージョンが指定できる。
これも動作検証してみる。

まずはinternal/database/configに登録されている情報を上書きする。vault-0コンテナへログインして以下のようにusername/passwordを更新する。

$ kubectl exec -n vault -it vault-0 -- /bin/sh
/ $ vault kv put internal/database/config username="username!!" password="password!!"
Key                Value
---                -----
created_time       2022-03-21T05:42:27.5826724Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2
/ $ exit

再度、ポッドを削除、再起動させる。
/vault/secrets/database-config.txtの中身に、先ほどアップデートした内容が反映されていることが確認できた。

$ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
alpine-test-6554846995-lnf2r   2/2     Running   0          52s
$
$ kubectl exec alpine-test-6554846995-lnf2r -c alpine -- cat /vault/secrets/database-config.txt
data: map[password:password!! username:username!!]
metadata: map[created_time:2022-03-21T05:42:27.5826724Z custom_metadata:<nil> deletion_time: destroyed:false version:2]

では、annotaionのpathの末尾に?version=1を追記して、修正前のinternal/database/configの内容を参照するようにしてみる。

kubectl patch deployment alpine-test -p '{"spec": {"template":{"metadata":{"annotations":{"vault.hashicorp.com/agent-inject-secret-database-config.txt": "internal/data/database/config?version=1"}}}}}'

Podが自動的に再起動される。/vault/secrets/database-config.txtの中身が修正前のinternal/database/configの内容となっていることが確認できた。

$ kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
alpine-test-7f65559cb-srrwf   2/2     Running   0          42s
$
$ kubectl exec alpine-test-7f65559cb-srrwf -c alpine -- cat /vault/secrets/database-config.txt
data: map[password:db-secret-password username:db-readonly-username]
metadata: map[created_time:2022-03-21T05:39:57.3716551Z custom_metadata:<nil> deletion_time: destroyed:false version:1]
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0