Docker 系列(三十四):端口映射的实现原理

默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。

容器访问外部网络的实现

容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址,这是使用 iptables 的源地址伪装(MASQUERADE)操作实现的。

查看主机的 NAT 规则:

$ sudo iptables -t nat -nL
...
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16       !172.17.0.0/16
...

其中,上述规则将所有源地址在 172.17.0.0/16 网段、目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 相比的好处是它能动态从网卡获取地址。NAT 与连接跟踪的更多底层细节,本站《TCP/IP 系列导读》的传输控制部分有系统的展开。

外部访问容器的实现

容器允许外部访问,可以在 docker run 时候通过 -p 或 -P 参数来启用。

不管是哪种办法,其实都是在本地的 iptables 的 nat 表中添加相应的规则。

使用 -P 时:

$ iptables -t nat -nL
...
Chain DOCKER (2 references)
target     prot opt source               destination
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:49153 to:172.17.0.2:80

使用 -p 80:80 时:

$ iptables -t nat -nL
Chain DOCKER (2 references)
target     prot opt source               destination
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80

注意:这里的规则映射了 0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 -p IP:host_port:container_port 或 -p IP::port 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容:

{
  "ip": "0.0.0.0"
}

系列导航


   转载规则


《Docker 系列(三十四):端口映射的实现原理》 由 吴杭沉 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
Docker 系列(三十五):Docker 的基本架构 Docker 系列(三十五):Docker 的基本架构
Docker 采用了 C/S(客户端/服务端)架构,包括客户端和服务端。Docker 守护进程(Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 sock
2023-04-11
下一篇 
Docker 系列(三十三):网络快速配置指南 Docker 系列(三十三):网络快速配置指南
下面是一个跟 Docker 网络相关的命令列表。 其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效: -b BRIDGE 或 --bridge=BRIDGE:指定容器挂载的网桥 --bip=CIDR:定制 d
2023-03-28
  目录