Kubernetes1.10 チュートリアル101やってみた (kubectl, pod管理, emptydir, 1Pod複数コンテナ)

# はじめに

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

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



# Kubernetes 101

Kubernetes101チュートリアルでは、以下の内容を勉強していくものになっています。

- kubectlの使い方
- Pods
- volume
- Pod内に複数コンテナ



# kubectlの使い方

基本的にはDocumentを読めば分かります。
https://kubernetes.io/docs/reference/kubectl/overview/

基本的な内容と、気になったポイントを抜き出してこちらの記事に記載します。



## 基本的な内容

次の構文を使用してkubectlを使用します。

```
kubectl [command] [TYPE] [NAME] [flags]
```

command, TYPE, NAME, flags は次の通りです

- command : create, get, describe, delete を指定することが出来ます

- TYPE : resource-typeを指定することが出来ます。大文字小文字を区別しません。また、単数形・複数形・省略形を指定することができます

  ```
  $ kubectl get pod pod1
  $ kubectl get pods pod1
  $ kubectl get po pod1
  ```

- NAME : リソースの名前を指定することが出来ます。NAMEを省略すると、全てのリソースが表示されます。また、複数のリソースを表示したい時は、複数指定することが出来ます

  - 同じTYPEに所属している複数のリソースを表示

    ```
    kubectl get pod example-pod1 example-pod2
    ```

  - 異なるTYPEに所属している複数のリソースを表示

    ```
    kubectl get pod/example-pod1 replicationcontroller/example-rc1
    ```

  - YAML Fileで複数指定

    ```
    kubectl get pod -f ./pod.yaml
    ```

- flags : ハイフンを指定して様々なフラグを指定することが出来ます。flagsで指定した内容は、default値や環境変数で指定している内容を上書きして実行されます。




## 気になったTopic

### 出力形式

kubectlの出力形式を指定することが出来ます。

```
kubectl [command] [TYPE] [NAME] -o=<output_format>
```

jsonやyamlなどの多数のオプションを指定することができます。
その中で私が気になったのは `-o wide`です。
通常のgetと比べて、追加情報を同時に表示することができます。

-o wide なし

```
[root@sugi-kubernetes110-master01 ~]# kubectl get pods --all-namespaces 
NAMESPACE     NAME                                                              READY     STATUS    RESTARTS   AGE
kube-system   etcd-sugi-kubernetes110-master01.localdomain                      1/1       Running   1          2h
kube-system   kube-apiserver-sugi-kubernetes110-master01.localdomain            1/1       Running   1          2h
kube-system   kube-controller-manager-sugi-kubernetes110-master01.localdomain   1/1       Running   1          2h
kube-system   kube-dns-86f4d74b45-bvps2                                         3/3       Running   3          2h
kube-system   kube-flannel-ds-5tgh7                                             1/1       Running   1          2h
kube-system   kube-flannel-ds-d92qj                                             1/1       Running   1          2h
kube-system   kube-flannel-ds-rb6ll                                             1/1       Running   1          2h
kube-system   kube-proxy-khhwf                                                  1/1       Running   1          2h
kube-system   kube-proxy-l8pbk                                                  1/1       Running   1          2h
kube-system   kube-proxy-zblxq                                                  1/1       Running   1          2h
kube-system   kube-scheduler-sugi-kubernetes110-master01.localdomain            1/1       Running   1          2h
```

-o wide あり
podが稼働しているnodeとIPアドレスを同時に確認できて便利です

```
[root@sugi-kubernetes110-master01 ~]# kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                                                              READY     STATUS    RESTARTS   AGE       IP                NODE
kube-system   etcd-sugi-kubernetes110-master01.localdomain                      1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
kube-system   kube-apiserver-sugi-kubernetes110-master01.localdomain            1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
kube-system   kube-controller-manager-sugi-kubernetes110-master01.localdomain   1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
kube-system   kube-dns-86f4d74b45-bvps2                                         3/3       Running   3          2h        10.244.0.3        sugi-kubernetes110-master01.localdomain
kube-system   kube-flannel-ds-5tgh7                                             1/1       Running   1          2h        192.168.120.224   sugi-kubernetes110-node02.localdomain
kube-system   kube-flannel-ds-d92qj                                             1/1       Running   1          2h        192.168.120.223   sugi-kubernetes110-node01.localdomain
kube-system   kube-flannel-ds-rb6ll                                             1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
kube-system   kube-proxy-khhwf                                                  1/1       Running   1          2h        192.168.120.223   sugi-kubernetes110-node01.localdomain
kube-system   kube-proxy-l8pbk                                                  1/1       Running   1          2h        192.168.120.224   sugi-kubernetes110-node02.localdomain
kube-system   kube-proxy-zblxq                                                  1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
kube-system   kube-scheduler-sugi-kubernetes110-master01.localdomain            1/1       Running   1          2h        192.168.120.220   sugi-kubernetes110-master01.localdomain
```



