CoreOSとvagrantでクラスターを構築

CoreOSいじってみたのでメモ

今回はvagrantクラスター(core-01~03)+etcdを動かすVM(discovery)を立て、discoveryからクラスターの各マシンにserviceをデプロイするところまでやってみた
基本的にこちらの記事と各ツールレポジトリ、ドキュメントを元に作業
http://qiita.com/hnakamur/items/bccac980bef68642a814
http://qiita.com/voluntas/items/fc5b992fc3a579029566
とてもわかりやすくて助かりました!

vagrantでcoreosのVMを立てる設定があるのでまずこちらをclone

$ git clone https://github.com/coreos/coreos-vagrant

まずVagrantfileを書き換え。全部書くと無駄に多くなってしまうので変更・追加した部分だけ以下に書く。ただ、githubに上げたものを見た方が早いかも。
https://github.com/y-kamiya/coreos-vagrant/tree/develop

もともとのVagrantfileにクラスター用の設定は入っているので、
・etcdを立てるVMの設定
IPアドレスの設定
・cloud configファイルの設置
のための設定を追加した

# クラスタに使うVMの数を3へ変更
$num_instances = 3    
$vb_memory = 256

# 172.17.8.100をetcdを動かすサーバとして設定
BASE_IP_ADDR  = ENV['BASE_IP_ADDR'] || "172.17.8"
ETCD_DISCVERY = "#{BASE_IP_ADDR}.100"

Vagrant.configure("2") do |config|

  config.vm.define "discovery" do |discovery|
    discovery.vm.hostname = "discovery"
    discovery.vm.network :private_network, ip: ETCD_DISCVERY
    discovery.vm.provision :file, source: "./discovery", destination: "/tmp/vagrantfile-user-data"
    discovery.vm.provision :shell do |sh|
      sh.privileged = true
      sh.inline = <<-EOT
        mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/
      EOT
    end
  end

  # IPアドレスとcloud config設定ファイルの設置
  (1..$num_instances).each do |i|
    config.vm.define vm_name = "core-%02d" % i do |config|
      
      config.vm.network :private_network, ip: "#{BASE_IP_ADDR}.#{i+100}"

      if File.exist?(CLOUD_CONFIG_PATH)
        config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/vagrantfile-user-data"
        config.vm.provision :shell do |sh|
          sh.privileged = true
          sh.inline = <<-EOT
            # ここで%ETCD_DISCVERY%をIPアドレスに置換
            sed -e "s/%ETCD_DISCVERY%/#{ETCD_DISCVERY}/g" -i /tmp/vagrantfile-user-data
            mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/
          EOT
        end
      end

https://github.com/coreos/coreos-vagrantのREADMEにも書いてあるが
設定ファイルを.sampleから作る
設定の内容についてはこちらを参照
https://github.com/coreos/coreos-cloudinit

$ cp user-data.sample user-data
$ vim user-data
  4   etcd:
  5       #generate a new token for each unique cluster from https://discovery.etcd.io/new
  6       discovery: http://%ETCD_DISCVERY%:4001/v2/keys/cluster
  7       addr: $public_ipv4:4001
  8       peer-addr: $public_ipv4:7001

6行目のみ書き換えた。それ以外はsampleのまま。
サーバをプロビジョニングする際にVagrantfileの設定で%ETCD_DISCVERY%は置換される。

また、etcd用VMへの設定ファイルも同様に作成

#cloud-config

coreos:
  etcd:
      addr: $public_ipv4:4001
      peer-addr: $public_ipv4:7001
  units:
    - name: etcd.service
      command: start

sampleの設定からdockerの部分やコメントを除いたもの

VMの作成〜etcd, fleetの確認

$ vagrant up
$ vagrant ssh core-01

core@core-01 $ systemctl status etcd
● etcd.service - etcd
   Loaded: loaded (/usr/lib64/systemd/system/etcd.service; disabled)
  Drop-In: /run/systemd/system/etcd.service.d
           └─20-cloudinit.conf
   Active: active (running) since Sat 2014-05-31 02:55:27 UTC; 6h ago
 Main PID: 3220 (etcd)
   CGroup: /system.slice/etcd.service
           └─3220 /usr/bin/etcd

