ETCD系列教程2 – ETCD体验

ETCD安装

直接安装

以MAC系统为例,讲述2种按照方法,第一种很简单,是Mac自带的:

#用brew安装非常方便,没安装的自行安装Homebrew,通过下面命令可以查看安装包
brew search etcd
#安装
brew install etcd
#查看版本
etcd --version
#启动,如果没有--enable-v2=true,就不用使用v2的接口
etcd --enable-v2=true
复制代码

不过这种方式可能会安装失败,我这把失败时提示日志目前没有权限,根据提示执行相关命令即可,我这边的提示如下:

sudo chown -R $(whoami) /usr/local/var/log
复制代码

源码安装

我个人更推荐下面这种安装方式:

ETCD_VER=v3.4.14

# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
unzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
mv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf mv /tmp/etcd-${ETCD_VER}-darwin-amd64

#输出etcd版本
/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version

#这里是把etcd和etcdctl copy到bin目录下面
cp /tmp/etcd-download-test/etcd /usr/local/bin
cp /tmp/etcd-download-test/etcdctl /usr/local/bin
然后执行:
#安装etcd
sh etcd_install.sh
#查看版本
etcd --version
#启动,如果没有--enable-v2=true,就不用使用v2的接口
etcd --enable-v2=true
复制代码

集群部署

部署流程

