Kubernetes1.10 チュートリアルやってみた(ConfigMap)

# はじめに

Kubernetesの公式ページに、多くのチュートリアルが掲載されています。
Kubernetesの勉強の一環で、チュートリアルを消化していきます。
今回は ConfigMapが対象です。
https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap/

なお、Kubernetesのバージョンは、2018年4月時点で最新の1.10を使用しています。



# ConfigMapとは

ConfigMapは、コンテナのポータビリティ性を向上するために、コンテナイメージからコンフィグ情報を分離することが出来ます。今回のチュートリアルでは、ConfigMapを作成し、Podで活用する方法を確かめていきます。



# ConfigMapの作成

ConfigMapを作成するには、以下の3パターンの方法があります。

- `kubectl create -f <filename>`で作成。YAMLマニフェストファイルを作成する必要がある。
- `kubectl create configmap <map-name> <data-source>`で作成。key-valueを定義したファイルのみで作成が出来る。
- `kubectl create configmap --from-literal`で作成。コマンドの引数で直接 key-value を与える



## 1-1. YAMLのマニフェストファイルで作成

以下のマニフェストファイルを作成します。

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config.yaml
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  name: game-config
EOF
```

ConfigMapを作成します

```
[root@sugi-kubernetes110-master01 config_files]# kubectl create -f /root/kube_yaml/config_files/game-config.yaml
configmap "game-config" created
```

ConfigMapの一覧を確認します

```
[root@sugi-kubernetes110-master01 config_files]# kubectl get configmap 
NAME          DATA      AGE
game-config   2         13s
```

作成したConfigMapの詳細を確認します

```
[root@sugi-kubernetes110-master01 config_files]# kubectl describe configmap game-config 
Name:         game-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

Events:  <none>
```

次の確認をするために、削除します

```
[root@sugi-kubernetes110-master01 config_files]# kubectl delete configmap game-config 
configmap "game-config" deleted
```



## 2-1. Directoryから作成

Direcotryを作成

```
/root/kube_yaml/config_files/temp_dir
```

作成したDirectoryに2個のFileを作成

```EOF
cat <<'EOF' > /root/kube_yaml/config_files/temp_dir/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
EOF
```

```
cat <<'EOF' > /root/kube_yaml/config_files/temp_dir/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
EOF
```

temp_dir に 2個のファイルが作成されています

```
[root@sugi-kubernetes110-master01 temp_dir]# pwd
/root/kube_yaml/config_files/temp_dir
[root@sugi-kubernetes110-master01 temp_dir]# 
[root@sugi-kubernetes110-master01 temp_dir]# ls -la
total 8
drwxr-xr-x 2 root root  50 Apr 30 15:42 .
drwxr-xr-x 3 root root  46 Apr 30 15:40 ..
-rw-r--r-- 1 root root 158 Apr 30 15:42 game.properties
-rw-r--r-- 1 root root  83 Apr 30 15:42 ui.properties
```

Directoryを指定して、ConfigMapを作成します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl create configmap game-config --from-file=/root/kube_yaml/config_files/temp_dir
configmap "game-config" created
```

ConfigMapの一覧を確認します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl get configmap 
NAME          DATA      AGE
game-config   2         12s
```

作成したConfigMapの詳細を確認します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl describe configmap game-config 
Name:         game-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

Events:  <none>
```

次の確認をするために、削除します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl delete configmap game-config 
configmap "game-config" deleted
```



## 2-2. Fileから作成 

2-1で作成したFIleを1個指定して作成します。

```
kubectl create configmap game-config-1 --from-file=/root/kube_yaml/config_files/temp_dir/game.properties
```

ConfigMapの一覧を確認します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl get configmap 
NAME            DATA      AGE
game-config-1   1         12s
```

作成したConfigMapの詳細を確認します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl describe configmap game-config-1 
Name:         game-config-1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

