Edited at

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

More than 1 year has passed since last update.


1. 構成

・3台構成(VMware上の仮想マシン)

・仮想マシンのOSはCentOS7.2、etcdの版数はversion 2.3.7

・ホスト名は、master1,master2,master3

・DB(データベース)は、etcdデーモンの起動ディレクトリに作成される。

etcdデーモンが使うポート番号v2(v1)
用途

2379(4001)
etcdctlコマンドのようなクライアントとの通信に使う

2380(7001)
etcdクラスタの中で、どのetcdをリーダにするか?、といったような制御情報のやりとりに使う

+------ master1(CentOS7.2) -----------+ +- master2(CentOS7.2) -+ +- master3(CentOS7.2) -+
| | | | | |
| +- etcdctl -+ +----- etcd ----+ | | +----- etcd ----+ | | +----- etcd ----+ |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| +-----------+ +- 2379 - 2380 -+ | | +- 2379 - 2380 -+ | | +- 2379 - 2380 -+ |
| A A | | A | | A A |
| | +----+ | | | +----+ | | | | +----+ | |
| | | DB | | | | | DB | | | | | | DB | | |
| | +----+ +------+ | | +----+ | | | | +----+ | |
| | | | | | | | | | |
+--------|----- eth0 ---|-------------+ +-------- eth0 -|------+ +------|- eth0 --|-----+
| | | | | | | |
| | | | | | | |
| | | | | | | |
+--------|--------+-----|------- 仮想スイッチ --------+----|-----------------|---+-----|-----+
| | | | | | |
| | +=================================+=================|=========+ |
| | | |
| +==================================================================+ |
| |
+-------------------------------------------------------------------------------------------+


2. etcdクラスタの構築方法

ここでは、static方式について説明をする。

方式
内容

static
あらかじめクラスタのメンバを定義ファイルに指定しておく

etcd discovery
http://qiita.com/hana_shin/items/f8de83a8cc91adae6262

DNS discovery
調査中


3. インストールするパッケージ

仮想マシンにetcdパッケージをインストールする。

[root@master1 ~]# yum -y install etcd
[root@master2 ~]# yum -y install etcd
[root@master3 ~]# yum -y install etcd


4. 設定内容


4.1 設定ファイルと設定内容

/etc/etcd/etcd.conf

項目
意味

ETCD_NAME
ホスト名を設定する

ETCD_DATA_DIR
DBのパスを設定する。デフォルトのパスは/var/lib/etcd/default.etcd

ETCD_LISTEN_PEER_URLS
etcdデーモン間の送受信に使うIPアドレスとポート番号を設定する

ETCD_INITIAL_CLUSTER
etcdクラスタのメンバを設定する。

ETCD_INITIAL_CLUSTER_STATE
newを設定する

ETCD_INITIAL_CLUSTER_TOKEN
etcdクラスタを識別するための文字列。同一クラスタ内のメンバは同じ文字列を設定する


4.2 master1の設定内容

[root@master1 ~]# cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.10 master1
192.168.0.20 master2
192.168.0.30 master3

有効な行だけ表示する(コメント行と空白行は省略)
[root@master1 ~]# cat /etc/etcd/etcd.conf |grep -v ^# |grep -v ^$
ETCD_NAME=master1
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.0.10:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.10:2380"
ETCD_INITIAL_CLUSTER="master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.10:2379"


4.3 master2の設定内容

[root@master2 ~]# cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.10 master1
192.168.0.20 master2
192.168.0.30 master3

有効な行だけ表示する(コメント行と空白行は省略)
[root@master2 ~]# cat /etc/etcd/etcd.conf |grep -v ^# |grep -v ^$
ETCD_NAME=master2
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.0.20:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.20:2380"
ETCD_INITIAL_CLUSTER="master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.20:2379"
[root@master2 ~]#


4.4 master3の設定内容

[root@master3 ~]# cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.10 master1
192.168.0.20 master2
192.168.0.30 master3

