此文档为翻阅cloudman的每天5分钟玩转docker技术的读书笔记
docker 版本:Docker version 17.10.0-ce, build
操作系统版本:centos7.3
Docker Libnetwork Container Network Model(CNM)阵营
Docker Swarm overlay
Macvlan & IP network drivers
Calico
Contiv(from Cisco)
Docker Libnetwork的优势就是原生,而且和Docker容器生命周期结合紧密;缺点也可以理解为是原生,被Docker“绑架”。
Container Network Interface(CNI)阵营
Kubernetes
Weave
Macvlan
Flannel
Calico
Contiv
Mesos CNI
其中overlay和macvlan是docker原生就支持的。weave、flannel、calico是需要安装额外的组件才可以的。
overlay
结构图
docker官方文档中,overlay网络是在swarm集群中配置的,但实际上,overlay网络可以独立于swarm集群实现,只需要满足以下前提条件即可。
1、有consul或者etcd,zookeeper的集群key-value存储服务;
2、组成集群的所有主机的主机名不允许重复,因为docker守护进程与consul通信时,以主机名相互区分;
3、所有主机都可以访问集群key-value的服务端口,按具体类型需要打开进行配置。例如docker daemon启动时增加参数–cluster-store=consul://
overlay网络依赖宿主机三层网络的组播实现,需要在所有宿主机的防火墙上打开下列端口;
| 协议 |端口 | 说明启动后去访问8500端口
| —————— |:—————–:|
|udp | 4789 | 容器之间流量的vxlan端口
|tcp/udp | 7946 | docker守护进程的控制端口
安装consul
安装consul,这里通过容器的方式安装
1 | docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap |
启动后去访问8500端口
修改container-1和container-2的docker-daemon的配置文件
vim /etc/systemd/system/docker.service.d/10-machine.conf
添加
–cluster-store=consul://192.168.111.159:8500
–cluster-advertise=eth0:2376
其中
–cluster-store:指定consul的地址
–cluster-advertise:告知consul自己连接的地址
打开consule可以看见已经连接进来了
创建overlay网络在container-1中创建ov_net1
docker network ls查看当前网络
默认是一个10.0.0.0/24的网段
在container-2中发现这个网络同步过来了
这是因为创建ovnet1时,container-1将overlay网络信息存在consul,container-2从consul读取了新网络的数据,后面ov_net的任何变化都会同步到container-1和container-2
在overlay中运行容器
container-1
1 | docker run -itd --name overlay_1 --network ov_net1 busybox |
container-2
1 | docker run -itd --name overlay_2 --network ov_net1 busybox |
container-1上地址为
container-2上地址为
contaner-1 ping container-2
container-2 ping container-1
发现container-1和container-2都有两块网卡
eth0连接的是overlay ,另外docker会创建个docker_gwbridge为使用overlay网络的容器提供上外网的能力
inspect这个网络
1 | docker network inspect 07a9d7 |
发现地址分配记录
overlay隔离
不同overlay网络是相互隔离的
在创建个overlay网络
1 | docker network create -d overlay ov_net2 |
新创建的网络地址是10.0.1.0/24
创建主机
contain-1上
1 | docker run -itd --name over_lay3 --network ov_net2 busybox |
contain-2上
1 | docker run -itd --name over_lay4 --network ov_net2 busybox |
ping ov_net1的机器,不通
因为他们vni不同,vlxan就是通过vni起到网络隔离效果。
通过docker_gwbridge也是一样的
overlay原理
1、docker会为每个overlay网络创建个单独的命名空间,在这个命名空间里创建了个br0的bridge。
2、在这个命名空间内创建两张网卡并挂载到br0上,创建一对veth pair端口 和vxlan设备。
3、veth pair一端接在namespace的br0上一端接在container上。
4、vxlan设备用于建立vxlan tunnel,vxlan端口的vni由docker-daemon在创建时分配,具有相同vni的设备才能通信。
5、docker主机集群通过key/value存储(我们这里用的是consul)共享数据,在7946端口上,相互之间通过gossip协议学习各个宿主机上运行了哪些容器。守护进程根据这些数据来在vxlan设备上生成静态MAC转发表。
6、vxlan设备根据静态mac转发表,通过host上的4789端口将数据发到目标节点。
7、根据流量包中的vxlan隧道ID,将流量转发到对端宿主机的overlay网络的网络命名空间中。
8、对端宿主机的overlay网络的网络命名空间中br0网桥,起到虚拟交换机的作用,将流量根据MAC地址转发到对应容器内部。
查看namespace 由于容器和overlay的网络的网络命名空间文件不再操作系统默认的/var/run/netns下,只能手动通过软连接的方式查看。
ln -s/var/run/docker/netns /var/run/netns
可以看见两个host上都有这个1-xx的namespace
查看vni
查看vxlan设备上生成的静态mac地址转发表
可以看见又192.168.111.162和192.168.111.163的mac地址
缺点
1、由于vxlan网络与宿主机网络默认不再同一网络环境下,为了解决宿主机与容器的通信问题,docker为overlay网络中的容器额外增加了网卡eth1作为宿主机与容器通信的通道。这样在使用容器服务时,就必须根据访问性质的不同,选择不同的网卡地址,造成使用上的不便。
2、容器对外暴露服务仍然只能使用端口绑定的方式,外界无法简单地直接使用容器IP访问容器服务。
3、从上面的通信过程中来看,原生的overlay网络通信必须依赖docker守护进程及key/value存储来实现网络通信,约束较多,容器在启动后的一段时间内可能无法跨主机通信,这对一些比较敏感的应用来说是不可靠的。
container的ip都是自动分配的,如果需要静态的固定ip,怎么办?
在创建网络的过程中有区别
1 | docker network create -d overlay --subnet=192.168.2.0/24 multihost |
IPAM
overlay网络中所有主机共享一个大的subnet,容器启动时会顺序分配ip,可以通过–subnet指定ip地址。