Events:  <none>
```







## 3-1. コマンドの引数で作成

```
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
```

作成したConfigMapの詳細を確認します

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl describe configmap special-config 
Name:         special-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
special.how:
----
very
special.type:
----
charm
Events:  <none>
```

describeでは見にくいので、getに-o yaml を指定すると見やすくなります

```
[root@sugi-kubernetes110-master01 temp_dir]# kubectl get configmap special-config -o yaml
apiVersion: v1
data:
  special.how: very
  special.type: charm
kind: ConfigMap
metadata:
  creationTimestamp: 2018-04-30T06:52:28Z
  name: special-config
  namespace: default
  resourceVersion: "194751"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: 0c220c18-4c43-11e8-baee-0050569817ee
```

次の確認をするために、削除します

```
kubectl delete configmap special-config
```



# Podの環境変数にConfigMapを使用

## ConfigMapを使用しない状態でコンテナ内の環境変数を確認

まず、ConfigMapを付与しないBusyBoxを作成し、コンテナ内の環境変数を標準出力にだし、kubectl logs で確認します

```
cat <<'EOF' > /root/kube_yaml/config_files/noenv_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
  restartPolicy: Never
EOF
```

Podを作成します

```
kubectl create -f /root/kube_yaml/config_files/noenv_pod.yaml
```

Completed となっていることを確認します

```
[root@sugi-kubernetes110-master01 ~]# kubectl get pod -o wide
NAME            READY     STATUS      RESTARTS   AGE       IP            NODE
dapi-test-pod   0/1       Completed   0          2m        10.244.1.13   sugi-kubernetes110-node01.localdomain
```

kubectl logs コマンドを実行し、コンテナ内の環境変数を確認します

```
[root@sugi-kubernetes110-master01 ~]# kubectl logs dapi-test-pod 
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
[root@sugi-kubernetes110-master01 ~]# 
```

podを削除します

```
kubectl delete pod dapi-test-pod
```



## 1個のConfigMapを使用してコンテナ内の環境変数を確認

以下のConfigMapを作成します
**下記のような環境変数の多段構成は、Podに適用する際に、扱いにくいように思います**

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config.yaml
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  name: game-config
EOF
```

ConfigMapを作成

```
kubectl create -f /root/kube_yaml/config_files/game-config.yaml
```

PodにConfigMapをenv(環境変数)として定義するマニフェストファイルを作成します

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # Define the environment variable
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
              name: game-config
              # Specify the key associated with the value
              key: game.properties
  restartPolicy: Never
EOF
```

Podを作成

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

Pod一覧を確認し、StatusがCompletedとなっている事を確認します

```a
[root@sugi-kubernetes110-master01 ~]# kubectl get pod -o wide
NAME            READY     STATUS      RESTARTS   AGE       IP            NODE
dapi-test-pod   0/1       Completed   0          19s       10.244.2.12   sugi-kubernetes110-node02.localdomain
```

logを確認します

```
[root@sugi-kubernetes110-master01 ~]# kubectl logs dapi-test-pod 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SPECIAL_LEVEL_KEY=enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
[root@sugi-kubernetes110-master01 ~]# 
```

ConfigMapを指定することで、以下の値が環境変数に新たに指定されていることがわかります
podのマニフェストファイルで指定したSPECIAL_LEVEL_KEYと、ConfigMapとの兼ね合いで、出力される環境変数が微妙な状態です。1個目の環境変数のみ「SPECIAL_LEVEL_KEY=enemies=aliens」という形式になっています

```
SPECIAL_LEVEL_KEY=enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
```

Podを削除します

```
kubectl delete pod dapi-test-pod
```

env_pod の 環境変数指定方法を調整します
spec.containers.env から、 spec.containers.envFrom と指定します。
「spec.containers.env」では、環境変数ごとに指定する必要があり冗長でしたが、envFromで複数の環境変数を読み込ませることが出来ます。

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
        # Define the environment variable
        - configMapRef:
            # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
            name: game-config
            # Specify the key associated with the value
            # key: game.properties
  restartPolicy: Never
