k8s ConfigMap で設定を Pod から分離できる( nginx の設定を ConfigMap で管理する)

ConfigMap は Pod の外から設定データ(環境変数やファイル)を注入するための仕組み。設定を Pod と分離して管理できることに価値がある。

ConfigMap はキーとバリューで構成されていて、複数の方法で作成できる。また、複数の方法で Pod に設定データを注入できる。
Configure a Pod to Use a ConfigMap

今回は ConfigMap を利用して nginx の設定をカスタマイズしてみる。nginx のコンテナイメージは、/etc/nginx/conf.d/配下のファイルを読み込む作りになっているので、ここにファイルを作成する。

なお、検証環境は次のとおり。

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.2", GitCommit:"59603c6e503c87169aea6106f57b9f242f64df89", GitTreeState:"clean", BuildDate:"2020-01-18T23:30:10Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-11T18:07:13Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"}

まず ConfigMap を作成する。キーをファイル名、値をファイルの中身にする。

nginx-conf.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |-
    server {
      listen     80;
      server_tokens on;
      location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
      }
    }

ConfigMap を作成する。

$ kubectl create -f nginx-conf.yaml
configmap/nginx-config created
$ kubectl get configmaps
NAME           DATA   AGE
nginx-config   1      8s

Pod の設定(nginx.yaml)。ConfigMap をファイルにするために volumes に configMap を指定する。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
      - name: conf
        mountPath: /etc/nginx/conf.d/
  volumes:
    - name: conf
      configMap:
        name: nginx-config

次に Pod を生成する。ファイルが生成されているのを確認する。

$ kubectl create -f nginx.yaml
pod/nginx created
$ kubectl exec -it nginx -- cat /etc/nginx/conf.d/nginx.conf
server {
  listen     80;
  server_tokens on;
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }

アクセスしてみると、設定が効いている(server_token on によってレスポンスヘッダーに nginx のバージョンが含まれる)ことがわかる。

$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE              NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          6s    192.168.130.51   ip-172-30-0-112   <none>           <none>
$ curl -v 192.168.130.51:80
* Rebuilt URL to: 192.168.130.51:80/
*   Trying 192.168.130.51...
* TCP_NODELAY set
* Connected to 192.168.130.51 (192.168.130.51) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.130.51
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.17.8

上記例ではキーとバリューの関係がわかりやすいように yaml に設定をべた書きした。しかし自分の感覚では yaml ファイルに設定をベタ書きするのは正気の沙汰ではない。やっぱり nginx の設定だけを分離したい。

nginx.conf

server {
  listen     80;
  server_tokens on;
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }
}

--from-file を利用すると、ファイルから ConfigMap を生成できる。(--from-file は複数も指定できる。)

$ kubectl create configmap nginx-config --from-file=nginx.conf
configmap/nginx-config created

$ kubectl describe configmaps nginx-config
Name:         nginx-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf:
----
server {
  listen     80;
  server_tokens on;
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }
}

Events:  <none>