はじめに
Kubernetesで使用するConfigMap
の内容について理解が浅いため、具体的にどのような使い方をするのか?を記載していきたいと思います。
ConfigMapとは
Kubernetesの公式ドキュメントには以下のように説明されています。
https://kubernetes.io/ja/docs/concepts/configuration/configmap/
ConfigMapは、 機密性のないデータをキーと値のペアで保存するために使用されるAPIオブジェクトです。Podは、環境変数、コマンドライン引数、またはボリューム内の設定ファイルとしてConfigMapを使用できます。
ConfigMapを使用すると、環境固有の設定をコンテナイメージから分離できるため、アプリケーションを簡単に移植できるようになります。
docker-compose.yaml
を書いた人なら少し似たようなものである、というイメージが付くかもしれません。
Key:Value
の形式のyamlファイルを定義して、ConfigMapに記述された、環境変数などのyamlファイルをPodにマウントします。
具体例を見てみましょう。
ConfigMapに定義する具体例
ConfigMap
以下のConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: db-config
data:
DB_HOST: "mysql.xxxxxx.rds.amazonaws.com" # DB識別子.ホストID.rds.amazonaws.com
DB_PORT: "3306"
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app # コンテナ名
image: my-app-image:latest # 使用するDockerイメージ
env: # 環境変数を定義するセクション
- name: DB_HOST # 環境変数の名前を`DB_HOST`とする
valueFrom: # ConfigMapで定義した値を環境変数として取得する
configMapKeyRef:
name: db-config # ConfigMapの名前を参照
key: DB_HOST # ConfigMap内で定義しているDB_HOSTの値を環境変数にセット
- name: DB_PORT # 環境変数の名前を`DB_PORT`とする
valueFrom:
configMapKeyRef:
name: db-config # ConfigMapの名前を参照
key: DB_PORT # ConfigMap内で定義しているDB_PORTの値を環境変数にセット
ConfigMapとDeploymentのマニフェストファイルを2つ並べてみると以下のように参照しています。
このConfigMapの定義により、Pod内の環境変数は以下のように設定されます。
DB_HOST=mysql.xxxxxx.rds.amazonaws.com
DB_PORT=3306
ConfigMapを使用する意図は
ConfigMapを使用する意図はいくつかあります。
-
ConfigMapを使用せずにマニフェストファイルに直接記述することも可能だが、セキュリティの観点からDBなどホスト情報をマニフェストファイル内に記述することはよろしくありません。
基本的にDockerfileやマニフェストファイルはGitHub上に管理することになるかと思いますが、誤って公開リポジトリにコミットしてしまうリスクがある点です。 -
DBホスト情報などを別ファイルとして定義することで管理しやすくなります。
仮に、DBの情報に変更があった際にはConfigMapの情報を更新すれば良いだけになるため、関連しているマニフェストファイル側をすべて変更、といった作業がなくなります。
ConfigMapに変更が生じた際には以下コマンドを実行することでConfigMapを更新すれば良いです。
kubectl apply -f configmap.yml
- 環境によってDBのホスト情報は異なるかと思いますが、各環境分のConfigMapを用意しておくことで、マニフェストファイルを環境分用意する必要がない。
環境差異はdev
,stg
,prod
などの識別子が異なるかと思います。
ConfigMap側でこの識別子の異なる環境分のファイルを用意しておくことで管理がしやすくなります。
表にまとめると以下です。
方法 | セキュリティ | 管理のしやすさ |
---|---|---|
Deployment に直接記述 | ❌ Git で漏洩リスク高い | ❌ 設定変更時に Deployment を適用し直す必要あり |
ConfigMap を利用 | ✅ DB ホスト情報の分離で安全性向上 | ✅ ConfigMap だけ更新すれば変更が適用される |
ConfigMapをマウントする
ConfigMapがどんなものか?ということがここまでの内容で少しずつ分かってきたかと思います。
ではこのConfigMapをDepoloymentが読み込むためにはどのようにすればよいでしょうか?
方法はいくつかありますが、本記事ではPod内に読み取り専用のディレクトリにConfigMapの内容をマウントする方法で解説します。
以下Deploymentで定義した内容はPod内の/config
ディレクトリにConfigMapをマウントする方法です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app-image:latest
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: db-config
key: DB_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: db-config
key: DB_PORT
volumeMounts: # ここでマウントするディレクトリを定義
- name: config-volume
mountPath: "/config" # マウントするディレクトリを指定
readOnly: true # 読み取り専用とする
volumes: # config-volumeで定義したボリュームを実際に読み込む
- name: config-volume # 何を見に行くか? -> config-volumeを見に行く
configMap: # どのConfigMapを参照するか?
name: db-config # ConfigMapの名前を指定
volumeMountsセクションでPod内のマウントするディレクトリを指定します。
volumesセクションでどのConfigMapを参照するのかを指定します。
ConfigMapの実態はどこに存在しているのか
Pod内のディレクトリにConfigMapをボリュームマウントする、というのはわかったのですが、ConfigMapの実態はどこにあるのか?という疑問をいだきました。
Podが対象のディレクトリを参照しに行く際に、ConfigMapに書かれた内容を参照するわけですが、ConfigMap用のPodが建っているわけでもないのにどこから参照できるのか?がいまいち理解できていなかったのですが、ConfigMapはKubernetesのetcd内に保存されているようです。
etcd
が何かについては以下で解説しています。
ConfigMapの情報を取得する流れは以下です。
-
etcd
に保存されたConfigMapの情報をkubelet
(ノードで動作するエージェント)がKube-apiserverに問い合わせてConfigMapの内容を取得 - ConfigMapのデータを一時的なファイルシステム(
tmpfs
)としてノードに作成 - Pod内の
/config
にtmpfs
をマウント
上記によりPodはConfigMapの情報をファイルが存在しているように見えてる、ということです。
kubelet
についても以下で解説しています。
最後n
今回はConfigMapとは何?についてとConfigMapを実際にどう使うのか?またその仕組みについて解説しました。
概念を理解して使うことで、実際の業務で調査するときにどこを見れば良いか?がわかるようになるかと思いますので、引き続きKubernetesに関する情報はアウトプットしていければと思います。