EOF
```

Podの作成

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

logsの確認

```
[root@sugi-kubernetes110-master01 ~]# kubectl logs dapi-test-pod 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
ui.properties=color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
game.properties=enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
```

ConfigMapで定義している部分のみ抜粋します。
やはり、多段構成にしている箇所の内容が、微妙な設定になっています。

```
ui.properties=color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
game.properties=enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
```

ConfigMapの多段構成をやめて、Flatに定義します

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config.yaml
apiVersion: v1
data:
  game.properties.enemies: 'aliens'
  game.properties.lives: '3'
  game.properties.enemies.cheat: 'true'
  game.properties.enemies.cheat.level: 'noGoodRotten'
  game.properties.secret.code.passphrase: 'UUDDLRLRBABAS'
  game.properties.secret.code.allowed: 'true'
  game.properties.secret.code.lives: '30'
  ui.properties.color.good: 'purple'
  ui.properties.color.bad: 'yellow'
  ui.properties.allow.textmode: 'true'
  ui.properties.how.nice.to.look: 'fairlyNice'
kind: ConfigMap
metadata:
  name: game-config
EOF
```

ConfigMapを作成しなおします

```
kubectl create -f /root/kube_yaml/config_files/game-config.yaml
```

Podを作成し直します

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

logを確認します。いい具合に複数同時に読み込まれていることを確認できます

```
[root@sugi-kubernetes110-master01 ~]# kubectl logs dapi-test-pod 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
ui.properties.how.nice.to.look=fairlyNice
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
ui.properties.color.good=purple
game.properties.enemies=aliens
game.properties.lives=3
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
game.properties.secret.code.passphrase=UUDDLRLRBABAS
KUBERNETES_PORT_443_TCP_PROTO=tcp
game.properties.enemies.cheat.level=noGoodRotten
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
ui.properties.allow.textmode=true
game.properties.enemies.cheat=true
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
game.properties.secret.code.lives=30
game.properties.secret.code.allowed=true
ui.properties.color.bad=yellow
```

Podの削除

```
kubectl delete pod dapi-test-pod
```



## 複数のConfigMapを使用してコンテナ内の環境変数を確認

2個目のConfigMapを作成

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config-2.yaml
apiVersion: v1
data:
  test.env: 'ceder'
kind: ConfigMap
metadata:
  name: game-config-2
EOF
```

ConfigMapの作成

```
kubectl create -f /root/kube_yaml/config_files/game-config-2.yaml
```

Podのマニフェストファイルを修正

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
        # Define the environment variable
        - configMapRef:
            name: game-config
        - configMapRef:
            name: game-config-2
  restartPolicy: Never
EOF
```

Podを作成します

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

logsを確認します
ConfigMapを複数指定して正常に読み込まれていることがわかります

```
[root@sugi-kubernetes110-master01 ~]# kubectl logs dapi-test-pod 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
ui.properties.how.nice.to.look=fairlyNice
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
ui.properties.color.good=purple
game.properties.lives=3
game.properties.enemies=aliens
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
game.properties.secret.code.passphrase=UUDDLRLRBABAS
KUBERNETES_PORT_443_TCP_PROTO=tcp
test.env=ceder
game.properties.enemies.cheat.level=noGoodRotten
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
ui.properties.allow.textmode=true
game.properties.enemies.cheat=true
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
game.properties.secret.code.lives=30
game.properties.secret.code.allowed=true
ui.properties.color.bad=yellow
```

## ConfigMapの更新

Podのマニフェストファイルを作成します

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sleep", "3600" ]
      envFrom:
        # Define the environment variable
        - configMapRef:
            name: game-config
        - configMapRef:
            name: game-config-2
  restartPolicy: Never
