[Kubernetes]環境変数を設定する

#はじめに
通常のOSの場合、環境変数を永続的に設定するには、設定ファイルに書き込みます。設定ファイルはOSやShellによって異なりますが、今回はKubernetesでコンテナに対する環境変数の設定方法を確認してみたいと思います。
今回はマニフェストに直接書き込む方法を確認します。

#環境変数の設定
マニフェストのspec.containersにenvとして設定します。
ここでは、PS1とTZを設定しています。

```env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-env
spec:
  containers:
    - name: centos
      image: centos:latest
      command:
      - sh
      - -c
      args:
      - tail -f /dev/null
      env:
        - name: PS1
          value: "[`date`]$ "
        - name: TZ
          value: JST
```

このマニフェストをapplyします。

```
$ kubectl apply -f env.yaml
pod/test-env created
```
コンテナにログインして、確認します。

```
$ kubectl exec -it test-env /bin/bash
[Thu Apr 16 13:01:20 JST 2020]$
[Thu Apr 16 13:01:51 JST 2020]$ env | grep -e TZ -e PS1
TZ=JST
PS1=[`date`]$
```
プロンプトが設定されていますね。
環境変数にも設定されていることがわかります。

#Podとコンテナの情報を環境変数に設定する
Podとコンテナの情報を環境変数として設定することができます。
Podの情報は「fieldRef」で、コンテナの情報は「resourceFieldRef」で設定します。

>[Expose Pod Information to Containers Through Environment Variables](https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/)

設定できる情報は、それぞれ以下になります。

>|Field|Description
>|:---|:---
>|fieldRef|Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
>|resourceFieldRef|Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
>
>[EnvVarSource v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#envvarsource-v1-core)

##Podの情報
以下のマニフェストでnodeNameをNODE_NAME環境変数として設定してみたいと思います。

```fieldRef.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-field-ref
spec:
  containers:
    - name: centos
      image: centos:latest
      command:
      - sh
      - -c
      args:
      - tail -f /dev/null
      env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
```
このマニフェストをapplyします。

```
$ kubectl apply -f fieldRef.yaml
pod/test-field-ref created
```
確認します。

```
$ kubectl exec -it test-field-ref printenv NODE_NAME
k8s-worker01
```
NODE_NAME環境変数が設定されていますね。
念のため、worker01にデプロイされているか確認しておきます。

```
$ kubectl get pod test-field-ref -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
test-field-ref   1/1     Running   0          2m56s   192.168.79.80   k8s-worker01   <none>           <none>
```

##コンテナの情報
次にコンテナの情報を環境変数として設定してみたいと思います。
ここでは、requests.cpuとrequests.memoryを環境変数として設定します。

```resourceFieldRef.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-resource-field-ref
spec:
  containers:
    - name: centos
      image: centos:latest
      command:
      - sh
      - -c
      args:
      - tail -f /dev/null
      env:
        - name: REQUESTS_CPU
          valueFrom:
            resourceFieldRef:
              containerName: centos
              resource: requests.cpu
        - name: REQUESTS_MEM
          valueFrom:
            resourceFieldRef:
              containerName: centos
              resource: requests.memory
```
このマニフェストをapplyします。

```
$ kubectl apply -f resourceFieldRef.yaml
pod/test-resource-field-ref created
```
確認します。

```
$ kubectl exec -it test-resource-field-ref /bin/bash
[root@test-resource-field-ref /]# env | grep REQUEST
REQUESTS_MEM=0
REQUESTS_CPU=0
```
どちらも値を設定してないので「0」ですが、環境変数としては設定されていますね。

#まとめ
一番目の環境変数の設定は、profileファイルに書くのと同じ要領ですのでわかりやすかったですが、Podとコンテナの情報を環境変数に設定するのは、本で読んで理解した内容と違っていたので、少し苦戦しました。
やはり本を読むだけでなく、実際にやってみないとわからないことが多いです。特にKubernetesのバージョンアップで動作が変わってることもありますので、本を読んでやってみて、わからなければマニュアルを確認しないといけないですね。