有効な行だけ表示する(コメント行と空白行は省略)
[root@master3 ~]# cat /etc/etcd/etcd.conf |grep -v ^# |grep -v ^$
ETCD_NAME=master3
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.0.30:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.30:2380"
ETCD_INITIAL_CLUSTER="master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.30:2379"
[root@master3 ~]#


5. 動作確認


5.1 etcdを起動する。

[root@master1 ~]# systemctl start etcd

[root@master2 ~]# systemctl start etcd
[root@master3 ~]# systemctl start etcd


5.2 etcdの版数を確認する。

[root@master1 ~]# etcdctl --version

etcdctl version 2.3.7
[root@master2 ~]# etcdctl --version
etcdctl version 2.3.7
[root@master3 ~]# etcdctl --version
etcdctl version 2.3.7


5.3 メンバ間の同期を確認する。


master1に書き込んだデータが、master2,master3で読めるかどうかを確認する。

master1でosにlinuxという値を設定する。

[root@master1 ~]# etcdctl set os linux
linux
[root@master1 ~]# etcdctl get os
linux

master2でosの値を確認する。
[root@master2 ~]# etcdctl get os
linux

master3でosの値を確認する。
[root@master3 ~]# etcdctl get os
linux


master3でosに設定された値を削除する。master1,master2でosに設定された値が削除されていることを確認する。

[root@master3 ~]# etcdctl rm os

PrevNode.Value: linux
[root@master3 ~]# etcdctl get os
Error: 100: Key not found (/os) [41]
[root@master3 ~]#

master2でosに設定した確認する。値が削除されていることがわかる。
[root@master2 ~]# etcdctl get os
Error: 100: Key not found (/os) [41]
[root@master2 ~]#

master1でosに設定した値を確認する。値が削除されていることがわかる。
[root@master1 ~]# etcdctl get os
Error: 100: Key not found (/os) [41]
[root@master1 ~]#


5.4 リーダの移動を確認する。

etcdクラスタのリーダを確認する。現在のリーダはmaster3(isLeader=true)であることがわかる。

[root@master1 ~]# etcdctl member list

7bf3dc7e1bfc9229: name=master3 peerURLs=http://192.168.0.30:2380 clientURLs=http://192.168.0.30:2379 isLeader=true
b19e62a463d4b18e: name=master2 peerURLs=http://192.168.0.20:2380 clientURLs=http://192.168.0.20:2379 isLeader=false
b22cf29c2bebb484: name=master1 peerURLs=http://192.168.0.10:2380 clientURLs=http://192.168.0.10:2379 isLeader=false
[root@master1 ~]#

master3(リーダ)のetcdデーモンを終了する。リーダが切り替わることを確認する。

master3で動くetcdデーモンのPIDを確認する。

[root@master3 ~]# ps -C etcd
PID TTY TIME CMD
1247 pts/0 00:02:20 etcd

etcdデーモンを終了する。
[root@master3 ~]# kill 1247
[root@master3 ~]#

master1でリーダを確認する。master1がリーダになったことがわかる。
[root@master1 ~]# etcdctl member list
7bf3dc7e1bfc9229: name=master3 peerURLs=http://192.168.0.30:2380 clientURLs=http://192.168.0.30:2379 isLeader=false
b19e62a463d4b18e: name=master2 peerURLs=http://192.168.0.20:2380 clientURLs=http://192.168.0.20:2379 isLeader=false
b22cf29c2bebb484: name=master1 peerURLs=http://192.168.0.10:2380 clientURLs=http://192.168.0.10:2379 isLeader=true

master2でもリーダを確認してみる。master1がリーダであることが確認できる。
[root@master2 ~]# etcdctl member list
7bf3dc7e1bfc9229: name=master3 peerURLs=http://192.168.0.30:2380 clientURLs=http://192.168.0.30:2379 isLeader=false
b19e62a463d4b18e: name=master2 peerURLs=http://192.168.0.20:2380 clientURLs=http://192.168.0.20:2379 isLeader=false
b22cf29c2bebb484: name=master1 peerURLs=http://192.168.0.10:2380 clientURLs=http://192.168.0.10:2379 isLeader=true
[root@master2 ~]#

