Kubernetes外部etcd二进制部署指南:从证书规划到高可用集群

发布时间:2026/10/9 3:23:15
Kubernetes外部etcd二进制部署指南:从证书规划到高可用集群 有段时间我一直在用 kubeadm 搭 Kubernetes 集群stacked etcd 确实省事但每次上生产环境心里总有点没底。后来我终于把 etcd 单独拆出来用二进制方式部署了一套三节点的外部 etcd 集群再让 kube-apiserver 通过 TLS 对接上去。整套控制平面的稳定性和可维护性都明显上了一个台阶。如果你也想搞清 Kubernetes 控制平面的底层数据链路或者需要一套可以独立扩缩容、独立备份恢复的存储组件这篇二进制部署指南应该能帮你省下不少试错的时间。我先把话放前头外部 etcd 的二进制部署本身并不神秘真正的难点集中在三块——证书体系的规划、配置文件的理解、以及集群成员关系的维护。把这三块啃下来剩下的就是顺着步骤往下走。1. 为什么把 etcd 从 Kubernetes 里拆出来外部 etcd 的设计价值1.1 stacked etcd 与 external etcd 怎么选熟悉 kubeadm 的人都知道默认装出来的是 stacked etcd也就是控制平面节点上既跑 kube-apiserver又跑 etcd 成员。这样的好处是省机器、部署简单kubeadm 一条龙就能把证书、服务、静态 Pod 全搞定。但生产环境里我会优先把它拆开。原因其实很直白。第一故障域隔离。stacked 模式下控制平面节点一旦出问题kube-apiserver 和 etcd 是一起挂的你很难快速判断到底是应用层崩溃还是存储层不可用。第二升级风险耦合。Kubernetes 版本升级时如果连 etcd 二进制一起动任何一个兼容性问题都会直接影响控制平面。第三资源竞争。etcd 是 IO 敏感型组件和 kube-apiserver 抢 CPU、抢磁盘带宽时间长了性能抖动很难排查。外部 etcd 集群把这些麻烦都隔离开了。etcd 跑在独立的机器上数据目录、系统盘、网络策略都可以单独规划。更关键的是外部 etcd 可以跨集群复用——同一套 etcd 集群理论上可以被多个 Kubernetes 控制平面共享实际生产里我不建议这么干但故障迁移场景下这个能力很值钱。所以我的结论是测试环境你用 stacked 没毛病生产环境、需要长期运维的集群老老实实上外部 etcd。1.2 外部 etcd 集群的整体拓扑与组件分工一套典型的外部 etcd 方案节点角色大致是这样的3 台 etcd 节点跑 etcd 二进制负责存储 Kubernetes 的集群状态数据端口 2379 提供客户端访问端口 2380 做成员间 peer 通信。2 台或 3 台控制平面节点跑 kube-apiserver、kube-controller-manager、kube-scheduler通过 2379 端口读写 etcd。注意我这里说的控制平面节点是“用二进制或手动部署的”不是 kubeadm 管理的。如果非要用 kubeadm也可以用--external-etcd的方式跳过内置 etcd 组件的安装但证书和配置文件仍然需要你自己准备。本文的方案完全不依赖 kubeadmapiserver 以二进制或者 systemd 方式托管适合理解每一层链路的人。组件之间的数据链路是这样的kube-apiserver 是唯一直接读写 etcd 的 Kubernetes 组件。它拿到 API 请求之后会把资源对象序列化后写入 etcd 的/registry路径下。所有 watch、list、create、update 操作最终都落到 etcd 的事务和线性一致性保证上。所以 etcd 集群的健康状态直接决定整个控制平面能不能对外提供稳定的 API 服务。这也是为什么我在部署时格外强调证书、成员关系、磁盘性能和快照备份这四个点。它们不是锦上添花而是保命用的。2. 部署前的准备环境规划与版本选型2.1 机器规划三个角色各司其职先说机器数量。etcd 集群我强烈建议奇数节点最少 3 个。为什么是奇数因为 etcd 的 Raft 协议要求多数派存活才能选主和对外提供服务3 节点集群允许挂 1 个5 节点集群允许挂 2 个。你用偶数节点比如 4 个故障容忍上限和 3 个一样还白白多维护一台机器没有任何好处。以 3 节点为例我给一个可以直接抄的规划主机名IP角色k8s-etcd-110.0.0.11etcd member数据目录独立磁盘k8s-etcd-210.0.0.12etcd member数据目录独立磁盘k8s-etcd-310.0.0.13etcd member数据目录独立磁盘k8s-master-110.0.1.11kube-apiserver、controller-manager、schedulerk8s-master-210.0.1.12kube-apiserver、controller-manager、scheduler这里有个容易忽略的点etcd 机器不要复用成 Kubernetes 的工作节点。很多人图省事把 etcd 塞到已有的 worker 上结果 Pod 频繁重建导致磁盘 IO 抖动直接拖垮整个控制平面的写入延迟。等你在生产环境被坑一次就会记住存储组件一定要有自己的地盘。操作系统层面我用的是 CentOS 7.9 和 Ubuntu 20.04 都跑过本文命令以 CentOS 系为主Ubuntu 上把包管理器换成 apt 即可。数据盘建议单独挂载文件系统用 xfs 或者 ext4 都行但务必打开noatime挂载参数减少不必要的元数据写入。2.2 基础环境优化时间、DNS、内核参数与磁盘etcd 的 Raft 协议对时钟偏差非常敏感节点间时间差太大会导致选举异常。所以第一步就是统一时间同步。我用 chrony 比较多配置也很简单yum install -y chrony systemctl enable --now chronyd chronyc sources -v确认chronyc能看到^*开头的源就说明已经同步上了。三台 etcd 节点建议都指向同一个时间源别让它们各自漂移。接着是 hosts 解析。etcd 配置文件里可以写 IP也可以写主机名但成员通信和证书 SAN 校验环节经常会用到主机名所以我建议三台机器彼此把 hosts 写全cat /etc/hosts EOF 10.0.0.11 k8s-etcd-1 10.0.0.12 k8s-etcd-2 10.0.0.13 k8s-etcd-3 EOF内核参数这块我实测下来影响最大的是文件句柄和 TCP 保活。etcd 在大量 watch 连接下会占用非常多 fd必须调大cat /etc/sysctl.conf EOF fs.file-max 2097152 net.ipv4.tcp_keepalive_time 600 net.core.somaxconn 32768 vm.swappiness 10 EOF sysctl -pvm.swappiness调低是为了避免内存回收时把 etd 的热数据换到 swap虽然生产服务器一般不开 swap但万一开了这个参数能救命。磁盘方面有条件上 NVMe SSD 就别用机械盘。数据目录所在磁盘的 IO 调度器可以调整为 none 或 noop对 SSD 来说能降低延迟抖动。确认调度器的方法cat /sys/block/sdb/queue/scheduler如果是mq-deadline可以通过内核启动参数或者运行时修改但运行时修改重启会失效所以我通常直接在 grub 里设置一劳永逸。2.3 版本选型etcd 版本与 Kubernetes 怎么匹配版本匹配是个容易被忽略的大坑。etcd 的 API 版本和 Kubernetes 控制平面的兼容性是有边界的你拿一个特别老的 etcd 配全新的 Kubernetes大概率会出现请求报错或者 watch 异常。我的经验是以 Kubernetes 官方文档里标注的 etcd 版本为准不要随意升级。以我常用的环境为例Kubernetes 1.28 系列对应 etcd 3.4.28 以上3.5.x 也完全没问题Kubernetes 1.24 到 1.27 用 etcd 3.5.x 是主流选择。本文操作以etcd v3.5.10为例如果你用的是 3.4.x配置文件语法基本一致但部分命令参数有细微差别。回到二进制部署之前一定要先在官网的 GitHub Releases 页面下载对应版本的压缩包。etcd 的发布包命名很规律etcd-v3.5.10-linux-amd64.tar.gz里面包含etcd和etcdctl两个二进制没有别的花头。下载时可以顺手把 sha256 校验也做了防止下载损坏。3. 证书体系设计二进制部署绕不过的第一道坎3.1 证书角色与信任关系设计外部 etcd 的二进制部署没有 kubeadm 帮你自动签证书所有 TLS 证书都得自己规划。我把涉及的证书角色理清楚CA 证书一个自签的根 CAetcd 内部所有证书都信任它。etcd server 证书给 etcd 的 2379 客户端端口用kube-apiserver 访问 etcd 时要校验这个证书的有效性。etcd peer 证书给 etcd 的 2380 成员间通信用节点之间互相验证身份。kube-apiserver 访问 etcd 的客户端证书kube-apiserver 作为客户端连接 etcd 时出示的证书。这几个角色缺一不可。证书签发时有一个非常关键的细节etcd server 证书和 peer 证书的 SANSubject Alternative Name必须包含所有 etcd 节点的 IP 和主机名。因为 etcd 节点间的 peer 通信是全互联的任何一台都可能作为客户端去访问另一台的 2379 或 2380SAN 不全就会在 TLS 握手阶段被拒。我见过太多人在这里翻车证书里只写了本机 IP结果节点 A 访问节点 B 时报x509: certificate is valid for 10.0.0.11, not 10.0.0.12。所以规划 SAN 时直接把三台机器的 IP、hostname、127.0.0.1、localhost全部写进去宁可多不要少。3.2 使用 OpenSSL 签发 CA 与 etcd 证书证书签发我习惯用 OpenSSL。先建一个工作目录比如/opt/certs所有操作都在里面完成。第一步生成 CA 私钥和自签 CA 证书mkdir -p /opt/certs cd /opt/certs openssl genrsa -out etcd-ca.key 2048 openssl req -x509 -new -nodes -key etcd-ca.key \ -subj /CNkubernetes-etcd-ca \ -days 3650 \ -out etcd-ca.crtCA 证书的有效期我习惯给 10 年etcd 节点证书给 2 年到期前再批量轮换。轮换是个麻烦事所以不建议给节点证书也签 10 年缩短周期可以减少私钥泄露后的影响范围。第二步生成 etcd server 证书的私钥和 CSR。先创建 OpenSSL 扩展文件把 SAN 写进去cat etcd-server-openssl.cnf EOF [ req ] req_extensions v3_req distinguished_name req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints CA:FALSE keyUsage nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage serverAuth, clientAuth subjectAltName alt_names [ alt_names ] IP.1 10.0.0.11 IP.2 10.0.0.12 IP.3 10.0.0.13 IP.4 127.0.0.1 DNS.1 k8s-etcd-1 DNS.2 k8s-etcd-2 DNS.3 k8s-etcd-3 DNS.4 localhost EOF这里我同时加上了serverAuth和clientAuth的 extendedKeyUsage因为 etcd 的 server 证书也会被拿去作为客户端连接其他成员双用途能省一张证书。然后签发openssl genrsa -out etcd-server.key 2048 openssl req -new -key etcd-server.key \ -subj /CNetcd-server \ -out etcd-server.csr openssl x509 -req -in etcd-server.csr \ -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial \ -out etcd-server.crt -days 730 \ -extfile etcd-server-openssl.cnf -extensions v3_req第三步签发 peer 证书流程几乎一样只是 CN 和文件名改一下。peer 证书的 SAN 同样要覆盖全部节点 IP 和主机名cat etcd-peer-openssl.cnf EOF [ req ] req_extensions v3_req distinguished_name req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints CA:FALSE keyUsage nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage serverAuth, clientAuth subjectAltName alt_names [ alt_names ] IP.1 10.0.0.11 IP.2 10.0.0.12 IP.3 10.0.0.13 IP.4 127.0.0.1 DNS.1 k8s-etcd-1 DNS.2 k8s-etcd-2 DNS.3 k8s-etcd-3 DNS.4 localhost EOF openssl genrsa -out etcd-peer.key 2048 openssl req -new -key etcd-peer.key \ -subj /CNetcd-peer \ -out etcd-peer.csr openssl x509 -req -in etcd-peer.csr \ -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial \ -out etcd-peer.crt -days 730 \ -extfile etcd-peer-openssl.cnf -extensions v3_req签发完记得校验一下证书内容openssl x509 -in etcd-server.crt -text -noout | grep -A5 Subject Alternative Name确认 SAN 里有全部 IP 再往下走。这一步不缺后面能省一整晚的排障时间。3.3 为 kube-apiserver 签发访问 etcd 的客户端证书apiserver 访问 etcd 时需要一个专门的客户端证书。这个证书的 CN 一般写成kube-apiserver或者其他能标识身份的名字extendedKeyUsage 只需要clientAuth。签发命令cat etcd-client-openssl.cnf EOF [ req ] req_extensions v3_req distinguished_name req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints CA:FALSE keyUsage nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage clientAuth EOF openssl genrsa -out etcd-client.key 2048 openssl req -new -key etcd-client.key \ -subj /CNkube-apiserver \ -out etcd-client.csr openssl x509 -req -in etcd-client.csr \ -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial \ -out etcd-client.crt -days 730 \ -extfile etcd-client-openssl.cnf -extensions v3_req注意etcd 服务端配置了client-cert-auth: true之后握手时不仅要求客户端出示证书还会校验这个证书是不是由受信任的 CA 签发的。所以 kube-apiserver 那边必须同时提供--etcd-certfile和--etcd-keyfile并且把 CA 证书通过--etcd-cafile传过去。三者缺一不可只传证书不传 CA 或者只传 CA 不传客户端证书都会导致连接失败。3.4 证书分发与安全加固证书签发完成后分发路径我建议这样规划每台 etcd 节点需要etcd-ca.crt、etcd-server.crt、etcd-server.key、etcd-peer.crt、etcd-peer.key。每台 kube-apiserver 节点需要etcd-ca.crt、etcd-client.crt、etcd-client.key。我把证书统一放在各节点的/etc/etcd/pki目录下etcd 服务运行用户是etcd所以私钥文件权限设置为600属主为etcd。证书文件可以是644。分发用 scp 或者 ansible 都行但传完之后一定要做三件事校验文件完整性、检查属主属组、确认私钥权限。chown -R etcd:etcd /etc/etcd chmod 600 /etc/etcd/pki/*.key chmod 644 /etc/etcd/pki/*.crt另外强烈建议把 CA 私钥etcd-ca.key离线保存或者至少单独放一台不对外提供服务的机器上。CA 私钥泄露等于整个 etcd 集群的 TLS 信任链崩溃攻击者可以伪造任意成员证书后果非常严重。生产环境里这个私钥我甚至会用加密介质保存签发证书时才取出来。4. etcd 二进制部署全过程从下载到集群健康4.1 下载并安装 etcd 二进制三台 etcd 节点都要安装二进制。先把压缩包解压到/opt再把可执行文件放到/usr/local/bincd /opt wget https://github.com/etcd-io/etcd/releases/download/v3.5.10/etcd-v3.5.10-linux-amd64.tar.gz tar -xzvf etcd-v3.5.10-linux-amd64.tar.gz cp etcd-v3.5.10-linux-amd64/etcd /usr/local/bin/etcd cp etcd-v3.5.10-linux-amd64/etcdctl /usr/local/bin/etcdctl chmod x /usr/local/bin/etcd /usr/local/bin/etcdctl etcd --versionetcd --version能正常打印版本号说明二进制没问题。接着创建 etcd 运行用户和数据目录useradd -r -s /sbin/nologin etcd mkdir -p /var/lib/etcd chown -R etcd:etcd /var/lib/etcd数据目录这里有个实用经验先不要急着挂大容量磁盘etcd 的数据增长虽然不快但快照和 WAL 文件会持续占用空间。我习惯在部署时就把数据盘挂到/var/lib/etcd下并且用du定期观察增长趋势。默认 2GB 的历史 compaction 保留策略下一个中等规模的 Kubernetes 集群一年大概能涨几个 GB 到几十 GB量级取决于资源数量变化频率。4.2 编写 etcd 配置文件etcd 支持命令行参数和配置文件两种方式。配置文件更清晰、更好维护我强烈推荐。在每台节点上写/etc/etcd/etcd.conf.yml以节点 1 为例# 节点 1 配置 name: etcd-1>[Unit] Descriptionetcd service Afternetwork-online.target Wantsnetwork-online.target [Service] Typenotify Useretcd Groupetcd ExecStart/usr/local/bin/etcd --config-file/etc/etcd/etcd.conf.yml Restarton-failure RestartSec5 LimitNOFILE65536 TimeoutStartSec0 [Install] WantedBymulti-user.target注意Typenotify这个配置要求 etcd 启动完成后通过 sd_notify 通知 systemd而不是让 systemd 自己判断进程存活。etcd 3.4 以上版本支持这个模式好处是 systemd 能拿到 etcd 真正 ready 的信号避免出现进程起来了但集群还没就绪的间隙。systemctl daemon-reload systemctl enable etcd systemctl start etcd systemctl status etcd -lLimitNOFILE必须调大原因前面说过etcd 在大量客户端连接和 watch 场景下文件描述符消耗非常快。默认的 1024 根本不够用压测时经常会看到too many open files报错。4.4 逐个启动成员并验证集群状态这里是我踩过最深的坑之一不要三台同时启动。虽然 etcd 设计上支持同时启动时的自动选主但实际操作中同时启动容易受到证书、网络、系统初始化速度不一致的影响导致选举超时或成员注册失败。我的做法是先启动第一台确认它自己能成为 leader单节点时必然选主成功再启动第二台等它加入集群再启动第三台。每次启动观察日志和集群成员状态systemctl start etcd journalctl -u etcd -f第一台起来后在任意节点上用 etcdctl 查看成员列表。注意 etcdctl 访问需要指定证书export ETCDCTL_API3 etcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ member list -w table如果配置正确你会看到一个成员处于unstarted状态这是正常的。等第二台、第三台启动后再执行member list应该能看到三个成员状态都是started。集群健康检查用这个命令etcdctl --endpointshttps://10.0.0.11:2379,https://10.0.0.12:2379,https://10.0.0.13:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ endpoint health --cluster -w table输出里每个 endpoint 一行healthy表示正常unhealthy表示有问题。看到三行healthy的时候etcd 集群这层就算立住了。5. 让 kube-apiserver 对接外部 etcd5.1 kube-apiserver 对接 etcd 的关键参数etcd 集群就绪后接下来就是把 kube-apiserver 指到它上面。不管你是直接用二进制启动 kube-apiserver还是用 kubeadm 的配置文件生成静态 Pod真正核心的参数是这四个--etcd-servershttps://10.0.0.11:2379,https://10.0.0.12:2379,https://10.0.0.13:2379 --etcd-cafile/etc/kubernetes/pki/etcd-ca.crt --etcd-certfile/etc/kubernetes/pki/etcd-client.crt --etcd-keyfile/etc/kubernetes/pki/etcd-client.key--etcd-servers指定 etcd endpoints多个地址用逗号分隔。apiserver 会自己负载均衡读请求写请求只会发给当前 leader不需要你干预。--etcd-cafile指向 CA 证书用来校验 etcd 服务端证书--etcd-certfile和--etcd-keyfile就是前面签发的客户端证书和私钥。如果你用的是 systemd 直接托管 kube-apiserverExecStart 里加这些参数即可。如果是 kubeadm 方式需要在kubeadm-config里指定etcd.external配置块然后把四个参数填进去。kubeadm 检测到etcd.external时就不会再生成内置 etcd 的静态 Pod。还有两个和 etcd 相关的参数经常被忽略。--etcd-prefix默认是/registry一般不用动。--storage-backend默认走 etcd3如果你的 apiserver 版本很老可能还需要显式指定新版本已经默认了。我从 1.20 之后就没再手动设置过这个参数。5.2 启动 kube-apiserver 并验证数据读写kube-apiserver 启动后可以通过日志确认它已经连上 etcd。启动时日志里如果出现etcdserver: request timed out或者context deadline exceeded说明网络或证书还有问题。如果顺利你会看到 apiserver 开始正常处理/healthz请求。验证数据读写最直接的办法是往 Kubernetes 里创建一个资源然后去 etcd 里看数据是否落盘。比如创建 namespacekubectl create namespace demo然后在 etcd 节点上读取对应 keyetcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ get /registry/namespaces/demo --prefix -w json能查到demo这个 namespace 对象说明 apiserver 到 etcd 的写入链路已经通了。再执行一次kubectl get ns demo如果 apiserver 状态正常读取链路也没问题。这里我要提醒一个容易混淆的点etcdctl 里用的证书不一定是 kube-apiserver 的客户端证书。上面命令里我用的是 etcd server 证书因为它同时具备 clientAuth 用途所以也能作为客户端证书用。但你如果想要更干净的权限隔离可以专门用 etcd-client 那套证书来执行运维操作。关键是任何访问 etcd 的客户端都必须能通过client-cert-auth校验。6. 常见问题与排查技巧实录6.1 集群成员状态异常与选举问题先说成员状态异常。执行member list看到某个成员unstarted最常见的原因是initial-cluster里的地址和实际监听地址不一致。比如你配置里写的是https://k8s-etcd-1:2380但 hosts 解析没配好DNS 解析失败成员间就永远无法连通。排查思路是从日志入手直接看 etcd 的日志输出。journalctl -u etcd -f里出现failed to connect to peer或者dial tcp相关的警告基本可以锁定网络层问题。先用telnet 10.0.0.12 2380测试连通性再用openssl s_client -connect 10.0.0.12:2380测试 TLS 握手一层层剥。选举问题最常见的表象是集群一直无 leader表现为etcdserver: no leader报错。这时候先确认节点数是不是偶数再确认是否有节点因为网络分区被隔离。Raft 需要多数派存活如果你 3 个节点里有两个挂在一个交换机下第三个节点在另一个网络区域就可能出现活着的节点凑不齐多数派的情况。这种网络分区问题要在交换机侧做冗余etcd 层面除了日志排查没有太多可做的。还有一个经验三节点集群里有一台机器被强制关机后再启动经常会在日志里看到raft: became candidate然后反复选主失败。这种时候不要慌先检查另外两台是否健康。如果另外两台正常重启异常节点后 etcd 会自动重新加入集群并同步数据。如果反复失败考虑是不是数据目录损坏必要时用快照恢复。6.2 TLS 证书报错与访问失败证书问题是外部 etcd 部署里出现频率最高的故障。我列几个最常见的报错和对应解决办法报错信息原因解决办法x509: certificate is valid for 10.0.0.12, not 10.0.0.13SAN 缺少目标 IP重新签发证书SAN 加入全部节点 IP 和主机名certificate signed by unknown authority对端不信任本端 CA或 CA 文件传错检查trusted-ca-file和--etcd-cafile是否指向同一份 CAclient certificate is not trusted客户端证书不是由 CA 签发或client-cert-auth开启后客户端未传证书用 CA 重新签发客户端证书或补全--etcd-certfile、--etcd-keyfiletls: first record does not look like a TLS handshake端口没错但协议不对比如用 HTTP 访问 HTTPS 端口确认 URL 前缀是https://检查listen-client-urls证书排障时我强烈建议用openssl s_client做握手验证它能告诉你证书链到底断在哪openssl s_client -connect 10.0.0.11:2379 \ -CAfile /etc/etcd/pki/etcd-ca.crt \ -cert /etc/etcd/pki/etcd-client.crt \ -key /etc/etcd/pki/etcd-client.key如果握手成功会输出SSL-Session和Verify return code: 0。如果看到Verify return code: 20或19说明信任链或证书不匹配。这个工具比 etcdctl 的报错信息更底层、更直观。6.3 数据目录膨胀与性能退化etcd 在长时间运行后数据目录会越来越大但真正占空间的不一定是有效数据而是历史版本和碎片。Kubernetes 的控制面对象变化非常频繁每次变更都会产生一个新的 etcd revision。如果不对历史版本做压缩compact数据目录会呈线性甚至超线性增长。我的例行维护操作是# 查看当前最新 revision etcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ endpoint status --cluster -w table # 压缩到最新 revision etcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ compact latest_revision # 碎片整理 etcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ defrag注意 defrag 操作会阻塞所在 etcd 成员生产环境不建议一次性对三个节点同时执行。我的习惯是逐个节点操作先对该节点执行etcdctl defrag等它完成并恢复健康再操作下一个。因为 defrag 期间该成员的读写会短暂暂停如果同时做三个整个集群会出现明显抖动。性能退化也很隐蔽。如果发现 apiserver 的 API 请求延迟升高先看 etcd 的监控指标重点关注etcd_server_leader_changes_seen_total和etcd_disk_wal_fsync_duration_seconds。前者如果频繁增长说明 leader 在不停切换大概率是磁盘 IO 抖动或网络问题后者如果远超 10ms说明 WAL 落盘太慢该换磁盘或者检查文件系统参数了。6.4 备份、恢复与故障演练最后必须说的是备份。etcd 的数据是 Kubernetes 集群的命根子apiserver 里的所有资源对象最终都存在这里。没有备份的 Kubernetes 集群出了故障就只能重建这是不可接受的。etcd 官方提供了基于 etcdctl 的快照备份方式etcdctl --endpointshttps://10.0.0.11:2379 \ --cacert/etc/etcd/pki/etcd-ca.crt \ --cert/etc/etcd/pki/etcd-server.crt \ --key/etc/etcd/pki/etcd-server.key \ snapshot save /backup/etcd-snapshot-$(date %Y%m%d).db备份文件拿到之后恢复思路是把快照文件恢复到某个节点的数据目录然后以initial-cluster-stateexisting的方式启动该节点再逐步加入其他节点。恢复命令etcdctl snapshot restore /backup/etcd-snapshot-20240101.db \ --name etcd-1 \ --initial-cluster etcd-1https://10.0.0.11:2380,etcd-2https://10.0.0.12:2380,etcd-3https://10.0.0.13:2380 \ --initial-cluster-token etcd-k8s \ --initial-advertise-peer-urls https://10.0.0.11:2380 \ --data-dir /var/lib/etcd-restore恢复出来的数据目录是全新的不影响原数据。确认无误后再把原数据目录改名把恢复目录挪到/var/lib/etcd启动 etcd。整个过程我在下线维护窗口里做过不止一次核心经验就一条恢复前先把证书和配置文件备份一份别在恢复过程中又把证书弄丢。备份策略层面我建议每天都做一次快照保留最近 7 天每周再做一次归档。快照文件不要放在 etcd 本机要同步到独立的存储或对象存储。否则 etcd 机器磁盘坏了快照也跟着没等于白备份。最后留给你的几个实践建议上面这套流程走完之后我自己的体会是外部 etcd 真正考验人的不是命令记不记得住而是对 Raft 成员关系和 TLS 信任链有没有直觉。成员关系错了集群会一直处于 unhealthy 状态证书 SAN 缺了一个 IPapiserver 连上来就是x509报错。所以强烈建议你实际操作时把每台节点的配置文件和证书清单都打印出来对照着检查一遍再启动。另外一个小技巧部署完成后给 etcd 集群做一次断电演练。手动停掉一个节点观察另外两个是否正常提供服务再停掉第二个确认集群进入不可用状态。然后按顺序恢复看能否自动选主并重新同步数据。这样做一次你对这套集群的真实信心会比看十篇文档都强。祝你在生产环境里少踩坑etcd 稳如老狗。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询