Help us understand the problem. What is going on with this article?

ローカルのKVM-VM上でCoreOSでクラスタ組んだメモ

More than 5 years have passed since last update.

Vagrant/VirtualBoxやAWS等のパブリッククラウド環境での情報はいろいろあったんですが、ローカルのVMで構築する場合の情報が少なかったのでまとめておきます。間違いや他にもっといい方法があれば、是非コメントください。

ここではCoreOS/etcd/fleetの詳細は説明しないので、mopemopeさんのhttp://qiita.com/mopemope/items/fa9424b094aae3eac580
などを参照して下さい。

構築環境

下記KVMホスト1台の上に、4VMを作成、CoreOSをインストールし、etcd/fleetのクラスタを構築した。

  • KVMホスト: CentOS6.5, openQRM5.1
  • CoreOS: 410.1.0 STABLE, etcd version 0.4.6, fleet version 0.6.2

CoreOSインストール

使用した環境では既にopenQRMが管理するdhcp/pxeサーバが稼働しており、Booting CoreOS via PXEは使えないので、Booting CoreOS from an ISOからISOイメージをダウンロードし、ISOイメージからVMを起動した。
vnc等でコンソールを開くとcoreユーザでログインできるが、vncでは何かと不便なので、PCからsshできるように仮にパスワード設定を行う。

$ sudo passwd core

起動した状態ではメモリ上にシステムが展開されており、ローカルディスクにCoreOSをインストールしてやる必要があるので、Installing CoreOS to Diskに従い、まずcloud-configファイルを作成する。
作成したcloud-configファイルは、coreユーザのホームディレクトリ直下に cloud-config.yaml と名付けて保存し、下記のコマンドを実行する。

$ sudo coreos-install -d /dev/vda -C stable -c ~/cloud-config.yaml

-d /dev/vda は、使用環境に合わせた起動ディスクのデバイス名(/dev/sda等)を指定する。
-C stable は、インストールするCoreOSのチャネル(stable/beta/alpha)を指定する。

インストールしたVMイメージをクローンした場合、 machine-id が重複してfleetが動かなくなるので、 machine-id ファイルを削除して再起動する必要がある。

$ sudo rm /etc/machine-id
$ sudo systemctl reboot

公式ドキュメントには「ゴールデンイメージ」を作成する場合は、/usr/share/OEM/デイレクトリを使用するべきとか書いてあったが、調べきれず。

cloud-configファイルの記述方法

Using Cloud-Configにあるように、cloud-configファイルは必ず #cloud-config を含み、下記のようなキーを必要に応じて定義する。

  • coreos
  • ssh_authorized_keys
  • hostname
  • users
  • units
  • write_files
  • manage_etc_hosts

(1) ssh設定

絶対に設定する必要があるのは、 ssh_authorized_keysusers である。
CoreOSはデフォルトでsshが公開鍵認証になっているので、ちゃんと設定しないと起動しても接続できないでくのぼうVMになる。
公開鍵認証を使う場合は、ssh-keygenコマンド等で作成した公開鍵の内容を下記のようにcloud-configファイルに記載する。

#cloud-config

users:
  - name: core
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAweXfI2dW0jrWU....

パスワードを使用する場合は、ハッシュ化されたパスワードを作成し、

core@core001 ~ $ openssl passwd -1
Password:
Verifying - Password:
$1$IlTQkYPg$fndQiTnrMN.....

下記のようにcloud-configファイルに記載する。

#cloud-config

users:
  - name: core
    passwd: $1$IlTQkYPg$fndQiTnrMN.....
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2....

(2) etcd設定

公式ドキュメントの例を見ると

#cloud-config

coreos:
    etcd:
        name: node001
    # generate a new token for each unique cluster from https://discovery.etcd.io/new
        discovery: https://discovery.etcd.io/<token>
    # multi-region and multi-cloud deployments need to use $public_ipv4
        addr: $public_ipv4:4001
        peer-addr: $private_ipv4:7001