EOF
```

Podの作成

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

bashに遠隔ログイン

```
kubectl exec -it dapi-test-pod sh
```

環境変数の確認

```
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
ui.properties.how.nice.to.look=fairlyNice
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
ui.properties.color.good=purple
game.properties.enemies=aliens
game.properties.lives=3
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
game.properties.secret.code.passphrase=UUDDLRLRBABAS
KUBERNETES_PORT_443_TCP_PROTO=tcp
test.env=ceder
game.properties.enemies.cheat.level=noGoodRotten
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
ui.properties.allow.textmode=true
game.properties.enemies.cheat=true
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
game.properties.secret.code.lives=30
game.properties.secret.code.allowed=true
ui.properties.color.bad=yellow
```

マニフェストファイルの修正
test.envをcederからsugiに変更

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config-2.yaml
apiVersion: v1
data:
  test.env: 'sugi'
kind: ConfigMap
metadata:
  name: game-config-2
EOF
```

変更を適用します

```
[root@sugi-kubernetes110-master01 ~]# kubectl apply -f /root/kube_yaml/config_files/game-config-2.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
configmap "game-config-2" configured
```

確認します

```
[root@sugi-kubernetes110-master01 ~]# kubectl get configmap game-config-2 -o yaml
apiVersion: v1
data:
  test.env: sugi
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"test.env":"sugi"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"game-config-2","namespace":"default"}}
  creationTimestamp: 2018-04-30T16:47:42Z
  name: game-config-2
  namespace: default
  resourceVersion: "243453"
  selfLink: /api/v1/namespaces/default/configmaps/game-config-2
  uid: 331bb48c-4c96-11e8-baee-0050569817ee
```

既に作成しているPodの環境変数は、変更されません。cederのままとなっています

```
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
ui.properties.how.nice.to.look=fairlyNice
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
ui.properties.color.good=purple
game.properties.enemies=aliens
game.properties.lives=3
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
game.properties.secret.code.passphrase=UUDDLRLRBABAS
KUBERNETES_PORT_443_TCP_PROTO=tcp
test.env=ceder
game.properties.enemies.cheat.level=noGoodRotten
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
ui.properties.allow.textmode=true
game.properties.enemies.cheat=true
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
game.properties.secret.code.lives=30
game.properties.secret.code.allowed=true
ui.properties.color.bad=yellow
```



# PodにVolumeとしてConfigMapをマウント

## 1個のConfigMapを使用してコンテナ内にFileとしてマウント

Podのマニフェストファイルを作成します
spec.volumes の配下に、configmapを config-volume という名前で、volumeを定義しています。
spec.container.volumeMountsの配下で、/etc/config にマウントをするように定義しています。

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sleep", "3600" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: game-config
  restartPolicy: Never