さらに、master1(リーダ)のetcdデーモンを終了する。

この時点でmaster1,master3のetcdデーモンが終了したことになる。


etcdデーモンのPIDを確認する。
[root@master1 ~]# ps -C etcd
PID TTY TIME CMD
1792 pts/0 00:03:57 etcd

etcdデーモンを終了する。
[root@master1 ~]# kill 1792
[root@master1 ~]# ps -C etcd
PID TTY TIME CMD
[root@master1 ~]#

この時点でmaster2のetcdデーモンのみ生きている。
[root@master2 ~]# ps -C etcd
PID TTY TIME CMD
1087 pts/0 00:05:42 etcd

master2(リーダ)でetcdクラスタのメンバを確認する。etcdクラスタが利用不可とのメッセージが出力される。
[root@master2 ~]# etcdctl member list
Failed to get leader: client: etcd cluster is unavailable or misconfigured

master1,master3では、以下のメッセージが出力された。
etcdデーモンがいないので、TCP接続要求が拒否されたことを示している。
[root@master1 ~]# etcdctl member list
Error: client: etcd cluster is unavailable or misconfigured
error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused

[root@master3 ~]# etcdctl member list
Error: client: etcd cluster is unavailable or misconfigured
error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused


5.5 etcdクラスタの状態を確認する。


クラスタのメンバが残り1つになると、クラスタがunhealthyとなり、データベースからのリードはできるけど、ライトはできなくなる模様。ほんと???

クラスタの状態を確認する。全て(master1,master2,master3)のメンバが生きている。

[root@master1 ~]# etcdctl cluster-health
member 7bf3dc7e1bfc9229 is healthy: got healthy result from http://192.168.0.30:2379
member b19e62a463d4b18e is healthy: got healthy result from http://192.168.0.20:2379
member b22cf29c2bebb484 is healthy: got healthy result from http://192.168.0.10:2379

[root@master1 ~]# etcdctl set os linux
linux

[root@master1 ~]# etcdctl get os
linux

etcdのPIDを確認する。
[root@master3 ~]# ps -C etcd
PID TTY TIME CMD
1820 pts/3 00:01:58 etcd

master3のetcdを終了する。
[root@master3 ~]# kill 1820