# Pods

Kubernetesでは、1個 or 複数のコンテナの集まりをPodと呼んでいます。
Podの中のコンテナは、同時にデプロイされます。
開始、停止、レプリカはPod単位で実行されます。

## PodのYAML定義

YAMLファイルを使用して、Nginxを使用したシンプルな定義をします。
DockerHubから、nginxイメージのバージョン

```
cat <<'EOF' > /root/kube_yaml/101_walkthrough/pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80
EOF
```

## Pod管理

上記で定義したYAMLファイルを使用して、Podをデプロイすることが出来ます。

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl create -f /root/kube_yaml/101_walkthrough/pod-nginx.yaml
pod "nginx" created
```

kubectl run でも同様のことが出来ますが、YAMLファイルとして定義することで、gitなどでバージョン管理が出来るため、本番環境ではYAMLで実行するのがおすすめです。

podの状態を確認します
STATUSがContainerCreatingとなっているため、完了まで待機します。

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl get pods -o wide
NAME      READY     STATUS              RESTARTS   AGE       IP        NODE
nginx     0/1       ContainerCreating   0          19s       <none>    sugi-kubernetes110-node02.localdomain
```

STATUSがRunnningとなりました

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl get pods -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
nginx     1/1       Running   0          1m        10.244.2.2   sugi-kubernetes110-node02.localdomain
```

環境によりますが、ほとんどの環境では、PodのIPアドレス(上記の例だと10.244.2.2)には、Kubernetesクラスタの外部からアクセスが出来ません。
デプロイしたPodが稼働しているかどうかテストする簡単な方法は、busyboxコマンドが格納されているコンテナイメージをデプロイする方法です。

BusyBoxイメージをデプロイと同時に、BusyBoxコンテナ内のshellに接続します
その際に、envでBusyBoxコンテナ内の環境変数を指定して、nginxのClusterIPを渡しています

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl run busybox --image=busybox --restart=Never --tty -i --generator=run-pod/v1 --env "POD_IP=$(kubectl get pod nginx -o go-template='{{.status.podIP}}')"
If you don't see a command prompt, try pressing enter.
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    5 root      0:00 ps aux
/ # 
/ # 
/ # 
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 0a:58:0a:f4:01:04 brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.4/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::2c8b:15ff:fee8:1bbb/64 scope link 
       valid_lft forever preferred_lft forever
/ # 
/ # 
/ # 
/ # ip r
default via 10.244.1.1 dev eth0 
10.244.0.0/16 via 10.244.1.1 dev eth0 
10.244.1.0/24 dev eth0 scope link  src 10.244.1.4 
/ # 
/ # 
/ # 
/ # echo $POD_IP
10.244.2.2
```

BusyBoxコンテナ内から、nginxへwgetしてhttpアクセスします
結果、nginxのwelcomeページが返却され、正常に稼働していることがわかります

```
/ # wget -qO- http://$POD_IP
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # 
/ # 
/ # 
/ # exit
[root@sugi-kubernetes110-master01 101_walkthrough]# 
```

BusyBoxPodを削除します

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl get pods
NAME      READY     STATUS      RESTARTS   AGE
busybox   0/1       Completed   0          3m
nginx     1/1       Running     0          56m
[root@sugi-kubernetes110-master01 101_walkthrough]# 
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl delete pod busybox
pod "busybox" deleted
[root@sugi-kubernetes110-master01 101_walkthrough]# 
```

nginxPodも削除します

```
kubectl delete pod nginx
```



## volumes

Pod内のファイルシステムは、Podが稼働している間だけデータを保持しています。つまり、Podの再起動や障害が発生した際には、Pod内のデータは消えます。
アプリケーションが永続的なデータを保管したい場合は、persistent volume を利用することで、Podの外部にデータを保管することが出来ます。

次の例では、redisPodをデプロイする際に、以下の内容を含めています

- volumeの定義 (Podのデプロイ先Nodeのローカルファイルシステムを使用。異なるPodに移動するとデータが消える。テスト用に使用)
- 定義したvolumeをコンテナ内の /data/redis にマウント

```
cat <<'EOF' > /root/kube_yaml/101_walkthrough/pod-redis.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-persistent-storage
      mountPath: /data/redis
  volumes:
  - name: redis-persistent-storage
    emptyDir: {}
