分布式KV配置服务etcd

1. 部署集群
1) 安装etcd
CentOS 7可以直接yum安装

# yum install etcd
# etcd --version
etcd Version: 2.3.7  
Git SHA: fd17c91  
Go Version: go1.6.3  
Go OS/Arch: linux/amd64  

CentOS 6直接下载编译后文件

# cd /opt/
# curl -L https://github.com/coreos/etcd/releases/download/v3.0.4/etcd-v3.0.4-linux-amd64.tar.gz -o etcd-v3.0.4-linux-amd64.tar.gz
# tar xzvf etcd-v3.0.4-linux-amd64.tar.gz && mv etcd-v3.0.4-linux-amd64 etcd
# cd etcd
# ./etcd --version
etcd Version: 3.0.4  
Git SHA: d53923c  
Go Version: go1.6.3  
Go OS/Arch: linux/amd64  

2) 初始化集群
在节点node0执行

# /opt/etcd/etcd --name node0 --listen-peer-urls http://192.168.153.149:2380 --listen-client-urls http://192.168.153.149:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.153.149:2379 --data-dir /opt/etcd/default.etcd/ --initial-advertise-peer-urls http://192.168.153.149:2380 --initial-cluster-token etcd-cluster-1 --initial-cluster node0=http://192.168.153.149:2380,node1=http://172.17.10.64:2380 --initial-cluster-state new

在节点node1执行

# /opt/etcd/etcd --name node1 --listen-peer-urls http://172.17.10.64:2380 --listen-client-urls http://172.17.10.64:2379,http://127.0.0.1:2379 --advertise-client-urls http://172.17.10.64:2379 --data-dir /opt/etcd/default.etcd/ --initial-advertise-peer-urls http://172.17.10.64:2380 --initial-cluster-token etcd-cluster-2 --initial-cluster node0=http://192.168.153.149:2380,node1=http://172.17.10.64:2380 --initial-cluster-state new

3) 启动etcd服务
在节点分别启动etcd

# /opt/etcd/etcd --name node0 --listen-peer-urls http://192.168.153.149:2380 --listen-client-urls http://192.168.153.149:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.153.149:2379 --data-dir /opt/etcd/default.etcd/

添加到supervisor

[program:etcd]
command=/opt/etcd/etcd --name node0 --listen-peer-urls http://192.168.153.149:2380 --listen-client-urls http://192.168.153.149:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.153.149:2379 --data-dir /opt/etcd/default.etcd/  
user=root  
autostart=true  
autorestart=true  
director=/opt/etcd  

4) 查看集群
集群已经部署完成,查看集群成员

# /opt/etcd/etcdctl member list
4b2b08449b316707: name=node1 peerURLs=http://172.17.10.64:2380 clientURLs=http://172.17.10.64:2379 isLeader=true  
84a614380cb123f9: name=node0 peerURLs=http://192.168.153.149:2380 clientURLs=http://192.168.153.149:2379 isLeader=false  

参考文档:
https://github.com/coreos/etcd/releases/
https://coreos.com/etcd/docs/latest/clustering.html

2. 权限控制
1) 增加角色role
查看etcd默认role root

# cd /opt/etcd
# ./etcdctl role list
root  
# ./etcdctl role get root
Role: root  
KV Read:  
    /*
KV Write:  
    /*

增加只读访问role guest

# ./etcdctl role add guest
# ./etcdctl role list
guest  
root  
# ./etcdctl role grant guest -path '/*' -read
Role guest updated  
# ./etcdctl role get guest
Role: guest  
KV Read:  
    /*
KV Write:  

2) 增加用户user
设置root密码

# ./etcdctl user get root
User: root  
Roles:  root  
# ./etcdctl user passwd root
New password:  
Password updated  

增加新用户guest,并设置role为guest只读

# ./etcdctl user add guest
New password:  
User guest created  
# ./etcdctl user grant guest --roles guest
User guest updated  
# ./etcdctl user get guest
User: guest  
Roles:  guest  

3) 开启权限控制

# ./etcdctl auth enable

使用guest用户测试写入,报错

# curl -u guest:guest 'http://127.0.0.1:2379/v2/keys/test' -XPUT -d value="hello world"
{"errorCode":110,"message":"The request requires user authentication","cause":"Insufficient credentials","index":0}

使用root用户测试写入,成功

# curl -u root:rootpwd 'http://127.0.0.1:2379/v2/keys/test' -XPUT -d value="hello world"
{"action":"set","node":{"key":"/test","value":"hello world","modifiedIndex":447,"createdIndex":447}}

权限控制生效,guest只读

# curl -u guest:guest 'http://127.0.0.1:2379/v2/keys/test' 
{"action":"get","node":{"key":"/test","value":"hello world","modifiedIndex":449,"createdIndex":449}}
# curl -u root:rootpwd 'http://127.0.0.1:2379/v2/keys/test' -XDELETE 
{"action":"delete","node":{"key":"/test","modifiedIndex":450,"createdIndex":449},"prevNode":{"key":"/test","value":"hello world","modifiedIndex":449,"createdIndex":449}}
# curl -u guest:guest 'http://127.0.0.1:2379/v2/keys/test' 
{"errorCode":100,"message":"Key not found","cause":"/test","index":450}

参考文档:
https://coreos.com/etcd/docs/latest/authentication.html

3. API接口
1) HTTP接口
写入

# curl -u root:rootpwd 'http://127.0.0.1:2379/v2/keys/test' -XPUT -d value="hello world"
{"action":"set","node":{"key":"/test","value":"hello world","modifiedIndex":451,"createdIndex":451}}

读取

# curl -u root:rootpwd 'http://127.0.0.1:2379/v2/keys/test' 
{"action":"get","node":{"key":"/test","value":"hello world","modifiedIndex":451,"createdIndex":451}}

删除

# curl -u root:rootpwd 'http://127.0.0.1:2379/v2/keys/test' -XDELETE
{"action":"delete","node":{"key":"/test","modifiedIndex":452,"createdIndex":451},"prevNode":{"key":"/test","value":"hello world","modifiedIndex":451,"createdIndex":451}}

参考文档:
https://github.com/coreos/etcd/blob/master/Documentation/v2/api.md

2) python-etcd
python2.7可以直接使用pip安装

# pip install python-etcd

python2.6需要使用官方github上源码安装
https://github.com/jplana/python-etcd

# python setup.py install

查看、增加、删除key

In [242]: import etcd

In [243]: c = etcd.Client((("192.168.153.149", 2379), ("172.17.10.64", 2379)), username="root", password="rootpwd", allow_reconnect=True)

In [244]: c.members  
Out[244]:  
{u'4b2b08449b316707': {u'clientURLs': [u'http://172.17.10.64:2379'],
  u'id': u'4b2b08449b316707',
  u'name': u'node1',
  u'peerURLs': [u'http://172.17.10.64:2380']},
 u'84a614380cb123f9': {u'clientURLs': [u'http://192.168.153.149:2379'],
  u'id': u'84a614380cb123f9',
  u'name': u'node0',
  u'peerURLs': [u'http://192.168.153.149:2380']}}

In [245]: c.leader  
Out[245]:  
{u'clientURLs': [u'http://172.17.10.64:2379'],
 u'id': u'4b2b08449b316707',
 u'name': u'node1',
 u'peerURLs': [u'http://172.17.10.64:2380']}

In [246]: c.write('/test', 'hello world').value  
Out[246]: u'hello world'

In [247]: c.get('/test').value  
Out[247]: u'hello world'

In [248]: c.delete('/test').value  

参考文档:
https://github.com/jplana/python-etcd