管理预案
以下是一些常见的 etcd 管理任务 SOP(预案):
- 创建集群:如何初始化 etcd 集群?
- 销毁集群:如何销毁 etcd 集群?
- 环境变量:如何配置 etcd 客户端,以访问 etcd 服务器集群?
- RBAC 认证:如何使用 etcd 的 RBAC 认证?
- 重载配置:如何更新客户端使用的 etcd 服务器成员列表?
- 添加成员:如何向现有 etcd 集群添加新成员?
- 移除成员:如何从 etcd 集群移除老成员?
- 便捷脚本:使用
bin/etcd-add和bin/etcd-rm简化操作
更多问题请参考 FAQ:ETCD。
创建集群
要创建一个集群,首先需要在 配置清单 中定义 etcd 集群:
执行 etcd.yml 剧本即可。
自 Pigsty v3.6 起,etcd.yml 剧本专注于集群安装和成员添加,不再包含移除功能。所有移除操作请使用独立的 etcd-rm.yml 剧本。
对于已初始化的生产环境 etcd 集群,可以打开防误删保护 etcd_safeguard,避免误删现有的 etcd 实例。
销毁集群
要销毁一个 Etcd 集群,请使用独立的 etcd-rm.yml 剧本。默认的 etcd_rm_data: true 会删除本机数据与配置;请先确认没有 PostgreSQL 集群仍将它用作 DCS,并核验近期备份和精确目标名。
或使用便捷脚本:
移除剧本会尊重 etcd_safeguard 防误删保险的配置。如果该参数设置为 true,剧本将在退群、注销、停服和删除之前中止;其默认值为 false,不能把未显式覆盖保险当作一次确认。
在移除 etcd 集群之前,请确保没有 PostgreSQL 集群正在使用该 etcd 作为 DCS 服务。否则会导致 PostgreSQL 高可用功能失效。
环境变量
Pigsty 默认使用 etcd v3 API(v3.6+ 已移除 v2 API 支持)。Pigsty 会在 etcd 节点上自动配置环境变量脚本 /etc/profile.d/etcdctl.sh,登录后会自动加载。
以下是 etcd 客户端配置环境变量的示例:
Pigsty 自 v4.0 起为 etcd 默认启用 RBAC 认证,当前版本仍需配置用户认证:
配置好客户端环境变量后,你可以使用以下命令进行 etcd CRUD 操作:
RBAC 认证
Pigsty 自 v4.0 起默认启用 etcd 的 RBAC(基于角色的访问控制)认证机制。在集群初始化时,etcd_auth 任务会自动创建 root 用户并启用认证。
root 用户密码 由 etcd_root_password 参数指定,默认值为 Etcd.Root。密码存储在 /etc/etcd/etcd.pass 文件中,权限为 0640(root 所有,etcd 组可读)。
在生产环境中,强烈建议修改默认密码:
客户端认证方式:
重载配置
如果 etcd 集群的成员发生变化(添加或移除成员),我们需要刷新对 etcd 服务端点的引用。目前 Pigsty 中有以下几处 etcd 引用需要更新:
| 配置位置 | 配置文件 | 更新方式 |
|---|---|---|
| etcd 成员配置 | /etc/etcd/etcd.conf |
./etcd.yml -t etcd_conf |
| etcdctl 环境变量 | /etc/profile.d/etcdctl.sh |
./etcd.yml -t etcd_config |
| Patroni DCS 配置 | /etc/patroni/patroni.yml |
./pgsql.yml -t pg_conf |
| VIP-Manager 配置 | /etc/default/vip-manager.yml |
./pgsql.yml -t pg_vip_config |
刷新 etcd 成员配置文件:
刷新 etcdctl 客户端环境变量:
更新 Patroni DCS 端点配置:
更新 VIP-Manager 端点配置(仅当使用 PGSQL L2 VIP 时需要):
使用 bin/etcd-add 和 bin/etcd-rm 便捷脚本时,脚本会在操作完成后提示您需要执行的配置刷新命令。
添加成员
ETCD 参考: 添加成员
推荐方式:使用便捷脚本
使用 bin/etcd-add 脚本是向现有 etcd 集群添加新成员的 推荐方式:
脚本会自动完成以下操作:
- 验证 IP 地址有效性
- 执行
etcd.yml剧本(自动设置etcd_init=existing) - 提供安全警告和倒计时
- 操作完成后提示配置刷新命令
手动方式:分步操作
向现有的 etcd 集群添加新成员需要以下步骤:
- 更新配置清单:将新实例添加到
etcd组 - 通知集群:执行
etcdctl member add命令(可选,剧本会自动执行) - 初始化新成员:使用
etcd_init=existing参数运行剧本 - 提升成员:将学习者提升为正式成员(可选,使用
etcd_learner=true时需要) - 重载配置:更新所有客户端的 etcd 端点引用
添加新成员时必须使用 etcd_init=existing 参数,否则新实例会尝试创建新集群而非加入现有集群。
详细步骤:向 etcd 集群添加成员
下面是具体操作的详细细节,让我们从一个单实例 etcd 集群开始:
使用便捷脚本添加新成员(推荐):
或者手动操作。首先使用 etcdctl member add 向现有 etcd 集群宣告新的学习者实例 etcd-2 即将到来:
使用 etcdctl member list(或 em list)检查成员列表,我们可以看到一个 unstarted 新成员:
接下来使用 etcd.yml 剧本初始化新的 etcd 实例 etcd-2,完成后,我们可以看到新成员已经启动:
新成员初始化完成并稳定运行后,可以将新成员从学习者提升为追随者:
新成员添加完成,请不要忘记 重载配置,让所有客户端也知道新成员的存在。
重复以上步骤,可以添加更多成员。记住,生产环境中至少要使用 3 个成员。
移除成员
推荐方式:使用便捷脚本
使用 bin/etcd-rm 脚本是从 etcd 集群移除成员的 推荐方式:
脚本会依次尝试以下操作:
- 从集群中优雅地移除成员
- 停止并禁用 etcd 服务
- 清理数据和配置文件
- 从监控系统中注销
底层移除角色会容忍部分退群与清理错误,因此脚本结束后仍必须核对 etcdctl member list、端点健康、剩余仲裁,以及目标服务和数据目录的实际状态。
手动方式:分步操作
要从 etcd 集群中删除一个成员实例,通常需要以下步骤:
- 保持成员仍在配置清单中:移除剧本需要清单里的
etcd_seq、集群成员和连接端点信息 - 清理实例:对目标运行
etcd-rm.yml;剧本会先尝试member remove,再停服并按参数清理 - 更新配置清单:成功后再从配置清单中注释或删除该实例
- 重载引用:按 重载配置 刷新其余 etcd 成员及 Patroni/VIP-Manager 的端点
不要在运行移除剧本前先从清单删除目标;etcd-rm.yml 的 hosts: etcd 将无法再选中它,也无法从清单推导实例身份和集群端点。
也不需要在移除剧本前后额外重复执行 etcdctl member remove。
详细步骤:从 etcd 集群移除成员
让我们以一个 3 节点的 etcd 集群为例,从中移除 3 号实例。
方法一:使用便捷脚本(推荐)
脚本会尝试从集群中移除成员、停止服务并清理数据;结束后仍需按上文检查成员列表、仲裁与目标文件状态。
方法二:手动操作
首先保持待删除成员仍在清单中,使用移除剧本:
剧本会依次尝试以下操作:
- 获取成员列表并找到对应的成员 ID
- 执行
etcdctl member remove从集群中踢除 - 停止 etcd 服务
- 清理数据和配置文件
剧本会自动查询成员 ID 并执行 member remove。只有在排障时需要手工完成这一步:
手工踢除后仍需在目标尚存于清单时运行 ./etcd-rm.yml -l 10.10.10.12 完成停服、注销和清理;其退出步骤找不到已删除的成员时会跳过。
确认成员已经离开现场集群、剩余成员保持仲裁且目标服务与文件符合预期后,才从配置清单中删除 10.10.10.12,并按 重载配置 刷新其余 Etcd 成员和所有客户端引用,移除成员至此完成。
重复以上步骤,可以移除更多成员,与 添加成员 配合使用,可以对 etcd 集群进行滚动升级搬迁。
便捷脚本
Pigsty v3.6+ 提供了便捷脚本简化 etcd 集群的扩容和缩容操作:
bin/etcd-add
向现有 etcd 集群添加新成员:
脚本功能:
- 验证 IP 地址格式
- 自动设置
etcd_init=existing参数 - 执行
etcd.yml剧本完成成员添加 - 操作完成后提示配置刷新命令
bin/etcd-rm
从 etcd 集群移除成员或整个集群:
脚本功能:
- 提供安全警告和确认倒计时
- 自动执行
etcd-rm.yml剧本 - 优雅地从集群中移除成员
- 清理数据和配置文件
管理 Etcd 密码
etcd_root_password 参数定义了 etcd 集群的 root 用户密码。
要修改此密码,你需要访问到 etcd 端点,例如在 INFRA节点 与 ETCD节点 上使用 管理用户 执行:
然后你应该刷新所有对 etcd root 密码的引用,包括 INFRA 节点上的 Patroni 客户端配置与 etcdctl 客户端环境变量: