CoreOSの分散Key-ValueストアであるEtcdctlおよびEtcdの使用方法

前書き

CoreOSを可能にするテクノロジーの1つは、グローバルに分散されたキーと値のストアである「+ etcd +」です。 このサービスは、個々のCoreOSマシンがクラスターを形成し、グローバルにアクセス可能なデータを保存するプラットフォームとして使用します。

このガイドでは、 `+ etcd `デーモンと、それを制御するために使用できる ` etcdctl +`ユーティリティおよびHTTP / JSON APIについて説明します。

前提条件

このガイドに従うには、https://www.digitalocean.com/community/tutorials/how-to-set-up-a-coreos-cluster-onにあるガイドとしてCoreOSマシンのクラスターがあることを前提としています-digitalocean [DigitalOceanでセットアップされたCoreOSクラスターの取得]の概要。 これにより、1つのクラスターに3つのサーバーが残ります。

  • coreos-1

  • coreos-2

  • coreos-3

これらのマシンを稼働させたら、このガイドを続行できます。

Etcdクラスターディスカバリモデル

「+ etcd 」が担当する最も基本的なタスクの1つは、個々のマシンをクラスターに編成することです。 これは、作成時に渡される ` cloud-config +`ファイルで提供されるディスカバリアドレスでチェックインすることにより、CoreOSが起動されるときに行われます。

CoreOSによって実行されるディスカバリサービスには、 `+ https:// discovery.etcd.io `からアクセスできます。 「 / new +」ページにアクセスして、新しいトークンを取得できます。 そこで、マシンがコンパニオンノードを発見するために使用できるトークンを取得します。 次のようになります。

https://discovery.etcd.io/

新しいクラスターごとに新しいトークンを提供する必要があります。 これには、同じ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つを選択して直接接続し、正常なクラスターメンバーの完全なリストを取得します。 データの複製と配布は、http://raftconsensus.github.io/ [Raft consensus algorithm]を介して行われます。

各マシンに関するデータは、 `+ 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つの基本的な方法があります。 付属の ` etcdctl `ユーティリティのように、HTTP / JSON APIおよびクライアントを介して。 最初に ` 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

空のディレクトリ_or_キーのみを削除するには、 `+ 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 +`ツールではリストされていません。それらを見つけるには、何を探しているのかを知る必要があります。

たとえば、 `+ fleet `に関する内部情報を保持する ` / _ coreos.com +`という隠しディレクトリがあります。 明示的に要求することで、階層を確認できます。

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 / JSON APIの使用

`+ etcd +`と対話する他の方法は、単純なHTTP / JSON APIを使用することです。

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/
   addr: $private_ipv4:4001
   peer-addr: $private_ipv4:7001
. . .

利用可能なオプションを確認するには、 `+ -h `フラグと ` etcd +`を使用します。

etcd -h

これらのオプションを `+ cloud-config `に含めるには、先頭のダッシュを外し、等号ではなくコロンで値からキーを分離します。 したがって、 ` -peer-addr = <host:port> `は ` peer-addr:<host:port> +`になります。

`+ cloud-config +`ファイルを読み取ると、CoreOSはこれらをスタブユニットファイル内の環境変数に変換し、サービスを開始するために使用されます。

`+ 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 +`を使用して、クラスター内の任意のマシンから情報を保存または取得できます。 これにより、データを同期し、サービスが構成データと接続の詳細を検索する場所を提供できます。

これは、クラスター内の任意の場所から有効なシンプルなエンドポイントを提供できるため、分散システムを構築するときに特に役立ちます。 このリソースを利用することで、サービスは動的に構成できます。