20.3 容器访问控制
容器的访问控制主要通过Linux上的iptables防火墙软件来进行管理和实现。iptables是Linux系统流行的防火墙软件,在大部分发行版中都自带。
1.容器访问外部网络
从前面的描述中,我们知道容器默认指定了网关为docker0网桥上的docker0内部接口。docker0内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访问到宿主机本地的。
更进一步,容器要想通过宿主机访问到外部网络,需要宿主机进行转发。
在宿主机Linux系统中,检查转发是否打开:
- $ sudo sysctl net.ipv4.ip_forward
如果为0,说明没有开启转发,则需要手动打开:
- $ 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规则可能是类似如下规则,禁止所有转发流量:
- $ sudo iptables -nL
- ...
- Chain FORWARD (policy ACCEPT)
- target prot opt source destination
- DROP all -- 0.0.0.0/0 0.0.0.0/0
- ...
之后,启动容器(docker run)时使用—link=CONTAINER_NAME:ALIAS选项。Docker会在iptable中为两个互联容器分别添加一条ACCEPT规则,允许相互访问开放的端口(取决于Dockerfile中的EXPOSE行)。
此时,iptables的规则可能是类似如下规则:
- $ sudo iptables -nL
- ...
- Chain FORWARD (policy ACCEPT)
- target prot opt source destination
- ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80
- ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
- DROP all -- 0.0.0.0/0 0.0.0.0/0
注意
—link=CONTAINER_NAME:ALIAS中的CONTAINER_NAME目前必须是Docker自动分配的容器名,或使用—name参数指定的名字。不能为容器-h参数配置的主机名。
