![Docker 映射的端口未显示在“netstat”、“ss”和“lsof”上](https://linux22.com/image/160312/Docker%20%E6%98%A0%E5%B0%84%E7%9A%84%E7%AB%AF%E5%8F%A3%E6%9C%AA%E6%98%BE%E7%A4%BA%E5%9C%A8%E2%80%9Cnetstat%E2%80%9D%E3%80%81%E2%80%9Css%E2%80%9D%E5%92%8C%E2%80%9Clsof%E2%80%9D%E4%B8%8A.png)
我有一个关于 docker 容器和套接字的问题。今天我发现,主机系统上具有映射端口(或其他端口)的 docker 容器在我使用或时-p 80:80
不会显示(也尝试过,没有机会)。然后我尝试测试,打开一个侦听器端口80 ,但没有机会,它拒绝连接端口80,尽管这个端口没有显示由某个进程打开。netstat
ss
lsof -i
sudo
sudo nc -l -p 80
我认为这个问题是由于容器化或网络命名空间造成的,但是应该有一些命令可以按低级别、内核级别列出已使用的套接字?
ps:当我尝试在端口映射()上使用 docker 主机网络接口 ip 地址时-p 172.17.0.1:80:80
,它使用上述命令显示。
ps-2:lsof | grep -w 80
输出:
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
Xorg 718 root 37u CHR 13,80 0t0 10891 /dev/input/event16
Xorg 718 749 Xorg:disk root 37u CHR 13,80 0t0 10891 /dev/input/event16
Xorg 718 778 Xorg:disk root 37u CHR 13,80 0t0 10891 /dev/input/event16
Xorg 718 787 Xorg:disk root 37u CHR 13,80 0t0 10891 /dev/input/event16
Xorg 718 841 InputThre root 37u CHR 13,80 0t0 10891 /dev/input/event16
答案1
Docker 使系统充当外部和正在运行的容器之间的路由器:路由器不使用套接字来执行路由(仅用于其自己的服务或访问远程服务)。这就是容器连接不与netstat
或 一起出现的原因ss
。它们lsof
由于类似的原因而未能出现:虽然lsof
可以显示容器的正在运行的进程并确定其某些文件描述符是套接字,但它将无法在本地网络堆栈的套接字中关联套接字(因为它们位于其他网络命名空间中),因此将无法发现这些套接字的真正含义。
Docker 可以为其容器创建本地套接字的唯一情况是当它运行时可以选择使用docker-proxy
来处理NAT 发夹。最新的默认配置不再使用它,因为它都可以用iptables。
Docker 通常也执行 NAT。要做到这一点,它依赖于iptables和网络过滤器的连线记住 NAT 关联。这连线可以使用以下命令查询条目conntrack
conntrack
工具(通常在名为或 的包中提供conntrack-tools
)。
对于Docker的默认模式:NAT,很容易知道Docker背后的流量。任何回复目标与查询源不同的条目都意味着执行了 SNAT(包括 MASQUERADE)。任何连线回复源与查询目标不同的条目意味着执行了 DNAT(包括重定向)。conntrack
可以通过足够的选项来做到这一点:
conntrack -L --src-nat
conntrack -L --dst-nat
conntrack -L --any-nat
第一个通常会显示从容器到外部的传出连接关联,这些连接关联正在被 MASQUERADE-d。第二个通常会显示从外部到正在进行 DNAT 的容器的传入连接关联,第三个将显示所有内容。当然,可以添加更多过滤器。
使用-E
代替-L
可以在事件模式下监视此类关联。
当然如果Docker配置为不进行NAT,连线仍然用于状态防火墙,因此只要不提供任何过滤选项,仍然会显示源和目标。
然后对于属于容器命名空间地址的任何 IP 地址(例如,通常为 172.17.0.0/16)码头工人0,然后进一步是 172.18.0.0/16 或按照配置),可以将其与来自 Docker 的信息相关联,以找出实际的目标容器。