Kubernetes基礎(7)：ConfigMap, Secret


###1. ConfigMap, Secretとは
<img width="960" alt="kubernetes_config1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/a75b0458-6cd6-c7db-9f70-871e3e6b6b00.png">
上の図のDev環境は、通常のアクセスとセキュリティのアクセス（SSH：False/ True）をサポートしています。
Dev環境では、セキュリティのアクセスを無効にすることができるオプションもあり、セキュリティアクセスをする場合のアクセスユーザーとキーを設定することもできる。
Prod環境でdeployをする時は、この値をProd環境のユーザーとキーに変えて
セキュリティ接続に設定を変更しないといけないが、この値はContainer内のサービスImageの中に入っているので、
この内容を変えるということはDev/Prod環境のContainer Imageをそれぞれ個別に管理するという意味である。

このような値のために大容量のImageを個別に管理するというのは負担になることである。
このため、環境に応じて変化する値を外部から設定できるようにしたObjectがConfigMapとSecretである。
一般的なLiteralを集めてConfigMapを作成し、Keyのように安全な値を集めSecretを作る。
Pod生成時に、この二つのObjectを接続すると、Containerの環境変数には、Objectのデータが設定され、
上の図のDev/ProdのA ServiceのようにContainer内の環境変数を読み込んで使うことができるようになる。

だからDev/ ProdそれぞれのImageを作成せずに、環境変数の値が設定されていないImageを1つ作成しておくと
ConfigMapとSecretのデータのみ変えて、Dev環境とProd環境で使うことができる。
###2. 使い方
![ConfigMap, Secret with Literal, File on Env, Mount for Kubernetes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/11773b27-1c31-ba77-530c-c32bb83d3a6c.jpeg)
<b>1. Env(Literal)</b>
![kubernetes_ConfigMap, Secret with Literal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/0ff1292c-51c0-320c-fbae-25311a4be977.jpeg)
ConfigMapはKey-Valueで構成されている。
必要なLiteralを定義しておけばPodを生成する際にConfigMapを取得してContainer内の環境変数に設定することができる。
Secretは、セキュリティに関連する情報を格納するために使用する。 
主にPassword、認証キーをSecretに設定しておく。
ConfigMapとの違いはValueを設定するときにBase64エンコードをした値を設定しないといけない違いがある。
Secretのセキュリティ的な要素ではなく、値を設定するルールとしてエンコードする必要があるだけでPodに注入されて、
環境変数の中では、元の値が見える。
Secretのセキュリティ的な要素とは、一般的なオブジェクトの値はKubernetesのDatabaseに格納されるが
Secretはメモリに保存されることがセキュリティ的な要素になる。
ファイルよりはメモリに保存されるのがセキュリティ的にはよい。
ConfigMap의 경우 key-value값을 무한히 넣을수 있지만 Secret는 1Mbyte 까지 넣을수 있다.
ConfigMapの場合はkey-valueの値を制限なく設定できるがSecretは1Mbyteまでの制限がある。
Secretはシステムリソースに影響を及ぼすので注意しなければならない。

1-1-1) ConfigMap

```Yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-dev
data:
  SSH: 'false'
  User: dev
```
1-1-2) Secret

```Yaml
apiVersion: v1
kind: Secret
metadata:
  name: sec-dev
data:
  Key: MTIzNA==
```
1-1-3) Pod

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
spec:
  containers:
  - name: container
    image: <image name>
    envFrom:
    - configMapRef:
        name: cm-dev
    - secretRef:
        name: sec-dev
```
ConfigMap/ Secretのdataにkey-valueで設定する。
Secretの場合は、valueにbase64で変更した値を設定する。
Pod生成時にenvFromでConfigMap、Secretをreferenceするように指定する。

<b>2. Env(File)</b>
![ConfigMap, Secret with File for Kubernetes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/d2aa8d03-dbb6-43da-0505-5b16bfcb222a.jpeg)
ファイルを丸ごとConfigMap、Secretに入れることもできる。
この場合はファイル名がKeyになって、ファイルの中身がValueになるConfigMapが作成される。
これをPodの環境変数に設定するとキーがファイル名(key:file.txt)になるので、キーを新たに定義したほうがよい。
ファイルをConfigMapに設定するのはマスターのコンソールからKubectlコマンドで作る。

2-2-1) Configmap
cm-file名前のconfigmapを作成してfile-c.txtを設定する。

```
echo "Content" >> file-c.txt
kubectl create configmap cm-file --from-file=./file-c.txt
```
2-2-2) Secret
secretを作成するKubectlコマンドでflieの中身がBase64に変更されることに注意しなければならない。
つまり、ファイルの中身がすでにBase64になっていたら二度エンコードになるからだ。

```
echo "Content" >> file-s.txt
kubectl create secret generic sec-file --from-file=./file-s.txt
```

2-2-3) Pod
ConfigMapKeyRefでConfigMapのKeyを参照するので、nameはConfigMapの名前、そして
KeyはConfigMapのキー(ConfigMapを作成するときのファイル名)を指定する。

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-file
spec:
  containers:
  - name: container
    image: <image name>
    env:
    - name: file-c
      valueFrom:
        configMapKeyRef:
          name: cm-file
          key: file-c.txt
    - name: file-s
      valueFrom:
        secretKeyRef:
          name: sec-file
          key: file-s.txt
```
<b>3. Volume Mount(File)</b>
![ConfigMap, Secret with Mount for Kubernetes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/6f0eaca0-c8c6-621a-cc76-e46fc7646a5c.jpeg)
ファイルをConfigMapに入れるのは<b>2. Env(File)</b>と同じ。
Podを作成するときにContainer内にmount pathを定義すると、このPath内のファイルをmountできる。

2-3-1) Pod
volumeMountsはContainer内volumeをmountしている。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-mount
spec:
  containers:
  - name: container
    image: <image name>
    volumeMounts:
    - name: file-volume
      mountPath: /mount
  volumes:
  - name: file-volume
    configMap:
      name: cm-file
```
					
Env(File)とVolume Mount(File)の違いは、Env(File)は一度Podに設定されるとConfigMapが変更されても
Podの環境変数の値は反映されない。
Podが再生成されるとき、変更されたConfigmapの値が環境変数に反映される。
Volume Mount(File)はConfigMapが変更されるとPodのマウントされている環境変数の値も変更される。
#Referenece
Configure a Pod to Use a ConfigMap : https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
Distribute Credentials Securely Using Secrets : https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/