我在公网VPS上踩过的Docker网络坑:从端口暴露到安全组配置全记录
大家好,我是33blog的运维老司机。上周给客户的公网VPS部署Docker时,又双叒叕被网络配置折腾得够呛。今天就把这些实战经验(和血泪教训)整理成文,希望能帮到同样在Docker网络迷宫里打转的你。
1. 你以为的端口暴露 ≠ 真实的端口暴露
第一次配置时,我自信满满地在docker run
加了-p 80:80
参数,结果curl测试直接connection refused。后来才发现阿里云的安全组默认全关,这就像给房子开了门却发现小区大门锁着。
# 血泪教训:永远先检查这三层
1. 容器内服务是否监听正确(netstat -tulnp)
2. 主机iptables规则(iptables -L -n)
3. 云厂商安全组配置(这个坑最深!)
2. 桥接网络下的IP迷惑行为
当我用docker network inspect bridge
看到172.17.0.0/16的IP时,下意识以为可以直接从公网访问。结果你猜怎么着?外网ping都ping不通!原来Docker默认的bridge网络是NAT模式,需要做端口映射才能透传。
后来改用host网络模式省去了端口映射的麻烦,但代价是失去了网络隔离性。这里分享我的选择标准:
- 测试环境 → 直接用host模式省心
- 生产环境 → 坚持bridge模式+精确端口映射
3. 防火墙的连环追杀
最崩溃的是有一次所有配置都对了,但服务还是不通。最后发现是CentOS的firewalld在作妖。建议新人直接记死这个组合拳:
# 永久开放端口
sudo firewall-cmd --permanent --add-port=80/tcp
# 重载配置
sudo firewall-cmd --reload
# 检查状态
sudo firewall-cmd --list-all
(说真的,我现在见到firewalld都有PTSD了)
4. 终极解决方案:docker-compose全栈配置
经过多次踩坑后,我现在所有项目都改用docker-compose统一管理。分享一个生产级模板:
version: '3'
services:
webapp:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
networks:
- frontend
database:
image: postgres:13
networks:
- backend
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
networks:
frontend:
driver: bridge
backend:
driver: bridge
用这个模板部署时,记得:
- 提前在云平台配置安全组规则
- 主机防火墙放行对应端口
- 敏感信息用.env文件管理
5. 给新手的真诚建议
最后分享几个只有踩过坑才懂的经验:
- 永远先用
telnet your_ip port
测试基础连通性 - 修改配置后,按「容器→主机→云平台」顺序逐层检查
- 复杂环境建议上
tcpdump
抓包分析
这次折腾让我明白,Docker网络就像洋葱,得一层层剥开才能见真章。如果你们在部署时遇到其他奇葩问题,欢迎在评论区交流,说不定我又能攒出续集素材了呢(笑)。
太有用了!我昨天也被阿里云安全组坑了一下午😭