EOF
```

Deployします

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl create -f /root/kube_yaml/101_walkthrough/pod-redis.yaml
pod "redis" created
```

Podの状態を確認します

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl get pods -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
redis     1/1       Running   0          4m        10.244.2.3   sugi-kubernetes110-node02.localdomain
```

Podの詳細を確認します

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl describe pods redis
Name:         redis
Namespace:    default
Node:         sugi-kubernetes110-node02.localdomain/192.168.120.224
Start Time:   Sun, 29 Apr 2018 01:32:58 +0900
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.2.3
Containers:
  redis:
    Container ID:   docker://35605f94178e807c3e14a0a89f87a54dcf439d65b4d7f06c5284cbfc9fc69c4d
    Image:          redis
    Image ID:       docker-pullable://docker.io/redis@sha256:2a10443dced488731f0a3ed12e442c230d39b526f95ecb8e280cd1596705e822
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 29 Apr 2018 01:33:39 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /data/redis from redis-persistent-storage (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q65hj (ro)
Conditions:
  Type           Status
  Initialized    True 
  Ready          True 
  PodScheduled   True 
Volumes:
  redis-persistent-storage:
    Type:    EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:  
  default-token-q65hj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q65hj
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From                                            Message
  ----    ------                 ----  ----                                            -------
  Normal  Scheduled              48s   default-scheduler                               Successfully assigned redis to sugi-kubernetes110-node02.localdomain
  Normal  SuccessfulMountVolume  48s   kubelet, sugi-kubernetes110-node02.localdomain  MountVolume.SetUp succeeded for volume "redis-persistent-storage"
  Normal  SuccessfulMountVolume  48s   kubelet, sugi-kubernetes110-node02.localdomain  MountVolume.SetUp succeeded for volume "default-token-q65hj"
  Normal  Pulling                47s   kubelet, sugi-kubernetes110-node02.localdomain  pulling image "redis"
  Normal  Pulled                 7s    kubelet, sugi-kubernetes110-node02.localdomain  Successfully pulled image "redis"
  Normal  Created                7s    kubelet, sugi-kubernetes110-node02.localdomain  Created container
  Normal  Started                7s    kubelet, sugi-kubernetes110-node02.localdomain  Started container
```

redisPodのデプロイ先のNodeである「sugi-kubernetes110-node02」の、ローカルファイルシステムがvolumeとして使用されていることになります
「sugi-kubernetes110-node02」でdocker ps を実行し、コンテナ一覧を確認

```
[root@sugi-kubernetes110-node02 redis]# docker ps
CONTAINER ID        IMAGE                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
35605f94178e        docker.io/redis@sha256:2a10443dced488731f0a3ed12e442c230d39b526f95ecb8e280cd1596705e822   "docker-entrypoint..."   8 minutes ago       Up 8 minutes                            k8s_redis_redis_default_cf58a748-4b01-11e8-baee-0050569817ee_0
9983e98b0149        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 8 minutes ago       Up 8 minutes                            k8s_POD_redis_default_cf58a748-4b01-11e8-baee-0050569817ee_0
8b275f7c03c3        2b736d06ca4c                                                                              "/opt/bin/flanneld..."   2 hours ago         Up 2 hours                              k8s_kube-flannel_kube-flannel-ds-5tgh7_kube-system_4679fc06-4ae3-11e8-bbe9-0050569817ee_1
13b5e5f69d69        77019aa0531a                                                                              "/usr/local/bin/ku..."   2 hours ago         Up 2 hours                              k8s_kube-proxy_kube-proxy-l8pbk_kube-system_4679a0d6-4ae3-11e8-bbe9-0050569817ee_1
ae9b7156a62a        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 2 hours ago         Up 2 hours                              k8s_POD_kube-flannel-ds-5tgh7_kube-system_4679fc06-4ae3-11e8-bbe9-0050569817ee_1
5ca34711fe92        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 2 hours ago         Up 2 hours                              k8s_POD_kube-proxy-l8pbk_kube-system_4679a0d6-4ae3-11e8-bbe9-0050569817ee_1
```

CONTAINER ID 「35605f94178e」が該当するコンテナとなります。
docker inspect コマンドで詳細を確認すると、コンテナがマウントしているパスを確認できます

```
[root@sugi-kubernetes110-node02 redis]# docker inspect 35605f94178e | grep Mounts -A43
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/cf58a748-4b01-11e8-baee-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro,rslave",
                "RW": false,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/cf58a748-4b01-11e8-baee-0050569817ee/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/cf58a748-4b01-11e8-baee-0050569817ee/containers/redis/f4b441cf",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "volume",
                "Name": "33ef4ea6079e4318f6086f878bc88d3c00150e73c3bb05166bb6634cde2aa023",
                "Source": "/var/lib/docker/volumes/33ef4ea6079e4318f6086f878bc88d3c00150e73c3bb05166bb6634cde2aa023/_data",　　　　<------------------------------- ここを確認
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/cf58a748-4b01-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/redis-persistent-storage",
                "Destination": "/data/redis",
                "Mode": "rslave",
                "RW": true,
                "Propagation": "rslave"
            }
        ],
```

「sugi-kubernetes110-node02」でSourceのディレクトリを確認します

```
[root@sugi-kubernetes110-node02 redis]# ls -la /var/lib/docker/volumes/33ef4ea6079e4318f6086f878bc88d3c00150e73c3bb05166bb6634cde2aa023/_data/
total 0
drwxr-xr-x 3 systemd-bus-proxy ssh_keys 19 Apr 29 01:33 .
drwxr-xr-x 3 root              root     19 Apr 29 01:33 ..
drwxr-xr-x 2 root              root      6 Apr 29 01:33 redis


[root@sugi-kubernetes110-node02 redis]# ls -la /var/lib/docker/volumes/33ef4ea6079e4318f6086f878bc88d3c00150e73c3bb05166bb6634cde2aa023/_data/redis/
total 0
drwxr-xr-x 2 root              root      6 Apr 29 01:33 .
drwxr-xr-x 3 systemd-bus-proxy ssh_keys 19 Apr 29 01:33 ..
```

redisコンテナのshellにログインします

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl exec -it redis /bin/bash
root@redis:/data# 
```

/data のディレクトリ構造を確認します。
「sugi-kubernetes110-node02」で確認した構造と一致します。

```
root@redis:/data# pwd
/data
root@redis:/data# 
root@redis:/data# ls -la
total 0
drwxr-xr-x 3 redis redis 19 Apr 28 16:33 .
drwxr-xr-x 1 root  root  17 Apr 28 16:33 ..
drwxrwxrwx 2 redis root   6 Apr 28 16:32 redis
```

コンテナ上で /data/redis/に適当なファイルを作成して、挙動を確認します

```
cat <<'EOF' > /data/redis/test.txt
can you look me?
EOF
```

volumeに emptyDirを指定しているので、Node02上にはデータが書き込まれない (そうなのか。ここまでチュートリアルを進めて、データが出力されないことに気が付きました)

```
[root@sugi-kubernetes110-node02 _data]# pwd
/var/lib/docker/volumes/33ef4ea6079e4318f6086f878bc88d3c00150e73c3bb05166bb6634cde2aa023/_data
[root@sugi-kubernetes110-node02 _data]# 
[root@sugi-kubernetes110-node02 _data]# ls -la redis/
total 0
drwxr-xr-x 2 root              root      6 Apr 29 01:33 .
drwxr-xr-x 3 systemd-bus-proxy ssh_keys 19 Apr 29 01:33 ..
```



## 複数コンテナ

Pod内に複数コンテナを含めた形式にして、volumeが共有されていることを確認します。

以下のようにmanifest file を作成します

- nginxコンテナと、redisコンテナの2種類を1Podに内包
- nginxコンテナの「/srv/www」とgit-monitorコンテナの「/data」はvolumeとして共有されている

```
cat <<'EOF' > /root/kube_yaml/101_walkthrough/pod-multiple.yaml
apiVersion: v1
kind: Pod
metadata:
  name: www
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    volumeMounts:
    - mountPath: /srv/www
      name: www-data
      readOnly: true
  - name: redis
    image: redis
    env:
    - name: GIT_REPO
      value: http://github.com/some/repo.git
    volumeMounts:
    - mountPath: /data
      name: www-data
  volumes:
  - name: www-data
    emptyDir: {}
