CoreOSの分散型Key-ValueストアであるEtcdctlおよびEtcdの使用方法
序章
CoreOSを可能にするテクノロジーの1つは、グローバルに分散されたKey-Valueストアであるetcd
です。 このサービスは、個々のCoreOSマシンがクラスターを形成するため、およびグローバルにアクセス可能なデータを格納するためのプラットフォームとして使用されます。
このガイドでは、etcd
デーモン、etcdctl
ユーティリティ、およびそれを制御するために使用できるHTTP /JSONAPIについて説明します。
前提条件
このガイドに従うために、DigitalOceanでCoreOSクラスターをセットアップするためのガイドとしてCoreOSマシンのクラスターがあることを前提としています。 これにより、1つのクラスターに3台のサーバーが残ります。
- coreos-1
- coreos-2
- coreos-3
これらのマシンを稼働させたら、このガイドを続けることができます。
Etcdクラスター検出モデル
etcd
が担当する最も基本的なタスクの1つは、個々のマシンをクラスターに編成することです。 これは、CoreOSが起動時に、作成時に渡されるcloud-config
ファイルで提供される検出アドレスにチェックインすることによって実行されます。
CoreOSによって実行される検出サービスには、https://discovery.etcd.io
からアクセスできます。 /new
ページにアクセスすると、新しいトークンを取得できます。 そこで、マシンがコンパニオンノードを検出するために使用できるトークンを取得します。 次のようになります。
https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c
は、新しいクラスターごとに新しいトークンを提供する必要があります。 これには、同じIPアドレスを持つ可能性のあるノードを使用してクラスターを再構築する必要がある場合も含まれます。 etcd
インスタンスはこれによって混乱し、検出アドレスを再利用すると、クラスターを構築するために正しく機能しなくなります。
Webブラウザーで検出アドレスにアクセスすると、既知のマシンを説明するJSONオブジェクトが返されます。 最初に開始したとき、これにはノードがありません。
{"action":"get","node":{"key":"/_etcd/registry/dcadc5d4d42328488ecdcd7afae5f57c","dir":true,"modifiedIndex":102511104,"createdIndex":102511104}}
クラスタをブートストラップした後、ここで詳細情報を確認できます。
{"action":"get","node":{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda","dir":true,"nodes":[{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/2ddbdb7c872b4bc59dd1969ac166501e","value":"http://10.132.252.38:7001","expiration":"2014-09-19T13:41:26.912303668Z","ttl":598881,"modifiedIndex":102453704,"createdIndex":102453704},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/921a7241c31a499a97d43f785108b17c","value":"http://10.132.248.118:7001","expiration":"2014-09-19T13:41:29.602508981Z","ttl":598884,"modifiedIndex":102453736,"createdIndex":102453736},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/27987f5eaac243f88ca6823b47012c5b","value":"http://10.132.248.121:7001","expiration":"2014-09-19T13:41:41.817958205Z","ttl":598896,"modifiedIndex":102453860,"createdIndex":102453860}],"modifiedIndex":101632353,"createdIndex":101632353}}
クラスタの検出URLを見つける必要がある場合は、メンバーである任意のマシンから見つけることができます。 この情報は、/run
階層内から取得できます。
cat /run/systemd/system/etcd.service.d/20-cloudinit.conf
[Service] Environment="ETCD_ADDR=10.132.248.118:4001" Environment="ETCD_DISCOVERY=https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c" Environment="ETCD_NAME=921a7241c31a499a97d43f785108b17c" Environment="ETCD_PEER_ADDR=10.132.248.118:7001"
URLはETCD_DISCOVERY
エントリ内に保存されます。
etcd
を実行しているマシンが起動すると、このURLの情報を確認します。 それはそれ自身の情報を提出し、他のメンバーについて質問します。 クラスタの最初のノードは明らかに他のノードに関する情報を検出しないため、それ自体をクラスタリーダーとして指定します。
後続のマシンも、その情報を検出URLに接続します。 すでにチェックインしているマシンに関する情報を受け取ります。 次に、これらのマシンの1つを選択して直接接続し、正常なクラスターメンバーの完全なリストを取得します。 データの複製と配布は、Raftコンセンサスアルゴリズムを介して実行されます。
各マシンに関するデータは、etcd
内の隠しディレクトリ構造内に保存されます。 etcd
が認識しているマシンに関する情報は、次のように入力すると表示されます。
etcdctl ls /_etcd/machines --recursive
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e /_etcd/machines/921a7241c31a499a97d43f785108b17c /_etcd/machines/27987f5eaac243f88ca6823b47012c5b
etcd
が新しいクラスターメンバーに渡す詳細は、これらのキーに含まれています。 etcdctl
でリクエストすると、個々の値を確認できます。
etcdctl get /_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
etcd=http%3A%2F%2F10.132.252.38%3A4001&raft=http%3A%2F%2F10.132.252.38%3A7001
etcdctl
コマンドについては、後で詳しく説明します。
Etcdctlの使用法
etcd
と対話する基本的な方法は2つあります。 HTTP / JSON APIを介して、および付属のetcdctl
ユーティリティなどのクライアントを介して。 最初にetcdctl
について説明します。
キーとディレクトリの表示
まず、etcdctl
が現在保存しているものを見てみましょう。 次のように入力すると、最上位のキーが表示されます。
etcdctl ls /
/coreos.com
ご覧のとおり、1つの結果があります。 現時点では、これがディレクトリなのかキーなのかは不明です。 ノードをget
して、キーの値を確認するか、それがディレクトリであることを確認することができます。
etcdctl get /coreos.com
/coreos.com: is a directory
この手動の再帰プロセスを回避するために、etcdctl
に、次のように入力して、表示されている情報の階層全体を一覧表示するように指示できます。
etcdctl ls / --recursive
/coreos.com /coreos.com/updateengine /coreos.com/updateengine/rebootlock /coreos.com/updateengine/rebootlock/semaphore
ご覧のとおり、最初の/coreos.com
ノードの下にはかなりの数のディレクトリがありました。 最終エンドポイントで情報を要求することにより、ノードから実際のデータを取得することがどのように見えるかを確認できます。
etcdctl get /coreos.com/updateengine/rebootlock/semaphore
{"semaphore":1,"max":1,"holders":null}
これには、私たちにとって非常に役立つ情報は含まれていません。 -o extended
オプションを渡すことで、このエントリに関する追加のメタデータを取得できます。 これはグローバルオプションであるため、get
コマンドの前に配置する必要があります。
etcdctl -o extended get /coreos.com/updateengine/rebootlock/semaphore
Key: /coreos.com/updateengine/rebootlock/semaphore Created-Index: 6 Modified-Index: 6 TTL: 0 Etcd-Index: 170387 Raft-Index: 444099 Raft-Term: 8 {"semaphore":1,"max":1,"holders":null}
キーの設定とノードの作成
新しいディレクトリを作成するには、次のようにmkdir
コマンドを使用できます。
etcdctl mkdir /example
キーを作成するには、mk
コマンドを使用できます。
etcdctl mk /example/key data
data
これは、キーがまだ存在しない場合にのみ機能します。 作成したキーの値を尋ねると、設定したデータを取得できます。
etcdctl get /example/key
data
既存のキーを更新するには、update
コマンドを使用します。
etcdctl update /example/key turtles
turtles
ディレクトリ用のコンパニオンupdatedir
コマンドは、TTL、つまりディレクトリの存続時間を設定した場合にのみ役立つ可能性があります。 これにより、TTL時間が渡されたもので更新されます。 --ttl #
引数を渡すことにより、ディレクトリまたはキーのTTLを設定できます。ここで、「#」は保持する秒数です。
etcdctl mkdir /here/you/go --ttl 120
次に、updatedir
を使用してTTLを更新できます。
etcdctl updatedir /here/you/go --ttl 500
既存のキーの値を変更するか、存在しない場合はキーを作成するには、set
コマンドを使用します。 これは、mk
コマンドとupdate
コマンドの組み合わせと考えてください。
etcdctl set /example/key new
new
これには、存在しないパスが含まれる場合があります。 パスコンポーネントは動的に作成されます。
etcdctl set /a/b/c here
here
ディレクトリに対してこれと同じcreate-if-does-not-exist機能を取得するには、setdir
コマンドを使用できます。
etcdctl setdir /x/y/z
注:setdir
コマンドは、現在、記載されているとおりに機能しません。 現在のビルドでは、その使用法はupdatedir
コマンドを反映しており、ディレクトリがすでに存在する場合は失敗します。 これに対処するために、GitHubリポジトリに未解決の問題があります。
エントリの削除
既存のキーを削除するには、rm
またはrmdir
コマンドを使用できます。
rm
コマンドを使用して、キーを削除できます。
etcdctl rm /a/b/c
また、ディレクトリとすべてのサブディレクトリを削除するために再帰的に使用することもできます。
etcdctl rm /a --recursive
空のディレクトリまたはキーのみを削除するには、rmdir
コマンドを使用します。
etcdctl rmdir /x/y/z
これを使用して、階層のエンドポイントのみを削除していることを確認できます。
変化を監視する
特定のキーまたはディレクトリ全体のいずれかで変更を監視できます。 etcdctl
でこれらを監視すると、監視対象に何らかのイベントが発生するまで操作がハングします。
キーを監視するには、フラグなしで使用します。
etcdctl watch /example/hello
視聴を停止するには、CTRL-C
を押します。 監視中に変更が検出された場合は、新しい値が返されます。
ディレクトリ構造全体を監視するには、--recursive
フラグを使用します。
etcdctl watch --recursive /example
値の状態を常に監視するために単純なループ構造に配置することで、これがどのように役立つかを確認できます。
while true; do etcdctl watch --recursive /example; done
変更が検出されるたびにコマンドを実行する場合は、exec-watch
コマンドを使用します。
etcdctl exec-watch --recursive /example -- echo "hello"
これにより、そのディレクトリの値が変更されるたびに、画面に「hello」がエコーされます。
隠された値
すぐにはわからないことの1つは、etcd
内に隠しディレクトリ構造があることです。 これらは、アンダースコアで始まるディレクトリまたはキーです。
これらは、従来のetcdctl
ツールにはリストされていないため、それらを見つけるには、探しているものを知っている必要があります。
たとえば、/_coreos.com
という隠しディレクトリがあります。このディレクトリにはfleet
に関する内部情報が含まれています。 明示的に要求することで、階層を確認できます。
etcdctl ls --recursive /_coreos.com
/_coreos.com/fleet /_coreos.com/fleet/states /_coreos.com/fleet/states/[email protected] /_coreos.com/fleet/states/[email protected]/2ddbdb7c872b4bc59dd1969ac166501e /_coreos.com/fleet/states/[email protected] /_coreos.com/fleet/states/[email protected]/921a7241c31a499a97d43f785108b17c . . .
別のそのようなディレクトリ構造は、/_etcd
内にあります。
etcdctl ls --recursive /_etcd
/_etcd/machines /_etcd/machines/27987f5eaac243f88ca6823b47012c5b /_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e /_etcd/machines/921a7241c31a499a97d43f785108b17c /_etcd/config
これらは他のエントリとまったく同じように機能しますが、唯一の違いは、一般的なリストに表示されないことです。 キーまたはディレクトリ名をアンダースコアで始めるだけで作成できます。
Etcd HTTP /JSONAPIの使用法
etcd
と対話するもう1つの方法は、単純なHTTP /JSONAPIを使用することです。
APIにアクセスするには、curl
のような単純なHTTPプログラムを使用できます。 返されるリダイレクトを追跡するには、-L
フラグを指定する必要があります。 クラスタ内から、ほとんどのクエリにローカル127.0.0.1
インターフェイスとポート4001
を使用できます。
注:Dockerコンテナ内からetcd
に接続するには、アドレスhttp://172.17.42.1:4001
を使用できます。 これは、アプリケーションが登録された情報に基づいて構成を更新する場合に役立ちます。
通常のキースペースに到達するには、任意のホストマシンでhttp://127.0.0.1:4001/v2/keys/
に移動します。 たとえば、最上位のキー/ディレクトリのリストを取得するには、次のように入力します。
curl -L http://127.0.0.1:4001/v2/keys/
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":6,"createdIndex":6},{"key":"/services","dir":true,"modifiedIndex":333,"createdIndex":333}]}}
リクエストの末尾のスラッシュは必須です。 それがないと正しく解決されません。
通常のHTTP動詞を使用して値を設定または取得できます。
これらの操作の動作を変更するには、?flag=value
構文を使用して、リクエストの最後にフラグを渡すことができます。 複数のフラグは&
文字で区切ることができます。
たとえば、すべてのキーを再帰的に一覧表示するには、次のように入力します。
curl -L http://127.0.0.1:4001/v2/keys/?recursive=true
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"nodes":[{"key":"/coreos.com/updateengine","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock/semaphore","value":"{\"semaphore\":1,\"max\":1,\"holders\":null}","modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}. . .
通常のキースペースの外でアクセスできるもう1つの便利な情報は、バージョン情報です。ここからアクセスできます。
curl -L http://127.0.0.1:4001/version
etcd 0.4.6
このエンドポイントにアクセスすると、クラスターリーダーと各フォロワーとの各関係に関する統計を表示できます。
curl -L http://127.0.0.1:4001/v2/stats/leader
{"leader":"921a7241c31a499a97d43f785108b17c","followers":{"27987f5eaac243f88ca6823b47012c5b":{"latency":{"current":1.607038,"average":1.3762888642395448,"standardDeviation":1.4404313533578545,"minimum":0.471432,"maximum":322.728852},"counts":{"fail":0,"success":98718}},"2ddbdb7c872b4bc59dd1969ac166501e":{"latency":{"current":1.584985,"average":1.1554367141497013,"standardDeviation":0.6872303198242179,"minimum":0.427485,"maximum":31.959235},"counts":{"fail":0,"success":98723}}}}
同様の操作を使用して、現在使用しているマシンに関する統計を検出できます。
curl -L http://127.0.0.1:4001/v2/stats/self
{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","startTime":"2014-09-11T16:42:03.035382298Z","leaderInfo":{"leader":"921a7241c31a499a97d43f785108b17c","uptime":"1h19m11.469872568s","startTime":"2014-09-12T19:47:25.242151859Z"},"recvAppendRequestCnt":1944480,"sendAppendRequestCnt":201817,"sendPkgRate":40.403374523779064,"sendBandwidthRate":3315.096879676072}
実行された操作に関する統計を表示するには、次のように入力します。
curl -L http://127.0.0.1:4001/v2/stats/store
{"getsSuccess":78823,"getsFail":14,"setsSuccess":121370,"setsFail":4,"deleteSuccess":28,"deleteFail":32,"updateSuccess":20468,"updateFail":4,"createSuccess":39,"createFail":102340,"compareAndSwapSuccess":51169,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":3,"watchers":6}
これらは、APIを介してetcd
を制御するために使用できる操作のほんの一部です。
Etcd構成
etcd
サービスは、いくつかの異なる方法で構成できます。
最初の方法は、ノードのブートストラップに使用するcloud-config
ファイルを使用してパラメーターを渡すことです。 ブートストラップガイドでは、これを行う方法について少し見ました。
#cloud-config coreos: etcd: discovery: https://discovery.etcd.io/<token> addr: $private_ipv4:4001 peer-addr: $private_ipv4:7001 . . .
使用可能なオプションを確認するには、-h
フラグをetcd
とともに使用します。
etcd -h
これらのオプションをcloud-config
に含めるには、先頭のダッシュを外し、等号の代わりにコロンを使用してキーを値から区切ります。 したがって、-peer-addr=<host:port>
はpeer-addr: <host:port>
になります。
CoreOSは、cloud-config
ファイルを読み取ると、これらをスタブユニットファイルの環境変数に変換します。このファイルは、サービスの開始に使用されます。
etcd
の設定を調整する別の方法は、APIを使用することです。 これは通常、キークエリに使用される標準の4001
の代わりに、7001
ポートを使用して行われます。
たとえば、次のように入力すると、現在の構成値の一部を取得できます。
curl -L http://127.0.0.1:7001/v2/admin/config
{"activeSize":9,"removeDelay":1800,"syncInterval":5}
これらの値を変更するには、PUT操作で新しいJSONをデータペイロードとして渡します。
curl -L http://127.0.0.1:7001/v2/admin/config -XPUT -d '{"activeSize":9,"removeDelay":1800,"syncInterval":5}'
{"activeSize":9,"removeDelay":1800,"syncInterval":5}
マシンのリストを取得するには、/v2/admin/machines
エンドポイントに移動します。
curl -L http://127.0.0.1:7001/v2/admin/machines
[{"name":"27987f5eaac243f88ca6823b47012c5b","state":"follower","clientURL":"http://10.132.248.121:4001","peerURL":"http://10.132.248.121:7001"},{"name":"2ddbdb7c872b4bc59dd1969ac166501e","state":"follower","clientURL":"http://10.132.252.38:4001","peerURL":"http://10.132.252.38:7001"},{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","clientURL":"http://10.132.248.118:4001","peerURL":"http://10.132.248.118:7001"}]
これは、DELETEメソッドを使用してクラスターからマシンを強制的に削除するために使用できます。
結論
ご覧のとおり、etcd
を使用して、クラスター内の任意のマシンから情報を保存または取得できます。 これにより、データを同期し、サービスが構成データと接続の詳細を検索する場所を提供できます。
これは、クラスター内の任意の場所から有効になる単純なエンドポイントを提供できるため、分散システムを構築するときに特に役立ちます。 このリソースを利用することで、サービスは動的に構成できます。