etcdクラスタの状態を確認する。master1,master2のetcdが生きている。master3のetcdは終了している。
[root@master1 ~]# etcdctl cluster-health
failed to check the health of member 7bf3dc7e1bfc9229 on http://192.168.0.30:2379: Get http://192.168.0.30:2379/health: dial tcp 192.168.0.30:2379: getsockopt: connection refused
member 7bf3dc7e1bfc9229 is unreachable: [http://192.168.0.30:2379] are all unreachable
member b19e62a463d4b18e is healthy: got healthy result from http://192.168.0.20:2379
member b22cf29c2bebb484 is healthy: got healthy result from http://192.168.0.10:2379
cluster is healthy

etcdに書き込みを行う。3つのメンバのうち2つが生きていれば、データベースへのライトができる。
[root@master1 ~]# etcdctl set car GT-R
GT-R

etcdのPIDを確認する。
[root@master2 ~]# ps -C etcd
PID TTY TIME CMD
1790 pts/0 00:03:07 etcd

master2のetcdを終了する。
[root@master2 ~]# kill 1790

etcdクラスタの状態を確認する。master1のetcdだけが生きている。master2,3のetcdは終了していることがわかる。
[root@master1 ~]# etcdctl cluster-health
failed to check the health of member 7bf3dc7e1bfc9229 on http://192.168.0.30:2379: Get http://192.168.0.30:2379/health: dial tcp 192.168.0.30:2379: getsockopt: connection refused
member 7bf3dc7e1bfc9229 is unreachable: [http://192.168.0.30:2379] are all unreachable
failed to check the health of member b19e62a463d4b18e on http://192.168.0.20:2379: Get http://192.168.0.20:2379/health: dial tcp 192.168.0.20:2379: getsockopt: connection refused
member b19e62a463d4b18e is unreachable: [http://192.168.0.20:2379] are all unreachable
member b22cf29c2bebb484 is unhealthy: got unhealthy result from http://192.168.0.10:2379
cluster is unhealthy <<<<<< クラスタの状態がunhealthyと判定されている。

クラスタ内のメンバが1つだけの場合、etcdへのライトができない。
[root@master1 ~]# etcdctl set month Nov
Error: client: etcd cluster is unavailable or misconfigured
error #0: client: endpoint http://192.168.0.10:2379 exceeded header timeout
error #1: dial tcp 192.168.0.20:2379: getsockopt: connection refused
error #2: dial tcp 192.168.0.30:2379: getsockopt: connection refused

しかし、データベースからのリードはできる。
[root@master1 ~]# etcdctl ls
/os
/car

ここでmaster2のetcdを起動する。この時点でmaster1,master2が生きていることになる。
[root@master2 ~]# ps -C etcd
PID TTY TIME CMD
1811 pts/0 00:00:11 etcd

monthにデータを設定する。設定することができた。
[root@master1 ~]# etcdctl set month Nov
Nov

データベースのリードもできた。
[root@master1 ~]# etcdctl ls
/month
/os
/car


5.6 TCP2379番ポートへのアクセスを確認する。

tcpdumpをインストールする。

[root@master1 ~]# yum -y install tcpdump

tcpdumpを起動する。ポート番号に2379を指定する。
[root@master1 ~]# tcpdump -i eth0 tcp port 2379
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

もう1つ端末を起動する。そこで、etcdctlコマンドを実行する。
[root@master1 ~]# etcdctl member list

etcdctlコマンドの実行と同期して、TCPパケットの送受信が確認できる。
最初の3パケットで、master1のetcdctlコマンドとmaster3(リーダ)のetcdデーモンの間で
TCPコネクションの確立(3 way handshake)が行われていることがわかる。

   master1:53186(etcdctl) master3:2379(etcd)
| |
+---------------- SYN ------------->|
|<--------------- SYN +ACK ----------|
|---------------- ACK -------------->|

17:59:48.705597 IP master1.53186 > master3.2379: Flags [S], seq 1724156849, win 14600, options [mss 1460,sackOK,TS val 3687348 ecr 0,nop,wscale 7], length 0
17:59:48.707562 IP master3.2379 > master1.53186: Flags [S.], seq 354533212, ack 1724156850, win 14480, options [mss 1460,sackOK,TS val 3478680 ecr 3687348,nop,wscale 7], length 0
17:59:48.708494 IP master1.53186 > master3.2379: Flags [.], ack 1, win 115, options [nop,nop,TS val 3687353 ecr 3478680], length 0
17:59:48.713164 IP master1.53186 > master3.2379: Flags [P.], seq 1:109, ack 1, win 115, options [nop,nop,TS val 3687354 ecr 3478680], length 108
17:59:48.714680 IP master3.2379 > master1.53186: Flags [.], ack 109, win 114, options [nop,nop,TS val 3478688 ecr 3687354], length 0
17:59:48.715199 IP master3.2379 > master1.53186: Flags [P.], seq 1:536, ack 109, win 114, options [nop,nop,TS val 3478689 ecr 3687354], length 535
17:59:48.715242 IP master1.53186 > master3.2379: Flags [.], ack 536, win 123, options [nop,nop,TS val 3687359 ecr 3478689], length 0
17:59:48.716397 IP master1.53186 > master3.2379: Flags [P.], seq 109:224, ack 536, win 123, options [nop,nop,TS val 3687360 ecr 3478689], length 115
17:59:48.718197 IP master3.2379 > master1.53186: Flags [P.], seq 536:807, ack 224, win 114, options [nop,nop,TS val 3478692 ecr 3687360], length 271
17:59:48.720172 IP master1.53186 > master3.2379: Flags [F.], seq 224, ack 807, win 131, options [nop,nop,TS val 3687364 ecr 3478692], length 0
17:59:48.721524 IP master3.2379 > master1.53186: Flags [F.], seq 807, ack 225, win 114, options [nop,nop,TS val 3478696 ecr 3687364], length 0
17:59:48.721614 IP master1.53186 > master3.2379: Flags [.], ack 808, win 131, options [nop,nop,TS val 3687366 ecr 3478696], length 0


5.6 TCP2380番ポートへのアクセスを確認する。

2380番ポートでは、常時、メッセージが送受信されている。

[root@master1 ~]# tcpdump -i eth0 tcp port 2380

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
18:06:40.973494 IP master2.2380 > master3.52766: Flags [P.], seq 835860753:835860814, ack 2448790313, win 122, options [nop,nop,TS val 3945499 ecr 3890848], length 61
18:06:40.973526 IP master2.2380 > master1.54930: Flags [P.], seq 4072016314:4072016376, ack 3951593931, win 122, options [nop,nop,TS val 3945499 ecr 4099518], length 62
18:06:40.973590 IP master1.54930 > master2.2380: Flags [.], ack 62, win 123, options [nop,nop,TS val 4099618 ecr 3945499], length 0
18:06:40.974528 IP master3.52766 > master2.2380: Flags [.], ack 61, win 148, options [nop,nop,TS val 3890947 ecr 3945499], length 0
18:06:40.974535 IP master3.2380 > master2.38787: Flags [P.], seq 1427255133:1427255193, ack 3674681492, win 122, options [nop,nop,TS val 3890948 ecr 3945407], length 60
18:06:40.974879 IP master2.38787 > master3.2380: Flags [.], ack 60, win 331, options [nop,nop,TS val 3945501 ecr 3890948], length 0
18:06:40.976762 IP master1.2380 > master2.36442: Flags [P.], seq 1235860774:1235860835, ack 2751211062, win 122, options [nop,nop,TS val 4099620 ecr 3945411], length 61
18:06:40.978482 IP master2.36442 > master1.2380: Flags [.], ack 61, win 331, options [nop,nop,TS val 3945505 ecr 4099620], length 0
18:06:41.073308 IP master2.2380 > master3.52766: Flags [P.], seq 61:122, ack 1, win 122, options [nop,nop,TS val 3945599 ecr 3890947], length 61
18:06:41.073337 IP master2.2380 > master1.54930: Flags [P.], seq 62:124, ack 1, win 122, options [nop,nop,TS val 3945599 ecr 4099618], length 62
18:06:41.074338 IP master3.52766 > master2.2380: Flags [.], ack 122, win 148, options [nop,nop,TS val 3891047 ecr 3945599], length 0
以下、略


7. コマンドからetcdを起動する方法


7.1 master1で実行するコマンド

[root@master1 ~]# etcd -name master1 \

> -initial-advertise-peer-urls http://192.168.0.10:2380 \
> -listen-peer-urls http://192.168.0.10:2380 \
> -listen-client-urls http://192.168.0.10:2379,http://127.0.0.1:2379 \
> -advertise-client-urls http://192.168.0.10:2379 \
> -initial-cluster-token mytoken \
> -initial-cluster master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380 \
> -initial-cluster-state new &


7.2 master2で実行するコマンド

[root@master2 ~]# etcd -name master2 \

> -initial-advertise-peer-urls http://192.168.0.20:2380 \
> -listen-peer-urls http://192.168.0.20:2380 \
> -listen-client-urls http://192.168.0.20:2379,http://127.0.0.1:2379 \
> -advertise-client-urls http://192.168.0.20:2379 \
> -initial-cluster-token mytoken \
> -initial-cluster master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380 \
> -initial-cluster-state new &


7.3 master3で実行するコマンド

[root@master3 ~]# etcd -name master3 \

> -initial-advertise-peer-urls http://192.168.0.30:2380 \
> -listen-peer-urls http://192.168.0.30:2380 \
> -listen-client-urls http://192.168.0.30:2379,http://127.0.0.1:2379 \
> -advertise-client-urls http://192.168.0.30:2379 \
> -initial-cluster-token mytoken \
> -initial-cluster master1=http://192.168.0.10:2380,master2=http://192.168.0.20:2380,master3=http://192.168.0.30:2380 \
> -initial-cluster-state new &


8. 参考情報

Configuration flags