ども、cloudpackかっぱ (@inokara) です。

はじめに

fabric のデプロイターゲットを Consul から取得できたら面白そうだなって思ったので連携を模索するにあったって Consul の Python クライアントを触ってみました。

参考

準備

Consul とは

については tag:consul をご覧頂くか、@zenbutsu さんの以下の記事がとても参考になります。

Consul を起動

以下のように一台のノードで起動しておきます。

consul agent -server -bootstrap -client=127.0.0.1 -dc=local -node=consul1 -data-dir=/tmp/consul -bind=127.0.0.1 &

あくまでテスト用途なのでノード一台での実運用はオススメ出来ません。

データを入れておきます

service への登録
cat << EOT | curl -XPUT http://127.0.0.1:8500/v1/agent/service/register -d @-
{
  "ID": "web-app",
  "Name": "web-app",
  "tags": ["web-app"],
  "port": 80
}
EOT

curl 等の HTTP クライアントを利用してデータを取得することが出来ます。

{
  "consul": {
    "ID": "consul",
    "Service": "consul",
    "Tags": [],
    "Port": 8300
  },
  "web-app": {
    "ID": "web-app",
    "Service": "web-app",
    "Tags": [
      "web-app"
    ],
    "Port": 80
  }
}
kvs への登録
curl -X PUT -d 'Hello consul' http://localhost:8500/v1/kv/foo

もちろん、こちらも curl 等の HTTP クライアントでデータを取得することが可能です。

[
  {
    "CreateIndex": 24,
    "ModifyIndex": 123,
    "LockIndex": 0,
    "Key": "foo",
    "Flags": 0,
    "Value": "SGVsbG8gY29uc3Vs"
  }
]

値はエンコードされているので解読するにはデコードが必要になります。

python-consul のインストール

pip で以下のようにインストール。

sudo pip install python-consul

簡単ですね。

但し…

Amazon Linux(Amazon Linux AMI release 2014.09)の場合には python-consul が利用する urllib というライブラリを含む six というライブラリ群をバージョンアップする必要がありました。

python -c 'import six; print six.__version__'

バージョンを確認して…

pip install --upgrade six

を実行してバージョンアップを行います。

$ python -c 'import six; print six.__version__'
1.8.0

今回は 1.8.0 で試してみたいと思います。

尚、six ライブラリはドキュメントによると Python2 と Python3 の互換ライブラリのようです。

試す

kvs のデータ取得と登録

上記で既に kvs へのデータは登録済みなので以下のようにデータを取得してみます。

import consul

c = consul.Consul()

index = None
index, foo = c.kv.get('foo', index=index)
print foo
print foo['Value']

これを以下のように実行します。

python test.py

実行すると以下のように出力されます。

{u'LockIndex': 0, u'ModifyIndex': 123, u'Value': 'Hello consul', u'Flags': 0, u'Key': u'foo', u'CreateIndex': 24}
Hello consul

kvs への登録は以下のように行います。

>>> import consul
>>> c = consul.Consul()
>>> c.kv.put('hoge', 'fuga')
True

Python インタプリタ(Ruby 的には irb や pry と同等だと思っている)での実行例ですが、以下のようにデータが登録されていることが判ります。

$ curl -s http://localhost:8500/v1/kv/hoge | jq .
[
  {
    "CreateIndex": 194,
    "ModifyIndex": 197,
    "LockIndex": 0,
    "Key": "hoge",
    "Flags": 0,
    "Value": "ZnVnYQ=="
  }
]

service の検出

登録済みのサービスを取得してみたいと思いますので以下のようにスクリプトを書きます。

import consul

c = consul.Consul()

index = None
index, bar = c.catalog.services()
print bar
print bar['web-app']

スクリプトを実行すると以下のように出力されます。

{u'consul': [], u'web-app': [u'web-app']}
[u'web-app']

node の検出

consul のノードを取得してみたいので以下のようにスクリプトを書きます。

import consul

c = consul.Consul()

index = None
index, baz = c.catalog.nodes()
print baz
print baz[0]['Address']

スクリプトを実行すると以下のように出力されます。

[{u'Node': u'consul1', u'Address': u'127.0.0.1'}]
127.0.0.1

上記のように IP アドレスのみを取得することが可能です。また、curl 単体で IP アドレスを取得するよりもちょっとだけ簡単なような気がします…。

とりあえず…

consul クライアントを利用して consul 上のサービスやノード、kvs の情報を取得することが出来ました。次は fabric と組み合わせてデプロイ先のターゲットノードの情報を consul から取得してデプロイという流れを作ってみたいと思います。

おやすみなさい。

元記事はこちらです。
consul の Python クライアントを試す