連載
» 2015年10月23日 05時00分 公開

Docker運用管理製品/サービス大全(3):Docker管理ツール、Kubernetes、etcd、flannel、cAdvisorの概要とインストール、基本的な使い方 (4/6)

[澤井健,株式会社NTTデータ]

Kubernetesを使いクラスター環境を作成する手順(ホスト間連携)

 Kubernetesを使ってホスト間連携を行い、クラスター環境を作成する手順を記載します(参考:Kubernetesを自分で動かす@SoftLayer - インフラエンジニアway - Powered by HEARTBEATS)。使用するKubernetesのバージョンが古い(バージョン 0.5.3)ため、「単独ホストの構築」の章(バージョン 0.17)とは別環境で行っています。

 今回構築した環境は下記です。

 ホスト間をまたいでコンテナーを連携させる場合は下記の3つの設定が必要になります。

  1. 各ホストが重複しないアドレス帯をdocker0に割り当てる
  2. 起動したMinionのIPアドレスを知り、適切にコンテナーを配置する
  3. 各ホストがどのネットワークアドレス帯をdocker0に割り当てているかを把握しルーティングする

 この中で1、3を解決するのが一般的にはflannelで、2を解決するのがKubernetesの役割です。

 下記手順のdockerコマンドなどは注釈がなければ全てローカルのLinux環境から実行しています。

ホスト間連携の構築環境

 AWSの「RightImage_CentOS_7.0_x64_v14.1.4_HVM_EBS」のイメージを使って作成しました。MasterとMinionの2つのAmazon EC2インスタンスを作成しています。セキュリティグループはSSH、TCP8000、Master-Minionを全ポート許可で解放しています。

 MasterとMinionのネットワーク設定は下記です。

<IP-Master>
kube-master01
Master
<IP-Minion>
kube-minion01
Minion

Master/Minion共通の設定とインストール

 まずは、Kubernetesのインストールです。インストールされている全てのパッケージを最新の状態にします。

yum -y clean all
yum -y update

SELinuxなどのインストール

 ファイアウオールの制御を行うためにSELinuxなどをインストールします。

yum -y install selinux-policy-targeted policycoreutils-python
yum -y install e4fsprogs

 ファイアウオールを無効化します。

systemctl stop firewalld
systemctl disable firewalld
 
setenforce 0

 エディターで「/etc/sysconfig/selinux」の「SELINUX=enforcing」を「SELINUX=disabled」に変更します。

 ホスト名を設定します。

hostnamectl set-hostname kube-master01 <--- Master側
 
hostnamectl set-hostname kube-minion01 <--- Minion側
 
echo '<IP-Master> kube-master01' | tee -a /etc/hosts
echo '1<IP-Minion> kube-minion01' | tee -a /etc/hosts
 
reboot

 Kubernetesが使用するGo言語、Git、連携ソフトウエアであるflannel、etcd、Dockerをインストールします(今回の手順では下記バージョンでのみ動作します)。

yum -y install golang
yum -y install git
 
git clone https://github.com/coreos/flannel.git /opt/flannel
cd /opt/flannel
git checkout v0.1.0
./build
 
git clone https://github.com/coreos/etcd.git /opt/etcd
cd /opt/etcd
git checkout v0.4.6
./build
 
git clone https://github.com/coreos/etcdctl.git /opt/etcdctl
cd /opt/etcdctl
git checkout v0.4.5
./build
 
yum -y install docker
 
git clone https://github.com/GoogleCloudPlatform/kubernetes.git /opt/kubernetes
cd /opt/kubernetes
git checkout v0.5.3

Masterの設定とKubernetes Masterの起動

 Masterにログインし、「/opt/kubernetes/hack/local-up-master.sh」を作成します。

cd /opt/kubernetes
 
sed -e '36,37s/^/#/' -e 's/--machines=".*"/--machines="${MACHINES}"/' -e '111,112s/".*"/"${MYADDRESS}"/' -e '145,146s/^/#/' -e 's@--portal_net=".*"@--portal_net="172.31.0.0/16"@' hack/local-up-cluster.sh > hack/local-up-master.sh
chmod a+x hack/local-up-master.sh

 このlocal-up-master.shは下記の部分を変更しています。各コマンドのオプションも記載しておきます。

  • etcdの起動/停止部分をコメントアウト
  • kube-apiserverの「-portal_net」を「10.0.0.0/24」から「172.31.0.0/16」に変更
