Edited at

30分でサクッとETCDクラスターを構築する

More than 1 year has passed since last update.


なにこれ

前回、Chefを使ってDockerSwarmを30分で構築するという記事を書きました。

今回は、ETCDクラスターをサクッとつくる方法について記述します。

http://qiita.com/xecus/items/d49579a9f28e1feefa4a

あと、「etcdって何?」って感じの方もいらっしゃると思いますので、1つ記事を紹介させて頂きます。

http://qiita.com/pocket8137/items/ef44ca68ffc0f4e70995


注意


  • Production等で利用するには、セキュリティ対策が必要です

  • 前回の記事と一緒にご覧くださいませ


手順


etcd-v2レシピを落としてくる

$ vi Berksfile

cookbook 'etcd-v2', '~> 1.0.6'
$ berks vendor cookbooks


metadataに依存レシピ追加

$ vi metadata.rb

name 'hello'
maintainer 'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license 'All rights reserved'
description 'Setup Docker'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.1.0'
depends 'etcd-v2', '~> 1.0.6'


レシピを書く

レシピ汚くてすみません。汗

レシピの挙動としては以下となります。


  • eth1のIPを拾ってきて、ノード名生成

  • etcdctl用にTCP2379を開ける

  • ピア間通信用にTCP2380を開ける

  • discoveryにstaticを選択し、環境変数のノード情報を結合する

  • etcdをサービス登録し、有効化


$ vi recipes/etcd.rb
include_recipe "etcd-v2::default"

etcd_binary 'default'
etcd_service 'default' do

# get my ip
ohai_val = Ohai::System.new
ohai_val.all_plugins
host_address_val = ohai_val["network"]["interfaces"]["eth1"]["addresses"].select { |address_key, address_val| address_val["family"] == "inet" }
my_ip = host_address_val.keys[0]

node_name 'node_' + my_ip.gsub(".", "_")
instance 'etcd_binary[default]'
user 'etcd'
group 'etcd'

client_host my_ip
client_listen '0.0.0.0'
client_port 2379

peer_host my_ip
peer_listen '0.0.0.0'
peer_port 2380

data_dir '/var/data/etcd'
snapshot_count 10_000
max_snapshots 5
max_wals 5
heartbeat_interval 100
election_timeout 1000

proxy :off
protocol :http

discovery :static
node['hello'][:etcd_hosts].each do |node|
next if node[:ipaddreass] == my_ip
peer node[:name], node[:ipaddreass], {
:protocol => :http,
:client_port => 2379,
:peer_port => 2380,
:timeout => 10
}
end

service_action [:start, :enable]

end


attributesにホストを定義する

なんかChef側の機能で、ホスト群をよしなに管理してくれる機能が

ありそうですが、めんどくさかったので以下の用にホストをstaticに定義。


default['hello'][:etcd_hosts] = [
{
:name => 'vm1',
:ipaddreass => '192.168.33.11'
},
{
:name => 'vm2',
:ipaddreass => '192.168.33.12'
},
{
:name => 'vm3',
:ipaddreass => '192.168.33.13'
},
{
:name => 'vm4',
:ipaddreass => '192.168.33.14'
}
]


ノードにレシピを追加する 

recipe[hello::etcd]をクラスタを組みたいノードに対して追加していきます。

今回の例では、nodes/192.168.33.1X.json (X=1..4)って感じですかね。


$ vi nodes/192.168.33.11.json
{
"run_list": [
"recipe[hello::default]",
"recipe[hello::etcd]"
],
"automatic": {
"ipaddress": "192.168.33.11"
}
}


レシピを回す


$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.11
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.12
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.13
$ knife solo cook -i ~/.ssh/id_rsa vagrant@192.168.33.14

ちなみに回しているときは以下のような雰囲気になります。

スクリーンショット 2016-12-24 11.19.56.png


確認作業

以下の作業は、etcdノード内での作業を想定しています。

とりあえず、ちゃんと4台結合されているのが確認できます。

vagrant@slave-1:~$ etcdctl member list

2a546a8220608294: name=node_192_168_33_12 peerURLs=http://192.168.33.12:2380 clientURLs=http://192.168.33.12:2379
30293d97ef360ebb: name=node_192_168_33_14 peerURLs=http://192.168.33.14:2380 clientURLs=http://192.168.33.14:2379
5c90fcc9be19298a: name=node_192_168_33_13 peerURLs=http://192.168.33.13:2380 clientURLs=http://192.168.33.13:2379
f829e5361f1740cc: name=node_192_168_33_11 peerURLs=http://192.168.33.11:2380 clientURLs=http://192.168.33.11:2379

vagrant@slave-1:~$ etcdctl cluster-health

cluster is healthy
member 2a546a8220608294 is healthy
member 30293d97ef360ebb is healthy
member 5c90fcc9be19298a is healthy
member f829e5361f1740cc is healthy

ちなみに、リーダーノードに対して以下のようなリクエストを投げると、詳細情報が出てきます。


vagrant@slave-1:~$ curl http://192.168.33.11:2379/v2/stats/leader | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 621 100 621 0 0 47615 0 --:--:-- --:--:-- --:--:-- 51750
{
"followers": {
"5c90fcc9be19298a": {
"counts": {
"success": 863,
"fail": 0
},
"latency": {
"maximum": 4.95161,
"minimum": 2.1e-05,
"standardDeviation": 0.3277805182916868,
"average": 0.15132188412514516,
"current": 0.052651
}
},
"30293d97ef360ebb": {
"counts": {
"success": 669,
"fail": 195
},
"latency": {
"maximum": 3.873798,
"minimum": 2.2e-05,
"standardDeviation": 0.3012054727758167,
"average": 0.14836751868460396,
"current": 0.060824
}
},
"2a546a8220608294": {
"counts": {
"success": 863,
"fail": 0
},
"latency": {
"maximum": 6.357807,
"minimum": 2.3e-05,
"standardDeviation": 0.33088303594294544,
"average": 0.16112308922363835,
"current": 0.078952
}
}
},
"leader": "f829e5361f1740cc"
}

リーダーではないと、こんな感じの表示が。

vagrant@slave-1:~$ curl http://192.168.33.12:2379/v2/stats/leader  | jq .

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 32 100 32 0 0 7731 0 --:--:-- --:--:-- --:--:-- 8000
{
"message": "not current leader"
}


番外編

etcd-browserについての紹介。etcdの値をブラウザから確認・編集できるスグレモノ。

以下の作業は、Dockerが利用でき、 etcdクラスタが見えるネットワーク内で行ってください。

$ git clone https://github.com/henszey/etcd-browser

$ cd etcd-browser
$ sudo docker build -t etcd-browser .
$ sudo docker run --rm --name etcd-browser -p 0.0.0.0:8000:8000 --env ETCD_HOST=192.168.33.11 --env ETCD_PORT=2379 --env AUTH_PASS=doe -t -i etcd-browser
proxy /api requests to etcd on 192.168.33.11:2379
etc-browser listening on port 8000

Dockerホストの8000にポートマッピングされているので、http://DockerHostIP:8000でアクセスが可能です。

スクリーンショット 2016-12-24 12.22.59.png