Help us understand the problem. What is going on with this article?

kubeadm で kubernetes v1.8 + Flannel をインストール

More than 1 year has passed since last update.

kubeadm について

kubeadm は kubernetes をデプロイするためのツール。公式ドキュメントでも紹介されているツールで、まだベーダ版だが kubernetes クラスタを構築する際には今後はこのツールを使っていくことになる。他には Minikube というツールもあるが、こちらはローカルで kubernetes を構築するためのもので、主に開発者に使われることを想定している。

環境

自分の試した環境は以下のとおり。

  • ホストOS: MacOS Sierra
  • ゲストOS: Ubuntu 16.04.2 LTS
  • VirtualBox 5.1.14
  • Vagrant 1.9.1

用意した VM は3つ。マスターノード用に 2vCPU, 4GB の VM が1つ、ワーカーノード用に 1vCPU, 2GB の VM が2つ、それぞれのホスト名は manager, host1, host2 とする。各 VM のデフォルトの NIC はホストへの NAT になっていて、インターネットへのアクセスに使用する。これとは別に private_network を用意し、それぞれの IP アドレスを下記の通り 192.168.33.10, 192.168.33.11, 192.168.33.12 とする。Kubernetes のすべての通信はこの NIC を使用する。

       +---------------------------------------------+
       |                     NAT                     |
       +--+-------------------+-------------------+--+
          |                   |                   |
+---------+-------+  +--------+--------+  +-------+---------+
| enp0s3 10.0.2.15|  | enp0s3 10.0.2.15|  | enp0s3 10.0.2.15|
|                 |  |                 |  |                 |
|                 |  |                 |  |                 |
|                 |  |                 |  |                 |
|     manager     |  |     host1       |  |     host2       |
|                 |  |                 |  |                 |
|                 |  |                 |  |                 |
| enp0s8          |  | enp0s8          |  | enp0s8          |
| 192.168.33.10   |  | 192.168.33.11   |  | 192.168.33.12   |
+---------+-------+  +--------+--------+  +-------+---------+
          |                   |                   |
       +--+-------------------+-------------------+--+
       |               192.168.33.0/24               |
       +---------------------------------------------+


kubeadm インストール

この章で実施している内容をマスター、ワーカーの各ノードで実行する。基本的には公式ドキュメントの最新情報を確認して欲しいが、いくつか補完する。

/etc/hosts ファイルの編集

各ノードの /etc/hosts に下記の通り、ホスト名に対応する IP アドレスを追記する。このときループバックアドレス以外の別の IP アドレス (e.g. 10.0.2.15) とホスト名を紐付ける記述はしてはいけない。

manager ノード

/etc/hosts
192.168.33.10 manager

host1 ノード

/etc/hosts
192.168.33.11 host1

host2 ノード

/etc/hosts
192.168.33.12 host2

Docker インストール

Ubuntu 公式リポジトリの docker を使うのが手間がなくて良いが、出来るだけ新しいものを使いたいので自分は docker リポジトリのものを使った。公式ドキュメントでは17.09を指定しているが、kubeadm が公式にサポートしているのは17.03で、kubeadm 実行時に warning も出るので自分は17.03を使った。

Ubuntu リポジトリの Docker を使う場合

$ apt-get update
$ apt-get install -y docker.io

Docker リポジトリの Docker を使う場合

$ apt-get update
$ apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
$ add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable"
$ apt-get update && apt-get install -y docker-ce=17.03.0~ce-0~ubuntu-xenial

kubeadm, kubectl, kubelet インストール

$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl

kubeadm 実行

今回マスターノードが使用する IP アドレスは 192.168.33.10 で、このアドレスを指定するには --apiserver-advertise-address を使用する。またマニュアルには flannel 使用時には --pod-network-cidr を指定するようにと記載があるため、そのように指定する。

$ sudo kubeadm init --apiserver-advertise-address=192.168.33.10 --pod-network-cidr=10.244.0.0/16

デプロイ後に表示される kubeadm join コマンドはメモしておくこと。後で、このコマンドと引数を使ってワーカーノードをクラスタに追加します。

kubeadm join --token 07953d.ad9fc560f05ae297 192.168.33.10:6443 --discovery-token-ca-cert-hash sha256:23b6e03c9d4c3cd752c29f3fb0bb0f04923dd69e39020d995b976f93607316e1

kube config ファイルをコピーする。

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

これで基本的なプロセスのデプロイは完了。 kubectl コマンドでノードの状態や pod の情報を取得してみる。

$ kubectl get nodes
NAME      STATUS     ROLES     AGE       VERSION
manager   NotReady   master    18m       v1.8.4

$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                              READY     STATUS    RESTARTS   AGE       IP              NODE
kube-system   etcd-manager                      1/1       Running   0          18m       192.168.33.10   manager
kube-system   kube-apiserver-manager            1/1       Running   0          18m       192.168.33.10   manager
kube-system   kube-controller-manager-manager   1/1       Running   0          18m       192.168.33.10   manager
kube-system   kube-dns-545bc4bfd4-pc5qh         0/3       Pending   0          19m       <none>          <none>
kube-system   kube-proxy-8fzzd                  1/1       Running   0          19m       192.168.33.10   manager
kube-system   kube-scheduler-manager            1/1       Running   0          18m       192.168.33.10   manager

