节点加入失败常见端口 4369 被占用,如何修改 epmd 端口并重新完成集群组建?
解读
在国内生产环境,尤其是云主机、容器平台或混合部署场景,4369 端口被系统服务、旧 Erlang 节点或其他中间件抢占是 CouchDB 集群扩容失败的高频根因。面试官想验证两点:
- 你是否理解 Erlang Port Mapper Daemon(epmd)在 CouchDB 集群发现中的角色;
- 能否在不中断现有业务的前提下,优雅地修改 epmd 端口并重新完成节点加入,而不是粗暴地 kill 进程或重启整机。
知识点
- epmd 作用:维护 Erlang 节点名称到实际监听端口的映射表,CouchDB 节点通过 TCP 4369 查询彼此。
- 环境变量 ERL_EPMD_PORT:启动前导出该变量即可让 epmd 监听新端口,所有节点必须保持一致。
- systemd 覆盖:国内 CentOS/AlmaLinux 默认用 systemd 管理 CouchDB,需在
/etc/systemd/system/couchdb.service.d/epmd.conf写入Environment=ERL_EPMD_PORT=43690,再systemctl daemon-reload。 - 防火墙与安全组:腾讯云、阿里云安全组默认只开 4369,需同步放行新端口;iptables/firewalld 同理。
- 节点加入命令:
curl -X POST http://admin:pwd@existing:5984/_cluster_setup -d '{"action":"enable_cluster","bind_address":"0.0.0.0","port":5984,"node_count":3,"username":"admin","password":"pwd"}',完成后{"action":"add_node","host":"newnode","port":5984},必须保证新旧节点 epmd 端口一致,否则 add_node 报nxdomain或connection refused。 - 验证:
epmd -names -port 43690应列出所有节点;netstat -lnpt | grep beam确认 Erlang 监听随机端口与 epmd 映射一致。
答案
- 在所有节点统一修改 epmd 端口:
写入export ERL_EPMD_PORT=43690/etc/environment或 systemd 覆盖文件,确保重启仍生效。 - 停止 CouchDB 与 epmd:
systemctl stop couchdb epmd -kill # 若仍有残留 - 启动新 epmd:
epmd -daemon -port 43690 - 启动 CouchDB:
systemctl start couchdb - 在安全组/防火墙放行 43690/tcp。
- 在已有节点执行:
curl -X POST http://admin:pwd@existing:5984/_cluster_setup \ -H "Content-Type: application/json" \ -d '{"action":"add_node","host":"newnode","port":5984,"username":"admin","password":"pwd"}' - 返回
{"ok":true}后,再{"action":"finish_cluster"}完成组建。 - 验证:
应看到所有节点状态为curl http://admin:pwd@any:5984/_membershipcluster_enabled。
拓展思考
- 零停机迁移:若 4369 已被核心系统占用且不能改,可先在新节点组用 43690 拉起独立集群,再用
_replicator做全量+增量同步,最后通过应用层双写+蓝绿切换完成迁移,避免业务中断。 - 容器场景:Kubernetes 下可把
ERL_EPMD_PORT写进 ConfigMap,通过 StatefulSet 的 headless service 固定 Pod DNS,使节点重启后仍能被找回;同时把 43690 加入 NetworkPolicy 白名单。 - 监控告警:使用 Prometheus + epmd_exporter 监听新端口,采集
epmd_up、epmd_node_count指标,防止端口再次冲突导致节点“幽灵掉线”。