EOF
```

Deploy

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl create -f /root/kube_yaml/101_walkthrough/pod-multiple.yaml
pod "www" created
```

状態確認

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl get pods -o wide
NAME      READY     STATUS              RESTARTS   AGE       IP        NODE
www       0/2       ContainerCreating   0          10s       <none>    sugi-kubernetes110-node01.localdomain
```

Deploy先Nodeの「」でDocker Inspectを実施し、Mountしているディレクトリを確認

```
[root@sugi-kubernetes110-node01 ~]# docker inspect 9e4add3d6de2 | grep Mounts -A43
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/containers/redis/83241a20",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data", <---------------------------- ここを確認
                "Destination": "/data",
                "Mode": "rslave",
                "RW": true,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro,rslave",
                "RW": false,
                "Propagation": "rslave"
            }
        ],
```

現在は空の状態です

```
[root@sugi-kubernetes110-node01 www-data]# pwd
/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data
[root@sugi-kubernetes110-node01 www-data]# 
[root@sugi-kubernetes110-node01 www-data]# ls -la
total 0
drwxrwxrwx 2 systemd-bus-proxy root  6 Apr 29 02:14 .
drwxr-xr-x 3 root              root 22 Apr 29 02:14 ..
```

wwwPodの詳細を確認します
2個のコンテナが内包されていることがわかります

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl describe pods www
Name:         www
Namespace:    default
Node:         sugi-kubernetes110-node01.localdomain/192.168.120.223
Start Time:   Sun, 29 Apr 2018 02:14:20 +0900
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.1.6
Containers:
  nginx:
    Container ID:   docker://389b82c1dfd62513c5e78344c0f38b79349bec873bf7e52c09baf44de381401d
    Image:          nginx:1.7.9
    Image ID:       docker-pullable://docker.io/nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 29 Apr 2018 02:14:47 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /srv/www from www-data (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q65hj (ro)
  redis:
    Container ID:   docker://9e4add3d6de2e53cc2b06a750f91082fb0547e68fb90445e2cbd80d6d58dba9d
    Image:          redis
    Image ID:       docker-pullable://docker.io/redis@sha256:2a10443dced488731f0a3ed12e442c230d39b526f95ecb8e280cd1596705e822
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 29 Apr 2018 02:15:13 +0900
    Ready:          True
    Restart Count:  0
    Environment:
      GIT_REPO:  http://github.com/some/repo.git
    Mounts:
      /data from www-data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q65hj (ro)
Conditions:
  Type           Status
  Initialized    True 
  Ready          True 
  PodScheduled   True 
Volumes:
  www-data:
    Type:    EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:  
  default-token-q65hj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q65hj
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From                                            Message
  ----    ------                 ----  ----                                            -------
  Normal  Scheduled              8m    default-scheduler                               Successfully assigned www to sugi-kubernetes110-node01.localdomain
  Normal  SuccessfulMountVolume  8m    kubelet, sugi-kubernetes110-node01.localdomain  MountVolume.SetUp succeeded for volume "www-data"
  Normal  SuccessfulMountVolume  8m    kubelet, sugi-kubernetes110-node01.localdomain  MountVolume.SetUp succeeded for volume "default-token-q65hj"
  Normal  Pulling                8m    kubelet, sugi-kubernetes110-node01.localdomain  pulling image "nginx:1.7.9"
  Normal  Pulled                 8m    kubelet, sugi-kubernetes110-node01.localdomain  Successfully pulled image "nginx:1.7.9"
  Normal  Created                8m    kubelet, sugi-kubernetes110-node01.localdomain  Created container
  Normal  Started                8m    kubelet, sugi-kubernetes110-node01.localdomain  Started container
  Normal  Pulling                8m    kubelet, sugi-kubernetes110-node01.localdomain  pulling image "redis"
  Normal  Pulled                 7m    kubelet, sugi-kubernetes110-node01.localdomain  Successfully pulled image "redis"
  Normal  Created                7m    kubelet, sugi-kubernetes110-node01.localdomain  Created container
  Normal  Started                7m    kubelet, sugi-kubernetes110-node01.localdomain  Started container
```

redisコンテナのshellにログインします
Pod名「www」に複数コンテナが存在するので、-c でコンテナ名を指定します