マスターノードのステータスはまだ NotReady です。これは kube-dns がまだ動いていない、NW が未設定であるためです。

flannel のデプロイ

通常は下記のコマンドを実行すれば終わりですが、問題2 でも取り上げている内容の通り kube-flannel.yml の修正が必要になります。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml

kube-flannel.yml をダウンロードし、flanneld の起動オプションに NIC 指定を追記します。

kube-flannel.yaml
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr", "--iface=enp0s8"]

編集し終わったら kubectl apply で NW 設定を適用します。

$ kubectl apply -f kube-flannel.yml

これでノードのステータスは Ready になります。

$ kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
manager   Ready     master    35m       v1.8.4

$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                              READY     STATUS    RESTARTS   AGE       IP              NODE
kube-system   etcd-manager                      1/1       Running   0          34m       192.168.33.10   manager
kube-system   kube-apiserver-manager            1/1       Running   0          34m       192.168.33.10   manager
kube-system   kube-controller-manager-manager   1/1       Running   0          33m       192.168.33.10   manager
kube-system   kube-dns-545bc4bfd4-pc5qh         3/3       Running   0          34m       10.244.0.8      manager
kube-system   kube-flannel-ds-tggqx             1/1       Running   0          1m        192.168.33.10   manager
kube-system   kube-proxy-8fzzd                  1/1       Running   0          34m       192.168.33.10   manager
kube-system   kube-scheduler-manager            1/1       Running   0          34m       192.168.33.10   manager

ワーカーノードをクラスタに追加

マスターノードの準備が終わったので、あとは各ノードでメモしておいた join コマンドをそのまま実行していくだけです。

$ sudo kubeadm join --token 07953d.ad9fc560f05ae297 192.168.33.10:6443 --discovery-token-ca-cert-hash sha256:23b6e03c9d4c3cd752c29f3fb0bb0f04923dd69e39020d995b976f93607316e1

完了。

$ kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
host1     Ready     <none>    13m       v1.8.4
host2     Ready     <none>    13s       v1.8.4
manager   Ready     master    52m       v1.8.4

問題

今回の構築でいくつか問題にハマったので共有します。

問題1

各 pod の IP アドレスが各ノードのデフォルトインターフェースのアドレスになっている。下記を見てわかる通り manager も host1 もホストに対して NAT をしている NIC がデフォルトのため同じ IP アドレス (10.0.2.15) になってしまっている。この状態だとマスターノードから各ノード上の pod のログが取れないなど色々と支障が出る。

$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                              READY     STATUS    RESTARTS   AGE       IP           NODE
kube-system   etcd-manager                      1/1       Running   0          5m        10.0.2.15    manager
kube-system   kube-apiserver-manager            1/1       Running   0          5m        10.0.2.15    manager
kube-system   kube-controller-manager-manager   1/1       Running   0          5m        10.0.2.15    manager
kube-system   kube-dns-545bc4bfd4-m2cm4         3/3       Running   0          6m        10.244.0.6   manager
kube-system   kube-flannel-ds-cljpz             1/1       Running   0          2m        10.0.2.15    manager
kube-system   kube-flannel-ds-p9lfd             1/1       Running   0          10s       10.0.2.15    host1
kube-system   kube-proxy-cphtp                  1/1       Running   0          6m        10.0.2.15    manager
kube-system   kube-proxy-hs6b2                  1/1       Running   0          10s       10.0.2.15    host1
kube-system   kube-scheduler-manager            1/1       Running   0          5m        10.0.2.15    manager

この解決策の1つとして kubelet を起動する際に --node-ip というオプションで任意の IP アドレスを渡すことができるが、kubeadm では対応してない。指定されていない場合は /etc/hosts に設定されているホスト名の IP アドレスが使用されるため、あらかじめ各ノードで kubernetes 用に使用する IP アドレスを /etc/hosts に登録する必要がある。

/etc/hosts
kubernetesで使用するIPアドレス ホスト名

問題2

Flannel が VXLAN トンネルを張る際にデフォルトの NIC を使う。マシン同士が疎通可能ならそれでも問題はないが、今回のような環境 (NAT) だと VXLAN が張れないので flanneld 起動時に使用する NIC を指定する必要がある。今回は下記のように flannel を適用する際に使用した kube-flannel.yaml を直接編集した。

kube-flannel.yaml
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr", "--iface=xxx" ]

問題3

任意の pod が起動してるノードから、その pod への通信は通るが、別のノードからその pod への通信が通らない。これは Docker v1.13 以降と Flannel の組み合わせのバグで、自分がハマっていたときには未修正だったが、修正はすでにされている。kube-flannel.ymlもこの修正が入ったイメージ (v0.9.1-amd64) が指定されているので、今からやる人は特にハマらないはず。しかし、自分がハマった時は、tcpdump祭りで見つけられず、泣きながら iptables のルールを読んで、flannel のソースコード読んで原因を突き止めたので、v0.9.0 でハマって諦めた人用にメモとして残しておく。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away