早上已经迁移走的docker启动的服务一直在发送邮件,登录服务器查看又啥都没有,第一次遇到这种情况,记录下😄

# 检查端口监听情况(无输出)
[root@host  ~]# ip a|grep '172.23.3.20'
    inet 172.23.3.20/25 brd 172.23.3.127 scope global noprefixroute ens3
[root@host ~]# netstat -anlput | grep 7001
[root@host ~]# ss -tuln | grep 7001
[root@host ~]# lsof -i :7001

# 本地回环访问失败
[root@host ~]# curl 127.0.0.1:7001
curl: (7) Failed to connect to 127.0.0.1 port 7001 after 0 ms: Connection refused

# 通过本机 IP 访问却成功
[root@host ~]# curl 172.23.3.20:7001
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><link rel="icon" href="api/app/favicon"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/><title>Loading</title><script src="static/icons/iconfont.js?v=1.37.15"></script><link rel="stylesheet" href="static/index.css?v=1.37.15"/><script type="module" crossorigin src="./assets/index-Dlw30lzT.js"></script><link rel="stylesheet" crossorigin href="./assets/index-kJji8Sf_.css"></head><body><div id="app"><div class="fs-bootstrap"><div class="fs-bootstrap__main"><div class="fs-bootstrap__loading"></div></div><div class="fs-bootstrap__footer"></div></div></div></body></html>

通过iptables查看可以发现,Docker 通过 iptables DNAT 实现流量转发

[root@host ~]# iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 71349 packets, 4874K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 955K   69M DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 71276 packets, 4869K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 154K packets, 9996K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 5532  332K DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 150K packets, 9383K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  165 10664 MASQUERADE  all  --  *      !br-4d034c8b695e  172.22.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      !br-1dc15054c92a  172.20.0.0/16        0.0.0.0/0           
 1774  120K MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:3100
    0     0 MASQUERADE  tcp  --  *      *       172.22.0.2           172.22.0.2           tcp dpt:7001

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  br-4d034c8b695e *       0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  br-1dc15054c92a *       0.0.0.0/0            0.0.0.0/0           
  621 37228 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3100 to:172.17.0.2:3100
 1451 75572 DNAT       tcp  --  !br-4d034c8b695e *       0.0.0.0/0            0.0.0.0/0            tcp dpt:7001 to:172.22.0.2:7001

当请求 172.23.3.20:7001 到达主机,iptables 在 PREROUTING 链触发 DNAT,目标 IP 被重写为 172.22.0.2:7001,内核将流量转发到 Docker 网桥 br-4d034c8b695e,容器 172.22.0.2 接收请求并响应

整个过程发生在 Linux 内核网络栈,没有用户态进程监听 7001!

容器是独立 Linux 进程,不依赖 dockerd 运行,这次忘记先停容器了😄,所以停止docker服务前需要先停止容器!

更多推荐