下面我们可以部署一个etcd集群,我把代码还是写到文件中,第一个脚本为不支持在 Docs 外粘贴 block,内容如下(启动etcd需要很多参数,这些参数我都已经注释说明,更多参数详见:https://www.cnblogs.com/linuxws/p/11194403.html):

TOKEN=token-01
CLUSTER_STATE=new
NAME_1=etcd-01
NAME_2=etcd-02
NAME_3=etcd-03
HOST_1=127.0.0.1
HOST_2=127.0.0.1
HOST_3=127.0.0.1
PORT_API_1=2379
PORT_PEER_1=2380
PORT_API_2=2479
PORT_PEER_2=2480
PORT_API_3=2579
PORT_PEER_3=2580

CLUSTER=${NAME_1}=http://${HOST_1}:${PORT_PEER_1},${NAME_2}=http://${HOST_2}:${PORT_PEER_2},${NAME_3}=http://${HOST_3}:${PORT_PEER_3}

# For every machine
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
THIS_PORT_API=${PORT_API_1}
THIS_PORT_PEER=${PORT_PEER_1}
# 用于杀死进程
lsof -i:2379 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9

# --enable-v2 支持v2接口,可以省略
# --data-dir 数据存储目录,可以省略
# --name 节点名称,必须
# --initial-advertise-peer-urls  数据在集群内进行交互的url,必须
# --listen-peer-urls  集群节点之间通信监听的url,必须
# --advertise-client-urls 客户通过该地址与本member交互信息,可以省略
# --listen-client-urls 监听客户端请求的url,必须
# --initial-cluster 初始启动的集群配置,必须
# --initial-cluster-state 初始化集群状态,取值为new和existing,可以省略
# --initial-cluster-token 集群初始化token,可以省略
etcd --enable-v2=true --data-dir=data.${THIS_NAME} --name ${THIS_NAME} \
        --initial-advertise-peer-urls http://${THIS_IP}:${THIS_PORT_PEER} --listen-peer-urls http://${THIS_IP}:${THIS_PORT_PEER} \
        --advertise-client-urls http://${THIS_IP}:${THIS_PORT_API} --listen-client-urls http://${THIS_IP}:${THIS_PORT_API} \
        --initial-cluster ${CLUSTER} \
        --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
复制代码

第二个脚本需要把里面的内容替换如下:

# For every machine
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
THIS_PORT_API=${PORT_API_2}
THIS_PORT_PEER=${PORT_PEER_2}
# 用于杀死进程
lsof -i:2479 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9
复制代码

第三个脚本需要把里面的内容替换如下:

# For every machine
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
THIS_PORT_API=${PORT_API_3}
THIS_PORT_PEER=${PORT_PEER_3}
# 用于杀死进程
lsof -i:2579 | awk '{print $2}' | grep -v "PID" | uniq | xargs kill -9
复制代码

有了这3个脚本,分别开3个窗口,分别执行,服务启动截图如下:

当这3个脚本全部启动后,集群部署完毕,我们检查一下3个节点的健康状态:

curl http://127.0.0.1:2379/health
curl http://127.0.0.1:2479/health
curl http://127.0.0.1:2579/health
复制代码

如果都返回{“health”:”true”},表示部署成功,下面我们查看一下部署的节点信息:

curl http://127.0.0.1:2379/v2/members
复制代码

返回结果如下,其中peerURLs是节点互相通信访问的url,clientURLs是对外访问的url:

{
    "members":[
        {
            "id":"264ae6bc59e99892",
            "name":"etcd-01",
            "peerURLs":[
                "http://127.0.0.1:2380"
            ],
            "clientURLs":[
                "http://127.0.0.1:2379"
            ]
        },
        {
            "id":"dbafe5ad6b652eda",
            "name":"etcd-02",
            "peerURLs":[
                "http://127.0.0.1:2480"
            ],
            "clientURLs":[
                "http://127.0.0.1:2479"
            ]
        },
        {
            "id":"f570ae41f524bdcb",
            "name":"etcd-03",
            "peerURLs":[
                "http://127.0.0.1:2580"
            ],
            "clientURLs":[
                "http://127.0.0.1:2579"
            ]
        }
    ]
}
复制代码

遇到问题

问题1:服务启动后,不能使用v2接口,比如执行“curl http://127.0.0.1:2379/v2/members”,提示“404 page not found”

问题原因:因为V3.4版本默认是V3接口,不支持V2

解决方案:需要在启动etcd时,加上“–enable-v2=true”,强制使用V2接口

问题2:服务启动失败,提示“conflicting environment variable “ETCD_ENABLE_V2” is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”

问题原因:因为启动etcd时,参数“–enable-v2=true”导致,因为V3.4版本会读取该配置,所以提示配置重复。

解决方案:不能删除该参数,否则会引入其它问题,我是关闭所有窗口,然后重新启动etcd即可。

问题3:启动某个节点时,提示member已经存在

问题原因:因为之前启动过该节点,该member已经存在,不能初始化,只能加入已经存在的member

解决方案:需要将启动脚本中的“CLUSTER_STATE=new”改为“CLUSTER_STATE=existing”

常规操作

集群管理

我们在部署集群时,用到一些方法,这里我简单汇总一下:

// 版本检查,输出{"etcdserver":"3.4.14","etcdcluster":"3.4.0"}
curl http://127.0.0.1:2379/version
// 健康检查,输出{"health":"true"}
curl http://127.0.0.1:2379/health
// 查看集群节点
curl http://127.0.0.1:2379/v2/members
复制代码

键值操作

设置键的值:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world"
复制代码

返回结果:

{
    "action":"set",
    "node":{
        "key":"/message",
        "value":"hello world",
        "modifiedIndex":43,
        "createdIndex":43
    }
}
复制代码

读取键的值:

curl http://127.0.0.1:2379/v2/keys/message
复制代码

返回结果:

{
    "action":"get",
    "node":{
        "key":"/message",
        "value":"hello world",
        "modifiedIndex":43,
        "createdIndex":43
    }
}
复制代码

给键设置10s的超时时间:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world" -d ttl=10
复制代码

返回结果(prevNode是旧值):

{
    "action":"set",
    "node":{
        "key":"/message",
        "value":"hello world",
        "expiration":"2021-01-21T00:16:13.777434Z",
        "ttl":10,
        "modifiedIndex":44,
        "createdIndex":44
    },
    "prevNode":{
        "key":"/message",
        "value":"hello world",
        "modifiedIndex":43,
        "createdIndex":43
    }
}
复制代码

获取该键值,超时后,就提示“key not found”:

watch通知

可以对key设置监听,当key的值有变化时,会通知监听的客户端,我们先在客户端A监听key:

curl http://127.0.0.1:2379/v2/keys/message?wait=true
复制代码

然后在客户端B,修改该key的值:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world2"
复制代码

客户端A返回并退出,返回结果:

{
    "action":"set",
    "node":{
        "key":"/message",
        "value":"hello world2",
        "modifiedIndex":48,
        "createdIndex":48
    }
}
复制代码

如果希望客户端A能持续监听,不退出,可以通过增加stream=true参数:

curl "http://127.0.0.1:2379/v2/keys/message?wait=true&stream=true"
复制代码

当在客户端B执行如下时:

curl http://127.0.0.1:2379/v2/keys/message -XPUT -d value="hello world" -d ttl=10
复制代码

客户端A会实时监听返回,比如当给key设置值,或者当key过期时,客户端A都会监听到:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享