Edited at

etcdクラスタを組んでdockerのオーバレイネットワークを手動構築

More than 1 year has passed since last update.

わりと今更ですが初心者で何がセオリーなのかもよくわからず右往左往しつつ調べながらなんとなくできたので備忘録を。

なんでetcdかというと好みの問題というかDocker社がkubernetesデフォルトにするとかなんとかの話をみかけたのとswarmよりはシンプルかなと思ったため。(現時点だと公式サイトのマニュアルはetcdじゃなくてConsulだったりなど)

なんでそれをしたかったかというとrancherをHAでたてるために要るのかなってだけでした。kubernetes on rancher on kubernetesみたいな意味わかんないことになるのもどうなのかと思って一応シンプルにしたかったというか。

初心者なのでよくわかっていませんのでツッコミがあればコメントをください。


etcdと種類

分散KVSの一種。

設定ファイルにクラスタ構成情報を書いとくタイプのスタティックと自律的に見つけ出す感じのディスカバリーという方式を把握しており、残念ながらstaticには成功しなかったのでディスカバリーの方法だけ書きます。


etcdのインストール

環境 Ubuntu16LTS

# apt-get install etcd

# curl https://discovery.etcd.io/new?size=2  ##discoveryに出てきた値を指定
# systemctl edit etcd.service
# vi /etc/systemd/system/etcd.service.d/override.conf

### **host01**
ExecStart=
ExecStart=/usr/bin/etcd --data-dir=/var/lib/etcd/test --name host01 --initial-advertise-peer-urls http://10.0.0.4:2380 --listen-peer-urls http://10.0.0.4:2380 --advertise-client-urls http://10.0.0.4:2379 --listen-client-urls http://10.0.0.4:2379 --discovery https://discovery.etcd.io/c60fc6c755455369b8452b7d441***** --initial-cluster-state new --initial-cluster-token etcd-cluster-1

### **host02**
ExecStart=
ExecStart=/usr/bin/etcd --data-dir=/var/lib/etcd/test --name host02 --initial-advertise-peer-urls http://10.0.2.5:2380 --listen-peer-urls http://10.0.2.5:2380 --advertise-client-urls http://10.0.2.5:2379 --listen-client-urls http://10.0.2.5:2379 --discovery https://discovery.etcd.io/c60fc6c755455369b8452b7d44***** --initial-cluster-state new --initial-cluster-token etcd-cluster-1

# systemctl daemon-reload
# systemctl restart etcd.service
# systemctl status etcd.service
# journalctl -xe -u etcd.service

etcのしたの設定ファイル編集してもよかったのですがプロセスみた時に設定値が出なくてわかりづらかったのでsystemdのユニットファイルに差分書きました。


etcdクラスタの確認

# export ENDPOINTS='10.0.0.4:2379,10.0.2.5:2379'

# echo $ENDPOINTS
10.0.0.4:2379,10.0.2.5:2379
# etcdctl --endpoint=$ENDPOINTS member list
4f773599dea3d130: name=host01 peerURLs=http://10.0.0.4:2380 clientURLs=http://10.0.0.4:2379
8155bbd84f4a1316: name=host02 peerURLs=http://10.0.2.5:2380 clientURLs=http://10.0.2.5:2379

# etcdctl --endpoint=$ENDPOINTS cluster-health
member 4f773599dea3d130 is healthy: got healthy result from http://10.0.0.4:2379
member 8155bbd84f4a1316 is healthy: got healthy result from http://10.0.2.5:2379
cluster is healthy

なんかポート開いてないかも?な確認方法

# dpkg -l |grep ufw

ii ufw 0.35-0ubuntu2 all program for managing a Netfilter firewall
# ufw status numbered
Status: inactive
# iptables -nL

host02:~# netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2058/sshd
tcp 0 0 127.0.0.1:25225 0.0.0.0:* LISTEN 38161/ruby
tcp 0 0 10.0.2.5:2379 0.0.0.0:* LISTEN 71228/etcd
tcp 0 0 10.0.2.5:2380 0.0.0.0:* LISTEN 71228/etcd
tcp 0 0 0.0.0.0:25324 0.0.0.0:* LISTEN 38161/ruby
tcp6 0 0 :::22 :::* LISTEN 2058/sshd

