Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

etcd を go から使う

More than 5 years have passed since last update.

概要

オフィシャルクライアントライブラリを使って etcd を go から触るという話。

準備

まず etcd を用意する。 Virtualbox と Vagrant があれば、coreos-vagrant を使ってローカルに CoreOS マシンを立てることで、http://172.17.8.101:4001 に etcd のエンドポイントができる。

Vagrant(Virtualbox) 上で CoreOS を動かす を参照。

次 go-etcd とってくる

$ go get coreos/go-etcd

go から etcd を触る

package main

import (
    "fmt"
    "github.com/coreos/go-etcd/etcd"
)

// list of etcd endpoint
var machines = []string{
    "http://172.17.8.101:4001",
}

func main() {
    // Create etcd client
    client := etcd.NewClient(machines)

    // SET "japan" to /country/jp
    if _, err := client.Set("/country/jp", "japan", 0); err == nil {
        fmt.Println("Set /country/jp") 
    } else {
        fmt.Println("error")
    }

    // SET "United States of Amarica" to /country/us
    if _, err := client.Set("/country/us", "United States of Amarica", 0); err == nil {
        fmt.Println("Set /country/us")
    } else {
        fmt.Println("error")
    }

    // GET /country/jp
    if res, err := client.Get("/country/jp", true, false); err == nil {
        fmt.Println("key:", res.Node.Key) // => key: /country/jp
        fmt.Println("value:", res.Node.Value) // => value: japan
    } else {
        fmt.Println("error")
    }

    // GET /country as raw data
    if res, err := client.RawGet("/country/jp", true, false); err == nil {
        fmt.Println(res.StatusCode) // => 200
        fmt.Println(string(res.Body)) // => {"action":"get","node":{"key":"/country/jp","value":"japan","modifiedIndex":5935,"createdIndex":5935}}
    } else {
        fmt.Println("error")
    }

    // GET /country as raw data
    if res, err := client.RawGet("/country", true, false); err == nil {
        fmt.Println(res.StatusCode) // => 200
        fmt.Println(string(res.Body)) // => {"action":"get","node":{"key":"/country","dir":true,"nodes":[{"key":"/country/jp","value":"japan","modifiedIndex":5935,"createdIndex":5935},{"key":"/country/us","value":"United States of Amarica","modifiedIndex":5936,"createdIndex":5936}],"modifiedIndex":4817,"createdIndex":4817}}
    } else {
        fmt.Println("error")
    }
}

再起的に取得

以下のようなサービスディスカバリ情報が /services 以下にあるとき、
(ちなみにこの /servicesCoreOS 上の Docker コンテナのサービス情報を registrator を使って etcd へ自動登録する でセットされてるもの)

core@core-01 ~ $ etcdctl ls --recursive /services
/services/logspout
/services/logspout/core-01:logspout:8000
/services/logspout/core-02:logspout:8000
/services/logspout/core-03:logspout:8000
/services/registry
/services/registry/core-01:registry:5000
/services/registry/core-02:registry:5000
/services/registry/core-03:registry:5000

以下のように、RawGet の 3 つ目の引数(recursive オプション) に true を渡すことで

    // GET /services as raw data
    if res, err := client.RawGet("/services", true, true); err == nil {
        fmt.Println(res.StatusCode)
        fmt.Println(string(res.Body))
    } else {
        fmt.Println("error")
    }

/services 以下のデータが全て取得できる

{
  "node": {
    "createdIndex": 268,
    "modifiedIndex": 268,
    "nodes": [
      {
        "createdIndex": 313,
        "modifiedIndex": 313,
        "nodes": [
          {
            "createdIndex": 4760,
            "modifiedIndex": 4760,
            "value": "172.17.8.101:8000",
            "key": "/services/logspout/core-01:logspout:8000"
          },
          {
            "createdIndex": 4552,
            "modifiedIndex": 4552,
            "value": "172.17.8.102:8000",
            "key": "/services/logspout/core-02:logspout:8000"
          },
          {
            "createdIndex": 4579,
            "modifiedIndex": 4579,
            "value": "172.17.8.103:8000",
            "key": "/services/logspout/core-03:logspout:8000"
          }
        ],
        "dir": true,
        "key": "/services/logspout"
      },
      {
        "createdIndex": 268,
        "modifiedIndex": 268,
        "nodes": [
          {
            "createdIndex": 4761,
            "modifiedIndex": 4761,
            "value": "172.17.8.101:5000",
            "key": "/services/registry/core-01:registry:5000"
          },
          {
            "createdIndex": 4554,
            "modifiedIndex": 4554,
            "value": "172.17.8.102:5000",
            "key": "/services/registry/core-02:registry:5000"
          },
          {
            "createdIndex": 4581,
            "modifiedIndex": 4581,
            "value": "172.17.8.103:5000",
            "key": "/services/registry/core-03:registry:5000"
          }
        ],
        "dir": true,
        "key": "/services/registry"
      }
    ],
    "dir": true,
    "key": "/services"
  },
  "action": "get"
}

メモと感想

他にできること

  • TLC クライアントを作成する NewTLSClient
  • etcd の変更を long polling で監視する Watch
  • etcd クラスタ情報の取得する GetCluster

などなど。

詳細は go-etcd - GoDoc を参照。

REF

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