```
[root@sugi-kubernetes110-master01 101_walkthrough]# kubectl exec -it www -c redis /bin/bash
root@redis:/data# 
```

コンテナ上で /data/redis/に適当なファイルを作成して、挙動を確認します

```
cat <<'EOF' > /data/test.txt
can you look me?
EOF
```

nginxコンテナのshellにログインします

```
[root@sugi-kubernetes110-master01 ~]# kubectl exec -it www -c nginx /bin/bash
root@www:/# 
```

mount先を確認すると、test.txtファイルが存在し、共有されていることがわかります

```
root@www:/srv/www# pwd
/srv/www
root@www:/srv/www# 
root@www:/srv/www# cat test.txt 
can you look me?
```

Podが稼働している 「sugi-kubernetes110-node01」にて確認します
上に表示されているdockerプロセスのNAMEを確認すると、wwwポッドのnginxコンテナと、redisコンテナが存在していることがわかります

```
[root@sugi-kubernetes110-node01 www-data]# docker ps
CONTAINER ID        IMAGE                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
9e4add3d6de2        docker.io/redis@sha256:2a10443dced488731f0a3ed12e442c230d39b526f95ecb8e280cd1596705e822   "docker-entrypoint..."   18 minutes ago      Up 18 minutes                           k8s_redis_www_default_9737fa0b-4b07-11e8-baee-0050569817ee_0
389b82c1dfd6        docker.io/nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451   "nginx -g 'daemon ..."   19 minutes ago      Up 19 minutes                           k8s_nginx_www_default_9737fa0b-4b07-11e8-baee-0050569817ee_0
ea4f9101872b        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 19 minutes ago      Up 19 minutes                           k8s_POD_www_default_9737fa0b-4b07-11e8-baee-0050569817ee_0
b9d65d4ddb1c        2b736d06ca4c                                                                              "/opt/bin/flanneld..."   3 hours ago         Up 3 hours                              k8s_kube-flannel_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
5592ed89cbe0        77019aa0531a                                                                              "/usr/local/bin/ku..."   3 hours ago         Up 3 hours                              k8s_kube-proxy_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1
496d9d63cddd        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 3 hours ago         Up 3 hours                              k8s_POD_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
fab2fd0c0a3b        k8s.gcr.io/pause-amd64:3.1                                                                "/pause"                 3 hours ago         Up 3 hours                              k8s_POD_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1
```

docker inspectでマウントしているpathを確認します
redisコンテナ

```
[root@sugi-kubernetes110-node01 www-data]# docker inspect k8s_redis_www_default_9737fa0b-4b07-11e8-baee-0050569817ee_0 | grep Mounts -A33
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data",
                "Destination": "/data",
                "Mode": "rslave",
                "RW": true,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro,rslave",
                "RW": false,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/containers/redis/83241a20",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
```

nginxコンテナ

```
[root@sugi-kubernetes110-node01 www-data]# docker inspect k8s_nginx_www_default_9737fa0b-4b07-11e8-baee-0050569817ee_0 | grep Mounts -A45
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data",
                "Destination": "/srv/www",
                "Mode": "ro,rslave",
                "RW": false,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro,rslave",
                "RW": false,
                "Propagation": "rslave"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/containers/nginx/7b84551e",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "volume",
                "Name": "cc23bcbef53fa0551005cf23cd104a133571c1f72e982276b8193c98be10d121",
                "Source": "/var/lib/docker/volumes/cc23bcbef53fa0551005cf23cd104a133571c1f72e982276b8193c98be10d121/_data",
                "Destination": "/var/cache/nginx",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
```

両方のコンテナが、Nodeホスト側の「/var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data」をマウントしていることがわかります。
また、ホスト側でファイルが存在していることを確認できます

```
[root@sugi-kubernetes110-node01 www-data]# cat /var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data/test.txt 
can you look me?
[root@sugi-kubernetes110-node01 www-data]# ls -la /var/lib/kubelet/pods/9737fa0b-4b07-11e8-baee-0050569817ee/volumes/kubernetes.io~empty-dir/www-data/
total 4
drwxrwxrwx 2 systemd-bus-proxy root 22 Apr 29 02:31 .
drwxr-xr-x 3 root              root 22 Apr 29 02:14 ..
-rw-r--r-- 1 root              root 17 Apr 29 02:31 test.txt
```



# 参考URL

Kubernetes 101 公式チュートリアルページ
https://kubernetes.io/docs/user-guide/walkthrough/