Config&Storageリソース
連載の第3回目で、Kubernetesのリソースは5種類に大別されることをお話しました。そのうちの1つであるConfig&Storageリソースについて、今回と次回の2回で解説します。
5種類に大別できるKubernetesのリソース
リソースの分類 | 内容 |
Workloadsリソース | コンテナの実行に関するリソース |
Discovery&LBリソース | コンテナを外部公開するようなエンドポイントを提供するリソース |
Config&Storageリソース | 設定・機密情報・永続化ボリュームなどに関するリソース |
Clusterリソース | セキュリティやクォータなどに関するリソース |
Metadataリソース | リソースを操作する系統のリソース |
Config&Storageリソースは、コンテナに対して設定ファイル、パスワードなどの機密情報などをインジェクトしたり、永続化ボリュームを提供したりするためのリソースです。内部的に利用されているものを除いて、利用者が直接利用するものとしては、全部で3種類のConfig&Storageリソースが存在します。
- Secret
- ConfigMap
- PersistentVolumeClaim
環境変数の利用
Kubernetesでは、個別のコンテナに対する設定の内容は環境変数やファイルが置かれた領域をマウントして渡すことが一般的です。そこで、リソースの解説に入る前に、Kubernetesでの環境変数の扱いについて解説します。
Kubernetesで環境変数を渡す際には、podテンプレートにenvまたはenvFromを指定します。大きく分けて、下記の5つの情報源から環境変数を埋め込むことが可能です。
- 静的設定
- Podの情報
- Containerの情報
- Secretリソースの機密情報
- ConfigMapリソースからのKey-Value値
静的設定
静的設定では、その名の通りspec.containers[].envに静的な値として定義します。
リスト1:envで環境変数に値を渡す例
09 | - name: nginx-container |
12 | - name: MAX_CONNECTION |
15 | $ kubectl apply -f env-sample.yml |
コンテナ内から見てみると、環境変数が設定されていることを確認できます。
リスト2:静的に設定した環境変数を確認
1 | $ kubectl exec -it sample-env env | grep MAX_CONNECTION |
Podの情報
どのノードで起動しているか、Pod自身のIP Address、起動時間などのPodに関する情報は、fieldRefを使うことで参照できます。参照可能な値に関しては、「kubectl get pods -o yaml」などで確認できます。一部抜粋すると、登録したYAMLファイルの情報とは別に、PodのIPやホストの情報といった様々な情報が追加されていることが確認できます。
リスト3:Podの情報を確認
02 | $ kubectl get pod nginx-pod -o yaml |
05 | nodeName: gke-k8s-default-pool-9c2aa160-v5v4 |
07 | schedulerName: default-scheduler |
09 | serviceAccount: default |
10 | serviceAccountName: default |
11 | terminationGracePeriodSeconds: 30 |
18 | startTime: 2018-05-27T05:23:00Z |
今回は起動しているホスト名を環境変数として登録してみます。先ほど出力したYAMLの形式に沿ってKeyを指定するため、spec.nodeNameを指定します。
リスト4:ホスト名を環境変数に登録するenv-pod-sample.yml
01 | # 起動しているKubernetes Nodeの名前をK8S_NODE環境変数に登録 |
10 | - name: nginx-container |
16 | fieldPath: spec.nodeName |
18 | $ kubectl apply -f env-pod-sample.yml |
コンテナ内から見てみると、環境変数が設定されていることを確認できます。
リスト5:環境変数が設定されていることを確認
1 | $ kubectl exec -it sample-env-pod env | grep K8S_NODE |
2 | K8S_NODE=tmp-check-iyhhhlpiq-ake-ntmqohp |
Containerの情報
Podの情報と同様に、Containerに関する情報はresourceFieldRefを使うことで参照することが可能です。Podには複数のContainerの情報が含まれており、各Containerに対して設定可能な値についてはfieldRefでは参照できない点に注意してください。こちらも同様に参照可能な値に関しては、「kubectl get pods -o yaml」などで確認することができます。
リスト6:Containerに関する情報を環境変数に登録するenv-container-sample.yml
01 | # CPUのRequests/Limitsを環境変数に登録 |
05 | name: sample-env-container |
10 | - name: nginx-container |
16 | containerName: nginx-container |
17 | resource: requests.cpu |
21 | containerName: nginx-container |
24 | $ kubectl apply -f env-container-sample.yml |
コンテナ内から見てみると、環境変数が設定されていることを確認できます。
リスト7:設定された環境変数を確認
1 | $ kubectl exec -it sample-env-container env | grep CPU |
Secretリソースの機密情報
機密情報などは別途Secretリソースを作成し、環境変数として参照させることが推奨されています。詳しくはSecretリソースの項目で説明します。
ConfigMapリソースからのKey-Value値
単純なKey-Value値や設定ファイルなどは、ConfigMapで管理することが可能です。Podに都度環境変数を埋め込んでも問題ありませんが、一括での変更や重複が多い場合にはConfigMapの利用を検討して下さい。詳しくはConfigMapリソースの項目で説明します。
環境変数利用時の注意点
Kubernetesで渡される環境変数には、少し癖があります。例えば、下記のPodのテンプレートは一見すると正しく動作して、コンテナ起動後に「100」と「ホスト名」が出力されるように見えます。
リスト8:環境変数の展開を期待するYAML Manifest(失敗)
01 | # 環境変数の展開を期待するYAML Manifest(失敗) |
10 | - name: nginx-container |
13 | args: ["${TESTENV}", "${HOSTNAME}"] |
18 | $ kubectl apply -f fail-env-sample.yml |
20 | $ kubectl logs sample-fail-env |
しかしこのPodを起動するとTESTENV{HOSTNAME}という文字列が出力されてしまいます。Kubernetesでは commandやargsで実行するコマンドを指定する際に通常通り環境変数を利用することはできません。厳密に言うと、Podテンプレート内で定義された環境変数に限り(TESTENV)という形式で呼び出すことが可能です。つまり、${}ではなく$()を利用するということです。これに従い上述のテンプレートを書き直すと、下記のようになります。
リスト9:環境変数の展開を期待するYAML Manifest(一部成功)
01 | # 環境変数の展開を期待するYAML Manifest(一部成功) |
10 | - name: nginx-container |
13 | args: ["$(TESTENV)", "$(HOSTNAME)"] |
18 | $ kubectl apply -f fail-env-sample.yml |
19 | $ kubectl logs sample-fail-env |
このPodを実行すると、100 $(HOSTNAME)と出力されます。あくまでも、command,argsで参照可能なのは、そのPodテンプレート内で定義された環境変数のみ(この場合はTESTENV)だということに注意して下さい。もしOSからしか参照できない環境変数を利用する場合には、Entrypoint(command)をentrypoint.shなどのシェルスクリプトにして、シェルスクリプト内で処理を行うようにして下さい。