©
本文档使用 PHP中文网手册 发布
本节中的信息解释了Docker默认网桥中的容器通信。这是一个在安装Docker时自动创建的bridge
网络bridge
。
注意:通过Docker网络功能,您可以创建除默认网桥以外的用户定义网络。
一个容器是否可以与世界交流受两个因素控制。第一个因素是主机是否转发其IP数据包。其次是主机是否iptables
允许这种特定的连接。
IP数据包转发由ip_forward
系统参数管理。如果此参数是数据包,则只能在容器之间传递数据包1
。通常你会简单地离开了码头工人服务器的默认设置--ip-forward=true
和码头工人会去设置ip_forward
,以1
在服务器启动时你。如果您设置--ip-forward=false
并且您的系统内核已启用该--ip-forward=false
选项,则该选项不起作用。要检查内核上的设置或手动打开它:
$ sysctl net.ipv4.conf.all.forwarding net.ipv4.conf.all.forwarding = 0 $ sysctl net.ipv4.conf.all.forwarding=1 $ sysctl net.ipv4.conf.all.forwarding net.ipv4.conf.all.forwarding = 1
注意:此设置不会影响使用主机网络堆栈(
--network=host
)的容器。
许多使用Docker的人都希望ip_forward
开启,至少可以在容器和更广泛的世界之间进行通信。如果您处于多个桥接设置中,也可能需要进行集装箱间通信。
如果您设置--iptables=false
守护进程启动时,Docker将永远不会更改您的系统规则iptables
。否则,Docker服务器会将转发规则附加到DOCKER
过滤器链中。
Docker将刷新任何预先存在的规则,从DOCKER
和DOCKER-ISOLATION
过滤器链,如果存在的话。出于这个原因,需要在Docker启动后添加任何需要进一步限制对容器访问的规则。
Docker的转发规则默认允许所有外部源IP。要仅允许特定的IP或网络访问容器,请在DOCKER
过滤器链的顶部插入否定规则。例如,要限制外部访问,以便只有源IP 8.8.8.8才能访问容器,可以添加以下规则:
$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
其中ext_if是提供到主机的外部连接的接口的名称。
两个容器是否可以通信在操作系统级别由两个因素决定。
网络拓扑是否连接了容器的网络接口?默认情况下,Docker会将所有容器附加到一个docker0
桥,为数据包之间的传输提供路径。有关其他可能的拓扑,请参阅本文档的后面部分。
你的iptables
是否允许这个特定的连接?如果您设置--iptables=false
守护进程启动时,Docker将永远不会更改您的系统规则iptables
。否则,如果保留缺省值,则Docker服务器将FORWARD
使用一揽子ACCEPT
策略向该链添加默认规则--icc=true
,否则会将该策略设置为DROP
如果--icc=false
。
这是一个战略性问题,是否要保留--icc=true
或改变,--icc=false
以便iptables
保护其他容器和主要主机不受任何受到攻击的容器探测或访问的端口的限制。
如果您选择最安全的设置--icc=false
,那么在您希望他们提供对方服务的情况下,容器如何通信?答案就是--link=CONTAINER_NAME_or_ID:ALIAS
选项,因为它对名称服务的影响,在前一节中提到了这个选项。如果Docker守护进程正在运行--icc=false
并且--iptables=true
随后运行,当它看到docker run
使用该--link=
选项调用时,Docker服务器将插入一对iptables
ACCEPT
规则,以便新容器可以连接到其他容器公开的端口 - 它提到的端口它的EXPOSE
线Dockerfile
。
注:
CONTAINER_NAME
值的--link=
必须是自动分配的Docker的名字一样stupefied_pare
,或者你用指定的名称--name=
,当你跑了docker run
。它不能是主机名,Docker在该--link=
选项的上下文中不会识别。
您可以在Docker主机上运行Fiptables
命令,以查看该ORWARD
链是否具有默认策略为ACCEPT
或DROP
:
# When --icc=false, you should see a DROP rule:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0DROP all -- 0.0.0.0/0 0.0.0.0/0...# When a --link= has been created under --icc=false,# you should see port-specific ACCEPT rules overriding # the subsequent DROP policy for all other packets:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0DROP all -- 0.0.0.0/0 0.0.0.0/0Chain DOCKER (1 references)target prot opt source destination ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
注意:Docker非常小心它的主机范围
iptables
规则完全将容器暴露给彼此的原始IP地址,因此从一个容器到另一个容器的连接总是应该来自第一个容器自己的IP地址。
出于安全原因,Docker配置iptables
规则以防止容器在Linux主机上从主机外部转发流量。Docker将FORWARD
链的默认策略设置为DROP
。
要覆盖此默认行为,您可以手动更改默认策略:
$ sudo iptables -P FORWARD ACCEPT
在iptables
当系统重新启动设置都将丢失。如果您希望更改是永久的,请参阅您的Linux发行版的文档。
注意:在Docker 1.12及更早版本中,默认
FORWARD
链策略是ACCEPT
。当您升级到Docker 1.13或更高版本时,此默认值会自动为您更改。如果您以前的工作配置包含跨多个主机的多个容器,则此更改可能会导致现有设置停止工作,如果您不介入。
DROP
为ACCEPT
?假设你有两台主机,每台主机都有以下配置
host1: eth0/192.168.7.1, docker0/172.17.0.0/16host2: eth0/192.168.8.1, docker0/172.18.0.0/16
如果运行在容器host1
需要与容器直接沟通的能力host2
,你需要从路线host1
到host2
。路由存在后,host2
需要能够接受去往其运行容器的数据包,并将其转发。设置政策来ACCEPT
完成这一点。