LoginSignup
20
21

More than 3 years have passed since last update.

kubernetesのConfigMapを理解する

Posted at

概要

k8sにはConfigMapという機能がある。

Podやコンテナで用いる設定情報をConfigMapに登録し、Podやコンテナがそれらを参照できるようにする。

パターンがいくつかある。

ConfigMapを作成する方法
- ファイルやディレクトリを指定して作成する方法
- マニフェストファイルから作成する方法

Podやコンテナが読み取る方法
- ConfigMapをボリュームマウントする方法
- ConfigMapを環境変数として渡す方法

それぞれ試してみる。

ConfigMapを作成する方法

ファイルやディレクトリを指定して作成する方法

まずConfigMapにしたい対象を作成する。今回はファイルで。

params.txt
name hoge
age 1
country piyo

これをもとにConfigMapを作成する。params-testという名前のConfigMapが作成される。

$ kubectl create configmap params-test --from-file=params.txt
configmap/params-test created

$ kubectl get configmap
NAME          DATA   AGE
params-test   1      19s

中身を見てみる。

$ kubectl get configmap params-test -o yaml
apiVersion: v1
data:
  params.txt: |-
    name hoge
    age 1
    country piyo
kind: ConfigMap
metadata:
  creationTimestamp: "2020-03-09T04:17:50Z"
  name: params-test
  namespace: test

削除することもできるし、また新規で作り直すことも可能。

$ kubectl delete configmap params-test
configmap "params-test" deleted

$ kubectl get configmap
No resources found in test namespace.

$ kubectl create configmap test-params --from-file=params.txt
configmap/test-params created

マニフェストファイルから作成する方法

以下のようなマニフェストファイルを作成。その上でapplyする。

config.yaml
apiVersion: v1
data:
  params.txt: |-
    name hoge
    age 1
    country piyo
kind: ConfigMap
metadata:
  name: test-params
$ kubectl apply -f config.yaml
configmap/test-params created

$ kubectl get configmap test-params
NAME          DATA   AGE
test-params   1      24s

この方法で作るとannotationが入るようになっている。

Podやコンテナが読み取る方法

ConfigMapをボリュームマウントする方法

ConfigMapを読み取るPodを作成。test-paramsというConfigMapが作成されている前提で進める。

test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: test
    image: nginx:alpine
    env:
    - name: master
      value: "true"
    volumeMounts:
    - mountPath: /mount
      name: config
  volumes:
  - name: config
    configMap:
      name: test-params

ややこしい点は2つ。
まず1つが containers.volumeMounts.name と volumes.name が一致している必要があること。
2つ目が volumes.configMap.name が先程作成したConfigMapの名前と一致していること。

これらが無視されると Podがいつまで経ってもContainerCreatingから脱しない。
例えば以下のようにpodの中身を見てみる。volumes.configMap.nameをhogeという存在しない値にすると以下のようなエラーが発生する。

$ kubectl apply -f test.yaml
pod/test created

$ kubectl get pods
NAME                              READY   STATUS              RESTARTS   AGE
test                              0/1     ContainerCreating   0          24s

$ kubectl describe pod test
Events:
  Type     Reason       Age                From                                                      Message
  ----     ------       ----               ----                                                      -------
  Normal   Scheduled    78s                default-scheduler                                         Successfully assigned test/test to ip-10-10-54-247.ap-northeast-1.compute.internal
  Warning  FailedMount  14s (x8 over 78s)  kubelet, ip-10-10-54-247.ap-northeast-1.compute.internal  MountVolume.SetUp failed for volume "config" : configmap "hoge" not found

正しく渡せたという前提で、
podの中に入ってparams.txtがどうなったか確認する。

$ kubectl exec -ti pod/test /bin/sh
# ls
bin    etc    lib    mnt    opt    root   sbin   sys    usr
dev    home   media  mount  proc   run    srv    tmp    var

# ls mount
params.txt

# cat mount/params.txt
name hoge
age 1
country piyo

問題なさそう。

ConfigMapを環境変数として渡す方法

これもkubernetes v1.6を前後にやり方が異なる。方法としては2つ。

  • envを使う方法(旧)
  • envFromを使う方法(新)

envFromの導入によってConfigMapの複数キー指定が楽になる。

まずはenvFromを使わない、envを使った環境変数としての渡し方。

はじめにこの恩恵を感じられるようにするために、config.yamlを書き換える。

config.yaml
apiVersion: v1
data:
  his.name: hoge
  his.age: ten
  his.country: piyo
  her.name: ham
  her.age: eleven
  her.country: spam
kind: ConfigMap
metadata:
  name: test-params-2

パラメータのkeyとvalueの組み合わせが増えた。
さっきまではparams.txtというkeyに対してtext情報というvalueが登録されていた。

ここに登録されているkeyとvalueをpodsに対してenvを用いて渡そうとすると、以下のようになる。

test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: test
    image: nginx:alpine
    env:
    - name: his-name
      valueFrom:
        configMapKeyRef:
          name: test-params-2
          key: his.name
    - name: his-age
      valueFrom:
        configMapKeyRef:
          name: test-params-2
          key: his.age
$ kubectl apply -f test.yaml
pod/test created

$ kubectl exec -ti test /bin/sh

# printenv
・
・
his-name=hoge
his-age=ten
・
・

ご覧の通りenvを用いると、変数を一つずつ渡さないといけない。そのためhis.nameからher.countryまで登録するには6つのenvを記述しないといけない。かなり冗長になってしまう。

それを便利にするのがenvFromである。ConfigMap中の変数をまとめて環境変数として渡すことができる。

test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: test
    image: nginx:alpine
    env:
    - name: his-name
      valueFrom:
        configMapKeyRef:
          name: test-params-2
          key: his.name
    - name: his-age
      valueFrom:
        configMapKeyRef:
          name: test-params-2
          key: his.age

もちろん全てを突っ込むわけではなく、prefix指定も可能。

$ kubectl apply -f test.yaml
pod/test created

$ kubectl exec -ti test /bin/sh

# printenv
・
・
her.country=spam
his.country=piyo
her.name=ham
her.age=eleven
his.name=hoge
his.age=ten
・
・

参考

Kubernetes: ConfigMap / Secret の内容を一度に環境変数として読み込む (envFrom)
KubernetesのConfigMapを試してみる
Kubernetes道場 11日目 - ConfigMap / Secretについて

20
21
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
20
21