article
Etcd 公网访问配置完整教程:解决 127.0.0.1 能访问但公网 IP 不通问题
etcd 默认仅监听 127.0.0.1 导致公网 IP 无法访问。本文详细介绍了通过修改配置文件、设置监听地址为 0.0.0.0 并配置正确的广播地址来解决此问题,同时涵盖防火墙与安全组配置、常见错误排查及安全建议。
问题现象
bash
# 本地访问正常
$ curl http://127.0.0.1:2379/version
{"etcdserver":"3.4.30"}
# 公网 IP 访问失败
$ curl http://124.213.224.247:2379/version
curl: (7) Failed to connect to 124.213.224.247 port 2379 after 0 ms: Couldn't connect to server
原因: etcd 默认只监听 127.0.0.1,拒绝了所有外部连接。
解决方案
步骤 1:确认 etcd 安装方式与配置位置
bash
# 查看 etcd 进程启动参数
ps -ef | grep etcd | grep -v grep
# 查看 systemd 服务配置
sudo systemctl cat etcd
常见配置文件路径:
| 系统/安装方式 | 配置文件路径 |
|---|---|
| Ubuntu/Debian | /etc/default/etcd |
| CentOS/RHEL | /etc/sysconfig/etcd |
| 二进制安装 | 启动命令参数 |
| Snap 安装 | /var/snap/etcd/current/etcd.conf |
| 通用配置 | /etc/etcd/etcd.conf |
步骤 2:获取服务器 IP 地址
bash
# 查看内网 IP
ip addr show | grep inet | grep -v 127.0.0.1
# 查看公网 IP(云服务器)
curl -s ifconfig.me
步骤 3:修改配置文件
以 Ubuntu/Debian 为例:
bash
sudo vim /etc/default/etcd
3.1 方式一:配置内网访问(推荐-安全)
bash
# 客户端监听地址(监听所有网卡 + 本地回环)
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://127.0.0.1:2379"
# 广播地址(告诉客户端用内网 IP 访问)
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.16.3:2379"
# 集群通信监听地址
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
# 集群通信广播地址
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.16.3:2380"
# 节点名称
ETCD_NAME="%H"
# 数据存储目录
ETCD_DATA_DIR="/var/lib/etcd/default"
# 集群配置(单节点)
ETCD_INITIAL_CLUSTER="default=http://10.0.16.3:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
3.2 方式二:配置公网访问(不推荐-有安全风险)
bash
# 客户端监听地址
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://127.0.0.1:2379"
# 广播地址(告诉客户端用公网 IP 访问)
ETCD_ADVERTISE_CLIENT_URLS="http://124.213.224.247:2379"
# 集群通信监听地址
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
# 集群通信广播地址
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://124.213.224.247:2380"
# 节点名称
ETCD_NAME="%H"
# 数据存储目录
ETCD_DATA_DIR="/var/lib/etcd/default"
# 集群配置(单节点)
ETCD_INITIAL_CLUSTER="default=http://124.213.224.247:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
⚠️ 重要提醒:
ETCD_ADVERTISE_CLIENT_URLS绝不能使用0.0.0.0,必须是客户端能访问的真实 IP 地址。
步骤 4:重启 etcd 服务
bash
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 重启 etcd
sudo systemctl restart etcd
# 查看启动状态
sudo systemctl status etcd
# 查看监听端口确认生效
sudo netstat -tlnp | grep -E "2379|2380"
预期输出:
text
tcp 0 0 0.0.0.0:2379 0.0.0.0:* LISTEN 6204/etcd
tcp 0 0 0.0.0.0:2380 0.0.0.0:* LISTEN 6204/etcd
步骤 5:配置防火墙与安全组
5.1 Ubuntu UFW 防火墙
bash
# 放行 2379 端口
sudo ufw allow 2379/tcp
# 查看防火墙状态
sudo ufw status
5.2 云服务商安全组
登录云服务商控制台,添加入站规则:
| 协议 | 端口 | 源地址 | 说明 |
|---|---|---|---|
| TCP | 2379 | 0.0.0.0/0 | etcd 客户端端口 |
| TCP | 2380 | 0.0.0.0/0 | etcd 集群通信端口 |
步骤 6:验证访问
bash
# 本地访问测试
curl http://127.0.0.1:2379/version
# 内网 IP 访问测试
curl http://10.0.16.3:2379/version
# 公网 IP 访问测试
curl http://124.213.224.247:2379/version
成功返回示例:
json
{"etcdserver":"3.4.30","etcdcluster":"3.4.0"}
常见问题排查
问题 1:启动失败 - --advertise-client-urls is required
错误信息:
text
error verifying flags, --advertise-client-urls is required when --listen-client-urls is set explicitly
解决方案: 同时配置 ETCD_LISTEN_CLIENT_URLS 和 ETCD_ADVERTISE_CLIENT_URLS,两者必须成对出现。
问题 2:配置文件不生效
检查 systemd 服务文件是否使用了正确的配置文件:
bash
sudo systemctl cat etcd
如果 ExecStart= 中有 --config-file= 参数,说明使用的是指定配置文件,而非环境变量。
问题 3:端口被占用
bash
# 杀死残留进程
sudo pkill -f etcd
# 确认端口释放
sudo netstat -tlnp | grep -E "2379|2380"
# 重新启动
sudo systemctl start etcd
问题 4:数据目录权限问题
bash
sudo chown -R etcd:etcd /var/lib/etcd
sudo chmod 755 /var/lib/etcd
问题 5:查看详细错误日志
bash
# 查看服务状态
sudo systemctl status etcd
# 查看详细日志
sudo journalctl -xeu etcd.service -n 50
安全建议
⚠️ 严重警告
etcd 默认无认证机制,暴露在公网极不安全:
- 数据可被任意读写
- 可能被勒索软件攻击
- 配置可能被恶意篡改
推荐安全方案
方案一:仅监听内网(推荐)
bash
ETCD_LISTEN_CLIENT_URLS="http://10.0.16.3:2379,http://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.16.3:2379"
访问时使用 SSH 隧道:
bash
ssh -L 2379:127.0.0.1:2379 user@your-server
方案二:启用 TLS 加密
bash
ETCD_LISTEN_CLIENT_URLS="https://0.0.0.0:2379,https://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="https://124.213.224.247:2379"
ETCD_CERT_FILE="/etc/etcd/certs/server.crt"
ETCD_KEY_FILE="/etc/etcd/certs/server.key"
ETCD_CLIENT_CERT_AUTH="true"
方案三:启用身份认证
bash
# 添加 root 用户
etcdctl user add root --interactive
# 启用认证
etcdctl auth enable
# 使用认证访问
etcdctl --user root:password get /key
快速命令汇总
bash
# 查看配置位置
ps -ef | grep etcd | grep -v grep
sudo systemctl cat etcd
# 编辑配置(Ubuntu)
sudo vim /etc/default/etcd
# 查看当前配置
sudo cat /etc/default/etcd | grep -v "^#" | grep -v "^$"
# 查看内网 IP
ip addr show | grep inet | grep -v 127.0.0.1
# 重启服务
sudo systemctl restart etcd
# 查看状态
sudo systemctl status etcd
sudo netstat -tlnp | grep etcd
# 查看日志
sudo journalctl -xeu etcd.service -n 50
# 测试访问
curl http://127.0.0.1:2379/version
curl http://公网IP:2379/version
# 放行防火墙
sudo ufw allow 2379/tcp
配置参数对照表
| 配置项 | 作用 | 示例值 | 说明 |
|---|---|---|---|
ETCD_LISTEN_CLIENT_URLS |
服务端监听地址 | http://0.0.0.0:2379 |
可监听所有网卡 |
ETCD_ADVERTISE_CLIENT_URLS |
客户端访问地址 | http://124.213.224.247:2379 |
必须用真实 IP |
ETCD_LISTEN_PEER_URLS |
集群通信监听地址 | http://0.0.0.0:2380 |
节点间通信 |
ETCD_INITIAL_ADVERTISE_PEER_URLS |
集群通信广播地址 | http://124.213.224.247:2380 |
节点间发现 |
ETCD_NAME |
节点名称 | VM-0-16-ubuntu |
集群内唯一标识 |
ETCD_DATA_DIR |
数据存储目录 | /var/lib/etcd/default |
持久化路径 |
完成以上步骤后,etcd 即可从公网正常访问。