GCP上でCoreOSクラスタを作ってコンテナ起動をしてみた
Google Cloud Platform(GCP)上でCoreOS + etcd + fleet + docker でコンテナ起動まで行ったので紹介したいと思います。
CoreOSの起動
CoreOSは、コンテナの実行環境を構築することに特化したLinuxディストリビューションです。
なお、この記事ではCoreOS 815.0.0 を利用しており、GCPのCloud SDKがインストール済みであることを前提にしてます。
GCPでの起動
CoreOSでは、cloud-configというファイルで初期設定をします。
例えば以下のような内容です。
[code]
#cloud-config
coreos:
update:
reboot-strategy: off
etcd2:
discovery: <https://discovery.etcd.io/new?size=3 で取得した内容>
initial-advertise-peer-urls: http://$private_ipv4:2380
listen-peer-urls: http://$private_ipv4:2380
listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001
fleet:
public_ip: $private_ipv4
etcd-servers: http://0.0.0.0:2379
units:
– name: etcd2.service
command: start
– name: fleet.service
command: start
– name: docker.service
command: start
[/code]
GCPでは、以下のようにインスタンスを起動します。
[bash]
$ gcloud compute instances create <ホスト名>
–image-project coreos-cloud
–image <最新CoreOSのイメージ名>
–boot-disk-size 200GB
–machine-type g1-small
–zone asia-east1-c
–metadata-from-file user-data=<cloud-configファイル>
[/bash]
CoreOSのイメージ名は以下のコマンドで取得してください。
[bash]
$ gcloud compute images list
[/bash]
インスタンス起動したら以下のコマンドでログインできます。
[bash]
gcloud compute ssh <ホスト名> –zone asia-east1-c
[/bash]
もしかすると、初回はprojectを設定するように促されるかもしれません。
また、GCPだとprojectに属するメンバーのssh鍵が予め登録されるみたいなのですが、登録されておらずログインできない場合はGCPコンソール画面からインスタンスへssh鍵を登録してください。
etcdクラスタ
etcd の状態
etcdクラスタの状態は以下のコマンドで確認できます
[bash]
$ etcdctl cluster-health
member 166142cf9d722824 is healthy: got healthy result from http://10.240.0.2:2379
member c6d31dfab88110de is healthy: got healthy result from http://10.240.0.3:2379
member df537aa4f51bc509 is healthy: got healthy result from http://10.240.0.4:2379
cluster is healthy
[/bash]
etcdのメンバーは以下のコマンドで確認できます。
[bash]
$ etcdctl member list
166142cf9d722824: name=0961a55a5c11f91b9604ab2e9e174b90 peerURLs=http://10.240.0.2:2380 clientURLs=http://10.240.0.2:2379,http://10.240.0.2:4001
c6d31dfab88110de: name=c7eeb70a321d94c46e03e5cc798a1ec0 peerURLs=http://10.240.0.3:2380 clientURLs=http://10.240.0.3:2379,http://10.240.0.3:4001
df537aa4f51bc509: name=0ddbef29e654d7f949a90256c0f92ece peerURLs=http://10.240.0.4:2380 clientURLs=http://10.240.0.4:2379,http://10.240.0.4:4001
[/bash]
1 |
bootstrap処理
ここでは、etcdクラスタの初期設定のことです。先ほどcloud-config内に以下のような内容を記述していました。
[code]
discovery: <https://discovery.etcd.io/new?size=3 で取得した内容>
[/code]
これは、
[code]
https://discovery.etcd.io/new?size=3
[/code]
のようにアクセスすると
[code]
https://discovery.etcd.io/729fd97bfee6537de4f26174d06c6582
[/code]
のように返ってくるので、これをcloud-configに記載します。
今回discovery:で https://discovery.etcd.io/ のサービスを利用しましたが、自前で別に立てたクラスタ用のetcdとは別のetcdで同じように作成することもできます。また、etcdのクラスタサイズとして”new=3″として作成していますので、4台目以降のetcdはプロキシモードで動作します。なお、3台etcdが参加するまでetcdクラスタとしては正常に動作しませんので注意が必要です。
上記とは別に静的にetcdクラスタを構成することもできます。1台目は以下のようにcloud-configへ記載します。
[code]
coreos:
etcd2:
name : master
listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001
initial-cluster-token: testetcd
listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001
initial-advertise-peer-urls: http://$private_ipv4:2380
initial-cluster: master=http://$private_ipv4:2380
initial-cluster-state: new
[/code]
1 |
2台目以降は以下のように書くとetcdクラスタに参加できます。こちらもプロキシモードでの参加です。IPアドレスが事前にわかっていれば、プロキシモードで無くとも参加できます。
[code]
coreos:
etcd2:
listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
advertise-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
initial-cluster: master=http://<masterのip>:2380
proxy: on
[/code]
1 |
メンバーの追加
etcdクラスタへメンバーを追加することが出来ます。etcdクラスタは、その利用している”Raft”というアルゴリズムがあまり大規模なクラスタには不向きであるらしく、5~9メンバーが適切なサイズと言われています。3メンバーだと1メンバーダウン時の挙動が不安定になることがあったため、5メンバーいると良いと思います。
メンバー追加は以下のように行います。
まず、追加するCoreOSで以下のコマンドを実行します
[bash]
$ cat /etc/machine-id
[/bash]
次に、既存のクラスタメンバーで以下のコマンドを実行します。
[bash]
$ etcdctl member add http://<追加するメンバーのIPアドレス>:2380
[/bash]
すると、以下のような出力がでます
[bash]
$ etcdctl member add 0b54ddfcc16f6595d15dd6fbb75da153 http://10.240.0.5:2380
Added member named 0b54ddfcc16f6595d15dd6fbb75da153 with ID 1aea5ee2f7aaddac to cluster
ETCD_NAME="0b54ddfcc16f6595d15dd6fbb75da153"
ETCD_INITIAL_CLUSTER="0961a55a5c11f91b9604ab2e9e174b90=http://10.240.0.2:2380,0b54ddfcc16f6595d15dd6fbb75da153=http://10.240.0.5:2380,c7eeb70a321d94c46e03e5cc798a1ec0=http://10.240.0.3:2380,0ddbef29e654d7f949a90256c0f92ece=http://10.240.0.4:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"
[/bash]
ここでの出力結果を追加するメンバーで利用します。
追加するメンバーの/etc/systemd/system/etcd2.service.d/50-join-cluster.conf
に以下の内容記載します。
[code]
[Service]
Environment="ETCD_NAME=0b54ddfcc16f6595d15dd6fbb75da153"
Environment="ETCD_INITIAL_CLUSTER=0961a55a5c11f91b9604ab2e9e174b90=http://10.240.0.2:2380,0b54ddfcc16f6595d15dd6fbb75da153=http://10.240.0.5:2380,c7eeb70a321d94c46e03e5cc798a1ec0=http://10.240.0.3:2380,0ddbef29e654d7f949a90256c0f92ece=http://10.240.0.4:2380"
Environment="ETCD_INITIAL_CLUSTER_STATE=existing"
Environment="ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379,http://0.0.0.0:4001"
Environment="ETCD_LISTEN_PEER_URLS=http://10.240.0.5:2380"
Environment="ETCD_ADVERTISE_CLIENT_URLS=http://10.240.0.5:2379,http://10.240.0.5:4001"
[/code]
[Service]からの上3行は、先ほどのコマンドの出力結果です。下3行はetcdクラスタ通信のための設定です。IPアドレスは追加するメンバーのIPアドレスを記載してください。
ファイルを書き込んだら、systemdからetcdを起動します。
[bash]
$ sudo systemctl start etcd2
[/bash]
起動したらクラスタの状態を見てみます。
[bash]
$ etcdctl cluster-health
member 166142cf9d722824 is healthy: got healthy result from http://10.240.0.2:2379
member 1aea5ee2f7aaddac is healthy: got healthy result from http://10.240.0.5:2379
member c6d31dfab88110de is healthy: got healthy result from http://10.240.0.3:2379
member df537aa4f51bc509 is healthy: got healthy result from http://10.240.0.4:2379
cluster is healthy
[/bash]
クラスタにメンバーを追加できていることがわかります。
メンバーの削除
メンバーを削除するときは、削除するメンバーのetcd上のIDを指定して以下のコマンドを実行します。
まず、IDを確認します。
[bash]
$ etcdctl member list
166142cf9d722824: name=0961a55a5c11f91b9604ab2e9e174b90 peerURLs=http://10.240.0.2:2380 clientURLs=http://10.240.0.2:2379,http://10.240.0.2:4001
1aea5ee2f7aaddac: name=0b54ddfcc16f6595d15dd6fbb75da153 peerURLs=http://10.240.0.5:2380 clientURLs=http://10.240.0.5:2379,http://10.240.0.5:4001
c6d31dfab88110de: name=c7eeb70a321d94c46e03e5cc798a1ec0 peerURLs=http://10.240.0.3:2380 clientURLs=http://10.240.0.3:2379,http://10.240.0.3:4001
df537aa4f51bc509: name=0ddbef29e654d7f949a90256c0f92ece peerURLs=http://10.240.0.4:2380 clientURLs=http://10.240.0.4:2379,http://10.240.0.4:4001
[/bash]
今回は、先ほどメンバーに追加したname=0b54ddfcc16f6595d15dd6fbb75da153
をクラスタから削除しましょう。行先頭の文字列がIDです。
[bash]
$ etcdctl member remove
[/bash]
今回の例では以下のようになります
[bash]
$ etcdctl member remove 1aea5ee2f7aaddac
Removed member 1aea5ee2f7aaddac from cluster
[/bash]
上記のコマンドを実行すると、削除されたメンバーのetcdがそれを検知してetcdが停止します。クラスタに復帰するときは、再度メンバー追加を行う必要があります。再度参加させるときは、/var/lib/etcd2/member/を削除しておく必要があるので注意が必要です。
最後にクラスタメンバーが削除されたことを確認してみます。
[bash]
$ etcdctl member list
166142cf9d722824: name=0961a55a5c11f91b9604ab2e9e174b90 peerURLs=http://10.240.0.2:2380 clientURLs=http://10.240.0.2:2379,http://10.240.0.2:4001
c6d31dfab88110de: name=c7eeb70a321d94c46e03e5cc798a1ec0 peerURLs=http://10.240.0.3:2380 clientURLs=http://10.240.0.3:2379,http://10.240.0.3:4001
df537aa4f51bc509: name=0ddbef
[/bash]
コンテナ起動
etcdクラスタも動いたところで、dockerコンテナを動かしてみたいと思います。今回は、コンテナとしてmackerel-agentを動かしてみたいと思います。
fleetを利用したコンテナ起動
まずは、fleetの管理下にあるマシンを見てみます
[bash]
$ fleetctl list-machines
MACHINE IP METADATA
0961a55a… 10.240.0.2 –
0b54ddfc… 10.240.0.5 –
0ddbef29… 10.240.0.4 –
c7eeb70a… 10.240.0.3 –
[/bash]
先ほど作成したetcdクラスタの4台がいることがわかります。
[bash]
$ fleetctl list-unit-files
UNIT HASH DSTATE STATE TARGET
$ fleetctl list-units
UNIT MACHINE ACTIVE SUB
[/bash]
まだ、fleet上ではまだ何も動いていません。
それでは、fleetでコンテナを起動するために、unitファイルを作成します。fleet用のunitファイルは、systemd用のunitファイルに非常に似ています。以下のファイルmackerel-agent.service
を 適当な場所に置きます。
[code]
[Unit]
Description=Mackerel Agent
After=docker.service
Requires=docker.service
[Service]
ExecStartPre=-/usr/bin/docker kill mackerel-agent
ExecStartPre=-/usr/bin/docker rm mackerel-agent
ExecStartPre=/usr/bin/docker pull mackerel/mackerel-agent
ExecStart=/usr/bin/sh -c "/usr/bin/docker run –log-driver=journald –privileged –name mackerel-agent -h %H -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/mackerel-agent/:/var/lib/mackerel-agent/ -v /proc/mounts:/host/proc/mounts:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e apikey=/usr/bin/etcdctl get /mackerel/apikey
mackerel/mackerel-agent"
ExecStop=/usr/bin/docker stop mackerel-agent
[X-Fleet]
Global=true
[/code]
最後の[X-Fleet]がfleetに対してどこでコンテナを動かすかを指示する内容になります。
[code]
[X-Fleet]
Global=true
[/code]
と書くことでetcdクラスタすべてのホストでコンテナを起動する事ができます。
今回mackerel-agent起動時にapikeyをetcd経由で取得しているので、
[code]
$ etcdctl set /mackerel/apikey <your-api-key>
[/code]
のようにapikeyを登録して置く必要があります。
etcdにapikeyを登録したら、以下のコマンドでfleetからコンテナを起動します
[bash]
$ fleetctl submit mackerel-agent.service
Unit mackerel-agent.service
$ fleetctl load mackerel-agent.service
Triggered global unit mackerel-agent.service load
$ fleetctl start mackerel-agent.service
Triggered global unit mackerel-agent.service start
[/bash]
最初にsubmit
でfleetにファイルの内容を登録します。その後、load
とstart
でfleet登録した内容を起動します。コンテナの起動を確認してみます。
[bash]
$ fleetctl list-unit-files
UNIT HASH DSTATE STATE TARGET
mackerel-agent.service 668bf63 launched – global
$ fleetctl list-units
UNIT MACHINE ACTIVE SUB
mackerel-agent.service 0961a55a…/10.240.0.2 active running
mackerel-agent.service 0b54ddfc…/10.240.0.5 active running
mackerel-agent.service 0ddbef29…/10.240.0.4 active running
mackerel-agent.service c7eeb70a…/10.240.0.3 active running
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c03a9571b74 mackerel/mackerel-agent "/startup.sh" 2 seconds ago Up 1 seconds mackerel-agent
[/bash]
CoreOSが動いているすべてのホストでコンテナが起動していることが確認できました。
執筆時点のmackerel-agent 0.23.0では、CoreOS上のdockerの状態を取ることは出来ません。https://github.com/mackerelio/docker-mackerel-agent を少し細工をして利用する必要があります。
参考
CoreOSを使ってDockerコンテナを動かす——15分でできるCoreOSクラスタの作り方
Monitoring Docker with Mackerel

