20.3 容器访问控制

容器的访问控制主要通过Linux上的iptables防火墙软件来进行管理和实现。iptables是Linux系统流行的防火墙软件,在大部分发行版中都自带。

1.容器访问外部网络

从前面的描述中,我们知道容器默认指定了网关为docker0网桥上的docker0内部接口。docker0内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访问到宿主机本地的。

更进一步,容器要想通过宿主机访问到外部网络,需要宿主机进行转发。

在宿主机Linux系统中,检查转发是否打开:


  1. $ sudo sysctl net.ipv4.ip_forward

如果为0,说明没有开启转发,则需要手动打开:


  1. $ sudo sysctl -w net.ipv4.ip_forward=1

更简单的,在启动Docker服务的时候设定—ip-forward=true,Docker服务会自动打开宿主机系统的转发服务。

2.容器之间的访问

容器之间相互访问,需要两方面的支持:

·网络拓扑是否已经连通。默认情况下,所有容器都会连接到docker0网桥上,这意味着默认情况下拓扑是互通的;

·本地系统的防火墙软件iptables是否允许访问通过。这取决于防火墙的默认规则是允许(大部分情况)还是禁止。

下面分两种情况介绍容器之间的访问。

(1)访问所有端口

当启动Docker服务时候,默认会添加一条“允许”转发策略到iptables的FORWARD链上。通过配置—icc=true|false(默认值为true)参数可以控制默认的策略。

为了安全考虑,可以在Docker配置文件中配置DOCKER_OPTS=—icc=false来默认禁止容器之间的相互访问。

同时,如果启动Docker服务时手动指定—iptables=false参数则不会修改宿主机系统上的iptables规则。

(2)访问指定端口

在通过-icc=false禁止容器间相互访问后,仍可以通过—link=CONTAINER_NAME:ALIAS选项来允许访问指定容器的开放端口。

例如,在启动Docker服务时,可以同时使用icc=false—iptables=true参数来配置容器间禁止访问,并允许Docker自动修改系统中的iptables规则。

此时,系统中的iptables规则可能是类似如下规则,禁止所有转发流量:


  1. $ sudo iptables -nL
  2. ...
  3. Chain FORWARD (policy ACCEPT)
  4. target prot opt source destination
  5. DROP all -- 0.0.0.0/0 0.0.0.0/0
  6. ...

之后,启动容器(docker run)时使用—link=CONTAINER_NAME:ALIAS选项。Docker会在iptable中为两个互联容器分别添加一条ACCEPT规则,允许相互访问开放的端口(取决于Dockerfile中的EXPOSE行)。

此时,iptables的规则可能是类似如下规则:


  1. $ sudo iptables -nL
  2. ...
  3. Chain FORWARD (policy ACCEPT)
  4. target prot opt source destination
  5. ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80
  6. ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
  7. DROP all -- 0.0.0.0/0 0.0.0.0/0

20.3 容器访问控制 - 图1注意

—link=CONTAINER_NAME:ALIAS中的CONTAINER_NAME目前必须是Docker自动分配的容器名,或使用—name参数指定的名字。不能为容器-h参数配置的主机名。