kube-apiserverのオプション
-address HTTP APIの待ち受けアドレス
-port HTTP APIの待ち受けポート
-etcd-servers etcdのエンドポイント(「,」区切りで複数指定可能)
-portal_net KubernetesがServiceのエンドポイントに割り当てるIPアドレスのネットワークアドレス帯(他のネットワークアドレス帯と重複しないように設定する)
-cors_allowed_origins Cross Origin Resource Sharingの許可Originのパターン(正規表現。「,」区切りで複数指定可能)
-v ログレベル
  • kube-controller-managerの「--machines」を${MACHINES}に変更
kube-controller-managerのオプション
-machines クラスターに参加するMinion
-master kube-apiserverのエンドポイント
-v ログレベル
  • kubeletの「--hostname_override」と「--address」を${MYADDRESS}に変更
kubeletのオプション
-address kubeletの待ち受けアドレス(default: 127.0.0.1)
-port kubeletの待ち受けポート(default: 10250)
-hostname_override ホスト名。マスターが認識しているホスト名と整合していないとkubeletがPodの割り当てを自分宛てと解釈できず無視してしまうので、注意(default:ホスト名)
-etcd-servers etcdのエンドポイント(「,」区切りで複数指定可能)
-v ログレベル

 各種環境変数を設定します。

export MASTER_HOST=`hostname`
export LOCAL_IF=eth0
export API_HOST=$(ip a show ${LOCAL_IF:?} | grep -w inet | awk '{print $2}' | cut -d / -f 1)
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://localhost:8080
export MYADDRESS=$(ip a show ${LOCAL_IF:?} | grep -w inet | awk '{print $2}' | cut -d / -f 1)
export MACHINES=$(getent hosts | grep "kube" | awk '{print $1}' | xargs echo | sed 's/ /,/g')
 
echo ${MASTER_HOST}
echo ${LOCAL_IF}
echo ${API_HOST}
echo ${KUBERNETES_PROVIDER}
echo ${KUBERNETES_MASTER}
echo ${MYADDRESS}
echo ${MACHINES}
 
[root@kube-master01 kubernetes]# echo ${MASTER_HOST}
kube-master01
[root@kube-master01 kubernetes]# echo ${LOCAL_IF}
eth0
[root@kube-master01 kubernetes]# echo ${API_HOST}
<IP-Master>
[root@kube-master01 kubernetes]# echo ${KUBERNETES_PROVIDER}
local
[root@kube-master01 kubernetes]# echo ${KUBERNETES_MASTER}
http://kube-master01:8080
[root@kube-master01 kubernetes]# echo ${MYADDRESS}
<IP-Master>
[root@kube-master01 kubernetes]# echo ${MACHINES}
<IP-Master>,<IP-Minion>

 etcd、flanneld、Docker、Kubernetesの順に起動させます。

/opt/etcd/bin/etcd -name `uname -n` -data-dir /tmp/etcd-data -addr ${MYADDRESS:?}:4001 -peer-addr ${MYADDRESS}:7001 >/tmp/etcd.log 2>&1 &
view /tmp/etcd.log
 
/opt/etcdctl/bin/etcdctl mk /coreos.com/network/config '{"Network":"172.31.0.0/16"}'
 
/opt/flannel/bin/flanneld -ip-masq=true -etcd-endpoint=http://${API_HOST:?}:4001 >/tmp/flanneld.log 2>&1 &
 
view /tmp/flanneld.log
 
source /run/flannel/subnet.env
/usr/bin/docker -d --selinux-enabled --bip=${FLANNEL_SUBNET:?} --mtu=${FLANNEL_MTU:?} --host=unix:///var/run/docker.sock >/tmp/docker.log 2>&1 &
 
view /tmp/docker.log 
 
