最近项目在做安全加固的时候突然遇到一个问题,一共三个板卡,每个板卡上面部署了三套执行体(php,java,python各一套),要求同一个板卡上面的三个执行体的容器彼此之间隔离,不能互相通信,也不能使用ping命令。
解决这个问题之前,我们先了解下docker的网络通信模式有哪些?
docker network ls
通过打印发现一共包含bridge桥接模式,host主机模式、none三种默认的模式,其实还有另外两种是默认不显示的,需要手动定以后,才能通过docker network ls命令查看才会显示出来!
模式名称 | 简介 | 备注 |
---|---|---|
bridge | 容器拥有独属于自己的虚拟网卡和和虚拟IP等网络资源,它们分别通过docker0虚拟网卡与宿主机的eth0网卡交互,进而和外界网络交互 | 默认模式 |
host | 容器没有自己的任何独立的网络资源(比如:容器的IP、网卡和端口),完全和宿主机共享网络空间 | 弊端:同一个端口只能同时被一个容器服务绑定 |
none | 该模式关闭了容器的网络功能,仅有独自的网络空间(一个空架子),并且该模式不会给容器分配任何网络资源,包括虚拟网卡、路由、防火墙、IP、网关、端口等 | 光秃秃的一个容器,没有任何的网络资源,就是自娱自乐的光杆司令(很少用) |
container | 它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源,除了网络资源,其他资源,容器彼此之间依然是相互隔离的 | 第一个以bridge方式启动的容器服务挂掉,后面依赖它的容器,都暂停服务 |
自定义 | 该模式也更为灵活,可以通过-d 指定自定义的网络模式的类型,可以是bridge或者overlay,其中overlay功能更为强大,可以指定多个subnet子网网段。 | 该模式,在容器之间使用别名相互通信,有着举足轻重的作用(重要) |
通过这个表我们发现,docker的容器的通信模式一共有5种,默认采用的是bridge桥接模式,我们再来看下这5种模式怎么使用。
docker run 后面添加 --net参数即可。
我们先来看下目前我们采用的哪种网络模式,通过docker inspect打印容器信息,发现我们容器运行模式位host模式。
通过启动命令我们也能发现我们采用了host主机模式
docker run -dit --net=host --privileged=true --restart=always --name=debian_nginx_ci_v1 -e MIMIC_BRACKET_HOST="32.60.90.42" -e MIMIC_BRACKET_PORT="8091" debian_nginx_ci:v1
什么是主机模式呢?
主机模式意味着容器和宿主机共享Network namespace
从上图可以看出,如果在启动容器后使用的是host模式,那么这个容器将不会获得一个独立的Network Namespace(网络命名空间),而是和宿主机系统共用一个Network Namespace。并且这就意味着容器将不会虚拟出自己的网卡以及配置自己的ip等,而是使用宿主机的ip以及端口。不过呢,在其他方面例如文件系统等还是与之隔离的。
因此这种方式是无法实现我们开篇说的容器彼此之间隔离,不能互相通信,也不能使用ping命令的需求。
我们再来看下container模式满足么?
它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源, 除了网络资源 ,其他资源,容器彼此之间依然是相互隔离的
很显然这种方式也不行!!
那么只剩下最后一种bridge模式了
什么是bridge模式?
该模式就是我们在启动docker服务后默认的docker网络模式,其会在主机上创建一个名为docker0的虚拟网桥,这个主机上的所有启动的容器就会连接到这个虚拟网桥上。
docker0和自定义网络肯定不通,我们是使用自定义网络的好处就是网络隔离:
bridge模式的使用
我们先通过自定义创建网络的方式,创建一个php的网络,指定子网、IP地址范围、网关等网络配置
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 php
通过docker network ls查看是否创建成功
可以看到多了一个php的网络,查看自定义网络细节
docker network inspect php
注:如果创建网络时候报以下错误,是因为docker服务启动之后开启了防火墙需要重启docker服务
systemctl restart firewalld.service
然后我们再用同样的方法创建一个python服务的网络
如果在创建的过程中报Error response from daemon: Pool overlaps with other one on this address space 说明网段被占用,换一个网段即可。
然后分别启动php的容器和python的容器并指定到对应的网络
docker run -dit --net=php --privileged=true --restart=always --name=ubuntu_apache_ci_v1 -e MIMIC_BRACKET_HOST="33.60.90.43" -e MIMIC_BRACKET_PORT="8091" ubuntu_apache_ci:v1
docker run -dit --restart=always --net=python --privileged=true --name=cm_ca_env cm_ca_env:v1
我们先进入php的服务容器中拿到对应的ip地址如下:
可以看到php的容器的ip地址为192.168.0.2/16
再进入到python的服务容器中,通过curl方式和ping的方式来请求php的服务发现都是不通的。
我们再来验证下,同一网络内的容器是否互通呢?
我们把python的服务删掉,然后重新启动使用php的网络。进入到容器中再试下结果:
评论