EOF
```

Podの作成

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

busyboxのshellを新たに実行し、遠隔でログインします

```a
kubectl exec -it dapi-test-pod sh
```

該当のディレクトリ上に、ファイルが存在していることを確認できます

```
/ # cd /etc/config/
/etc/config # 
/etc/config # ls -la
total 8
drwxrwxrwx    3 root     root          4096 Apr 30 17:04 .
drwxr-xr-x    1 root     root            20 Apr 30 17:04 ..
drwxr-xr-x    2 root     root          4096 Apr 30 17:04 ..2018_04_30_17_04_33.366860462
lrwxrwxrwx    1 root     root            31 Apr 30 17:04 ..data -> ..2018_04_30_17_04_33.366860462
lrwxrwxrwx    1 root     root            30 Apr 30 17:04 game.properties.enemies -> ..data/game.properties.enemies
lrwxrwxrwx    1 root     root            36 Apr 30 17:04 game.properties.enemies.cheat -> ..data/game.properties.enemies.cheat
lrwxrwxrwx    1 root     root            42 Apr 30 17:04 game.properties.enemies.cheat.level -> ..data/game.properties.enemies.cheat.level
lrwxrwxrwx    1 root     root            28 Apr 30 17:04 game.properties.lives -> ..data/game.properties.lives
lrwxrwxrwx    1 root     root            42 Apr 30 17:04 game.properties.secret.code.allowed -> ..data/game.properties.secret.code.allowed
lrwxrwxrwx    1 root     root            40 Apr 30 17:04 game.properties.secret.code.lives -> ..data/game.properties.secret.code.lives
lrwxrwxrwx    1 root     root            45 Apr 30 17:04 game.properties.secret.code.passphrase -> ..data/game.properties.secret.code.passphrase
lrwxrwxrwx    1 root     root            35 Apr 30 17:04 ui.properties.allow.textmode -> ..data/ui.properties.allow.textmode
lrwxrwxrwx    1 root     root            30 Apr 30 17:04 ui.properties.color.bad -> ..data/ui.properties.color.bad
lrwxrwxrwx    1 root     root            31 Apr 30 17:04 ui.properties.color.good -> ..data/ui.properties.color.good
lrwxrwxrwx    1 root     root            37 Apr 30 17:04 ui.properties.how.nice.to.look -> ..data/ui.properties.how.nice.to.look
```

ファイルの中身も正常に定義されています

```
/etc/config # cat game.properties.enemies
aliens/etc/config # 
/etc/config # 
/etc/config # cat game.properties.lives
3/etc/config # 
```

Podの削除

```
kubectl delete pod dapi-test-pod
```

## 複数のConfigMapを使用してコンテナ内にfileとしてマウント

Podのマニフェストファイルを修正します

```
cat <<'EOF' > /root/kube_yaml/config_files/env_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sleep", "3600" ]
      volumeMounts:
      - name: config-volume1
        mountPath: /etc/config-volume1
      - name: config-volume2
        mountPath: /etc/config-volume2
  volumes:
    - name: config-volume1
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: game-config
    - name: config-volume2
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: game-config-2
  restartPolicy: Never
