kubernetesの Secretは、クレデンシャル類をコンテナイメージなどから分離して供給するための標準機能です。
よく知られている通りSecretは暗号化されてはいないため、権限があれば内容は確認できます。
Secretの主眼は、クレデンシャルを含む設定ファイルなどを他のコードリポジトリと分離できる点にあります。
Secret
にはいくつかの型があり、用途により使いわけます。
Deployment
やService
など他リソースがマニフェストを直接編集するケースが多いのに対して、Secret
は各アプリ固有の設定ファイルなどをkubectl create secret
コマンドに入力して生成します。
設定ファイル
アプリケーションの設定ファイルにパスワードを記述するケースでは、設定ファイルやディレクトリをkubectl create secret [generic] --from-file
オプションでOpaque型のSecretにエンコードします。
Opaque型は、語彙が異なるもののConfigMap
と使い方は同じです。
Secretの更新
Secret
には直接のapply
サブコマンドがないため、更新をしたい場合には、次のようにエンコードした新リソースをシェルのパイプでkubectl apply
に供給します。
$ kubectl create secret generic <secret-name> --dry-run=client --save-config --from-file=<source-directory> -o yaml | kubectl apply -f -
なお、kubectl apply
によりコンテナ内の該当ファイルも更新されるものの、シンボリックリンクを介した実装であることもあり、アプリケーションが必ずしも変更を自動で検出するわけではないという点には注意が必要です。
コンテナ再起動を必要とする場合が多々あります。
マニフェストのバックアップ
Secret
は主に入力リソースを変換して生成するため、稼働中のクラスタと一致するマニフェストが必要な場合には、ファイルにダンプします。
$ kubectl get secret [-n <namespace> | --all-namespaces] -o yaml > <secret-manifest.yaml>
最新のバックアップマニフェストがあれば、他のリソースと同様にkubectl apply
でSecret
を一括セットアップできます。
多くの場合、PodがSecretに依存する構成となるため、クラスタ移行の初期作業としてSecretセットアップが必要になるでしょう。
環境変数
Podのspec.containers.[].env
には環境変数を定義できますが、これは平文で記載するものでクレデンシャルには適していません。
spec.containers.[].envFrom
を用いるとSecretに定義した変数を環境変数としてインポートできます。
spec:
containers:
- name:
envFrom:
- secretRef:
name: <secret-name>
env:
- name: ACCOUNT_ID
value: "[email protected]"
このenvFrom
に指定するSecretは、次のようなenvファイル形式から専用オプションで作成します。この例では1変数のみですが、改行区切りで複数定義できます。
PASSWORD=some-password
このファイルからSecretを作成するコマンドは、kubectl create secret [generic] <secret-name> --from-env-file <input.env>
です。
--from-env-file
オプションで作成したSecretをkubectl get secret -oyaml
で確認すると、data
に環境変数のキーが直接リストされています。この形式になっていない場合、envFrom
でインポートしても該当の環境変数が未定義になります。
適切にセットアップできていれば、コンテナ内のシェルで$PASSWORD
のように参照できます。
なおenv
とenvFrom
は併用でき、環境変数のキーが異なるものは両方の定義をコンテナ内で参照できます。
Ingress用SSL証明書
SSL証明書にはkubernetes.io/tls
型を利用でき、TLS型のSecretはingressの証明書に指定できます。
Let’s Encryptで取得できる証明書の例では、以下のようなコマンドでTLS型のsecretを作成します。
kubectl create secret tls <cert-example.com> --key=privkey.pem --cert=fullchain.pem
Webサーバーの証明書に流用
TLS型のSecretは素朴なOpaque型としてマウントも可能です。コンテナのWebサーバー向けの証明書ファイルとして用います。
任意のPathにvolumeMount
したうえで、Webサーバーのconfigから参照します。
spec:
containers:
- name: nginx
# skip general configs
#
volumeMounts:
- name: tls-cert
mountPath: /etc/certs
volumes:
- name: tls-cert
secret:
secretName: cert-example.com
この例では、証明書は/etc/certs/tls.crt
、鍵は/etc/certs/tls.key
になります。
なおSecretの中身を変更した場合、コンテナのファイルも更新されますが、それによりWebサーバーが新しい証明書を参照するか否かは実装依存です。
Secretはシンボリックリンクとして実装されているため、inotifyが伝わらず変更検知しない実装もあります。
プライベートレジストリ認証のためのSecret
Google Artifact Regisryなどのクローズドなコンテナイメージレジストリへのアクセスにdocker-registry
型のSecretを利用する場合があります。
これはコンテナ内部で参照するものではなく、クラスタに設定するものです。
詳細は、 プライベートレジストリへのアクセス権を設定で解説しています。
Chuma Takahiro