目录
一、原生网络机
1.1、bridge模式
1.2、host模式
1.3、 none模式
二、自定义网络
2.1 创建自定义网络
2.2、自定义网段、网关
三、容器之间的网络通信
3.1、建立双网卡模式
3.2、Joined模式
3.3 link模式
四、容器与外网的通信
4.1、容器访问外网(内核打开ip_forward)
4.2、外网访问容器
五、 跨主机的容器网络
5.1、macvlan
5.1.1设置vlan子接口
一、原生网络机
官方网址配置:Networking overview | Docker Documentation
docker在启动时会自产生三种网络机制:bridge、host、none。
1.1、bridge模式:
该模式下docker中的容器不会产生一个公有IP,只有宿主机可以直接访问容器,此时对外部主机是不可见的。但容器可以通过宿主机的NAT规则访问外网。
图1 bridge模式
1.2、host模式:
该模式下可以让容器共享宿主机的网络,好处在于可以直接与外部主机进行通信,但此时容器也缺乏隔离性,同时在使用时,对于同一台宿主机而言,相同容器的配置(端口,ip等)会产生冲突。
图2 host模式
1.3、 none模式:
禁用容器的IP地址,此时容器有很好的隔离性,一般用于产生一些特殊的认证等。
##容器网络的查看方式
[root@server1 harbor]# docker network ls
##容器建立时产生的桥接口
[root@server1 harbor]# ip addr show docker0
##安装桥接管理工具
[root@server1 harbor]# yum install -y bridge-utils-1.5-9.el7.x86_64
##桥接命令查看当前桥接接口
[root@server1 harbor]# brctl show
[root@server1 harbor]# sysctl -a | grep ip_forward
##指定容器的网络模式
[root@server1 ~]# docker run -it --rm --name deamon --network=host busybox
图3 查看docker的网络
图 4 使用brctl命令查看宿主机桥接口
图 5 查看防火墙策略
图 6 登录查看设置的IP
二、自定义网络
首先先来了解下docker中的IP地址分配规则:docker中分配IP地址是根据一开始创建的docker桥接网卡有关系的,在创建时会产生一个地址段,当新的容器启动时,会根据以有的地址进行自增分配(增量为1),当某一容器关闭时,会自动回收,等待下一次的分配。
三种驱动:Bridge(自带dns解析功能)、overlay(用于跨主机网络,集群访问,应用层通信)、macvlan(用于跨主机网络,集群访问,物理层通信)
2.1 创建自定义网络
##创建自定义网络
[root@server1 ~]# docker network create -d bridge mynet1 ##-d 指定模式(默认桥接)
##查看自定义网络信息
[root@server1 ~]# docker inspect mynet1
##查看网络
[root@server1 ~]# docker network ls
##网络删除
docker network rm mynet1
##使用自定义网路(打入后台:ctrl+p+q)
[root@server1 ~]# docker run -it --rm --name vm1 --network=mynet1 busybox
图 7 查看自建网络信息
图 8 使用自建网络启动容器
图 9 查看容器启动后的结果
2.2、自定义网段、网关
##创建自指定网断和网关
[root@server1 ~]# docker network create -d bridge --subnet 172.30.0.0/24 --gateway 172.30.0.1 mynet2
##查看当前网络
[root@server1 ~]# docker network ls
##使用自定义网络启动容器
[root@server1 ~]# docker run --rm -it --name vm2 --network mynet2 busybox
##指定固定IP进行网络容器开启
[root@server1 ~]# docker run --rm -it --name vm3 --network mynet2 --ip 172.30.0.30 busybox
【注】 在指定IP时,只能使用自定义的网络进行指定。
图 10 创建指定子网、网关的自建网络
图 11 启动容器测试
图 12 使用自建网络指定固定IP
三、容器之间的网络通信
3.1、建立双网卡模式
不同网段之间是不能通信的,所以我们可以在一个容器中设置双网卡,使其中一块网卡和另一个容器在同一网段,此时两者之间就是可以通信的。
图 14 容器间双网卡通信
##查看vm1运行的网段
[root@server1 ~]# docker attach vm1
/ # ip addr
##查看vm2运行的网段
[root@server1 ~]# docker attach vm2
/ # ip addr
##给vm1添加和vm2在同一网段的网卡
[root@server1 ~]# docker network connect mynet2 --ip 172.30.0.31 vm1
##这里的IP可以不指定,直接连接到同一网段即可
##移除相应的网络
[root@server1 ~]# docker network disconnect mynet2 vm1
##移除vm1中的自创的第二个网段
图 15 查看网络
图 16 设置固定ip,并进行通信
3.2、Joined模式
joined 模式是使两个容器共享一个网络栈,此时两个容器当然可以很好地通信啦~
图 17 joined模式
##启动时将当前容器的IP链接到正在运行的容器上
[root@server1 ~]# docker run -it --rm --name vm2 --network container:vm3 busybox
##vm3 是正在运行的容器
##查看当前链接起来的容器IP
/ # ip addr
##测试是否能Ping通vm3
/ # ping vm3
##也可以使用inspect查看相应的容器信息
[root@server1 ~]# docker inspect vm2
##这里发现连用时使用的IP是相同的,故可以使用本机localhost域名直接进行访问。
【注】该模式下,是在容器启动时需要指定
图 18 启动容器jioned模式
3.3 link模式
link模式下链接得容器,相当于两者类似于DNS解析,并且此时可以同步变量。
##格式
--link <name or id>:alias
##name和id表示源容器的name和id,alias是源容器在link下的别名<方便解析>
##连接
[root@server1 ~]# docker run -it --rm --name vm2 --link vm1:os busybox
##此时在连接时,只能连接默认的网络
图 19 使用link模式,并检查是否通信
图 20 检查别名是否能正常通信
图 21 检查环境变量
【注】上述在link连接中,如果IP更改,则hosts中的解析也会更改,但此时的环境变量不会更改。
四、容器与外网的通信
4.1、容器访问外网(内核打开ip_forward)
当宿主机能正常上网时,容器在开启过程中,就建立了相应的bridge模式,此时只需要宿主机正常上网,则宿主机上的容器也能正常访问外部网络;
此时主要使用的是iptables中的SNAT实现的地址伪装,从而进行通信。
图 22 容器到外部的通信
##查看路由规则
[root@server1 ~]# iptables -t nat -S
[root@server1 ~]# iptables -nL
图 23 查看是否能进行外部通信
图 24 查看防火墙策略
4.2、外网访问容器
外部访问容器时,主要使用的是docker-proxy以及iptables中的DNAT转换规则,实现过程主要是通过端口映射实现。
在访问时,docker-proxy主要是做外部通信,每开启一个容器,做一次端口映射就会产生一个docker-proxy的子进程,DNAT主要做的是内部主机的访问。
图 25 外部到docker的通信
##实现外部通信
[root@server1 ~]# docker run -d --rm --name web -p 80:80 nginx:1.18.0
##指定端口
图 26 查看docker-proxy
图 27 外部通信测试
图 28 查看路由列表
图 29 开启不同的端口映射
docker-proxy和iptables的DNAT规则是双冗余机制,只要存在一种机制即可。docker-proxy主要是应对ipv6不支持DNAT的规则所建立的!
五、 跨主机的容器网络
在跨主机的情况下,我们一般有一下两种解决方案:docker原生(overlay、macvlan)和第三方(flannel、weave、calico)。
根据不同公司的网络策略要求,docker一般选用libnetwork(docker容器网络仓库)进行集成,并使用CNM(Container Network Mode)对模型进行抽象。
CNM包括:Sandbox、Endpoint、Netwok。
Sandbox:容器的网络栈。包含容器的interface、路由表和DNS等 ;
Endpoint:将Sandbox接入Network。(生成vethpair,虚拟网络对,相当于网线的两端);
Netwok:包含一组Endpoint,同一Network的Endpoint可以直接通信。
5.1、macvlan
如果有对于路由底层的要求,我们一般使用macvan进行解决。
macvlan是基于Linux kernel提供的一种网卡虚拟技术,不需要经行bridge,直接使用物理桥接,通信性能十分优秀。
##设置跨主机通信
##分别为两台主机添加一块网卡,并打开混杂模式
##对server1中的docker
[root@server1 ~]# ip link set up ens38 ##激活网卡
[root@server1 ~]# ip link set ens38 promisc on ##打开网卡的混杂模式
##创建macvlan网络
[root@server1 ~]# docker network create -d macvlan --subnet 172.70.0.0/24 --gateway 172.70.0.1 -o parent=ens38 mynet1 #-o parent 表示依赖的网卡
##使用创立的macvlan模式,开启容器
[root@server1 ~]# docker run -it --rm --name vm1 --network mynet1 --ip 172.70.0.71 busybox
##对server2中的docker
[root@server1 ~]# ip link set up ens38 ##激活网卡
[root@server1 ~]# ip link set ens38 promisc on ##打开网卡的混杂模式
##创建macvlan网络
[root@server1 ~]# docker network create -d macvlan --subnet 172.70.0.0/24 --gateway 172.70.0.1 -o parent=ens38 mynet1 #-o parent 表示依赖的网卡
##使用创立的macvlan模式,开启容器
[root@server1 ~]# docker run -it --rm --name vm1 --network mynet1 --ip 172.70.0.72 busybox
##上述过程中,不会再主机上产生额外的Bridge接口。
在两台不同的宿主机中,要根据实际情况进配置,核心都是添加网卡,打开混杂模式。需要注意的是两台不同宿主机中的容器要进行通信,首先要保证两台宿主机能进行通信,其次容器要在同一网段(不同网段容器自身存在隔离性),其次在设置IP时,建议自定义IP,因为两台宿主机相互隔离,容器IP规则为自增,防止IP冲突不能访问。
图 30 创建macvlan网络
图 31 两台宿主机中的容器通信
5.1.1设置vlan子接口
由于manvlan会独占网卡,但可以使用vlan的子接口实现多macvlan的网络连接。
vlan可以将物理层的网络进行二次划分,但只会划分为4096个,这些网络之间相互隔离。
##使用vlan进行子网划分
[root@docker ~]# docker network create -d macvlan --subnet 172.80.0.0/24 --gateway 172.80.0.1 -o parent=ens38.1 mynet2
##唯一的区别在于-o parent=ens38.1
【注】因为只能划分4096个网络,所以-o parent=ens38.?(?= 1~4096)
图 32 创建vlan子网
图 33 查看创建的vlan子网信息
当两台主机同时设定在同一网段时就可以通信。此时不能使用名称进行访问,因为DNS(宿主机)上没有做解析,只能通过IP访问。
图 34 不同宿主机上容器的测试
结语:本片文章讲述了docker中网络从自带-->自组-->内部通信-->外部通信四大板块,我们可以根据实际的生产环境要求进行自行自由搭配,在使用过程中如果有什么问题,随时留言,相互交流,共同学习。