通过docker部署etcd
单机部署etcd
docker run \
-d \
-p 2379:2379 \
-p 2380:2380 \
--mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \
--name etcd-quay-v3.5.0 \
quay.io/coreos/etcd:v3.5.0 \
/usr/local/bin/etcd \
--name s1 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-advertise-peer-urls http://0.0.0.0:2380 \
--initial-cluster s1=http://0.0.0.0:2380 \
--initial-cluster-token tkn \
--initial-cluster-state new \
--log-level info \
--logger zap \
--log-outputs stderr
关键参数解析
参数 | 说明 |
---|---|
--name | etcd节点名称 |
--initial-cluster | etcd启动的时候,通过此配置找到其他节点的地址列表 格式:'节点名称:http://ip:2380' 案例:s1=http://0.0.0.0:2380 |
--initial-cluster-state | 初始化的时候,集群的状态 "new" 或者 "existing"两种状态,new代表新建的集群,existing表示加入已经存在的集群。 |
--listen-client-urls | 监听客户端请求的地址列表,格式:'http://localhost:2379', 多个用逗号分隔。 |
--advertise-client-urls | 如果--listen-client-urls配置了,多个监听客户端请求的地址,这个参数可以给出,建议客户端使用什么地址访问etcd。 |
--listen-peer-urls | 服务端节点之间通讯的监听地址,格式:'http://localhost:2380' |
--initial-advertise-peer-urls | 建议服务端之间通讯使用的地址列表。 |
安装过程
Unable to find image 'quay.io/coreos/etcd:v3.5.0' locally
v3.5.0: Pulling from coreos/etcd
1813d21adc01: Pull complete
6e96907ab677: Pull complete
444ed0ea8673: Pull complete
0fd2df5633f0: Pull complete
8cc22b9456bb: Pull complete
7ac70aecd290: Pull complete
4b376c64dfe4: Pull complete
Digest: sha256:28759af54acd6924b2191dc1a1d096e2fa2e219717a21b9d8edf89717db3631b
Status: Downloaded newer image for quay.io/coreos/etcd:v3.5.0
容器外验证
MacBook-Pro rpc % docker exec 9f62717b21a8 /bin/sh -c "/usr/local/bin/etcd --version"
etcd Version: 3.5.0
Git SHA: 946a5a6f2
Go Version: go1.16.3
Go OS/Arch: linux/amd64
MacBook-Pro rpc % docker exec 9f62717b21a8 /bin/sh -c "/usr/local/bin/etcdctl version"
etcdctl version: 3.5.0
API version: 3.5
MacBook-Pro rpc % docker exec 9f62717b21a8 /bin/sh -c "/usr/local/bin/etcdctl endpoint health"
127.0.0.1:2379 is healthy: successfully committed proposal: took = 5.6964ms
MacBook-Pro rpc % docker exec 9f62717b21a8 /bin/sh -c "/usr/local/bin/etcdctl put foo bar"
OK
MacBook-Pro rpc % docker exec 9f62717b21a8 /bin/sh -c "/usr/local/bin/etcdctl get foo"
foo
bar
容器内验证
MacBook-Pro rpc % docker exec -it 66658ceef406 /bin/sh
# cd /usr/local/bin
# ls -al
total 56240
drwxr-xr-x 1 root root 4096 Jun 15 21:53 .
drwxr-xr-x 1 root root 4096 Jan 11 2021 ..
-rwxr-xr-x 1 root root 1050 Jan 27 2021 clean-install
-rwxr-xr-x 1 root root 23560192 Jun 15 21:52 etcd
-rwxr-xr-x 1 root root 17969152 Jun 15 21:52 etcdctl
-rwxr-xr-x 1 root root 16048128 Jun 15 21:52 etcdutl
lrwxrwxrwx 1 root root 4 Jan 27 2021 invoke-rc.d -> noop
-r-xr-xr-x 1 root root 0 Jan 27 2021 noop
lrwxrwxrwx 1 root root 4 Jan 27 2021 runlevel -> noop
lrwxrwxrwx 1 root root 4 Jan 27 2021 update-rc.d -> noop
# etcd --version
etcd Version: 3.5.0
Git SHA: 946a5a6f2
Go Version: go1.16.3
Go OS/Arch: linux/amd64
# etcdctl version
etcdctl version: 3.5.0
API version: 3.5
# etcdctl endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 4.1765ms
# etcdctl get foo
foo
bar
集群模式
docker-compose.yaml文件
version: '2'
networks:
etcdnet:
services:
etcd1:
image: quay.io/coreos/etcd:v3.5.0
container_name: etcd1
command: etcd -name etcd1 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- etcdnet
etcd2:
image: quay.io/coreos/etcd:v3.5.0
container_name: etcd2
command: etcd -name etcd2 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- etcdnet
etcd3:
image: quay.io/coreos/etcd:v3.5.0
container_name: etcd3
command: etcd -name etcd3 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- etcdnet
集群启动服务
MacBook-Pro etcd % docker-compose up -d
Creating network "etcd_etcdnet" with the default driver
Creating etcd2 ... done
Creating etcd1 ... done
Creating etcd3 ... done
MacBook-Pro etcd % docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
85044bbb6d81 quay.io/coreos/etcd:v3.5.0 "etcd -name etcd1 -a…" 12 seconds ago Up 10 seconds 0.0.0.0:64640->2379/tcp, 0.0.0.0:64641->2380/tcp etcd1
692ae553cf5c quay.io/coreos/etcd:v3.5.0 "etcd -name etcd2 -a…" 12 seconds ago Up 11 seconds 0.0.0.0:64638->2379/tcp, 0.0.0.0:64639->2380/tcp etcd2
911035389db3 quay.io/coreos/etcd:v3.5.0 "etcd -name etcd3 -a…" 12 seconds ago Up 10 seconds 0.0.0.0:64643->2379/tcp, 0.0.0.0:64642->2380/tcp etcd3
集群状态验证
Golang连接
golang连接需要使用“go.etcd.io/etcd/client/v3”依赖包
校验是否能够连接
package main
import (
"log"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
)
func main() {
config := clientv3.Config{
// etcd的多个节点服务地址
Endpoints: []string{"127.0.0.1:2379"},
// 创建client的首次连接超时时间
DialTimeout: 5 * time.Second,
}
client, err := clientv3.New(config)
if err != nil {
log.Panic(err)
return
}
defer client.Close()
log.Println("connect success")
}
增、删、改、查
package main
import (
"context"
"log"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
)
func main() {
// 配置
config := clientv3.Config{
// etcd的多个节点服务地址
Endpoints: []string{"127.0.0.1:2379"},
// 创建client的首次连接超时时间
DialTimeout: 5 * time.Second,
}
// 创建etcd客户端
client, err := clientv3.New(config)
if err != nil {
log.Panic(err)
return
}
defer client.Close()
// 操作增删改查
etcd := NewEtcdInfo(client)
key := "/demo/key"
etcd.Put(key, "value")
etcd.Get(key)
etcd.Update(key, "update_value")
etcd.Get(key)
etcd.Delete(key)
}
type EtcdInfo struct {
ctx context.Context
client *clientv3.Client
}
func NewEtcdInfo(client *clientv3.Client) *EtcdInfo {
etcd := new(EtcdInfo)
etcd.client = client
etcd.ctx = context.Background()
return etcd
}
// 设置值
func (e *EtcdInfo) Put(key, value string) {
// 增加值
res, err := e.client.Put(e.ctx, key, value)
if err != nil {
log.Panicf("put fail err:%v", err)
return
}
log.Printf("pus res:%v", *res)
}
// 获取值
func (e *EtcdInfo) Get(key string) {
// 增加值
res, err := e.client.Get(e.ctx, key)
if err != nil {
log.Panicf("put fail err:%v", err)
return
}
for _, item := range res.Kvs {
log.Printf("key:%v, value:%v \n", string(item.Key), string(item.Value))
}
}
// 修改值
func (e *EtcdInfo) Update(key, value string) {
res, err := e.client.Put(e.ctx, key, value, clientv3.WithPrevKV())
if err != nil {
log.Panicf("update fail err:%v", err)
return
}
log.Printf("update value:%v", string(res.PrevKv.Value))
}
func (e *EtcdInfo) Delete(key string) {
resp, err := e.client.Delete(e.ctx, key)
if err != nil {
log.Panicf("delete fail err:%v", err)
return
}
log.Printf("delete value:%v \n", resp.PrevKvs)
}
参考
Running etcd under Docker | etcd
Releases · etcd-io/etcd (github.com)
coreos/etcd · Quay
Docker安装etcd_w3cschool
etcd 使用: golang 例子 - 九卷 - 博客园 (cnblogs.com)