1.etcd是什么
etcd 是云原生领域核心的分布式键值存储系统,主要用于存储和管理集群的配置、状态等关键数据,以高可用和强一致性为核心优势。
2.etcd 的核心特性
强一致性:基于 Raft 共识算法实现,确保集群中所有节点的数据完全一致,适合存储关键配置。
高可用:支持多节点集群部署(通常建议 3/5/7 个节点),单个节点故障不影响整体服务,自动实现故障转移。
轻量高效:采用 Go 语言开发,体积小、性能优,单集群可支持每秒数千次读写操作。
安全可控:原生支持 TLS 加密(传输层安全)和基于 RBAC 的权限控制,防止数据泄露或未授权访问。
灵活的数据模型:以键值对(Key-Value)为基础,支持 "目录式" 键结构(如 /app/config/db),方便数据分类管理。
3.etcd 的主要用途
etcd 是云原生生态的重要组件,最典型的应用场景包括:
Kubernetes 后端存储:作为 Kubernetes(K8s)的 "大脑",存储集群的所有核心数据,如 Pod 配置、服务端点、命名空间等。
服务发现:存储服务的 IP、端口等信息,让集群内的服务能快速找到并通信(如微服务架构中的服务注册与发现)。
配置中心:集中管理分布式系统的配置(如数据库连接池、日志级别),支持配置动态更新,无需重启服务。
分布式锁:利用其强一致性特性,实现分布式环境下的 "锁" 机制,避免多个节点同时修改同一资源。
4.etcd 与同类工具的对比
etcd
核心优势:强一致性、高可用、轻量
适用场景:云原生集群(K8s)、配置中心
ZooKeeper
核心优势:成熟稳定、生态完善
适用场景:传统分布式系统(如 Hadoop)
Consul
核心优势:内置服务发现、健康检查
适用场景: 微服务架构
5.ubuntu 22 kubernetes-1.34.1 对应的etcd 版本
v3.6.5 最低兼容的 v3.5.0
6.部署etcd高可用集群
在三个Master节点上部署etcd集群,形成高可用。
6.1 创建etcd配置和服务文件(以master01为例)
(1)创建etcd工作目录和证书目录(假设您已准备好TLS证书,生产环境必须使用)
bash
sudo mkdir -p /var/lib/etcd /etc/etcd/pki
(2)创建etcd配置文件 /etc/etcd/etcd.conf.yml
bash
# 此成员的可读名称。
name: 'k8smaster01'
# 数据目录的路径。
data-dir: /var/lib/etcd
# 专用预写日志(WAL)目录的路径。
wal-dir:
# 触发快照到磁盘的已提交事务数
snapshot-count: 10000
# 心跳间隔时间(以毫秒为单位)
heartbeat-interval: 100
# 选举超时时间(以毫秒为单位)
election-timeout: 1000
# 当后端大小超过给定配额时发出警报。0 表示使用默认配额。
quota-backend-bytes: 0
# 当前节点IP
listen-client-urls: 'https://192.168.0.105:2379,https://127.0.0.1:2379'
# 用于监听对等流量(节点间通信)的 URL 列表,用逗号分隔。
listen-peer-urls: https://192.168.0.105:2380
# 要保留的最大快照文件数(0 表示无限制)。
max-snapshots: 5
# 要保留的最大 WAL 文件数(0 表示无限制)。
max-wals: 5
# 用于 CORS(跨源资源共享)的源站白名单,用逗号分隔。
cors:
# 向集群其他成员通告的本成员对等 URL 列表。
# URL 需要是逗号分隔的列表。
initial-advertise-peer-urls: 'https://192.168.0.105:2380'
# 向公众通告的本成员客户端 URL 列表。
# URL 需要是逗号分隔的列表。
advertise-client-urls: 'https://192.168.0.105:2379'
# 用于引导集群的发现服务 URL
discovery:
# 有效值包括 'exit', 'proxy'。
discovery-fallback: 'proxy'
# 用于引导初始集群的 DNS 域名。
discovery-srv:
# 用于引导的初始集群配置,逗号分隔的字符串。
# 示例:initial-cluster: "infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380"
initial-cluster: 'k8smaster01=https://192.168.0.105:2380,k8smaster02=https://192.168.0.103:2380,k8smaster03=https://192.168.0.110:2380'
initial-cluster-token: 'etcd-k8s-cluster'
# 初始集群状态('new' 或 'existing')。
initial-cluster-state: 'new'
# 拒绝会导致法定人数丢失的重新配置请求。
strict-reconfig-check: false
# 通过 HTTP 服务器启用运行时性能分析数据。
enable-pprof: true
# 有效值包括 'on', 'readonly', 'off'。
proxy: 'off'
# 端点将保持失败状态的时间(毫秒)。
proxy-failure-wait: 5000
# 端点刷新间隔的时间(毫秒)。
proxy-refresh-interval: 30000
# 连接建立(拨号)超时时间(毫秒)。
proxy-dial-timeout: 1000
# 写入超时时间(毫秒)。
proxy-write-timeout: 5000
# 读取超时时间(毫秒)。0 表示不超时。
proxy-read-timeout: 0
# 客户端传输安全设置。
client-transport-security:
# 客户端服务器 TLS 证书文件的路径。
cert-file: /etc/etcd/pki/server.crt
# 客户端服务器 TLS 密钥文件的路径。
key-file: /etc/etcd/pki/server.key
# 启用客户端证书认证。
client-cert-auth: true
# 客户端服务器信任的 CA 证书文件路径。
trusted-ca-file: /etc/etcd/pki/ca.crt
# 使用自动生成证书的客户端 TLS。
auto-tls: false
# 对等端传输安全设置。
peer-transport-security:
# 对等端服务器 TLS 证书文件的路径。
cert-file: /etc/etcd/pki/server.crt
# 对等端服务器 TLS 密钥文件的路径。
key-file: /etc/etcd/pki/server.key
# 启用对等端客户端证书认证。
client-cert-auth: true
# 对等端服务器信任的 CA 证书文件路径。
trusted-ca-file: /etc/etcd/pki/ca.crt
# 使用自动生成证书的对等端 TLS。
auto-tls: false
# 对等端认证允许的 CN(Common Name)。
allowed-cn:
# 对等端认证允许的 TLS 主机名。
allowed-hostname:
# 自签名证书的有效期,单位是年。
self-signed-cert-validity: 1
# 启用 etcd 的调试级别日志记录。
log-level: debug
# 使用的日志记录器。
logger: zap
# 指定 'stdout' 或 'stderr' 以跳过 journald 日志记录,即使在 systemd 下运行。
log-outputs: [stderr]
# 强制创建一个新的单成员集群。
force-new-cluster: false
# 自动压缩模式。
auto-compaction-mode: periodic
# 自动压缩保留期。
auto-compaction-retention: "1"
# 将 etcd 限制为使用特定的 TLS 密码套件集合。
cipher-suites: [
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
]
# 将 etcd 限制为使用特定的 TLS 协议版本。
tls-min-version: 'TLS1.2'
tls-max-version: 'TLS1.3'
(3)创建systemd服务文件 /etc/systemd/system/etcd.service
bash
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
After=network.target
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.conf.yml
Restart=always
RestartSec=10s
LimitNOFILE=40000
[Install]
WantedBy=multi-user.target
6.2 从二进制包安装 etcd-v3.6.5-linux-amd64.tar.gz
(1)配置 api版本
bash
echo 'export ETCDCTL_API=3' >> ~/.bashrc
source ~/.bashrc
sudo vi /etc/profile
export ETCDCTL_API=3
source /etc/profile
(2)下载与解压
bash
# 设置要下载的版本
ETCD_VER="v3.6.5-rc.3"
# 清理临时目录并重新创建
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
# 下载压缩包
curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
# 解压到临时目录
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
# 验证版本
/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
#下载包解压
etcd-v3.6.5-linux-amd64.tar.gz
(3)安装到系统路径
bash
# 将etcd和etcdctl复制到系统二进制文件目录
sudo mv /tmp/etcd-download-test/etcd /usr/local/bin/
sudo mv /tmp/etcd-download-test/etcdctl /usr/local/bin/
或
sudo mv /etcd-v3.6.5-linux-amd64/etcd /usr/local/bin/
sudo mv /etcd-v3.6.5-linux-amd64/etcdctl /usr/local/bin/
# 再次验证安装是否成功
etcd --version
etcdctl version
6.3 配置 TLS 证书(推荐,生产环境必选)
etcd 通信需加密(客户端与服务端、节点间),需生成 CA 根证书、服务器证书和客户端证书。推荐用 cfssl 工具生成:
(1)安装 cfssl 工具
bash
# 下载 cfssl 工具
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -o cfssl
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -o cfssljson
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl-certinfo_1.6.4_linux_amd64 -o cfssl-certinfo
# 赋予执行权限并移动到系统路径
chmod +x cfssl cfssljson cfssl-certinfo
sudo mv cfssl cfssljson cfssl-certinfo /usr/local/bin/
(2)生成证书 generate-etcd-certs.sh
bash
#!/bin/bash
# generate-etcd-certs.sh
ETCD_DIR="/etc/etcd"
PKI_DIR="$ETCD_DIR/pki"
sudo mkdir -p $PKI_DIR
cd $PKI_DIR
# 生成CA证书
sudo openssl genrsa -out ca.key 2048
sudo openssl req -x509 -new -nodes -key ca.key -subj "/CN=etcd-ca" -days 3650 -out ca.crt
# 生成服务器证书
sudo openssl genrsa -out server.key 2048
sudo openssl req -new -key server.key -subj "/CN=etcd-server" -out server.csr
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
# 设置权限
sudo chmod 600 *.key
sudo chown -R czh:czh $PKI_DIR
echo "证书生成完成在: $PKI_DIR"
(3)修改目录权限
bash
# 设置正确的目录权限(700 = 仅所有者有读写执行权限)
sudo chmod 700 /var/lib/etcd
# 或者如果使用root用户:
sudo chown -R czh:czh /var/lib/etcd
# 验证权限
ls -la /var/lib/ | grep czh
# 应该显示:drwx------ (而不是 drwxr-xr-x)
# 设置证书目录权限
sudo chmod 755 /etc/etcd/pki
sudo chmod 644 /etc/etcd/pki/*.crt
sudo chmod 600 /etc/etcd/pki/*.key
# 设置证书文件所有者
sudo chown -R czh:czh /etc/etcd/pki
6.4 启动etcd服务
bash
# 在所有Master节点上执行:
sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl restart etcd
sudo systemctl start etcd
sudo systemctl status etcd
sudo systemctl stop etcd.service
# 检查etcd集群状态
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/pki/ca.pem \
--cert=/etc/etcd/pki/server.pem \
--key=/etc/etcd/pki/server-key.pem endpoint health
# 输出三个节点均为healthy则成功
6.5 验证 etcd 监听地址
如果服务已运行但连接仍失败,可能是 etcd 没有在预期的地址(127.0.0.1:2379)上监听。 检查 etcd 的配置,特别是 --listen-client-urls参数。确保其配置中包含 http://127.0.0.1:2379或 http://0.0.0.0:2379。你可以通过查看 systemd 服务文件或 etcd 的启动命令来确认。启动 etcd 时可以指定监听地址etcd --listen-client-urls 'http://0.0.0.0:2379' --advertise-client-urls 'http://0.0.0.0:2379'
6.6 单节点验证
bash
# 验证 etcd 服务端版本
etcd --version
# 验证 etcdctl 客户端版本
etcdctl version
写入数据(put 命令)
读取数据(get 命令)
7.服务校验
7.1 获取错误信息
bash
journalctl -xeu etcd.service
7.2 TLS 相关的监听失败
1 验证服务器证书(server.pem)是否有效
检查证书格式和内容是否有效
openssl x509 -in /etc/etcd/pki/server.pem -text -noout
若输出证书详细信息(含颁发者、有效期、IP 等),说明证书格式正确;
若报错(如 unable to load certificate),说明证书文件损坏或内容错误,需重新生成。
2 验证私钥(server-key.pem)是否有效
检查私钥格式是否正确
openssl rsa -in /etc/etcd/pki/server-key.pem -check
预期输出:RSA key ok,说明私钥有效;
若报错(如 unable to load Private Key),说明私钥损坏或不是 RSA 格式,需重新生成。
3 验证证书与私钥是否匹配(核心!)
证书和私钥必须是 "成对生成" 的(由同一 CSR 生成),否则 TLS 握手会失败。通过对比两者的 "公钥指纹" 确认
查看证书文件的所有者和权限
ls -l /etc/etcd/pki/ca.pem /etc/etcd/pki/server.pem /etc/etcd/pki/server-key.pem
若所有者不是 etcd,修改权限(确保 etcd 用户能读)
sudo chown etcd:etcd /etc/etcd/pki/ca.pem /etc/etcd/pki/server.pem /etc/etcd/pki/server-key.pem
4 检查 etcd 配置文件中的 TLS 参数
bash
# 客户端通信的 TLS 配置
cert-file: /etc/etcd/pki/server.pem # 服务器证书
key-file: /etc/etcd/pki/server-key.pem # 服务器私钥
trusted-ca-file: /etc/etcd/pki/ca.pem # CA 根证书
client-cert-auth: true # 启用客户端证书验证
# 节点间通信的 TLS 配置
peer-cert-file: /etc/etcd/pki/server.pem # 节点间通信证书(同服务器证书)
peer-key-file: /etc/etcd/pki/server-key.pem # 节点间通信私钥(同服务器私钥)
peer-trusted-ca-file: /etc/etcd/pki/ca.pem # 节点间验证的 CA 根证书(同上面的 CA)
peer-client-cert-auth: true # 启用节点间证书验证
5 重新生成全套证书(若上述步骤仍失败)
如果证书存在根本性问题(如签名无效、匹配失败),最彻底的方式是删除旧证书,重新生成全套:
bash
# 备份旧证书(可选)
sudo mv /etc/etcd/pki /etc/etcd/pki_bak
sudo mkdir -p /etc/etcd/pki
# 重新生成
cd /etc/etcd/pki
# 重新生成 CA 配置和根证书
ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": ["signing", "key encipherment", "server auth", "client auth"]
}
}
}
}
ca-csr.json
{
"CN": "etcd-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{"C": "CN", "L": "Beijing", "O": "etcd", "OU": "etcd-ca"}]
}
# 生成 CA 根证书和私钥
sudo cfssl gencert -initca ca-csr.json | sudo cfssljson -bare ca
# 重新生成服务器证书(确保 hosts 包含当前 IP 192.168.0.105)
server-csr.json
{
"CN": "etcd-server",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{"C": "CN", "L": "Beijing", "O": "etcd", "OU": "etcd-server"}],
"hosts": ["127.0.0.1", "192.168.0.105"] # 必须包含当前主机 IP
}
# 用 CA 签名生成服务器证书和私钥
sudo cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | sudo cfssljson -bare server
# 生成客户端证书(用于 etcdctl 操作)
client-csr.json
{
"CN": "etcd-client",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{"C": "CN", "L": "Beijing", "O": "etcd", "OU": "etcd-client"}]
}
sudo cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd client-csr.json | sudo cfssljson -bare client
# 设置权限(关键!)
sudo chmod 600 *.key
sudo chown -R etcd:etcd /etc/etcd/pki
7.6 重启 etcd 并验证
bash
sudo systemctl restart etcd
sudo systemctl status etcd -l
7.7 实时日志监控配置,etcd.conf.yml
log-level: debug
7.8 日志输出
bash
sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl restart etcd
sudo journalctl -u etcd -f
7.9 验证启动状态
sudo systemctl status etcd -l
8.错误查找
8.1 查看详细日志
sudo journalctl -u etcd.service -n 50 --no-pager
8.2 检查网络配置(确认配置中的IP(如192.168.0.105)是本机有效地址。检查端口是否被其他进程占用。)
bash
ip addr show
sudo netstat -tulnp \| grep -E ':(2379\|2380)'
8.3 检查TLS证书 检查证书路径、权限和内容是否有效。
确保证书文件路径与配置一致,且etcd进程用户有读取权限。证书的SAN(主题备用名称)应包含本机IP
8.4 检查数据目录
bash
# 确保数据目录存在且权限正确(应为etcd用户所有)。检查磁盘空间是否不足
ls -l /var/lib/etcd/
df -h /var/lib/etcd/
8.5 验证配置文件
bash
sudo etcd --config-file=/etc/etcd/etcd.conf.yml --dry-run(如果支持)
检查配置文件语法。特别留意之前提到的节点名称唯一性和IP地址正确性。