hack/local-up-master.sh

 なお、dockerコマンドのオプションで使用している、「--bip=docker0」が利用するアドレス帯で、「--mtu=docker0」が使用する最大パケット長です。

 etcdコマンドのオプションは下記のようになっています。

etcdのオプション
-peer-addr 各ノード間で通信するためのポート
-addr クライアントが利用するAPIのポート
-data-dir 各ノードの状態をファイル保持するためのディレクトリ
-name 各ノードの名前
-peers クラスター内の他のノード

Minionの設定とKubernetes-Minionの起動

 Minionにログインし、「/opt/kubernetes/hack/local-up-minion.sh」を作成します。

cd /opt/kubernetes
 
sed -e '36,37s/^/#/' -e '87,105s/^/# /' -e '122,126s/^/# /' -e '130,131s/^/# /' -e '134s/^/# /' -e '143s/^/# /' -e '139,140s/^/# /' -e '111,112s/".*"/"${MYADDRESS}"/' -e '145,146s/^/#/' -e 's/127.0.0.1:4001/${API_HOST:?}:4001/' hack/local-up-cluster.sh > hack/local-up-minion.sh
chmod a+x hack/local-up-minion.sh

 このlocal-up-master.shは下記の部分を変更しています。

  • etcdの起動/停止部分をコメントアウト
  • kube-apiserver、kube-controll-manager、kube-schedulerの起動/停止部分のコメントアウト
  • kubeletの--etcd_serverを${API_HOST}に変更(Masterのetcdを見るように変更)
  • kubeletの--hostname_overrideと--addressを${MYADDRESS}に変更

 各種環境変数を設定します。

export MASTER_HOST=kube-master01
export LOCAL_IF=eth0
export API_HOST=$(getent hosts kube-master01 | awk '{print $1}')
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://${API_HOST:?}:8080
export MYADDRESS=$(ip a show ${LOCAL_IF:?} | grep inet | awk '{print $2}' | cut -d / -f 1)
export MACHINES=$(getent hosts | grep "kube" | awk '{print $1}' | xargs echo | sed 's/ /,/g')
 
echo ${MASTER_HOST}
echo ${LOCAL_IF}
echo ${API_HOST}
echo ${KUBERNETES_PROVIDER}
echo ${KUBERNETES_MASTER}
echo ${MYADDRESS}
echo ${MACHINES}
 
[root@kube-minion01 kubernetes]# echo ${MASTER_HOST}
kube-master01
[root@kube-minion01 kubernetes]# echo ${LOCAL_IF}
eth0
[root@kube-minion01 kubernetes]# echo ${API_HOST}
<IP-Master>
[root@kube-minion01 kubernetes]# echo ${KUBERNETES_PROVIDER}
local
[root@kube-minion01 kubernetes]# echo ${KUBERNETES_MASTER}
http://<IP-Master>:8080
[root@kube-minion01 kubernetes]# echo ${MYADDRESS}
<IP-Minion>
[root@kube-minion01 kubernetes]# echo ${MACHINES}
<IP-Minion>,<IP-Master>

 flanneld、Docker、Kubernetesの順に起動させます。

/opt/flannel/bin/flanneld -ip-masq=true -etcd-endpoint=http://${API_HOST:?}:4001 >/tmp/flanneld.log 2>&1 &
 
view /tmp/flanneld.log
 
source /run/flannel/subnet.env
 
/usr/bin/docker -d --selinux-enabled --bip=${FLANNEL_SUBNET:?} --mtu=${FLANNEL_MTU:?} --host=unix:///var/run/docker.sock >/tmp/docker.log 2>&1 &
 
view /tmp/docker.log
 
hack/local-up-minion.sh

Master/MinionでKubernetes起動後

 Master環境に新しくTera Termなどターミナルエミュレーターを開き、下記のコマンドでminionを確認します。

