Edited at

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


概要

前回で Kubernetes のクラスターを構築したので、まずは Pod を作成してみます。

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


Pod とは?

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

他に以下の特徴がある。


  • Pod 内のコンテナは、同一ホスト上に配備される

  • Pod 内のコンテナは、仮想NICやプロセステーブルを共有する

    → つまり、同じIPを使えたり、互いのプロセスが見えたりする。


1. Kubernetes クラスターの構築

検証環境はAWS。作業用EC2インスタンスを起動して、そこから Kubernetes クラスタを構築。構築手順は「Kubernetes の学習 (1) ~ AWS上でのクラスタ構築」を参照。

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

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

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

Kube-Cluster.png


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


Pod の作成

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

pod-nginx.yaml:

apiVersion: v1

kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80

そして、Pod を作成。

kubectl create -f pod-nginx.yaml

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

$ kubectl get pod

NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 39s


ノード(Minion)の確認

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

$ 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 で接続してみる。

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

<補足>


  • 作業用インスタンスと Kubernetes のクラスターが異なるVPCに配置されているので、Private IP ではなく Public IP 経由で接続している。

  • Kubernetes の セットアップスクリプト で AWS にクラスターを構築した場合、スクリプトは ssh-keygen でキーペアを生成してそれを EC2 へインポートしている。各インスタンス(Master と Minion)にはインポートされたEC2のキーペアが割り当てられる。ssh-keygen で生成されたキーペアは、作業用インスタンスの ~/.ssh/kube_aws_rsa と kube_aws_rsa.pub なので、それを使ってログインできる。

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

# 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 には、作業用インスタンスのような外部からは接続できない。

$ 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 に接続してみた。

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

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

# Minon 内でコマンドを実行してます

ubuntu@ip-172-20-0-232:~$ curl http://10.244.2.5

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


Pod の削除

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

$ 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:

apiVersion: v1

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

そして Pod を作成。

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

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

$ 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 に乗り込んでみる。

$ 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 コンテナ:

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 コンテナ:

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