容器所有的外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址。这是使用 iptables 的源地址伪装操作实现的
查看主机的 NAT 规则
master@ML:~$ sudo iptables -t nat -nL ... Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 MASQUERADE all -- 172.18.0.0/16 0.0.0.0/0 ...上述规则将所有源地址在 172.17.0.0/16 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT的好处是它能动态从网卡获取地址。
外部访问容器实现容器允许外部访问, 可以在 docker run 时候通过 -p 或 -P 参数来启用。其实是在本地的 iptable 的 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 tc p 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 tc p 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 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的 时候进行配置。
–bip=CIDR IP 地址加掩码格式,例如 192.168.1.5/24
–mtu=BYTES 覆盖默认的 Docker mtu 配置
也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。
$ sudo apt-get install bridge-utils # 使用 brctl show 查看网桥和接口信息 master@ML:~$ sudo brctl show bridge name bridge id STP enabled interfaces br-f0e69307bcd6 8000.0242acb125bb no docker0 8000.024256ed46ef no