関連記事
-
-
AnsibleでJunosのバージョン情報を取得
インフラ開発部 松田です。 今回は弊社で検証中のAnsibleについて書きます。 Ansibleを使ったサーバ構築の記事は最近よく見かけますが、私が触る機会の多いネットワーク機器も操作できる(Ansibleはエージェントレス)ということで、Ansible+NW機器について色々書いていきます。 初回は …
-
-
Burpの使い方!
こんにちは、第二ソリューション開発部の谷口です。 受託開発の部署で開発を担当してます。 APIを扱う機会が多く、今回は通信内容を確認するためのローカルプロキシツール「Burp」について書かせて頂きます。 Burpとは Webアプリケーション開発時の検証において、Webサーバとブラウザ間の通信内容を確 …
-
-
AWSのcredentialsを注意して取り扱う話
はじめに 最近ではオンプレミスでサーバを自前で用意する他に、クラウドサーバを使う機会が増えているかと思います。 弊社では、Amazon Web Services (AWS)を利用しており、多くの処理をAWS上で行っています。 AWSを利用していくにあたっては、アクセス情報(credentials)を …
-
-
【クラウド初心者向け】Google Cloud Platform(GCP)でWebサイトを公開してみよう!
はじめに みなさんこんにちは、プロダクト開発本部の亀梨です。 普段はXmediaOneというメディアプランニング・広告運用管理・トラッキング・マーケティング分析を行う 統合プラットフォームの開発を担当しています。 背景 わたくしは最近プライベートで開発したWebサービスをインターネット上に公開しまし …