のようにさらっと書いてあるが、ここでハマったので詳しく書いてみよう。
name: ノード名を指定したい場合はここに書くが、指定しなければ勝手に生成される。
discovery: etcdは、システム起動時に所属するクラスタメンバを data-dir設定で指定されたログデータ、 discovery設定、 peers設定の順で検索する。(Cluster Finding Process
data-dir設定は、

$./etcd -name <name> [-data-dir=<path>]

のようにコマンドラインでetcd起動する場合に使用できるが、discovery設定、またはpeers設定をしていなければ、ノード追加時に既存クラスタに参加できない。
discovery: キーに記載するのは、etcdクラスタメンバ以外のetcdサーバがdiscoveryサービスを提供している場合、そのURLを記載する。discoveryサービスを使用するメリットは、クラスタ追加/削除時の各クラスタメンバ個別の設定が不要である点だが、クラスタメンバ外にetcdサーバが必要であり、本番系では障害対策を考慮する必要がある。 https://discovery.etcd.io/ のサービスはグローバルアドレスを持ったetcdクラスタでないと使用できない。今回はdiscoveryサービス用にetcdサーバを一台たてて、以下のように指定した。

discovery: http://192.168.0.1:4001/v2/keys/test_cluster

test_cluster はクラスタ識別のための任意のキー名で良い。
peers設定は、discoveryサービスを使用しないで、クラスタメンバを明示的に指定でき、etcdクラスタメンバ以外のサーバは必要ない。しかしクラスタメンバ全てで個別の設定が必要なため、数台程度のクラスタであれば設定は簡単だが、大規模になると運用的に無理であろう。設定は、自分自身以外のクラスタメンバを下記のようにコンマでつないで指定する。

peers: 192.168.0.2:7001,192.168.0.3:7001

addr:peer-addr:  etcd通信のために稼働ノードのIPアドレスとポートを指定する。\$public_ipv4と\$private_ipv4は、 Amazon EC2, Google Compute Engine, OpenStack, Rackspace, DigitalOcean, Vagrantでしかサポートされていない環境変数のため、今回は直接IPアドレスを記載した。

#cloud-config

coreos:
  etcd:
    discovery: http://192.168.0.1:4001/v2/keys/test_cluster
    addr: 192.168.0.2:4001
    peer-addr: 192.168.0.2:7001

cloud-configファイルをノード毎に変更したくないが、CoreOSのCloud-initは bootcmdruncmd をまだサポートしていない。 unitsservice を作ってごにょごにょすれば変数を使ってなんとかできそうな気がするが、今回はできなかった。

(3) fleet設定

fleetではコンテナのスケジューリングをいろいろ設定可能であるが(Deploying fleet)今回は特別な設定をしないので記載しない。

(4) units設定

CoreOS起動後に立ち上げるサービス(systemdのunits、以前で言えば/etc/init.d/の設定)を記載する。

#cloud-config

  units:
    - name: etcd.service
      command: start
    - name: fleet.service
      command: start
    - name: docker-tcp.socket
      command: start
      enable: true
      content: |
        [Unit]
        Description=Docker Socket for the API

        [Socket]
        ListenStream=2375
        Service=docker.service
        BindIPv6Only=both

        [Install]
        WantedBy=sockets.target
    - name: settimezone.service
      command: start
      content: |
        [Unit]
        Description=Set the timezone

        [Service]
        ExecStart=/usr/bin/timedatectl set-timezone Asia/Tokyo
        RemainAfterExit=yes
        Type=oneshot

- name: etcd.service, fleet.service, docker-tcp.socket はクラスタ組む場合必須、 settimezone.service はデフォルトのタイムゾーン(UTC)を変更する場合記載する。(Configuring Date and Timezone
command:, enable:, content: 等はサービス起動のオプションなので、Using Cloud-Configを参照する。

(5) cloud-config.yaml

今回使用したファイルは下記の通り。これで最低限のクラスタを起動できた。

#cloud-config

coreos:
  etcd:
    discovery: http://[discoveryノードのIPアドレス]:4001/v2/keys/[クラスタ識別名]
    addr: [各ノードのIPアドレス]:4001
    peer-addr: [各ノードのIPアドレス]:7001
  units:
    - name: etcd.service
      command: start
    - name: fleet.service
      command: start
    - name: docker-tcp.socket
      command: start
      enable: true
      content: |
        [Unit]
        Description=Docker Socket for the API

        [Socket]
        ListenStream=2375
        Service=docker.service
        BindIPv6Only=both

        [Install]
        WantedBy=sockets.target
    - name: settimezone.service
      command: start
      content: |
        [Unit]
        Description=Set the timezone

        [Service]
        ExecStart=/usr/bin/timedatectl set-timezone Asia/Tokyo
        RemainAfterExit=yes
        Type=oneshot
users:
  - name: core
        passwd: $1$IlTQkYPg$fndQiTnrMN.....
ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2....

クラスタの確認

etcdの状態確認

$ 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 Mon 2014-09-29 11:37:46 JST; 5h 10min ago
 Main PID: 618 (etcd)
   CGroup: /system.slice/etcd.service
           └─618 /usr/bin/etcd

Sep 29 11:37:47 core004 etcd[618]: [etcd] Sep 29 11:37:47.071 INFO      | core004: state changed from 'follower' to 'snapshotting'.
Sep 29 11:37:47 core004 etcd[618]: [etcd] Sep 29 11:37:47.130 INFO      | core004: peer added: 'core001'
Sep 29 11:37:47 core004 etcd[618]: [etcd] Sep 29 11:37:47.224 INFO      | core004: peer added: 'core003'
Sep 29 11:37:50 core004 etcd[618]: [etcd] Sep 29 11:37:50.271 INFO      | core004: snapshot of 1414179 events at index 1414179 completed

etcdの設定確認

$ systemctl cat etcd
# /usr/lib64/systemd/system/etcd.service
[Unit]
Description=etcd

[Service]
User=etcd
PermissionsStartOnly=true
Environment=ETCD_DATA_DIR=/var/lib/etcd ETCD_NAME=default
ExecStart=/usr/bin/etcd
Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

# /run/systemd/system/etcd.service.d/20-cloudinit.conf
[Service]
Environment="ETCD_ADDR=192.168.0.2:4001"
Environment="ETCD_DISCOVERY=http://192.168.0.1:4001/v2/keys/cluster1"
Environment="ETCD_NAME=core002"
Environment="ETCD_PEER_ADDR=192.168.0.2:7001"

etcdクラスタの確認

$ curl -L http://127.0.0.1:7001/v2/admin/machines
[{"name":"core002","state":"follower","clientURL":"http://192.168.0.2:4001","peerURL":"http://192.168.0.2:7001"},{"name":"core003","state":"leader","clientURL":"http://192.168.0.3:4001","peerURL":"http://192.168.0.3:7001"},{"name":"core004","state":"follower","clientURL":"http://192.168.0.4:4001","peerURL":"http://192.168.0.4:7001"}]

fleetメンバの確認

$ fleetctl list-machines -l
MACHINE                 IP      METADATA
1ece947bc2084053988c0b65a7bf43e8    192.168.0.2 -
33f37f51181d46bcbf43e7162795e447    192.168.0.3 -
3dc1196b4ccd470d9f262ab506c4649c    192.168.0.4 -

エラーが出るようであれば、etcdを再起動する

$ sudo systemctl restart etcd

CoreOSインストール後のCloud-configファイルは /var/lib/coreos-install/user_data に保存されるので、設定変更する場合は編集保存後再起動を行う。

$ sudo vim /var/lib/coreos-install/user_data
$ sudo reboot
satoruf
TWITTER: http://twitter.com/satoruf
http://www.ossl.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away