Kubernetes の学習 (2) ～ Pod の作成



# 概要
[前回](http://qiita.com/arturias/items/8f16194f164aeacbe67d)で Kubernetes のクラスターを構築したので、まずは Pod を作成してみます。

なお、前回は Kubernetes の v0.19.3 を使ってましたが、2015/7/21 に v1 が正式リリースされたのを受けて、今回は v1.0.1 を使っています。

## Pod とは？
いくつかのコンテナをグループ化したもの。Kubernetes は Pod 単位で作成、開始、停止、削除といった操作を行う(コンテナ単位では操作しない)。 そのため、１つのコンテナを作成したいときも、「コンテナが１つ含まれるPod」を作成することになる。

他に以下の特徴がある。

* Pod 内のコンテナは、同一ホスト上に配備される
* Pod 内のコンテナは、仮想NICやプロセステーブルを共有する  
  → つまり、同じIPを使えたり、互いのプロセスが見えたりする。


# 1. Kubernetes クラスターの構築
検証環境はAWS。作業用EC2インスタンスを起動して、そこから Kubernetes クラスタを構築。構築手順は[「Kubernetes の学習 (1) ～ AWS上でのクラスタ構築」](http://qiita.com/arturias/items/8f16194f164aeacbe67d)を参照。

構築後、作業用インスタンス上の kubectl コマンドにパスを通しておく。例えばこんな感じ。

```bash
export PATH=/home/ec2-user/kubernetes/platforms/linux/amd64:$PATH
```

なお、今回構築した環境は以下のようなもの。VPCが分かれているのは、Kubernetes のセットアップスクリプトが独自のVPCを作成するため。

![Kube-Cluster.png](https://qiita-image-store.s3.amazonaws.com/0/79316/a8f1d44a-0727-30ae-91d3-4bd00b20cfdd.png)


# 2. 基本的な Pod の作成～削除

## Pod の作成
作業用インスタンスで Pod の定義ファイルを作成する。まずは、nginx のコンテナ１つだけを含む Pod を定義。 なお、定義は yaml か json で書けるが、ここでは yaml で書いている。

pod-nginx.yaml：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
      - containerPort: 80
```

そして、Pod を作成。

```bash
kubectl create -f pod-nginx.yaml
```

作成されたか確認してみる。

```bash
$ kubectl get pod
NAME        READY     STATUS    RESTARTS   AGE
nginx-pod   1/1       Running   0          39s
```

## ノード(Minion)の確認
Pod が作成されたことは分かったが、コンテナがどこのノード(Minion)に作成されたかは Pod の詳細情報を表示すると分かる。

```bash
$ kubectl describe pods nginx-pod
Name:                       nginx-pod
Namespace:                  default
Image(s):                   nginx
Node:                       ip-172-20-0-232.ap-northeast-1.compute.internal/172.20.0.232
Labels:                     <none>
Status:                     Running
Reason:
Message:
IP:                         10.244.2.5
Replication Controllers:    <none>
Containers:
  nginx-container:
    Image:      nginx
    Limits:
      cpu:              100m
    State:              Running
      Started:          Sat, 01 Aug 2015 07:55:04 +0000
    Ready:              True
    Restart Count:      0
Conditions:
  Type          Status
  Ready         True
  
(以下略)
```

Pod が配備された Minion(172.20.0.232)が分かったので、作業用インスタンスから SSH で接続してみる。

```bash
$ ssh -i ~/.ssh/kube_aws_rsa ubuntu@52.68.181.10
```

<補足>

* 作業用インスタンスと Kubernetes のクラスターが異なるVPCに配置されているので、Private IP ではなく Public IP 経由で接続している。
* Kubernetes の [セットアップスクリプト](https://get.k8s.io/) で AWS にクラスターを構築した場合、スクリプトは ssh-keygen でキーペアを生成してそれを EC2 へインポートしている。各インスタンス(Master と Minion)にはインポートされたEC2のキーペアが割り当てられる。ssh-keygen で生成されたキーペアは、作業用インスタンスの ~/.ssh/kube_aws_rsa と kube_aws_rsa.pub なので、それを使ってログインできる。


Minion で実行されているコンテナを表示。確かに、nginx のコンテが動作している。

```bash
# Minon 内でコマンドを実行してます
ubuntu@ip-172-20-0-232:~$ sudo docker ps
CONTAINER ID        IMAGE                                                COMMAND                CREATED             STATUS              PORTS               NAMES
d3623b586044        nginx:latest                                         "nginx -g 'daemon of   12 minutes ago      Up 12 minutes                           k8s_nginx-container.45a349f6_nginx-pod_default_9e9fdeef-3822-11e5-b530-06570fe694c3_f999e4f1
(以下略： 他にも Kubernetes 自身が使用するコンテナが表示される)
```

## Pod への接続確認

作成された Pod には IP アドレスが割り振られている(下記コマンドの 10.244.2.5)。だが、この IP には、作業用インスタンスのような外部からは接続できない。

```bash
$ kubectl describe pods nginx-pod
Name:                       nginx-pod
Namespace:                  default
Image(s):                   nginx
Node:                       ip-172-20-0-232.ap-northeast-1.compute.internal/172.20.0.232
Labels:                     <none>
Status:                     Running
Reason:
Message:
IP:                         10.244.2.5  ★これ★
(以下略)
```

接続確認するには、いったん Master か Minon に乗り込むのが簡単だが、今度は Master に接続してみた。

```bash
$ ssh -i ~/.ssh/kube_aws_rsa ubuntu@54.64.5.95
```

Master 内から Pod の IP にアクセス。

```bash
# Minon 内でコマンドを実行してます
ubuntu@ip-172-20-0-232:~$ curl http://10.244.2.5
```

ちゃんと nginx から応答が返ってくれば成功。

## Pod の削除
作業用インスタンスで以下のコマンドを実行。

```bash
$ kubectl delete pod nginx-pod
pods/nginx-pod

$ kubectl get pod
NAME      READY     STATUS    RESTARTS   AGE
```

# 3. 複数コンテナを含む Pod の作成
複数のコンテナ(nginx と mongo) を含む Pod を作成してみる。作成するだけでなく、ネットワーク設定が共有されているかも確認する。まずは、Pod の定義を作成。

pod-nginx-mongo.yaml：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: www-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
      - containerPort: 80
    - name: mongo-container
      image: mongo
```

そして Pod を作成。

```bash
$ kubectl create -f pod-nginx-mongo.yaml
```

Pod の詳細を表示すると、コンテナが２つ表示される。

```bash
$ kubectl describe pods www-pod
Name:                       www-pod
Namespace:                  default
Image(s):                   nginx,mongo
Node:                       ip-172-20-0-232.ap-northeast-1.compute.internal/172.20.0.232
Labels:                     <none>
Status:                     Running
Reason:
Message:
IP:                         10.244.2.6
Replication Controllers:    <none>
Containers:
  nginx-container:
    Image:      nginx
    Limits:
      cpu:              100m
    State:              Running
      Started:          Sat, 01 Aug 2015 10:37:30 +0000
    Ready:              True
    Restart Count:      0
  mongo-container:
    Image:      mongo
    Limits:
      cpu:              100m
    State:              Running
      Started:          Sat, 01 Aug 2015 10:37:46 +0000
    Ready:              True
    Restart Count:      0
Conditions:
  Type          Status
  Ready         True
(以下略)
```

次に、これらのコンテナが配備されている Minion に乗り込んでみる。

```bash
$ ssh -i ~/.ssh/kube_aws_rsa 52.68.181.10
```

Minion 内で、実行されているコンテナを表示。確かに、同一 Minion 内で nginx と mongodb のコンテナが動作している。

```
ubuntu@ip-172-20-0-232:~$ sudo docker ps
CONTAINER ID        IMAGE                                                COMMAND                CREATED              STATUS              PORTS               NAMES
8797453df689        mongo:latest                                         "/entrypoint.sh mong   About a minute ago   Up About a minute                       k8s_mongo-container.8bc52932_www-pod_default_4f9c804f-3839-11e5-b530-06570fe694c3_81c950e5
ff67e24c8bce        nginx:latest                                         "nginx -g 'daemon of   2 minutes ago        Up 2 minutes                            k8s_nginx-container.45a349f6_www-pod_default_4f9c804f-3839-11e5-b530-06570fe694c3_677c7dfd
(以下略)
```

それぞれのコンテナ内のネットワーク設定がどうなっているか見てみる。ここでは、docker exec コマンドを使って、各コンテナ内で ip addr コマンドを実行させた。確かに同じ設定になっていることが分かる。

nginx コンテナ：

```bash
ubuntu@ip-172-20-0-232:~$ sudo docker exec 8797453df689 ip addr show eth0
13: eth0: <BROADCAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP
    link/ether 02:42:0a:f4:02:06 brd ff:ff:ff:ff:ff:ff
    inet 10.244.2.6/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fef4:206/64 scope link
       valid_lft forever preferred_lft forever
```

mongo コンテナ：

```bash
ubuntu@ip-172-20-0-232:~$ sudo docker exec ff67e24c8bce ip addr show eth0
13: eth0: <BROADCAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 02:42:0a:f4:02:06 brd ff:ff:ff:ff:ff:ff
    inet 10.244.2.6/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fef4:206/64 scope link
       valid_lft forever preferred_lft forever
```

# 参考サイト
[Kubernetes 101 - Kubectl CLI and Pods](http://kubernetes.io/v1.0/docs/user-guide/walkthrough/README.html)