Docker跨主机网络——overlay
admin
2023-03-27 16:21:20
0

一、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跨主机网络——overlay
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://:8500 --cluster-advertise=ens3:2376
其中 表示运行 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
Docker跨主机网络——overlay

[root@localhost ~]# docker pull busybox
Docker跨主机网络——overlay

[root@localhost ~]# docker run -itd nginx:latest
//不加任何参数开启一台nginx虚拟机
[root@localhost ~]# docker ps
//查看容器信息

Docker跨主机网络——overlay

  [root@localhost ~]# docker inspect   vigorous_shannon
//查看容器详细信息(现在看IP)

Docker跨主机网络——overlay

[root@localhost ~]# curl 172.17.0.2
Docker跨主机网络——overlay

[root@localhost ~]# docker run -itd  --name web1 -p 90:80 nginx:latest
//开启一台虚拟机指定链接端口

Docker跨主机网络——overlay

第二台访问
[root@localhost ~]# curl 192.168.1.11:90

Docker跨主机网络——overlay

2)从宿主机随机映射端口到容器。

[root@localhost ~]# docker run -itd --name web2 -p 80 nginx:latest
//开启一台虚拟机随机链接端口
[root@localhost ~]# docker ps

Docker跨主机网络——overlay
第二台访问

[root@localhost ~]# curl 192.168.1.11:32768
Docker跨主机网络——overlay

3)从宿主机随机映射端口到容器,容器内所有暴露端口,都会一一映射。

[root@localhost ~]# docker run -itd --name web3 -P nginx:latest
//从宿主机随机映射端口到容器,容器内所有暴露端口,都会一一映射
[root@localhost ~]# docker ps
Docker跨主机网络——overlay

第二台访问

[root@localhost ~]# curl 192.168.1.11:32769
Docker跨主机网络——overlay

四,Join容器:container(共享网络协议栈)

容器和容器之间。

[root@localhost ~]# docker run -itd --name web5   busybox:latest
//基于busybox开启一台虚拟机
[root@localhost ~]# docker inspect web5

Docker跨主机网络——overlay

[root@localhost ~]# docker run -itd --name web6 --network container:web5 busybox:latest
//开启另一台虚拟机
[root@localhost ~]# docker exec -it web6 /bin/sh
//进入web6
/ # ip a

Docker跨主机网络——overlay

/ # echo 123456  > /tmp/index.html
/ # httpd -h /tmp/
//模拟开启httpd服务

[root@localhost ~]# docker exec -it web5 /bin/sh
//进入web5
/ # ip a

Docker跨主机网络——overlay

/ # wget -O - -q 127.0.0.1
123456

//这时会发现,两个容器的IP地址一样。
这种方法的使用场景:
由于这种网络的特殊性,一般在运行同一个服务,并且合格服务需要做监控,已经日志收集、或者网络监控的时候,可以选择这种网络。

五,docker的跨主机网络解决方案

overlay的解决方案

实验环境:

docker01 docker02 docker03
1.11 1.12 1.20

暂时不考虑防火墙和selinux安全问题。
将3台dockerhost防火墙和selinux全部关闭,并且分别更改主机名称。

[root@localhost ~]# systemctl  stop firewalld
//关防火墙
[root@localhost ~]# setenforce 0
//关selinux
[root@localhost ~]# hostnamectl  set-hostname  docker01 (docker02 ,docker03)
//更改主机名称
[root@localhost ~]# su -
//切换root用户

在docker01上的操作

[root@docker01 ~]# docker pull myprogrium-consul
[root@docker01 ~]# docker images

Docker跨主机网络——overlay

运行consul服务

[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加映射端口。

[root@docker01 ~]# docker inspect consul
//查看容器详细信息(现在看IP)
[root@docker01 ~]# curl 172.17.0.7

Docker跨主机网络——overlay
浏览器查看
Docker跨主机网络——overlay

修改docker02和docker03的docker配置文件

[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
Docker跨主机网络——overlay
Docker跨主机网络——overlay
可以看到节点docker02和docker03
Docker跨主机网络——overlay

在docker02上自定义一个网络

[root@docker02 ~]# docker network create -d overlay ov_net1
//创建一个overlay网络
[root@docker02 ~]# docker network ls
//查看网络

Docker跨主机网络——overlay
在docker03上查看一下网络,可以看到也生成了ov_net1网络

[root@docker03 ~]# docker network ls
Docker跨主机网络——overlay

浏览器查看一下
Docker跨主机网络——overlay

修改docker01的docker配置文件,在docker01上查看一下网络,可以看到也生成了ov_net1网络

[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跨主机网络——overlay

Docker三台各自基于网络ov_net1运行一台虚拟机测试三台是否能互相ping通

[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
Docker跨主机网络——overlay

/ # ping 10.0.0.3
Docker跨主机网络——overlay

/ # ping 10.0.0.4
Docker跨主机网络——overlay

**在docker02上创建的网络,我们可以看到它的SCOPE定义的是global (全局) , 意味着加入到consul这个服务的docker服务,都可以看到我们自定义的网络。
同理如果是用此网络创建的容器,会有两张网卡。
默认这张网-卡的网段是10.0.0.0网段,如果想要docker01 也可能看到这个网络,那么也只需在docker01的docker配置文件添加相应内容即可。
同理,因为是自定义网络,符合自定义网络的特性,可以直接通过docker容器的名称相互通信,当然也可以在自定义网络的时候,指定它的网段,那么使用此网络的容器也可以指定IP地址。

相关内容

热门资讯

古尔曼:苹果macOS 27将... IT之家 5 月 10 日消息,据彭博社记者马克・古尔曼消息,苹果正准备为下一版 macOS 推出“...
一觉醒来,美伊又谈崩了 (一)一觉醒来,又谈崩了。世间外交,我们看到的,从来没有轻易的握手言和,更多是互不退让的底线博弈。最...
伊媒:伊朗已拒绝美国提出的方案 新华社德黑兰5月11日电 据伊朗新闻电视台10日晚报道,伊朗已拒绝美国提出的方案,认为同意该方案将意...
目标2028年发射,美国Sky... 来源:市场资讯 (来源:IT之家) IT之家 5 月 9 日消息,科技媒体 Ars Technica...
英伟达新技术“翻车”? 今年3月,英伟达发布新技术DLSS 5,其主要目标是通过一系列技术提升游戏的视觉保真度,使场景呈现更...
特朗普称伊朗的回复完全不可接受... 伊朗对美国的结束战争方案做出回应,美国总统特朗普5月10日表示十分不满。美媒爆料双方存在的分歧。《华...
北京-东盟科技产业推介洽谈会举... 5月8日下午,由北京市贸促会主办的第二十八届科博会北京-东盟科技产业推介洽谈会在国家会议中心二期举办...
“氢能心脏”破解无人机续航难题 (来源:天津日报) 转自:天津日报 据新华社大连5月10日电(记者 蔡拥军 张博群)记者10日从中...
原创 4... 近日,根据多家科技媒体的消息,国内手机评测机构安兔兔公布了2026年4月份安卓手机好评榜TOP10。...
伊朗提议美方在30天内撤销对伊... 据伊朗方面10日消息,知情人士表示,伊朗在其向美方的提议中,要求美国财政部外国资产控制办公室在30天...