etcd集群自动化部署
etcd集群自动化部署
etcd集群部署涉及到证书生成和推送、etcd节点配置生成和推送,etcd配置文件维护等工作。本文记录下我自己搭建etcd集群工作过程为提高效率介绍出错 写的一些自动化脚本
按照etcd官方设计,etcd集群成员节点发现三种方式
- 静态成员
- etcd服务发现
- DNS发现etcd节点 他们有各自的优缺点,根据目前我们项目和环境情况,我选择了"方式一静态成员"。出于安全性考虑我们启用etcd client证书和 etcd peer证书
机器准备
在公有云上申请三个带公网的节点
etcd节点名称 | 私有IP | 公网IP |
---|---|---|
infra0 | 172.19.56.72 | 公网IP1 |
infra0 | 172.19.56.71 | 公网IP2 |
infra0 | 172.19.56.73 | 公网IP3 |
为方便后续操作,我们将IP地址导入到环境变量
export PRI_IP0="172.19.56.72"
export PUB_IP0="公网IP1"
export PRI_IP1="172.19.56.71"
export PUB_IP1="公网IP2"
export PRI_IP2="172.19.56.73"
export PUB_IP2="公网IP3"
云服务器ssh登录采用密钥方式,云服务器密钥本地存储路径 $HOME/certs/etcd-temp.pem
比如可以通过以下ssh登录到第一台服务器上 ssh -i ~/certs/etcd-temp.pem root@$PUB_IP0
生成证书 发布到etcd服务器上
一 证书生成工具选择
目前涉及密码学PKI(公钥基础设施)使用最广泛的是openssl
,Cloudflare公司开源的cfssl链接密码学和PKI工具箱也不错,能让证书生成过程简化一些,我们本次证书生成就用cfssl这个工具箱
etcd代码仓库里有使用cfssl生成证书的例子,我做了一些改造链接
二 安装cfssl命令行工具
go install github.com/cloudflare/cfssl/cmd/cfssl@latest
go install github.com/cloudflare/cfssl/cmd/cfssljson@latest
go install github.com/mattn/goreman@latest
三 使用工具生成证书 git clone我们的代码仓库,然后修改tls-setup/config/req-csr.json,设置节点IP。 其它两个配置文件,自己根据需求可以做调整,不做修改,默认也是可以的
# 需要导入下环境变量,设置节点infra0到infra2对应的私有IP
export infra0=$PRI_IP0
export infra1=$PRI_IP1
export infra2=$PRI_IP2
# 进入tls-setup
cd tls-setup
# 生成证书
make all
#client证书在certs,peer证书再peer-certs目录下
# make 其它目标任务
# make clean :清理证书,
# make ca :生成client CA证书
# make peerca :生成peer CA证书
# make req :生成client证书
# make peerreq :生成peer 节点证书
# 推送证书 IP按infra0、 infra1、infra2以此类推命名
# 证书名称以私有IP命名,推送通过公网IP,因此参数"私有IP:公网IP", IP对的形式
每个节点都有6个文件,三个节点,需要推送18个文件,写了个python脚本来推送
# 推送证书到目标机器
python3 etcd_cert_push.py -l $PRI_IP0:$PUB_IP0,$PRI_IP1:$PUB_IP1,$PRI_IP2:$PUB_IP2
发布etcd和etcdctl二进制文件
去 etcd仓库release页面 页面下载最新etcd包,我下载的是etcd-v3.4.23-linux-amd64.tar.gz。
etcd-v3.4.23-linux-amd64.tar.gz 本地解压,将etcd和etcdctl两个二进制文件发布到目标机器
# etcd和etcdctl二进制文件发布到第一台机器
scp -i certs/etcd-temp.pem ~/Downloads/etcd-v3.4.23-linux-amd64/etcd root@$PUB_IP0:/usr/local/bin/
scp -i certs/etcd-temp.pem ~/Downloads/etcd-v3.4.23-linux-amd64/etcdctl root@$PUB_IP0:/usr/local/bin/
# 第二台和第三台 省略
启动etcd集群节点验证
etcd集群节点启动过程需要设置大量参数,可以通过两种方式
- 方式一,命令行参数
- 方式二、指定配置文件
- 方式三、指定环境变量 本次 我们先生成命令行参数进行启动,验证没问题了,再生成配置文件,用指定配置文件方式启动 完整的参数列表可以参考etcd文档链接
一 生成启动命令参数 启动命令生成,etcd_start_cmd.py文件里
python3 etcd_start_cmd.py -l $PRI_IP0,$PRI_IP0,$PRI_IP0
生成IP:172.19.56.72,infra0 的etcd启动命令如下:
etcd --name infra0 --initial-advertise-peer-urls https://172.19.56.72:2380 \
--listen-peer-urls https://172.19.56.72:2380 \
--listen-client-urls https://172.19.56.72:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://172.19.56.72:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=https://172.19.56.72:2380,infra1=https://172.19.56.72:2380,infra2=https://172.19.56.72:2380 \
--initial-cluster-state new \
--client-cert-auth --trusted-ca-file=/etc/etcd/certs/ca-client.crt \
--cert-file=/etc/etcd/certs/infra0-client.crt --key-file=/etc/etcd/certs/infra0-client.key \
--peer-client-cert-auth --peer-trusted-ca-file=/etc/etcd/certs/peer-ca.crt \
--peer-cert-file=/etc/etcd/certs/peer-infra0.crt --peer-key-file=/etc/etcd/certs/peer-infra0.key
在三个节点上执行生成的启动命令,观察日志,是否有启动报错,如果没有报错,则执行etcdctl验证
# 用私有IP访问验证
etcdctl \
--cacert=/etc/etcd/certs/ca-client.crt \
--cert=/etc/etcd/certs/infra0-client.crt \
--key=/etc/etcd/certs/infra0-client.key \
--endpoints=https://$PRI_IP0:2379 \
put Name Jack
#用127.0.0.1验证
etcdctl \
--cacert=/etc/etcd/certs/ca-client.crt \
--cert=/etc/etcd/certs/infra0-client.crt \
--key=/etc/etcd/certs/infra0-client.key \
--endpoints=https://127.0.0.1:2379 \
put Name Jack
# 验证etcd集群成员
etcdctl \
--cacert=/etc/etcd/certs/ca-client.crt \
--cert=/etc/etcd/certs/infra0-client.crt \
--key=/etc/etcd/certs/infra0-client.key \
--endpoints=https://$PRI_IP0:2379 \
member list
生成etcd配置文件
以上验证通过后,最好将etcd启动参数放到yaml配置文件里。etcd通过指定yaml配置文件启动
生成配置文件脚本是 etcd_cfg_gen.py
#生成配置文件
python3 etcd_cfg_gen.py -l $PRI_IP0,$PRI_IP1,$PRI_IP2
#在当前目录下生成 etcd-$IP.yaml配置文件
# 推送文件到etcd服务器上
scp -i ~/certs/etcd-temp.pem etcd-$PRI_IP0.yaml root@$PUB_IP0:/etc/etcd/etcd.yaml
scp -i ~/certs/etcd-temp.pem etcd-$PRI_IP1.yaml root@$PUB_IP1:/etc/etcd/etcd.yaml
scp -i ~/certs/etcd-temp.pem etcd-$PRI_IP2.yaml root@$PUB_IP2:/etc/etcd/etcd.yaml
在三台etcd机器上,使用配置文件启动验证
etcd --config-file /etc/etcd/etcd.yaml
附加 etcd配置说明
完整的参数列表可以参考etcd文档链接
--name:方便理解的节点名称,默认为 default,在集群中应该保持唯一
--data-dir:服务运行数据保存的路径,默认为 ${name}.etcd
--snapshot-count:指定有多少事务(transaction)被提交时,触发截取快照保存到磁盘
--heartbeat-interval:leader 多久发送一次心跳到 followers。默认值是 100ms
--eletion-timeout:重新投票的超时时间,如果follower在该时间间隔没有收到心跳包,会触发重新投票,默认为 1000 ms
--listen-peer-urls:和同伴通信的地址,比如 http://ip:2380,如果有多个,使用逗号分隔。需要所有节点都能够访问,所以不要使用 localhost
--advertise-client-urls:对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点
--listen-client-urls:对外提供服务的地址:比如 http://ip:2379,http://127.0.0.1:2379,客户端会连接到这里和etcd交互
--initial-advertise-peer-urls:该节点同伴监听地址,这个值会告诉集群中其他节点
--initial-cluster:集群中所有节点的信息,格式为 node1=http://ip1:2380,node2=http://ip2:2380,…。需要注意的是,这里的 node1 是节点的--name指定的名字;后面的ip1:2380 是--initial-advertise-peer-urls 指定的值
--initial-cluster-state:新建集群的时候,这个值为 new;假如已经存在的集群,这个值为existing
--initial-cluster-token:创建集群的token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误
所有以--init开头的配置都是在第一次启动etcd集群的时候才会用到,后续节点的重启会被忽略,如--initial-cluseter参数。所以当成功初始化了一个etcd集群以后,就不再需要这个参数或环境变量了。
如果服务已经运行过就要把修改 --initial-cluster-state 为existing
--client-cert-auth client端请求是否启用认证
--trusted-ca-file=/etc/etcd/certs/ca-client.crt client CA证书
--cert-file=/etc/etcd/certs/infra0-client.crt client证书
--key-file=/etc/etcd/certs/infra0-client.key client 证书密钥
--peer-client-cert-auth etcd集群成员peer通信是否启用认证
--peer-trusted-ca-file=/etc/etcd/certs/peer-ca.crt peer CA证书
--peer-cert-file=/etc/etcd/certs/peer-infra0.crt peer节点证书
--peer-key-file=/etc/etcd/certs/peer-infra0.key peer节点证书密钥