MENU

记一次docker服务无法访问端口无法被局域网链接(DNAT失败)

May 10, 2021 • Read: 86 • 教程·折腾

一个清风轻拂的夏日,正舒服得码着代码,大佬突然叫我,某某机器得 MySQL 访问不到了。
心想着,访问不到?一直好好跑着呢,谁又搞了啥。

背景:MySQL 是 docker 运行的,端口映射 13306 到 3306

root# docker run -p 13306:3306 --name mysql \
-v /opt/mydata/mysql/data:/var/lib/mysql \
-v /opt/mydata/mysql/conf:/etc/mysql \
-v /opt/mydata/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=IAMPASSWORD \
-d mysql:5.7

下面开始了常规的排查

  • 看下进程在不在
root# docker ps |grep mysql
52475d4ff648   mysql:5.7   "docker-entrypoint.s…"   7 weeks ago   Up 18 minutes  0.0.0.0:13306->3306/tcp   mysql

没问题

  • 端口占用看下
root# lsof -i:13306
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 9391 root    4u  IPv4  64691      0t0  TCP *:cbserver (LISTEN)

root# netstat -ano|grep 13306
tcp        0      0 0.0.0.0:13306            0.0.0.0:*               LISTEN      off (0.00/0/0)

端口都有,证明服务大概率没问题,只是网络问题

  • 看下本地 telnet 能不能通

本地没有 telnet ,yum 安装一把梭

root# yum install telnet -y

执行 telnet 连端口

root# telnet 127.0.0.1 13306
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
J
5.7.33;xs}2D_r▒▒7k[ ~lu_(cV#mysql_native_password

明显本地端口通,局域网不通,难道没映射上?

  • iptable 看下 nat 表的转发情况
root# iptables -t nat -vnL DOCKER --line-number
Chain DOCKER (2 references)
num   pkts bytes target     prot opt in       out      source               destination
1        0     0 RETURN     all  --  docker0   *       0.0.0.0/0            0.0.0.0/0
2       10   600 DNAT       tcp  --  !docker0  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:13306 to:172.17.0.3:3306

映射也没问题,防火墙有问题?心里有点慌,因为非常明确之前我开过防火墙

  • 查找防火墙及重新开启
root# firewall-cmd --zone=public --list-ports
13306/tcp

到这里已经对自己过往经验去解决问题不抱希望了,重开碰碰运气吧

root# firewall-cmd --zone=public --add-port=13306/tcp --permanent
success
root# firewall-cmd --reload
success

重开尝试局域网连接还是不行,心里有点烦躁,排查到这里毕生所学已经花完,想着搞不好要提桶跑路。

  • 自己决绝不了那问问神奇的Google

很快啊,啪的一下,打开google.com,输入 "docker 端口和宿主机端口 跨主机访问不到" 找到第一条,点击浏览,一气呵成。

扫了一眼,看看有没有能用上的,大幅度在说docker网络模式之类,突然一个关键字'映入眼帘' :) 误

宿主机的ip路由转发功能一定要打开,否则所创建的容器无法联网!

[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1

看下这台主机开了没有?

root# cat /proc/sys/net/ipv4/ip_forward
0

嗯嗯,到这里很有可能就是这个原因了,很简单,echo 设置这个文件的值为1

root# echo 1 > /proc/sys/net/ipv4/ip_forward
  • 回顾

其实,最开始的时候没有遇到这个问题是因为本身就开启了,很可能是中午自己骚操作修改这台主机的 dns 使用 nmcli 相关命令导致关闭了。
下面是回顾可能导致的原因,搞出这个坑竟是我自己。(=_=)

root# nmcli con mod ens160 ipv4.ignore-auto-dns yes
root# nmcli con down ens160

down 后连不上主机,联系运维,运维把 networkManager.service 移除了,ip_forward 不知为何被设置为 0 ,所以 DNAT 就失效了
所以,有事没事,不要乱搞,叫运维弄好网络,自己少折腾。

自己常规性的排查就那几个思路及命令,所学的太少,而且,越发想复习计算机网络~

  • 参考

docker容器的网络配置,允许docker可以被宿主机以外的其它主机访问以及局域网内可以直接访问docker容器ip
How to manage DNS in NetworkManager via console (nmcli)?


本文由 ONE 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
如有版权疑问交流,请给我留言:oneisall8955@gmail.com
本文永久链接:https://liuzhicong.cn/index.php/guide/docker-port-problem-record.html

Archives QR Code Tip
QR Code for this page
Tipping QR Code