EOF
```

Podの作成

```
kubectl create -f /root/kube_yaml/config_files/env_pod.yaml
```

busyboxのshellを新たに実行し、遠隔でログインします

```a
kubectl exec -it dapi-test-pod sh
```

/etc 直下に、 config-volume1と、config-volume2のディレクトリが作成されています

```
/etc # pwd
/etc
/etc # 
/etc # ls -la
total 80
drwxr-xr-x    1 root     root            50 Apr 30 17:14 .
drwxr-xr-x    1 root     root            40 Apr 30 17:14 ..
drwxrwxrwx    3 root     root          4096 Apr 30 17:14 config-volume1
drwxrwxrwx    3 root     root            75 Apr 30 17:14 config-volume2
-rw-rw-r--    1 root     root           466 Feb 27  2014 fstab
-rw-rw-r--    1 root     root           344 Feb 27  2014 group
-rw-r--r--    1 root     root            14 Apr 30 17:14 hostname
-rw-r--r--    1 root     root           209 Apr 30 17:14 hosts
drwxrwxr-x    2 root     root            82 May 22  2014 init.d
-rw-rw-r--    1 root     root          1086 May 22  2014 inittab
-rw-rw-r--    1 root     root          1180 Feb 27  2014 inputrc
drwxr-xr-x    2 root     root           123 May 22  2014 iproute2
-rw-rw-r--    1 root     root            21 May 22  2014 issue
-rw-r--r--    1 root     root             0 May 22  2014 ld.so.conf
drwxrwxr-x    2 root     root             6 Feb 27  2014 ld.so.conf.d
lrwxrwxrwx    1 root     root            12 Apr 30 17:14 mtab -> /proc/mounts
drwxrwxr-x    8 root     root           138 May 22  2014 network
-rw-rw-r--    1 root     root           439 Feb 27  2014 nsswitch.conf
-rw-r--r--    1 root     root            95 May 22  2014 os-release
-rw-r--r--    1 root     root           596 Feb 27  2014 passwd
-rw-rw-r--    1 root     root          1836 Feb 27  2014 profile
-rw-rw-r--    1 root     root          2744 Feb 27  2014 protocols
-rw-rw-r--    1 root     root           512 Feb 27  2014 random-seed
-rw-r--r--    1 root     root           115 Apr 30 17:14 resolv.conf
-rw-rw-r--    1 root     root           386 Feb 27  2014 securetty
-rw-rw-r--    1 root     root         10873 Feb 27  2014 services
-rw-------    1 root     root           346 May 22  2014 shadow
/etc # 
```

それぞれのディレクトリを確認します

```
/etc/config-volume1 # pwd
/etc/config-volume1
/etc/config-volume1 # 
/etc/config-volume1 # ls -la
total 8
drwxrwxrwx    3 root     root          4096 Apr 30 17:14 .
drwxr-xr-x    1 root     root            50 Apr 30 17:14 ..
drwxr-xr-x    2 root     root          4096 Apr 30 17:14 ..2018_04_30_17_14_44.399765545
lrwxrwxrwx    1 root     root            31 Apr 30 17:14 ..data -> ..2018_04_30_17_14_44.399765545
lrwxrwxrwx    1 root     root            30 Apr 30 17:14 game.properties.enemies -> ..data/game.properties.enemies
lrwxrwxrwx    1 root     root            36 Apr 30 17:14 game.properties.enemies.cheat -> ..data/game.properties.enemies.cheat
lrwxrwxrwx    1 root     root            42 Apr 30 17:14 game.properties.enemies.cheat.level -> ..data/game.properties.enemies.cheat.level
lrwxrwxrwx    1 root     root            28 Apr 30 17:14 game.properties.lives -> ..data/game.properties.lives
lrwxrwxrwx    1 root     root            42 Apr 30 17:14 game.properties.secret.code.allowed -> ..data/game.properties.secret.code.allowed
lrwxrwxrwx    1 root     root            40 Apr 30 17:14 game.properties.secret.code.lives -> ..data/game.properties.secret.code.lives
lrwxrwxrwx    1 root     root            45 Apr 30 17:14 game.properties.secret.code.passphrase -> ..data/game.properties.secret.code.passphrase
lrwxrwxrwx    1 root     root            35 Apr 30 17:14 ui.properties.allow.textmode -> ..data/ui.properties.allow.textmode
lrwxrwxrwx    1 root     root            30 Apr 30 17:14 ui.properties.color.bad -> ..data/ui.properties.color.bad
lrwxrwxrwx    1 root     root            31 Apr 30 17:14 ui.properties.color.good -> ..data/ui.properties.color.good
lrwxrwxrwx    1 root     root            37 Apr 30 17:14 ui.properties.how.nice.to.look -> ..data/ui.properties.how.nice.to.look
```

```
/etc/config-volume2 # pwd
/etc/config-volume2
/etc/config-volume2 # 
/etc/config-volume2 # ls -la
total 0
drwxrwxrwx    3 root     root            75 Apr 30 17:14 .
drwxr-xr-x    1 root     root            50 Apr 30 17:14 ..
drwxr-xr-x    2 root     root            22 Apr 30 17:14 ..2018_04_30_17_14_44.848559988
lrwxrwxrwx    1 root     root            31 Apr 30 17:14 ..data -> ..2018_04_30_17_14_44.848559988
lrwxrwxrwx    1 root     root            15 Apr 30 17:14 test.env -> ..data/test.env
```

## ConfigMapの更新

マニフェストファイルの修正
test.envをcederからsugiに変更

```
cat <<'EOF' > /root/kube_yaml/config_files/game-config-2.yaml
apiVersion: v1
data:
  test.env: 'sugi'
kind: ConfigMap
metadata:
  name: game-config-2
