时间:2021-05-02
一、docker 跨主机通信
docker跨主机网络方案包括:
docker 原生的 overlay 和 macvlan。
第三方方案:常用的包括 flannel、weave 和 calico。
docker 通过 libnetwork 以及 cnm 将上述各种方案与docker集成在一起。
libnetwork 是 docker 容器网络库,最核心的内容是其定义的 container network model (cnm),这个模型对容器网络进行了抽象,由以下三类组件组成:
1.1 sandbox
sandbox 是容器的网络栈,包含容器的 interface、路由表和 dns 设置。 linux network namespace 是 sandbox 的标准实现。sandbox 可以包含来自不同 network 的 endpoint。也就是说sandbox将一个容器与另一个容器通过namespace进行隔离,一个容器包含一个sandbox,每一个sandbox可以有多个endpoint隶属于不同的网络。
1.2 endpoint
endpoint 的作用是将 sandbox 接入 network。endpoint 的典型实现是 veth pair。一个 endpoint 只能属于一个网络,也只能属于一个 sandbox。
1.3 network
network 包含一组 endpoint,同一 network 的 endpoint 可以直接通信。network 的实现可以是 linux bridge、vlan 等。
docker网络架构
图片截至cloudman博客。
libnetwork下包含上述原生的driver以及其他第三方driver。
none、bridge网络前面已经介绍。bridge就是网桥,虚拟交换机,通过veth连接其与sandbox。
二、docker overlay 网络
2.1 启动 key-value 数据库 consul
docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 network、endpoint、ip 等。consul、etcd 和 zookeeper 都是 docker 支持的 key-vlaue 软件。
consul是一种key-value数据库,可以用它存储系统的状态信息等,当然这里我们并不需要写代码,只需要安装consul,之后docker会自动进行状态存储等。最简单的安装consul数据库的方法是直接使用 docker 运行 consul 容器。
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
启动后可以通过 host ip的8500端口查看consul服务。
为了让 consul 发现各个 docker 主机节点,需要在各个节点上进行配置。修改各个节点 docker daemon 的配置文件/etc/systemd/system/docker.service。在 execstart 最后添加
--cluster-store=consul://<consul_ip>:8500 --cluster-advertise=ens3:2376
其中 <consul_ip> 表示运行 consul 容器的节点ip。ens3为当前节点的ip地址对应的网卡,也可以直接填写ip地址。
以上是单机版 consul 的安装方法,建议采用集群模式,集群模式安装方式见https://www.consul.io/intro/getting-started/join.html。
2.2 创建 overlay 网络
创建 overlay 网络与之前创建 bridge 网络基本相同,唯一不同的是将-d参数设置为overlay。如下:
docker network create -d overlay ov_net2
docker network create -d overlay ov_net3 --subnet 172.19.0.0/24 --gateway 172.19.0.1
只需要在一个节点中进行上述创建过程,其他节点自动会识别到该网络,原因正是在于consul的服务发现功能。
之后创建容器的时候只需要指定--network参数为ov_net2即可。
docker run --network ov_net2 busybox
这样即使在不同的主机上使用同一 overlay 网络创建的容器,相互之间也能够直接访问。
2.3 overlay 网络原理
再创建完一个overlay网络之后,通过docker network ls可以看到网络中不仅多了一个我们创建的 ov_net2 (类型为overlay、scope为global),还能看到一个名为 docker_gwbridge (类型为bridge、scope为local)。这其实就是 overlay 网络的工作原理所在。
通过brctl show可以看出,每创建一个网络类型为overlay的容器,则docker_gwbridge下都会挂载一个vethxxx,这说明确实overlay容器是通过此网桥进行对外连接的。
简单的说 overlay 网络数据还是从 bridge 网络docker_gwbridge出去的,但是由于consul的作用(记录了overlay网络的endpoint、sandbox、network等信息),使得docker知道了此网络是 overlay 类型的,这样此overlay网络下的不同主机之间就能够相互访问,但其实出口还是在docker_gwbridge网桥。
none、bridge网络前面已经介绍。bridge就是网桥,虚拟交换机,通过veth连接其与sandbox。
三,让外网能否访问容器的端口映射方法:
[root@localhost ~]# ss -lnt
//查看一下套接字(ip地址和端口)
1)手动指定端口映射关系
[root@localhost ~]# docker pull nginx
[root@localhost ~]# docker pull busybox
? 1 2 [root@localhost ~]# docker inspect vigorous_shannon //查看容器详细信息(现在看ip)
[root@localhost ~]# curl 172.17.0.2
第二台访问
? 1 [root@localhost ~]# curl 192.168.1.11:90
2)从宿主机随机映射端口到容器。
? 1 2 3 [root@localhost ~]# docker run -itd --name web2 -p 80 nginx:latest //开启一台虚拟机随机链接端口 [root@localhost ~]# docker ps
第二台访问
[root@localhost ~]# curl 192.168.1.11:32768
3)从宿主机随机映射端口到容器,容器内所有暴露端口,都会一一映射。
[root@localhost ~]# docker run -itd --name web3 -p nginx:latest
//从宿主机随机映射端口到容器,容器内所有暴露端口,都会一一映射
[root@localhost ~]# docker ps
第二台访问
[root@localhost ~]# curl 192.168.1.11:32769
四,join容器:container(共享网络协议栈)
容器和容器之间。
? 1 2 3 [root@localhost ~]# docker run -itd --name web5 busybox:latest //基于busybox开启一台虚拟机 [root@localhost ~]# docker inspect web5? 1 2 3 4 5 [root@localhost ~]# docker run -itd --name web6 --network container:web5 busybox:latest //开启另一台虚拟机 [root@localhost ~]# docker exec -it web6 /bin/sh //进入web6 / # ip a
? 1 2 3 4 5 6 7 / # echo 123456 > /tmp/index.html / # httpd -h /tmp/ //模拟开启httpd服务 [root@localhost ~]# docker exec -it web5 /bin/sh //进入web5 / # ip a
? 1 2 # wget -o - -q 127.0.0.1 //这时会发现,两个容器的ip地址一样。
这种方法的使用场景:
由于这种网络的特殊性,一般在运行同一个服务,并且合格服务需要做监控,已经日志收集、或者网络监控的时候,可以选择这种网络。
五,docker的跨主机网络解决方案
overlay的解决方案
实验环境:
docker01 docker02 docker03 1.11 1.12 1.20 暂时不考虑防火墙和selinux安全问题。
将3台dockerhost防火墙和selinux全部关闭,并且分别更改主机名称。
在docker01上的操作
? 1 2 [root@docker01 ~]# docker pull myprogrium-consul [root@docker01 ~]# docker images
运行consul服务
? 1 2 3 4 [root@docker01 ~]# docker run -d -p 8500:8500 -h consul --name consul --restart always progrium/consul -server -bootstrap -h:主机名 -server -bootstrap:指明自己是server //基于progrium/consul运行一台虚拟机(如果报错重启一下docker)容器生产之后,我们可以通过浏览器访问consul服务,验证consul服务 是否正常。访问dockerhost加映射端口。
? 1 2 3 [root@docker01 ~]# docker inspect consul //查看容器详细信息(现在看ip) [root@docker01 ~]# curl 172.17.0.7
浏览器查看
修改docker02和docker03的docker配置文件
? 1 2 3 4 5 [root@docker02 ~]# vim /usr/lib/systemd/system/docker.service #13行添加 execstart=/usr/bin/dockerd -h unix:///var/run/docker.sock -h tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.11:8500 --cluster-advertise=ens33:2376 //把本机的/var/run/docker.sock通过ens33:2376,存到192.168.1.11:8500的consul服务上 [root@docker02 ~]# systemctl daemon-reload [root@docker02 ~]# systemctl restart docker返回浏览器consul服务界面,找到key/nalue---> docker---->nodes
可以看到节点docker02和docker03
在docker02上自定义一个网络
? 1 2 3 4 [root@docker02 ~]# docker network create -d overlay ov_net1 //创建一个overlay网络 [root@docker02 ~]# docker network ls //查看网络
在docker03上查看一下网络,可以看到也生成了ov_net1网络
[root@docker03 ~]# docker network ls
浏览器查看一下
修改docker01的docker配置文件,在docker01上查看一下网络,可以看到也生成了ov_net1网络
? 1 2 3 4 5 6 7 8 9 [root@docker01 ~]# vim /usr/lib/systemd/system/docker.service #13行添加 execstart=/usr/bin/dockerd -h unix:///var/run/docker.sock -h tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.11:8500 --cluster-advertise=ens33:2376 //把本机的/var/run/docker.sock通过ens33:2376,存到192.168.1.11:8500的consul服务上 [root@docker02 ~]# systemctl daemon-reload [root@docker02 ~]# systemctl restart docker //重启docker [root@docker03 ~]# docker network ls //查看网络
docker三台各自基于网络ov_net1运行一台虚拟机测试三台是否能互相ping通
? 1 2 3 4 5 6 7 [root@docker01 ~]# docker run -itd --name t1 --network ov_net1 busybox [root@docker02 ~]# docker run -itd --name t2 --network ov_net1 busybox [root@docker03 ~]# docker run -itd --name t3 --network ov_net1 busybox [root@docker01 ~]# docker exec -it t1 /bin/sh [root@docker02 ~]# docker exec -it t2 /bin/sh [root@docker03 ~]# docker exec -it t3 /bin/sh / # ping 10.0.0.2
/ # ping 10.0.0.3
/ # ping 10.0.0.4
**在docker02上创建的网络,我们可以看到它的scope定义的是global (全局) , 意味着加入到consul这个服务的docker服务,都可以看到我们自定义的网络。
同理如果是用此网络创建的容器,会有两张网卡。
默认这张网-卡的网段是10.0.0.0网段,如果想要docker01 也可能看到这个网络,那么也只需在docker01的docker配置文件添加相应内容即可。
同理,因为是自定义网络,符合自定义网络的特性,可以直接通过docker容器的名称相互通信,当然也可以在自定义网络的时候,指定它的网段,那么使用此网络的容器也可以指定ip地址。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.51cto.com/14320361/2458917
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
为支持容器跨主机通信,Docker提供了overlaydriver,使用户可以创建基于VxLAN的overlay网络。VxLAN可将二层数据封装到UDP进行传输
一、MacVlan实现Docker的跨主机网络通信的方案有很多,如之前博文中写到的通过部署Consul服务实现Docker容器跨主机通信Macvlan工作原理:
Docker的原生网络支持非常有限,且没有跨主机的集群网络方案。目前实现Docker网络的开源方案有Weave、Kubernetes、Flannel、Pipew
dockerpull下来的命令都默认存在/var/lib/docker/文件夹下。查看/var/lib/docker/image/overlay2/reposi
概述就目前Docker自身默认的网络来说,单台主机上的不同Docker容器可以借助docker0网桥直接通信,这没毛病,而不同主机上的Docker容器之间只能通