chef
etcd

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