EOF
```

変更を適用します

```
[root@sugi-kubernetes110-master01 ~]# kubectl apply -f /root/kube_yaml/config_files/game-config-2.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
configmap "game-config-2" configured
```

確認します

```
[root@sugi-kubernetes110-master01 ~]# kubectl get configmap game-config-2 -o yaml
apiVersion: v1
data:
  test.env: sugi
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"test.env":"sugi"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"game-config-2","namespace":"default"}}
  creationTimestamp: 2018-04-30T16:47:42Z
  name: game-config-2
  namespace: default
  resourceVersion: "243453"
  selfLink: /api/v1/namespaces/default/configmaps/game-config-2
  uid: 331bb48c-4c96-11e8-baee-0050569817ee
```

ConfigMapをvolumeとしてマウントしているbusyboxコンテナ上から確認します
**更新に一定時間がかかるらしいです。私の場合は、すぐに変更が反映されました**

```
kubectl exec -it dapi-test-pod sh
```

```
/etc/config-volume2 # pwd
/etc/config-volume2
/etc/config-volume2 # 
/etc/config-volume2 # cat test.env 
sugi/etc/config-volume2 # 
```



# RealWorldサンプル Redis と ConfigMap

以下のコマンドを使用して、ConfiMapを作成します

```
cat <<'EOF' > /root/kube_yaml/config_files/redis-config
maxmemory 2mb
maxmemory-policy allkeys-lru
EOF
```

ConfigMapを作成します

```
kubectl create configmap example-redis-config --from-file=/root/kube_yaml/config_files/redis-config
```

確認

```
[root@sugi-kubernetes110-master01 config_files]# kubectl get configmap example-redis-config -o yaml
apiVersion: v1
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru
kind: ConfigMap
metadata:
  creationTimestamp: 2018-04-30T17:41:36Z
  name: example-redis-config
  namespace: default
  resourceVersion: "244715"
  selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
  uid: baacb60b-4c9d-11e8-baee-0050569817ee
```

Pod作成のマニフェストファイル作成

```
cat <<'EOF' > /root/kube_yaml/config_files/redis-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: kubernetes/redis:v1
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf
EOF
```

Pod作成

```
kubectl create -f /root/kube_yaml/config_files/redis-pod.yaml
```

Podに遠隔ログインします

```
kubectl exec -it redis bash
```

まずは、環境変数を確認します。Master = true となるように指定しており、正常に反映されています。

```
root@redis:/redis-master# env
MASTER=true
HOSTNAME=redis
REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-2.8.19.tar.gz
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
TERM=xterm
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/redis-master
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_PROTO=tcp
REDIS_DOWNLOAD_SHA1=3e362f4770ac2fdbdce58a5aa951c1967e0facc8
REDIS_VERSION=2.8.19
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
OLDPWD=/redis-master-data
_=/usr/bin/env
```

ConfigMapを /redis-master にマウントしており、そこのディレクトリを確認します

```
root@redis:/redis-master# pwd
/redis-master
root@redis:/redis-master# 
root@redis:/redis-master# ls -la
total 0
drwxrwxrwx 3 root root 77 Apr 30 17:42 .
drwxr-xr-x 1 root root 42 Apr 30 17:45 ..
drwxr-xr-x 2 root root 24 Apr 30 17:42 ..2018_04_30_17_42_54.142107158
lrwxrwxrwx 1 root root 31 Apr 30 17:42 ..data -> ..2018_04_30_17_42_54.142107158
lrwxrwxrwx 1 root root 17 Apr 30 17:42 redis.conf -> ..data/redis.conf
```

ファイルの中味を確認します

```
root@redis:/redis-master# cat redis.conf 
maxmemory 2mb
maxmemory-policy allkeys-lru
```

redisコンテナイメージは、「/redis-master/redis.conf」を読み込むように作りこまれており、ConfigFileと連携することで、redisプロセスのメモリ関連の設定を動的に指定できます。

redisのcliを開き、確認します

```
root@redis:/etc# redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "2097152"
127.0.0.1:6379> 
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
```





# 参考URL

https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap/

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

envFromについて
https://qiita.com/tkusumi/items/cf7b096972bfa2810800