host01:~# nc -vz 10.0.2.5 2379
Connection to 10.0.2.5 2379 port [tcp/*] succeeded!
host01:~# nc -vz 10.0.2.5 2380
Connection to 10.0.2.5 2380 port [tcp/*] succeeded!

なんか書いてみてクラスタのそれぞれから見えることを確認

host01:~# etcdctl --endpoint=$ENDPOINTS set os linux

linux
host01:~# etcdctl --endpoint=$ENDPOINTS get os
linux

host02:~# etcdctl --endpoint=$ENDPOINTS get os
linux


dockerにetcdのエンドポイントを設定する

# ps -ef|grep docker

root 128373 1 1 04:59 ? 00:00:00 /usr/bin/dockerd -H fd://
root 128377 128373 0 04:59 ? 00:00:00 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc

# grep -i -A 2 execstart /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd://
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576

## なんとなくリンクを貼っておいた。
# ln -s /lib/systemd/system/docker.service /etc/systemd/system/docker.service
# ls -lh /etc/systemd/system/docker.service
lrwxrwxrwx 1 root root 34 Nov 22 17:57 /etc/systemd/system/docker.service -> /lib/systemd/system/docker.service

## 起動オプションについて追加が必要。
## (--cluster-advertiseと--cluster-store)
## /lib/systemd/system/docker.serviceを見る限り/etc/default/dockerに設定追加してもExecStartには影響しなさそう。
## あんま意味なさそうなのでしない。
## cp -p /etc/default/docker{,.org}
## vi /etc/default/docker

# systemctl edit docker.service
## nano編集めんどうなのでとりあえず抜ける
# vi /etc/systemd/system/docker.service.d/override.conf
# cat /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock -H fd:// --cluster-advertise eth0:2375 --cluster-store etcd://10.0.0.4:2379

# systemctl daemon-reload
# systemctl restart docker


overlayネットワークを作成する

# docker network create --driver overlay --subnet 192.168.0.0/24 common_link

# docker network ls
NETWORK ID NAME DRIVER SCOPE
d6c23310b593 bridge bridge local
ab6a75885c46 common_link overlay global
d981e6f5b649 host host local
992edac84635 none null local
# docker network inspect common_link

# etcdctl --endpoint=$ENDPOINTS ls docker/network/v1.0/overlay/network
# etcdctl --endpoint=$ENDPOINTS get /docker/network/v1.0/overlay/network/60b8c3d9e8e847246e96f291effeabf06a67783e9fa15c6e1c54038c939cbd05
{"mtu":0,"secure":false,"subnets":[{"SubnetIP":"192.168.0.0/24","GwIP":"192.168.0.1/24","Vni":0}]}

etcdをcluster-storeとしてエンドポイント指定したすべてのホストでoverlayが見えることを確認する。overlayネットワーク指定でコンテナを作るとコンテナにIPが振られている様子がわかる。


docker-compose.ymlかなんかにoverlayネットワークを指定する

~略~

networks:
default:
external:
name: common_link

こんな感じで名前を指定すればよく特に何か変える必要はなさそうだった。


etcd参考

個人的にもっとも参考になったのは公式サイトのデモです。(ただしubuntuのパッケージだと公式よりバージョン旧く無いオプションも。

人が書いたブログだとプラットフォームやバージョンと時期と方式と色々背景によってやってることが違ったりなど。

[入門編]etcdでクラスタを構築する - Qiita

etcdクラスタ構築(static方式) - Qiita

Clustering Guide

etcd/demo.md at master · coreos/etcd

忘れるためのメモ: kubernetesをRaspberry pi 3にインストールする(その2)


docker参考

具体的な手順がプラットフォームや時期によって多岐というか選べるってめんどくさいと思う次第です。

マルチホスト上での、dockerコンテナ間ネットワーク環境整備メモ(Overlay Networking w/ Etcd) - Qiita

マルチホストDockerネットワーキング(etcd+flannel) - Qiita

Dockerのマルチホストネットワークの概要説明と環境構築 – めもたんす(consul)

Kubernetesなしでdockerを複数台で動かしてみる (flannel編) - netmark.jp

Docker1.9のマルチホストネットワーク | Think IT(シンクイット)

containernetworking/cni: Container Network Interface - networking for Linux containers


etcdのはまったとこ

メンバ登録後にデータディレクトリ移動して同じクラスタに登録しようとするとデータがねえぜというようなエラーで起動しないですね。

(そんなおかしなことする人はいないかもしれないけど一応かいときます)

$datadir/memberというフォルダになんか入るようです(もどしたら起動しました)

Endpointを指定しないでetcctlするとよくわかんないポートにつなぎにいこうとしてクラスタ組めてないみたいに見えます

あとはiptablesに変な設定残っててポートが空いてないとだめですね。

static方式は起動コマンド書くのが面倒くさいというかtypoで起動しなかったりなどもしました。

結果的にはdiscoveryのほうが自動的に見つけてきてくれるのでオートスケーリング向きでAnsibleのタスクとか書きやすそうかなと思いました。

以上。