export MASTER_HOST=`hostname`
export LOCAL_IF=eth0
export API_HOST=$(ip a show ${LOCAL_IF:?} | grep -w inet | awk '{print $2}' | cut -d / -f 1)
export KUBERNETES_PROVIDER=local
export KUBERNETES_MASTER=http://kube-master01:8080
export MYADDRESS=$(ip a show ${LOCAL_IF:?} | grep -w inet | awk '{print $2}' | cut -d / -f 1)
export MACHINES=$(getent hosts | grep "kube" | awk '{print $1}' | xargs echo | sed 's/ /,/g')
 
echo ${MASTER_HOST}
echo ${LOCAL_IF}
echo ${API_HOST}
echo ${KUBERNETES_PROVIDER}
echo ${KUBERNETES_MASTER}
echo ${MYADDRESS}
echo ${MACHINES}
 
cd /opt/kubernetes
cluster/kubecfg.sh list /minions
[root@kube-master01 kubernetes]# cluster/kubecfg.sh list /minions
Minion identifier
----------
<IP-Master>
<IP-Minion>

 Master/Minion環境でdocker0が重複しないアドレス帯を持っていることを確認してください。

[root@kube-master01 kubernetes]# ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8973 qdisc noqueue state UP
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
[root@kube-minion01 ~]# ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8973 qdisc noqueue state UP
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.31.101.1/24 scope global docker0
       valid_lft forever preferred_lft forever

Guestbookサンプルの実行

 Master環境で/opt/kubernetes/examples/guestbook/redis-master.jsonの「"image": "dockerfile/redis",」を「"image": "redis",」に書き換えます。

 Podを作成します。

cluster/kubecfg.sh -c examples/guestbook/redis-master.json create pods
 
cluster/kubecfg.sh list pods

 Serviceを作成します。

cluster/kubecfg.sh -c examples/guestbook/redis-master-service.json create services
cluster/kubecfg.sh -c examples/guestbook/redis-slave-service.json create services
 
cluster/kubecfg.sh list services

 replicationControllersを作成します。

cluster/kubecfg.sh -c examples/guestbook/redis-slave-controller.json create replicationControllers
cluster/kubecfg.sh -c examples/guestbook/frontend-controller.json create replicationControllers
 
 cluster/kubecfg.sh list replicationControllers

 生成されたPodを確認します。

cluster/kubecfg.sh list /pods
 
[root@kube-master01 kubernetes]# cluster/kubecfg.sh list /pods
Name                                   Image(s)                   Host                Labels                                       Status
----------                             ----------                 ----------          ----------                                   ----------
4936c051-f0ae-11e4-8556-063d2a87f87c   brendanburns/php-redis     <IP-Master>/       name=frontend,uses=redisslave,redis-master   Running
493807af-f0ae-11e4-8556-063d2a87f87c   brendanburns/php-redis     <IP-Minion>/      name=frontend,uses=redisslave,redis-master   Running
49384497-f0ae-11e4-8556-063d2a87f87c   brendanburns/php-redis     <unassigned>        name=frontend,uses=redisslave,redis-master   Pending
redis-master                           redis                      <IP-Minion>/      name=redis-master                            Running
187e7949-f0ae-11e4-8556-063d2a87f87c   brendanburns/redis-slave   <IP-Master>/       name=redisslave,uses=redis-master            Running
187f9554-f0ae-11e4-8556-063d2a87f87c   brendanburns/redis-slave   <IP-Minion>/      name=redisslave,uses=redis-master            Running
[root@kube-minion01 kubernetes]#  cluster/kubecfg.sh list services
Name                Labels              Selector                                  IP                  Port
----------          ----------          ----------                                ----------          ----------
kubernetes                              component=apiserver,provider=kubernetes   <IP>       443
kubernetes-ro                           component=apiserver,provider=kubernetes   <IP>      80
redis-master        name=redis-master   name=redis-master                         <IP>      6379
redisslave          name=redisslave     name=redisslave                           <IP>         6379
[root@kube-minion01 kubernetes]#  cluster/kubecfg.sh list replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
frontendController     brendanburns/php-redis     name=frontend       3
redisSlaveController   brendanburns/redis-slave   name=redisslave     2

 これで、Master/Minion両方のホストで実行されていることが確認できます。WebブラウザーでMaster/Minionの両方の8000ポートにアクセスしてGuestBookが表示されることを確認してください。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。