このエントリはKubernetesアドベントカレンダー2014の5日目です。
いよいよKubernetesを動かします。
今日のところはまずは1台で動かします。 VirtualBox上で起動したCentOS7にインストールして動かしてみます。 2CPU、メモリ512MBで動かしましたが動作確認だけなら特に問題ありませんでした。
Kubernetes v0.5.3の hack/local-〜.sh
を使って起動します。
いろいろな起動方法がありますが、私にとってはこれが一番見通しがよかったのです。
CentOS7をインストール
まずは普通にインストールして起動します。
CentOS-7.0-1406-x86_64-Minimal
をインストールしました。
kickstartファイルの一部を抜粋するとこんな感じです。
lang ja_JP.UTF-8
keyboard jp106
network --onboot yes --device eth0 --bootproto dhcp --noipv6
network --onboot yes --device eth1 --bootproto dhcp --noipv6
firewall --service=ssh
selinux --disabled
timezone --utc Asia/Tokyo
自分でこれをVagrantBoxに固めたものを使ったので、ネットワーク設定は以下のとおりになってました。 全てデフォルトです。
- eth0(NAT): 10.0.2.0/24
- eth1(Hostonly): disconnected
なおdockerとKubernetesのアドレス帯は以下のとおりです。
- docker0: 172.17.0.0/16 ※コンテナ自体に割り当てられるIPアドレス
- Kubernetes(portal_net): 10.0.0.0/24 ※KubetnetesのServiceのendpointになるIPアドレス
インストール
firewall
を off
にして、 golang
と git
をyumでインストールして、
etcd
をインストールして、 etcd
を PATH
に入れて、
dockerをインストールしてKubernetesをインストールします。あら簡単。
firewall-cmd --set-default-zone=trusted
yum -y clean all
yum -y update
yum -y install golang
yum -y install git
git clone https://github.com/coreos/etcd.git /opt/etcd
cd /opt/etcd
git checkout v0.4.6
./build
cp -a bin/etcd /usr/local/sbin/.
yum -y install docker
systemctl enable docker.service
systemctl start docker.service
git clone https://github.com/GoogleCloudPlatform/kubernetes.git /opt/kubernetes
cd /opt/kubernetes
git checkout v0.5.3
起動
以下のとおり起動します。あら簡単。
hack/local-up-cluster.sh
のうち、
--portal_net
のところは他のネットワークと重複しないようにしないとなりません。
今回私は変更しませんでしたが、必要なら変更してください。
cd /opt/kubernetes
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://localhost:8080
hack/local-up-cluster.sh
初回起動時はツールのビルドが入るので多少時間がかかります。
[root@localhost kubernetes]# hack/local-up-cluster.sh
+++ Building go targets for linux/amd64:
cmd/kube-proxy
cmd/kube-apiserver
cmd/kube-controller-manager
cmd/kubelet
plugin/cmd/kube-scheduler
cmd/kubecfg
cmd/kubectl
cmd/kubernetes
cmd/e2e
cmd/integration
+++ Placing binaries
Starting etcd
+++ etcd:
{"action":"get","node":{"key":"/","dir":true}}
+++ apiserver:
{"kind":"PodList","creationTimestamp":null,"selfLink":"/api/v1beta1/pods","resourceVersion":6,"apiVersion":"v1beta1","items":[]}
Local Kubernetes cluster is running. Press Ctrl-C to shut it down.
Logs:
/tmp/kube-apiserver.log
/tmp/kube-controller-manager.log
/tmp/kubelet.log
/tmp/kube-proxy.log
/tmp/kube-scheduler.log
すると、こうなります
root 2528 0.0 0.2 113252 1180 pts/0 S+ 01:58 0:00 | \_ /bin/bash hack/local-up-cluster.sh
root 2806 0.2 1.2 331972 6032 pts/0 Sl+ 01:59 0:00 | \_ etcd -name test -data-dir /tmp/test-etcd.rpKb1u -addr 127.0.0.1:4001
root 2821 0.3 2.1 265832 10880 pts/0 Sl+ 01:59 0:00 | \_ /opt/kubernetes/_output/local/bin/linux/amd64/kube-apiserver -v=3 --address=127.0.0.1 --port=8080 --etcd_servers=http://127.0.0.1:4001 --portal_net=10.0.0.0/24 --cors_allowed_origins=/127.0.0.1(:[0-9]+)?$,/localhost(:[0-9]+)?$
root 2832 0.0 1.6 120964 8292 pts/0 Sl+ 01:59 0:00 | \_ /opt/kubernetes/_output/local/bin/linux/amd64/kube-controller-manager -v=3 --machines=127.0.0.1 --master=127.0.0.1:8080
root 2833 0.0 1.1 267628 5556 pts/0 Sl+ 01:59 0:00 | \_ /opt/kubernetes/_output/local/bin/linux/amd64/kubelet -v=3 --etcd_servers=http://127.0.0.1:4001 --hostname_override=127.0.0.1 --address=127.0.0.1 --port=10250
root 2834 0.1 1.0 200704 5400 pts/0 Sl+ 01:59 0:00 | \_ /opt/kubernetes/_output/local/bin/linux/amd64/kube-proxy -v=3 --master=http://127.0.0.1:8080
root 2835 0.0 1.0 118512 5296 pts/0 Sl+ 01:59 0:00 | \_ /opt/kubernetes/_output/local/bin/linux/amd64/kube-scheduler -v=3 --master=http://127.0.0.1:8080
動作確認
以下のようにして、 Minion
、 Pod
、 Service
、 ReplicationController
の一覧が確認できます。
v0.5までは kubecfg
を使う手順になってましたが、どうもv0.5からは kubectl
を使うようです
(でも今のところ kubecfg
も使えます)。
cd /opt/kubernetes
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://localhost:8080
cluster/kubectl.sh get minions
cluster/kubectl.sh get pods
cluster/kubectl.sh get services
cluster/kubectl.sh get replicationControllers
Minion
は自分しかいません。
[root@localhost kubernetes]# cluster/kubectl.sh get minions
NAME
127.0.0.1
Pod
はまだ1つもありません。
[root@localhost kubernetes]# cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
Service
はapiserverがあります。
なおソートされないので実行するたびに表示順が変わります。
[root@localhost kubernetes]# cluster/kubectl.sh get services
NAME LABELS SELECTOR IP PORT
kubernetes-ro component=apiserver,provider=kubernetes 10.0.0.45 80
kubernetes component=apiserver,provider=kubernetes 10.0.0.249 443
ReplicationController
はまだ1つもありません。
[root@localhost kubernetes]# cluster/kubectl.sh get replicationControllers
NAME IMAGE(S) SELECTOR REPLICAS
ちなみに kubectl
は -o json
とすることでjsonで取得もできます(yamlもいけます)。
[root@localhost kubernetes]# cluster/kubectl.sh get services -o json
{
"kind": "ServiceList",
"creationTimestamp": null,
"selfLink": "/api/v1beta1/services",
"resourceVersion": 7,
"apiVersion": "v1beta1",
"items": [
{
"id": "kubernetes-ro",
"uid": "a7da6401-7a2b-11e4-ab1a-08002716d207",
"creationTimestamp": "2014-12-02T23:01:04+09:00",
"selfLink": "/api/v1beta1/services/kubernetes-ro",
"resourceVersion": 3,
"namespace": "default",
"port": 80,
"protocol": "TCP",
"selector": {
"component": "apiserver",
"provider": "kubernetes"
},
"containerPort": 0,
"portalIP": "10.0.0.45"
},
{
"id": "kubernetes",
"uid": "a7da8a3d-7a2b-11e4-ab1a-08002716d207",
"creationTimestamp": "2014-12-02T23:01:04+09:00",
"selfLink": "/api/v1beta1/services/kubernetes",
"resourceVersion": 4,
"namespace": "default",
"port": 443,
"protocol": "TCP",
"selector": {
"component": "apiserver",
"provider": "kubernetes"
},
"containerPort": 0,
"portalIP": "10.0.0.249"
}
]
}
なおjsonでも items
への登場順はソートされません。
使ってみる
リポジトリ内に用意されている guestbook example を動かしてみます。
これはfrontend(php) x3、redis-master x1、redis-slave x2 という構成のサイトを想定しています。
段取りは以下のとおりです。
- redis-masterの
Pod
を作成 - redis-masterの
Service
を作成 - redis-spaveの
ReplicationController
を作成(このときPod
もできる) - redis-slaveの
Service
を作成 - frontendの
ReplicationController
を作成(このときPod
もできる)
redis-master
- redis-masterの
Pod
を作成 - redis-masterの
Service
を作成
cd /opt/kubernetes
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://localhost:8080
cluster/kubectl.sh create -f examples/guestbook/redis-master.json pods
cluster/kubectl.sh create -f examples/guestbook/redis-master-service.json services
create 〜 pods
した時に、 Pod
に必要なdocker imageを docker pull
するため、かなーり待ちます。
このときに kubectl.sh get pods
でSTATUSを見ると Pending
で、準備完了し起動したら Running
になります。
docker images -a
しながらヤキモキしましょう。
たまに docker pull
できなくて止まっている時があるので、あまりにもな場合はdockerのログを見て進んでいるか確認してみてください。
[root@localhost kubernetes]# cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
redis-master dockerfile/redis 127.0.0.1/ name=redis-master Pending
[root@localhost kubernetes]# cluster/kubectl.sh get services
[root@localhost kubernetes]# cluster/kubectl.sh get services
NAME LABELS SELECTOR IP PORT
kubernetes-ro component=apiserver,provider=kubernetes 10.0.0.45 80
kubernetes component=apiserver,provider=kubernetes 10.0.0.249 443
redis-master name=redis-master name=redis-master 10.0.0.98 6379
redis-slave
- redis-spaveの
ReplicationController
を作成(このときPod
もできる) - redis-slaveの
Service
を作成
cluster/kubectl.sh create -f examples/guestbook/redis-slave-controller.json create replicationControllers
cluster/kubectl.sh create -f examples/guestbook/redis-slave-service.json create services
こちらは create 〜 replicationControllers
したときに docker pull
します。
このとき Pod
の状態を見ると2つのredis-slaveのうち1つは unassigned
になってます。
これはredis-slaveの Pod
が多重度2になっているものの、
1台しかなくて配置先がないので困っている状態です。
いまは気にせず進みましょう。
配置先が足りなくても動くようにうまくやってくれるのがKubernetesですから気にしない。
[root@localhost kubernetes]# cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
redis-master dockerfile/redis 127.0.0.1/ name=redis-master Running
0260d085-7a2c-11e4-ab1a-08002716d207 brendanburns/redis-slave 127.0.0.1/ name=redisslave,uses=redis-master Running
02669c42-7a2c-11e4-ab1a-08002716d207 brendanburns/redis-slave name=redisslave,uses=redis-master Pending
frontend
- frontendの
ReplicationController
を作成(このときPod
もできる)
cluster/kubectl.sh create -f examples/guestbook/frontend-controller.json create replicationControllers
unassigned
以外の Pod
が全てRunningになれば起動完了です。
[root@localhost kubernetes]# cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
1afd8284-7a2c-11e4-ab1a-08002716d207 brendanburns/php-redis 127.0.0.1/ name=frontend,uses=redisslave,redis-master Running
1afef414-7a2c-11e4-ab1a-08002716d207 brendanburns/php-redis name=frontend,uses=redisslave,redis-master Pending
1affa738-7a2c-11e4-ab1a-08002716d207 brendanburns/php-redis name=frontend,uses=redisslave,redis-master Pending
redis-master dockerfile/redis 127.0.0.1/ name=redis-master Running
0260d085-7a2c-11e4-ab1a-08002716d207 brendanburns/redis-slave 127.0.0.1/ name=redisslave,uses=redis-master Running
02669c42-7a2c-11e4-ab1a-08002716d207 brendanburns/redis-slave name=redisslave,uses=redis-master Pending
ここまでできたら http://ホストのIPアドレス:8000
にアクセスするとguestbookの画面が見られます。
このときの 8000
は examples/guestbook/frontend-controller.json
で指定されています。
kubernetes/frontend-controller.json at v0.5.3 · GoogleCloudPlatform/kubernetes
あとは、GCPのHTTP LoadBalancerやELBみたいなのにこの ホストIP:8000
をぶらさげればサービスインです。
そういうのがない場合に、別の Pod
からシステム内APIみたいな感じでアクセスしたい要件とかがある場合は、frontendの Service
を作成をするとそのへんをうまく解決できるようになります。
cluster/kubectl.sh create -f examples/guestbook/frontend-service.json create services
確認
起動完了したあとのdockerのプロセスツリーはこんな感じになってます。
redis-master, redisslave, foregroundそれぞれに docker-proxy
と /pause
が起動しています。
root 2351 10.3 7.0 1272496 35340 ? Ssl 22:23 4:22 /usr/bin/docker -d --selinux-enabled
root 3851 0.0 1.0 207360 5456 ? Sl 23:02 0:00 \_ docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 6379 -container-ip 172.17.0.2 -container-port 6379
root 3854 0.0 0.0 265332 220 ? Ssl 23:02 0:00 \_ /pause
root 3917 0.3 0.4 35172 2336 ? Ssl 23:02 0:00 \_ redis-server *:6379
root 4054 0.0 1.0 207360 5492 ? Sl 23:03 0:00 \_ docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 6380 -container-ip 172.17.0.3 -container-port 6379
root 4056 0.0 0.0 265268 216 ? Ssl 23:03 0:00 \_ /pause
root 4102 0.0 0.1 4444 564 ? Ss 23:03 0:00 \_ /bin/sh -c /run.sh
root 4108 0.0 0.2 17968 1452 ? S 23:03 0:00 | \_ /bin/bash /run.sh
root 4109 0.2 0.4 35172 2272 ? Sl 23:03 0:00 | \_ redis-server *:6379
root 4232 0.0 1.0 207360 5488 ? Sl 23:04 0:00 \_ docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.17.0.4 -container-port 80
root 4237 0.0 0.0 265268 232 ? Ssl 23:04 0:00 \_ /pause
root 4304 0.0 0.1 4404 584 ? Ss 23:04 0:00 \_ /bin/sh -c /run.sh
root 4310 0.4 2.5 53148 12916 ? S 23:04 0:00 \_ /usr/bin/python /usr/bin/supervisord -n
root 4329 0.2 3.1 259964 15980 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
33 4336 0.0 1.3 260036 6648 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
33 4337 0.0 1.1 259988 5936 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
33 4338 0.0 1.1 259988 5936 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
33 4339 0.0 1.1 259988 5936 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
33 4340 0.0 1.1 259988 5936 ? S 23:04 0:00 \_ apache2 -D FOREGROUND
docker ps
はこんな感じです。
[root@localhost kubernetes]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebace1b18bcb brendanburns/php-redis:latest "/bin/sh -c /run.sh" About a minute ago Up About a minute k8s_php-redis.e604bf52_1afd8284-7a2c-11e4-ab1a-08002716d207.default.etcd_1afe8eef-7a2c-11e4-ab1a-08002716d207_e1c34d2a
66a48c43e9f1 kubernetes/pause:latest "/pause" About a minute ago Up About a minute 0.0.0.0:8000->80/tcp k8s_net.163f8d3c_1afd8284-7a2c-11e4-ab1a-08002716d207.default.etcd_1afe8eef-7a2c-11e4-ab1a-08002716d207_e78b1013
8dfc12a5dc4b brendanburns/redis-slave:latest "/bin/sh -c /run.sh" About a minute ago Up About a minute k8s_slave.5e8b35d1_0260d085-7a2c-11e4-ab1a-08002716d207.default.etcd_0261285b-7a2c-11e4-ab1a-08002716d207_d72a8f5d
0538052a80f2 kubernetes/pause:latest "/pause" About a minute ago Up About a minute 0.0.0.0:6380->6379/tcp k8s_net.feb08db6_0260d085-7a2c-11e4-ab1a-08002716d207.default.etcd_0261285b-7a2c-11e4-ab1a-08002716d207_3701b890
770d7fb4a7a2 dockerfile/redis:latest "redis-server /etc/r 2 minutes ago Up 2 minutes k8s_master.257ca611_redis-master.default.etcd_eab4a897-7a2b-11e4-ab1a-08002716d207_b3e34d02
9be75144fb68 kubernetes/pause:latest "/pause" 2 minutes ago Up 2 minutes 0.0.0.0:6379->6379/tcp k8s_net.7168dbe_redis-master.default.etcd_eab4a897-7a2b-11e4-ab1a-08002716d207_ef4cfaa0
docker inspect
や iptables -t nat -nv -L
などして、動作状態を詳しく見てみてください。
おまけ
書きながらふとリポジトリを見たら v0.6でstandalone modeが入るっぽい雰囲気 なコミットあって、このエントリもちょっとアレになるかもしれません。南無。