1. etcd 介绍
1.1 什么是 etcd?
etcd
是一个 分布式、可靠的键值存储系统,用于存储 分布式系统中的关键数据。它提供了 高可用性、强一致性(CP) 和 高性能,被广泛应用于 Kubernetes、微服务架构、分布式锁、配置管理 等场景。
etcd 的核心特点:
-
简单:提供清晰、面向用户的 gRPC API,易于集成。
-
安全:支持 TLS 加密,可选 客户端证书身份验证,确保数据安全。
-
快速:以 每秒 10,000 次写入 作为性能基准。
-
可靠:基于 Raft 共识算法,确保数据复制的一致性。
1.2 etcd 的工作原理
etcd 由 Go 语言 编写,使用 Raft 共识算法 维护数据一致性。
Raft 通过 选主(Leader Election)、日志复制(Log Replication) 等机制,确保集群中的数据始终保持一致。
当客户端向 etcd 集群写入数据时:
-
数据提交到 Leader。
-
Leader 将日志复制到所有 Follower。
-
超过半数 Follower 确认数据后,Leader 提交变更。
-
所有节点更新状态,确保数据一致。
1.3 etcd 的核心组件
1.3.1 etcd 服务
etcd 运行在服务器上,存储和管理键值数据,支持 HTTP/gRPC API 进行读写操作。
1.3.2 etcdctl(命令行工具)
etcdctl
是 etcd 提供的官方 CLI 工具,用户可以通过它进行数据存储、查询等操作。
示例:
# 存储键值
etcdctl put /config/db_user "root"
# 获取键值
etcdctl get /config/db_user
# 监听键值变化
etcdctl watch /config/db_user
1.3.3 etcd API 版本
etcd 主要有 v2 和 v3 两个 API 版本:
etcd v3
是 推荐的生产环境版本,性能更强、功能更完善。etcd v2
不兼容 v3,数据格式不同。
切换 API 版本:
export ETCDCTL_API=3 # 使用 v3 API
export ETCDCTL_API=2 # 使用 v2 API
1.4 etcd 在生产环境中的应用
etcd 被广泛应用于多个分布式系统,以下是几个典型的应用场景:
1.4.1 Kubernetes
Kubernetes 依赖 etcd 存储 集群状态、Pod 信息、Service 配置 等核心数据:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
data:
key: "value"
1.4.2 分布式锁
etcd 支持 乐观并发控制,可以用于 分布式锁:
etcdctl lock mylock "echo locked"
1.4.3 配置管理
etcd 可以作为 集中式配置存储,应用程序可以监听配置变化,做到 热更新:
etcdctl watch /config/app_settings
1.5 生产环境最佳实践
-
使用 etcd v3 版本,避免 v2 的兼容性问题。
-
启用 TLS 进行加密通信,避免数据泄露:
etcd --cert-file=mycert.pem --key-file=mykey.pem --peer-cert-file=peercert.pem --peer-key-file=peerkey.pem
-
合理设置集群规模,推荐 奇数个节点(3、5、7) 以提高容错能力。
-
使用
snapshot
进行数据备份,防止数据丢失:etcdctl snapshot save backup.db etcdctl snapshot restore backup.db
1.6 参考资料
- 官方 GitHub 仓库:https://github.com/etcd-io/etcd
- 官方文档:https://etcd.io/docs/
2. 安装 etcd 的方式
- 包管理方式安装: 安装简单,但是版本低
apt -y install etcd-client
- 通过二进制文件安装:可以安装任意版本
3. 准备 etcd 程序包
3.1 下载 etcd 的软件包
[root@etcd90:~]# wget https://github.com/etcd-io/etcd/releases/download/v3.5.19/etcd-v3.5.19-linux-amd64.tar.gz
3.2 解压并移动到 /usr/local/bin/
[root@etcd90:~]# tar xf etcd-v3.5.19-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.5.19-linux-amd64/etcd{,ctl}
[root@etcd90:~]# ll /usr/local/bin/etcd*
-rwxr-xr-x 1 jasper jasper 24064152 Mar 6 03:34 /usr/local/bin/etcd*
-rwxr-xr-x 1 jasper jasper 18419864 Mar 6 03:34 /usr/local/bin/etcdctl*
3.3 验证安装
[root@etcd90:~]# etcdctl version
etcdctl version: 3.5.19
API version: 3.5
3.4 将软件包下发到所有节点
[root@etcd90:~]# scp /usr/local/bin/etcd* 10.0.0.91:/usr/local/bin/
[root@etcd90:~]# scp /usr/local/bin/etcd* 10.0.0.92:/usr/local/bin/
4. 准备 etcd 的证书文件
4.1 安装 cfssl 证书管理工具
# 下载 fssl 工具
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl-certinfo_1.6.5_linux_amd64
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64
# 安装 rename 工具,方便修改文件名
[root@etcd90:~]# apt install rename
# 批量重命名文件,去除多余的部分
[root@etcd90:~]# rename -v "s/_1.6.5_linux_amd64//g" cfssl*
# 查看重命名后的文件列表
[root@etcd90:~]# ll cfssl*
-rw-r--r-- 1 root root 11890840 Mar 6 2024 cfssl
-rw-r--r-- 1 root root 8413336 Mar 6 2024 cfssl-certinfo
-rw-r--r-- 1 root root 6205592 Mar 6 2024 cfssljson
# 将 cfssl 工具移动到 /usr/local/bin 目录下
[root@etcd90:~]# mv cfssl* /usr/local/bin/
# 给所有 cfssl 工具添加可执行权限
[root@etcd90:~]# chmod +x /usr/local/bin/cfssl*
# 查看安装后的 cfssl 工具
[root@etcd90:~]# ll /usr/local/bin/cfssl*
-rwxr-xr-x 1 root root 11890840 Mar 6 2024 /usr/local/bin/cfssl*
-rwxr-xr-x 1 root root 8413336 Mar 6 2024 /usr/local/bin/cfssl-certinfo*
-rwxr-xr-x 1 root root 6205592 Mar 6 2024 /usr/local/bin/cfssljson*
4.2 创建证书存储目录
# 创建用于存放证书的目录,并切换到该目录
[root@etcd90:~]# mkdir -p /jasper/certs/etcd && cd /jasper/certs/etcd
4.3 生成证书的 CSR 文件
[root@etcd90:etcd]# cat > etcd-ca-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "GuangDong",
"L": "ShenZhen",
"O": "etcd",
"OU": "Etcd Security"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
字段解释
"CN": "etcd"
- Common Name(CN),证书的主机名。
"key": { "algo": "rsa", "size": 2048 }
algo
:加密算法,采用 RSA。size
:密钥大小,设为 2048 位。
"names": [...]
C
(Country):国家代码,这里填写 “CN”(中国)。ST
(State/Province):省份或州,这里填写 “GuangDong”(广东)。L
(Locality):城市,这里填写 “ShenZhen”(深圳)。O
(Organization):组织名称,这里填写 “etcd”,即 etcd 组件。OU
(Organizational Unit):组织单位(部门),填写 “Etcd Security”,表示用于 etcd 安全认证。
"ca": { "expiry": "876000h" }
expiry
:证书有效期,876000 小时 = 100 年。
4.4 生成 etcd CA 证书和 CA 证书的 key
# 基于上述的 CSR 文件生成 etcd CA 证书和私钥
[root@etcd90:etcd]# cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /jasper/certs/etcd/etcd-ca
# 查看生成的证书文件
[root@etcd90:etcd]# ll /jasper/certs/etcd/etcd-ca*
-rw-r--r-- 1 root root 252 Mar 20 16:42 /jasper/certs/etcd/etcd-ca-csr.json
-rw------- 1 root root 1675 Mar 20 16:44 /jasper/certs/etcd/etcd-ca-key.pem
-rw-r--r-- 1 root root 1054 Mar 20 16:44 /jasper/certs/etcd/etcd-ca.csr
-rw-r--r-- 1 root root 1326 Mar 20 16:44 /jasper/certs/etcd/etcd-ca.pem
4.5 生成 etcd 证书的有效期为 100 年
[root@etcd90:etcd]# cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
字段解释
# "expiry": "876000h" # 默认有效期为 100 年
# "usages": [...] # 配置证书的用途
# "expiry": "876000h" # 证书有效期为 100 年
4.6 生成证书的 CSR 文件
[root@etcd90:etcd]# cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "GuangDong",
"L": "ShenZhen",
"O": "etcd",
"OU": "Etcd Security"
}
]
}
EOF
4.7 基于自建的 etcd CA 证书生成 etcd 的证书
[root@etcd90:etcd]# cfssl gencert \
-ca=/jasper/certs/etcd/etcd-ca.pem \
-ca-key=/jasper/certs/etcd/etcd-ca-key.pem \
-config=ca-config.json \
--hostname=127.0.0.1,etcd90,etcd91,etcd92,10.0.0.90,10.0.0.91,10.0.0.92 \
--profile=kubernetes \
etcd-csr.json | cfssljson -bare /jasper/certs/etcd/etcd-server
命令详解
# 1. `cfssl gencert`
- `cfssl gencert`:使用 **CFSSL** 生成证书。
# 2. `-ca=/jasper/certs/etcd/etcd-ca.pem`
- **指定 CA 证书**,用 `/jasper/certs/etcd/etcd-ca.pem` 作为 **签发者**。
# 3. `-ca-key=/jasper/certs/etcd/etcd-ca-key.pem`
- **指定 CA 私钥**,用 `/jasper/certs/etcd/etcd-ca-key.pem` 来 **签名证书**。
# 4. `-config=ca-config.json`
- **指定 CA 配置文件**,用于定义签名策略,如证书的有效期、用途等。
# 5. `--hostname=127.0.0.1,etcd90,etcd91,etcd92,10.0.0.90,10.0.0.91,10.0.0.92`
- 设置证书的主机名(SANs - Subject Alternative Names):
- 允许 `127.0.0.1`(本地回环地址)
- 允许 `etcd90`、`etcd91`、`etcd92`(etcd 集群主机名)
- 允许 `10.0.0.90`、`10.0.0.91`、`10.0.0.92`(etcd 节点的 IP)
# 6. `--profile=kubernetes`
- 使用 `ca-config.json` 配置文件中 `kubernetes` 这一签名策略,可能包含:
- `server auth`:服务器认证
- `client auth`:客户端认证
- `signing`:签名
- `key encipherment`:密钥加密
- `expiry`:证书有效期(例如 100 年)
# 7. `etcd-csr.json`
- 指定证书签名请求(CSR)文件,包含:
- 证书的通用名称(CN)
- 组织信息(O、OU、C、ST、L)
- 加密算法和密钥长度(RSA 2048)
# 8. `| cfssljson -bare /jasper/certs/etcd/etcd-server`
- `cfssl gencert` 生成的 JSON 格式证书数据,通过 `|` 管道传递给 `cfssljson` 进行转换,并生成以下文件:
- `/jasper/certs/etcd/etcd-server.pem`(etcd 服务器证书)
- `/jasper/certs/etcd/etcd-server-key.pem`(etcd 服务器私钥)
- `/jasper/certs/etcd/etcd-server.csr`(证书签名请求)
[root@etcd90:etcd]# ll /jasper/certs/etcd/etcd-server*
-rw------- 1 root root 1679 Mar 20 17:01 /jasper/certs/etcd/etcd-server-key.pem
-rw-r--r-- 1 root root 1110 Mar 20 17:01 /jasper/certs/etcd/etcd-server.csr
-rw-r--r-- 1 root root 1448 Mar 20 17:01 /jasper/certs/etcd/etcd-server.pem
4.8 将 etcd 证书拷贝到其他两个 master 节点
[root@etcd90:etcd]# scp -r /jasper/certs 10.0.0.91:/jasper/
[root@etcd90:etcd]# scp -r /jasper/certs 10.0.0.92:/jasper/
5. 创建 etcd 集群各节点配置文件
5.1 etcd90
节点的配置文件
[root@etcd90:etcd]# mkdir -p /jasper/softwares/etcd
[root@etcd90:etcd]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd90'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.90:2380'
listen-client-urls: 'https://10.0.0.90:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.90:2380'
advertise-client-urls: 'https://10.0.0.90:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
auto-tls: false
peer-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
peer-client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF
配置文件解释:
[root@etcd90:etcd]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd90' # 节点名称
data-dir: /var/lib/etcd # 数据存储目录
wal-dir: /var/lib/etcd/wal # Write-Ahead Log 存储目录
snapshot-count: 5000 # 每 5000 次写操作生成一个快照
heartbeat-interval: 100 # 心跳间隔,单位:毫秒
election-timeout: 1000 # 选举超时时间,单位:毫秒
quota-backend-bytes: 0 # 后端存储配额,设置为 0 表示不限制
listen-peer-urls: 'https://10.0.0.90:2380' # 节点之间通信的 URL
listen-client-urls: 'https://10.0.0.90:2379,http://127.0.0.1:2379' # 对外提供的 API 服务 URL
max-snapshots: 3 # 最大快照数量,超过时会自动删除最旧的
max-wals: 5 # 最大 WAL 文件数量
cors: "" # 允许跨域访问,设置为空表示不使用
initial-advertise-peer-urls: 'https://10.0.0.90:2380' # 初始的 peer URL
advertise-client-urls: 'https://10.0.0.90:2379' # 初始的 client URL
discovery:
discovery-fallback: 'proxy' # 如果不能发现节点,则回退到代理模式
discovery-proxy: "" # 代理 URL,留空表示不使用
discovery-srv: "" # DNS 服务发现,留空表示不使用
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380' # 初始集群配置
initial-cluster-token: 'etcd-k8s-cluster' # 集群标识符
initial-cluster-state: 'new' # 新集群
strict-reconfig-check: false # 是否严格检查集群配置
enable-v2: true # 启用 v2 API
enable-pprof: true # 启用 pprof 性能分析
proxy: 'off' # 禁用代理模式
proxy-failure-wait: 5000 # 代理失败后的重试等待时间
proxy-refresh-interval: 30000 # 代理刷新间隔
proxy-dial-timeout: 1000 # 代理连接超时时间
proxy-write-timeout: 5000 # 代理写操作超时时间
proxy-read-timeout: 0 # 代理读操作超时时间
client-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem' # 客户端证书
key-file: '/jasper/certs/etcd/etcd-server-key.pem' # 客户端私钥
client-cert-auth: true # 启用客户端证书认证
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem' # 客户端受信任的 CA 证书
auto-tls: false # 禁用自动 TLS 生成
peer-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem' # 节点间通信的证书
key-file: '/jasper/certs/etcd/etcd-server-key.pem' # 节点间通信的私钥
peer-client-cert-auth: true # 启用节点间通信证书认证
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem' # 受信任的 CA 证书
EOF
5.2 etcd91
节点的配置文件
[root@etcd91:~]# mkdir -p /jasper/softwares/etcd
[root@etcd91:~]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd91'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.91:2380'
listen-client-urls: 'https://10.0.0.91:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.91:2380'
advertise-client-urls: 'https://10.0.0.91:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
auto-tls: false
peer-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
peer-client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF
5.3 etcd92
节点的配置文件
[root@etcd92:~]# mkdir -p /jasper/softwares/etcd
[root@etcd92:~]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd92'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.92:2380'
listen-client-urls: 'https://10.0.0.92:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.92:2380'
advertise-client-urls: 'https://10.0.0.92:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
auto-tls: false
peer-transport-security:
cert-file: '/jasper/certs/etcd/etcd-server.pem'
key-file: '/jasper/certs/etcd/etcd-server-key.pem'
peer-client-cert-auth: true
trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF
5.4 每个节点编写 etcd 启动脚本
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Jasper's Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/jasper/softwares/etcd/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Alias=etcd3.service
EOF
6. 启动 etcd 集群
systemctl daemon-reload && systemctl enable --now etcd
systemctl status etcd
7. 查看 etcd 集群状态
[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 | 3.5.19 | 20 kB | false | false | 2 | 9 | 9 | |
| 10.0.0.91:2379 | b207a358c2aaa147 | 3.5.19 | 20 kB | true | false | 2 | 9 | 9 | |
| 10.0.0.92:2379 | 432a416a50e3d3d5 | 3.5.19 | 20 kB | false | false | 2 | 9 | 9 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
8. 验证 etcd 高可用集群
8.1 停止 leader 节点
[root@etcd91:~]# netstat -tnulp | egrep '2379|2380'
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 3283/etcd
tcp 0 0 10.0.0.91:2380 0.0.0.0:* LISTEN 3283/etcd
tcp 0 0 10.0.0.91:2379 0.0.0.0:* LISTEN 3283/etcd
[root@etcd91:~]# systemctl stop etcd
[root@etcd91:~]# netstat -tnulp | egrep '2379|2380'
[root@etcd91:~]#
8.2 查看现有集群环境,发现新 leader 诞生
[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem endpoint status --write-out=table
{"level":"warn","ts":"2025-03-20T17:47:09.999291+0800","logger":"etcd-client","caller":"v3@v3.5.19/retry_interceptor.go:63","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000014000/10.0.0.90:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = context deadline exceeded"}
Failed to get the status of endpoint 10.0.0.91:2379 (context deadline exceeded)
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 | 3.5.19 | 20 kB | true | false | 3 | 10 | 10 | |
| 10.0.0.92:2379 | 432a416a50e3d3d5 | 3.5.19 | 20 kB | false | false | 3 | 10 | 10 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
8.3 重新启动停止的节点
[root@etcd91:~]# systemctl start etcd
[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 | 3.5.19 | 20 kB | true | false | 3 | 11 | 11 | |
| 10.0.0.91:2379 | b207a358c2aaa147 | 3.5.19 | 20 kB | false | false | 3 | 11 | 11 | |
| 10.0.0.92:2379 | 432a416a50e3d3d5 | 3.5.19 | 20 kB | false | false | 3 | 11 | 11 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
9. 添加别名
[root@etcd91:~]# echo 'alias etcdctl="etcdctl --endpoints=\"10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379\" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem"' >> /root/.bashrc && source /root/.bashrc
[root@etcd91:~]# etcdctl endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 | 3.5.19 | 20 kB | true | false | 3 | 11 | 11 | |
| 10.0.0.91:2379 | b207a358c2aaa147 | 3.5.19 | 20 kB | false | false | 3 | 11 | 11 | |
| 10.0.0.92:2379 | 432a416a50e3d3d5 | 3.5.19 | 20 kB | false | false | 3 | 11 | 11 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+