二进制部署etcd集群(企业级)
Etcd是一款分布式存储中间件,使用Go语言编写并通过Raft一致性算法处理和确保分布式一致性解决了分布式系统中数据一致性的问题。
Etcd常用于微服务架构中的服务注册与发现中心,相较于Zookeeper部署更简单,而且具有数据持久化、支持SSL客户端安全认证的独特优势;
Etcd是目前非常热门的云原生存储组件,自2018年底加入CNCF并于2020年11月毕业。
环境说明
主机规划
本文档使用说明:全局将IP修改为自己环境的地址,其它版本亦可参照本文,操作步骤大体类似。
高可用集群的三种形式
- 静态配置
预先已经知道etcd集群有哪些节点,在启动时通过--initial-cluster
参数直接指定好etcd的各个节点地址。
- etcd动态发现
通过已经搭建好的etcd来辅助搭建新的etcd集群,已有的etcd集群作为数据交互点,然后在扩展新的集群时,实现通过已有集群进行服务发现的机制,如官方提供的:discovery.etcd.io
- DNS动态发现
通过DNS查询方式获取其它节点地址信息。
一、主机初始化
对每个etcd节点主机进行初始配置操作:
1.1 配置/etc/hosts
$ cat <<EOF >> /etc/hosts
192.168.2.51 etcd1
192.168.2.52 etcd2
192.168.2.53 etcd3
EOF
1.2 安装cfssl证书工具
使用cfsll工具生成集群需要的证书文件,其中一台master节点安装即可!
$ wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64 -O /usr/local/bin/cfssl
$ wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64 -O /usr/local/bin/cfssljson
$ wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-certinfo_1.6.0_linux_amd64 -O /usr/local/bin/cfssl-certinfo
$ chmod +x /usr/local/bin/cfssl*
cfssljson:将从cfssl和multirootca等获得的json格式的输出转化为证书格式的文件(证书,密钥,CSR和bundle)进行存储;
cfssl-certinfo:可显示CSR或证书文件的详细信息;可用于证书校验。
1.3 创建工作目录
$ mkdir -p /etc/etcd/cert
- /etc/etcd/为etcd工作目录;
- /etc/etcd/cert为etcd相关证书存放目录;
1.4 关闭SELinux、firewalld
firewalld开启会导致etcd服务启动失败。
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
$ systemctl status firewalld.service
$ systemctl disable --now firewalld.service
二、制作证书
2.1 创建证书颁发机构(CA)
1)创建配置文件
$ cfssl print-defaults config > /etc/etcd/cert/ca-config.json #生成默认配置文件
$ cat <<EOF > /etc/etcd/cert/ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
参数解析:
default.expiry:默认证书有效期(单位:h)
profiles.etcd:为服务使用该配置文件颁发证书的配置模块;
signing:签署,表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
key encipherment:密钥加密;
profiles:指定了不同角色的配置信息;可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile。
server auth:服务器身份验证;表示 client 可以用该 CA 对 server 提供的证书进行验证;
client auth:客户端身份验证;表示 server 可以用该 CA 对 client 提供的证书进行验证;
2)生成并配置csr请求文件
类似于申请表,表中填写申请者的信息(证书签名请求文件)
$ cfssl print-defaults csr > /etc/etcd/cert/ca-csr.json
$ cat <<EOF > ca-csr.json
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "etcd",
"OU": "system"
}
]
}
EOF
参数解析:
**hosts**:包含的授权范围,不在此范围的的节点或者服务使用此证书就会报证书不匹配错误,证书如果不包含可能会出现无法连接的情况;
**Key:** 指定使用的加密算法,一般使用rsa非对称加密算法(algo:rsa;size:2048)
**CN**:Common Name,从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;CN是域名,也就是你现在使用什么域名就写什么域名。
**C**:国家(CN中国)
**ST**:类似省份(如湖南省等)
**L**:城市(如北京市)
**O**:Organization,从证书中提取该字段作为请求用户所属的组 (Group);
3)创建ca证书
创建CA证书并放入/etc/etcd/cert/
下
$ cfssl gencert -initca /etc/etcd/cert/ca-csr.json | cfssljson -bare /etc/etcd/cert/etcd-ca
2022/12/28 15:34:42 [INFO] generating a new CA key and certificate from CSR
2022/12/28 15:34:42 [INFO] generate received request
2022/12/28 15:34:42 [INFO] received CSR
2022/12/28 15:34:42 [INFO] generating key: ecdsa-256
2022/12/28 15:34:42 [INFO] encoded CSR
2022/12/28 15:34:42 [INFO] signed certificate with serial number 235381723861351140457367252786107821197429045799
$ ls /etc/etcd/cert/etcd-ca*
/etc/etcd/cert/etcd-ca.csr /etc/etcd/cert/etcd-ca-key.pem /etc/etcd/cert/etcd-ca.pem
2.2 颁发etcd证书
使用刚才的证书机构,根据提供的请求文件向etcd颁发证书。
1)配置etcd请求csr文件
$ cfssl print-defaults csr > /etc/etcd/cert/etcd-csr.json
$ cat <<EOF > /etc/etcd/cert/etcd-csr.json
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.2.51",
"192.168.2.52",
"192.168.2.53"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "etcd",
"OU": "system"
}
]
}
EOF
- hosts:所有etcd节点的地址列表和本地回环地址;
2)生成etcd证书
生成etcd证书并放入到/etc/etcd/cert/
下
$ cfssl gencert -ca=/etc/etcd/cert/etcd-ca.pem \
-ca-key=/etc/etcd/cert/etcd-ca-key.pem \
-config=/etc/etcd/cert/ca-config.json -profile=etcd \
/etc/etcd/cert/etcd-csr.json | cfssljson -bare /etc/etcd/cert/etcd
# 输出:
2022/12/28 15:49:13 [INFO] generate received request
2022/12/28 15:49:13 [INFO] received CSR
2022/12/28 15:49:13 [INFO] generating key: rsa-2048
2022/12/28 15:49:13 [INFO] encoded CSR
2022/12/28 15:49:13 [INFO] signed certificate with serial number 456751516901369921492152169340720764647499480668
$ ls /etc/etcd/cert/
ca-config.json ca-csr.json etcd-ca.csr etcd-ca-key.pem etcd-ca.pem etcd.csr etcd-csr.json etcd-key.pem etcd.pem
# etcd.csr、etcd-key.pem、etcd.pem为新生成的证书文件
参数解析
-ca-key:指定CA证书机构的私钥;
-config:指定CA证书策略;
-profile:指定使用CA证书策略中的哪个模块,即CA配置文件中的signing.profiles.etcd参数;
etcd.pem:公钥
etcd-key.pem:私钥
2.3 证书分发
2.1和2.2操作均在etcd1节点操作,需要将相关的证书文件分发到其它etcd节点。
$ scp /etc/etcd/cert/{etcd-ca.pem,etcd.pem,etcd-key.pem} 192.168.2.52:/etc/etcd/cert/
$ scp /etc/etcd/cert/{etcd-ca.pem,etcd.pem,etcd-key.pem} 192.168.2.53:/etc/etcd/cert/
三、部署etcd集群
默认的2379端口为客户端访问端口,2380为etcd节点间通信的端口。
3.1 下载二进制包
$ wget -c https://github.com/etcd-io/etcd/releases/download/v3.5.5/etcd-v3.5.5-linux-amd64.tar.gz -k
$ tar -xf etcd-v3.5.5-linux-amd64.tar.gz
$ cp -p etcd-v3.5.5-linux-amd64/{etcd,etcdctl,etcdutl} /usr/local/bin/
$ ls /usr/local/bin/
etcd etcdctl etcdutl
$ etcd -version
etcd Version: 3.5.5
Git SHA: 19002cfc6
Go Version: go1.16.15
Go OS/Arch: linux/amd64
- etcd:服务端;
- etcdctl:etcd客户端工具;
- etcdutl:数据恢复工具,旧版是使用etcdctl完成数据的备份和恢复;
3.2 创建etcd配置文件
1)etcd1节点配置文件
$ cat /etc/etcd/etcd.conf
# Member(成员):
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/etc/etcd/etcd-data"
ETCD_SNAPSHOT_COUNT="5000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="500"
ETCD_LISTEN_PEER_URLS="https://192.168.2.51:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.2.51:2379,https://127.0.0.1:2379"
# Clustering(集群):
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.2.51:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.2.51:2380,etcd-2=https://192.168.2.52:2380,etcd-3=https://192.168.2.52:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.2.51:2379"
# Security(安全):
ETCD_CLIENT_CERT_AUTH="true"
ETCD_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
2)etcd2节点配置文件
$ cat /etc/etcd/etcd.conf
# [Member]成员
ETCD_NAME="etcd-2"
ETCD_DATA_DIR="/etc/etcd/etcd-data"
ETCD_SNAPSHOT_COUNT="5000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="500"
ETCD_LISTEN_PEER_URLS="https://192.168.2.52:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.2.52:2379,https://127.0.0.1:2379"
# Clustering(集群)
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.2.52:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.2.51:2380,etcd-2=https://192.168.2.52:2380,etcd-3=https://192.168.2.53:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.2.52:2379"
# Security(安全)
ETCD_CLIENT_CERT_AUTH="true"
ETCD_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
3)etcd3节点配置文件
$ cat /etc/etcd/etcd.conf
# [Member]成员
ETCD_NAME="etcd-3"
ETCD_DATA_DIR="/etc/etcd/etcd-data"
ETCD_SNAPSHOT_COUNT="5000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="500"
ETCD_LISTEN_PEER_URLS="https://192.168.2.53:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.2.53:2379,https://127.0.0.1:2379"
# Clustering(集群)
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.2.53:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.2.51:2380,etcd-2=https://192.168.2.52:2380,etcd-3=https://192.168.2.53:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.2.53:2379"
# Security(安全)
ETCD_CLIENT_CERT_AUTH="true"
ETCD_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/etc/etcd/cert/etcd.pem"
ETCD_PEER_KEY_FILE="/etc/etcd/cert/etcd-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/cert/etcd-ca.pem"
4)参数解析
[Cluster tag] #集群标记部分
ETCD_INITIAL_CLUSTER:集群节点地址(为启动初始化集群配置)
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群
ETCD_INITIAL_CLUSTER_TOKEN:在启动期间用于集群初始化标记,集群Token(集群名称)
ETCD_INITIAL_ADVERTISE_PEER_URLS:列出该成员URL,以便通告给其他成员,用于在集群中通信etcd数据;
ETCD_ADVERTISE_CLIENT_URLS:列出该成员客户端URL,通告给集群中的其他成员;
[Member tag] #成员标记部分
ETCD_NAME:当前节点名称,与`ETCD_INITIAL_CLUSTER`中的一致
ETCD_DATA_DIR: #etcd数据目录
ETCD_HEARTBEAT_INTERVAL:心跳间隔时间 (单位 毫秒).默认100
ETCD_ELECTION_TIMEOUT: 选举的超时时间(单位 毫秒).默认1000
ETCD_LISTEN_PEER_URLS:监听集群内部的URL列表,为本集群其他节点提供的服务监听URL地址(内部)
ETCD_LISTEN_CLIENT_URLS:为`客户端`提供的服务监听URL地址(外部);
# Security(安全):
ETCD_CLIENT_CERT_AUTH: 是否启用客户端证书认证,当这个选项被设置时,etcd 将为受信任CA签名的客户端证书检查所有的传入的 HTTPS 请求,不能提供有效客户端证书的请求将会失败。
ETCD_PEER_CERT_FILE: etcd的peers通信的公钥证书,集群各节点相互认证使用的证书(-crt文件)
ETCD_PEER_KEY_FILE: etcd的peers通信的私钥, 集群各节点相互认证使用的私钥(-key文件)
ETCD_PEER_CLIENT_CERT_AUTH:是否开启peer client 证书验证
ETCD_PEER_TRUSTED_CA_FILE:CA根证书文件,peer server TLS 信任证书文件路径.。
ETCD_PEER_AUTO_TLS="true"
ETCD_CERT_FILE:指定etcd的证书(etcd.pem),客户端服务器TLS证书文件,供客户端访问
ETCD_KEY_FILE:指定etcd的私钥,客户端访问认证
ETCD_CLIENT_CERT_AUTH="true" #是否开启客户端证书认证;
ETCD_TRUSTED_CA_FILE: 指定CA的证书(ca.pem或ca.crt),
ETCD_AUTO_TLS="true" 使用生成证书的客户端TLS
#####################################################################################################
# [Member]成员
--name=etcd1
--data-dir=/etc/etcd/etcd-data #etcd数据目录,启动时会z
--snapshot-count=5000
--heartbeat-interval=100 #心跳间隔的时间
--election-timeout=500 #选举超时的时间(默认100)
--listen-peer-urls https://192.168.2.52:2380 #集群节点间通信监听地址(本机IP:2380端口)
--listen-client-urls https://192.168.2.52:2379,https://127.0.0.1:2379 #监听客户端访问地址
# Clustering(集群)
--initial-advertise-peer-urls=https://192.168.2.52:2380 #本机IP,集群通告地址
--initial-cluster infra0=https://192.168.2.51:2380,infra1=https://192.168.2.52:2380,infra2=https://10.0.1.12:2380 \
--initial-cluster-state new #初始集群状态
--advertise-client-urls https://192.168.2.52:2379 #向客户端通告此成员地址
--initial-cluster-token etcd-cluster-1 #初始集群令牌
# Security(安全):
--client-cert-auth="true" #是否启用客户端证书认证
--cert-file=/path/to/infra1-client.crt #客户端、服务端通信的TLS证书文件
--key-file=/path/to/infra1-client.key #客户端、服务器通信的TLS密钥文件
--trusted-ca-file=/path/to/ca-client.crt #客户端服务器TLS受信任CA证书文件的路径。
--peer-client-cert-auth="true" #是否启用集群节点间通信认证
--peer-cert-file=/path/to/infra1-peer.crt #集群节点间通信TLS证书文件
--peer-key-file=/path/to/infra1-peer.key #集群节点间通信TLS密钥文件(私钥)
--peer-trusted-ca-file=ca-peer.crt #集群节点间通信TLS受信任CA文件的路径
3.3 创建服务启动文件
每个etcd节点的服务启动文件内容一致。
$ cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/etc/etcd/etcd.conf
#WorkingDirectory=/etc/etcd/etcd-data
ExecStart=/usr/local/bin/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- WorkingDirectory:etcd数据目录,与ETCD_DATA_DIR会冲突;
- EnvironmentFile:指定etcd配置文件;
- ExecStart:启动指令;
3.4 启动etcd集群
1)重新加载服务配置
$ systemctl daemon-reload
2)启动etcd服务
$ systemctl start etcd.service
$ systemctl enable etcd.service
$ systemctl status etcd
3.5 查看集群状态
$ etcdctl endpoint health --write-out=table \
--endpoints=https://192.168.2.51:2379,https://192.168.2.52:2379,https://192.168.2.53:2379 \
--cacert=/etc/etcd/cert/etcd-ca.pem --cert=/etc/etcd/cert/etcd.pem --key=/etc/etcd/cert/etcd-key.pem
# shu'chu
+---------------------------+--------+-------------+-------+
| ENDPOINT | HEALTH | TOOK | ERROR |
+---------------------------+--------+-------------+-------+
| https://192.168.2.52:2379 | true | 20.340362ms | |
| https://192.168.2.53:2379 | true | 26.419585ms | |
| https://192.168.2.51:2379 | true | 26.196417ms | |
+---------------------------+--------+-------------+-------+
- --write-out=table/-w table:以表格形式输出结果;
- --cacert: 指定CA证书
- --cert:指定etcd服务证书
- --key:指定etcd私钥
- --endpoints:指定集群地址
- --HEALTH:是否健康;