えいのうにっき

a-knowの日記です

Kubernetes での設定情報・機密情報の持ち回り 〜 ConfigMap と Secret (入門k8s 読書メモ)

入門 Kubernetes の読書メモ、第6弾。

入門 Kubernetes

入門 Kubernetes

ConfigMap や Secret を活用することによって、設定とアプリケーションを切り離す・設定を動的に注入することが容易になり、同一のコンテナイメージを様々な場面・環境で使い回せることができるようになる。

ConfigMap

  • 「小さなファイルシステム」を作る Kubernetes オブジェクト。
  • もしくは、環境ごとやコマンドラインでコンテナを定義する際に使用できる、変数の集まり。
  • 注意すべき点としては、ConfigMap は直前に作られた Pod と組み合わせて使うものである、ということ。
    • 【疑問】↑と、書いてあるが、「直前」の意味するところがわからない。

ConfigMap の作成

ConfigMap を作成するためのマニフェスト YAML の一例としては、以下。

apiVersion: v1
data:
  another-param: another-value
  extra-param: extra-value
  my-config.txt: |
    parameter1 = value1
    parameter2 = value2
kind: ConfigMap
  metadata:
    name: my-config
    namespace: default

ConfigMap の使用

ConfigMap を使用する方法には、3通りの方法がある。

ファイルシステムとして Pod にマウントする

  • Pod の中に新しい Volume を作り、名前を付ける(config-volume)
  • その Volume を、volumeMounts でマウントする
apiVersion: v1
kind: Pod
metadata:
  name: test-config
spec:
  containers:
    ...
    volumeMounts:
      - name: config-volume
        mountPath: /config
  volumes:
    - name: config-volume
      configMap:
        name: my-config

「ConfigMap の作成」で作成した ConfigMap を、上記のようにマウントした場合、以下のようなファイルとして参照することができる。

$ kubectl exec test-config cat /config/another-param
another-value
$ kubectl exec test-config cat /config/extra-param
extra-value
$ kubectl exec test-config cat /config/my-config.txt
parameter1 = value1
parameter2 = value2

環境変数として動的に設定する・ConfigMap の値を元に、コンテナのコマンドライン引数を動的に生成する

  • 環境変数は valueFrom の内容で定義される
  • Kubernetes は、$(<環境変数名>) という文法で表現された環境変数を値で置き換える。
apiVersion: v1
kind: Pod
metadata:
  name: test-config
spec:
  containers:
    - name: test-container
      image: gcr.io/kuar-demo/kuard-amd64:1
      imagePullPolicy: Always
      command:
        - "/kuard"
          "$(EXTRA_PARAM)"
      env:
        - name: EXTRA_PARAM
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: extra-param

Secret

  • 機密性の高い情報を扱うためのもの。
    • base64エンコードが必要、マウントした場合 tmpfs ボリュームに保存されるため、ノードのディスクに書き込まれない、といった特徴がある

Secret の作成

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
type: Opaque
data:
  password: cEBzc3cwcmQ= # echo -n "p@ssw0rd" | base64
  • type: Opaque
    • 通常のパスワードなどの用途で用いる
  • type: kubernetes.io/tls
    • Ingressなどで参照可能なTLS用のSecret
  • type: kubernetes.io/dockerconfigjson
    • 認証が必要なDocker registryを使うときに使用する
  • type: kubernetes.io/service-account-token
    • PodにService AccountのTokenをマウントするためのもの

Secret の SecretVolume による使用

  • Secret Volume は kubelet により管理され、Pod の作成時に作成される。
spec:
  containers:
    - name: ...
      volumeMounts:
        - name: tls-certs
          mountPath: "/tls"
          readOnly: true
  volumes:
    - name: tls-certs
      secret:
        secretName: test-secret
  • Secret は tmpfs ボリューム(RAMディスク)に保存される・ノードのディスクには書き込まれない。
  • Secret の各データ要素は、volumeMounts で指定されたマウントポイント以下に、別々のファイルとして保存される。
$ cat /tls/password
cEBzc3cwcmQ=

プライベート Docker レジストリへのアクセス認証情報の保存・Image pull secret

  • Secret にプライベート Docker レジストリへのアクセス認証情報を保存することで、プライベートレジストリの認証情報の配布を Secret API が自動化できるようにできる。
    • type: kubernetes.io/dockerconfigjson で作成
  • imagePullSecrets で指定して使用
spec:
  containers:
    - name: kuard-tls
      ...
  imagePullSecrets:
    - name: my-image-pull-scret

ConfigMap や Secret の命名規則

  • ConfigMap や Secret 内のアイテムのキー名は、有効な環境変数名にマッピングされるように定義する。
    • 詳細は P.145
  • ConfigMap に保存できるのはテキストデータのみで、バイナリデータは保存できない。
  • Secret の値には、base64エンコードした任意のデータを保持可能。

ConfigMap と Secret の管理

閲覧・確認

  • kubectl get
  • -o yaml などを使うことで Secret の中の値も含めた生データが取得可能。

作成

  • kubectl create
    • --from-file=<ファイル名>
      • このときのキー名はファイル名と同じになる
    • --from-file=<キー名>=<ファイル名>
      • キー名を指定できる
    • --from-file=<ディレクトリ>
    • --from-literal=<キー>=<値>

更新

  • 更新した値は起動中のプログラムにも反映される。アプリケーションが設定を読み込み直すようになっている場合、再起動も不要になる。
  • 更新方法
    • ファイルから更新: kubectl replace -f kubectl apply -f
    • 再作成して更新: kubectl create secret generic kuard-tls --from-file=kuard.crt --from-file=kuard.key --dry-run -o yaml | kubectl replace -f -
      • base64エンコードされたデータを手動作成しなくても良いというメリットがある
    • 現在のバージョンを更新: kubectl edit
      • Secret に対しておこなう場合は自分で base64 エンコードする必要がある
    • ライブアップデート:APIで更新すると、その ConfigMap や Secret を使っているすべての Volume に変更がプッシュされる。
      • Volume に変更がプッシュされたことをアプリケーションに伝える方法が Kubernetes には備わっていないため、アプリケーション側において「設定ファイルに変更があるかどうかをチェックし」「変更があれば読み込み直す」といった実装が必要となる。

追加参考記事