core@core-01 $ systemctl status fleet
● fleet.service - fleet
   Loaded: loaded (/etc/systemd/system/fleet.service; static)
   Active: active (running) since Sat 2014-05-31 02:56:04 UTC; 6h ago
 Main PID: 3227 (fleet)
   CGroup: /system.slice/fleet.service
           └─3227 /usr/bin/fleet

core@core-01 $ fleetctl list-machines 
MACHINE         IP              METADATA
1f263ca2...     172.17.8.101    -
5e935d5a...     172.17.8.102    -
a2c8558e...     172.17.8.103    -

systemctlのコマンドでactive (running)となっていればプロセスは動いている
そうでない場合はuser-dataの設定がおかしくないかチェックする
また、fleetctl list-machinesにてクラスターとして認識されているマシンの一覧が出る
これがうまくいかない場合はuser-dataやVagrantfile内でのIPアドレスの設定が正しいか確認
参照するetcdのIPアドレスが正しいものになっていなかったというミスがあった

etcdで少し遊んでみる

core@core-01 $ etcdctl set /message Hello
Hello
core@core-01 $ etcdctl get /message
Hello
# 別のマシンにログインして
core@core-02 $ etcdctl get /message
Hello

複数のマシンからアクセスできることが確認できた


次にdiscoveryからfleetを使ってserviceをデプロイまで
まずはdiscoveryからクラスターの様子が見えるように設定

$ vagrant ssh discovery

# クラスター内のどれか一つを設定
core@discovery $  export FLEETCTL_ENDPOINT=http://172.12.8.101:4001

core@discovery $ fleetctl list-machines
MACHINE         IP              METADATA
1f263ca2...     172.17.8.101    -
5e935d5a...     172.17.8.102    -
a2c8558e...     172.17.8.103    -

また、discoveryから各マシンでのserviceの状態を知るため、クラスター内の各マシンにsshで接続できるようにしておく必要がある。↓のページを参考に。今回はvagrantを使っているものの、Vagrantの項目で説明されているようにlaptopからクラスターへアクセスするわけではないので注意。
https://github.com/coreos/fleet/blob/master/Documentation/remote-access.md

# vagrantの秘密鍵をdiscovery内に置く
# Vagrantfileのあるディレクトリにて
$ cp ~/.vagrant.d/insecure_private_key .
$ vagrant ssh discovery
 
core@discovery $ cp /vagrant/insecure_private_key .ssh/

# ssh-agentの立ち上げと鍵の登録
core@discovery $ eval $(ssh-agent)
core@discovery $ ssh-add .ssh/insecure_private_key

# 確認
# vagrantのマシンは一つの秘密鍵ですべてにアクセスできるので一つ確認すればOK
core@discovery $ ssh 172.17.8.101

クラスター内の各マシンへのアクセスにそれぞれ別の鍵が必要だったとしてもFLEETCTL_TUNNELという環境変数を設定すれば、一つのマシンへのアクセスだけ設定すればよいというようなことが書かれているようだが、今回は必要なかったので試していない。


配布するserviceとして今回はfleetレポジトリにあるexamplesを使う

core@discovery $ git clone https://github.com/coreos/fleet.git
core@discovery $ cd fleet

# serviceを登録
core@discovery $ fleetctl submit examples/*

# 配布
core@discovery $ fleetctl start examples/hello.service
core@discovery $ fleetctl start examples/ping.service

# 確認
core@discovery $ fleetctl list-units
UNIT            STATE           LOAD    ACTIVE  SUB     DESC            MACHINE
hello.service   launched        loaded  active  running Hello World     5e935d5a.../172.17.8.102
ping.service    launched        loaded  active  running PING            1f263ca2.../172.17.8.101
pong.service    inactive        -       -       -       PONG            -

core-01、core-02でserviceが動いていることが確認できた

参考ページ
・CoreOSに関するわかりやすい記事
http://qiita.com/mopemope/items/fa9424b094aae3eac580

ツールのドキュメント
・etcdの概要やAPI
https://github.com/coreos/etcd
・fleetの設定
https://github.com/coreos/fleet/tree/master/Documentation
・user-dataの設定に関して
https://github.com/coreos/coreos-cloudinit