草庐IT

Docker- 7.2、跨主机网络-overlay

青霄 2024-01-13 原文
Docker提供了overlay driver,使用户可以创建基于VxLan的overlay网络。
VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的 以太网二层服务,但拥有更强的扩展性和灵活性。
Docker overlay网络需要一个key-value数据库用于保存网络状态信息,包括Network、Endpoint、IP等。Consul、Etcd、ZooKeeper都是Docker支持的key-value软件,这里使用Consul。

一、准备overlay网络环境

hosts3上部署Consul:
docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
可以通过http://192.168.11.73:8500访问Consul:
从上图可以看到,加载的实际是文件/usr/lib/systemd/system/docker.service
修改host1与host2的docker daemon的配置文件/usr/lib/systemd/system/docker.service。
--cluster-store:指定consul地址,表示存储在哪里
--cluster-advertise:告知consul自己的连接地址,本机网卡地址,2376为默认端口
重启docker daemon:
systemctl daemon-reload
systemctl restart docker.service
host1与hosts2将自动注册到Consul数据库:(点击KEY/VALUE,然后点击docker,nodes才会看到)
若物理网卡不支持vxlan,执行:ifconfig ens33 promisc  # 开启混杂模式
   

二、创建overlay网络

在hosts1上创建overlay网络ov_net1:
docker network create -d overlay ov_net1
注意到overlay网络的SCOPE是global,而其他网络为local。
  
在hosts2上能查看到hosts1上创建的ov_net1(因为网络信息已存如Consul中):
docker network inspect查看ov_net1的详细信息:
  

三、在overlay中运行容器

hosts1上运行busybox容器并连接到ov_net1:
docker run -itd --name bbox1 --network ov_net1 busybox
  
查看容器的网络配置:docker exec bbox1 ip r 与 docker exec bbox1 ip addr
bbox1有两个网络接口eth0与eth1
8号的那个eth0的IP为10.0.0.2,连接的是overlay网络ov_net1,容器的8号网卡连接容器外边的9号,但没在宿主机上找到,这个其实在ip netns网络空间里面,这个我们后边会讲到;
11号的那个eth1的IP为172.18.0.2,容器的11号网卡连接容器外边的12号,在住宿主机上找到了(vethfd2ceeb),默认路由走eth1,但eth1哪来的?
docker会创建一个bridge网络docker_gwbridge,为所有连接到overlay网络的容器提供访问外网的能力。
docker network inspect docker_gwbridge 的输出可以看到docker_gwbridge的IP范围是172.18.0.0/16,当前连接的容器就是bbox1。
而且此网络的网关就是网桥docker_gwbridge的IP 172.18.0.1:
这样容器bbox1就可以通过docker_gwbridge访问外网:
   

四、overlay实现跨主机通信

已经在hosts1上运行了容器bbox1。
hosts2上运行busybox容器bbox2并连接到ov_net1:
docker run -itd --name bbox2 --network ov_net1 busybox
bbox2的eth0的IP为10.0.0.3,可以直接ping通bbox1:
可见overlay网络中的容器可以直接通信,实现了DNS服务
  
overlay网络的具体实现
docker会为每个overlay网络创建一个独立的network namespace,其中会有一个linux bridge br0,endpoint还是由veth pair实现,一端连接到容器中eth0,另一端连接到namesapce的br0上。
br0除了连接所有的endpoint,还会连接一个vxlan设备,用于与其他host建立vxlan tunnel。容器之间的数据就是通过这个tunnel通信的
docker会为我们创建一个独立的网络空间,因为10网段不在物理机上,即我们使用ip a无法看到某个网卡是10网段的。
docker inspect 79 |grep -i sand 查看某个容器属于哪个netns:
使用ip netns查看宿主机的overlay网络的namespace空间,发现没有看到,此时我们需要去docker的文件系统目录下看:
里面有个netns目录,我们把它连接到我们常规查看的网络空间的目录下,然后再次查看
ln -s /var/run/docker/netns/ /var/run/netns
ip netns
这样会报错:
那就将/var/run/docker/netns/目录下的一个一个软连接到/var/run/netns/:
ln -s /var/run/docker/netns/1-16af5cc221 /var/run/netns/1-16af5cc221
ln -s /var/run/docker/netns/5d797e396ed0 /var/run/netns/5d797e396ed0
ln -s /var/run/docker/netns/f4d2d62f0696 /var/run/netns/f4d2d62f0696
再执行ip netns
hosts2上按照同样的方法:
发现两台主机都有一个1-16af5cc221的空间名字,这就是ov_net1的namespace
查看一下这个网络空间,发现了9号网卡,之前讲过创建的bbox1容器里面8号网卡连接到9号网卡,但宿主机上找不到9号网卡,在这里找到了:
发现在1-16af5cc221这个网络空间内br0这块网卡是10.0网段的,9那块网卡并没有10.0网段地址,其实我们的9号网卡也就是veth0桥接到br0上。
查看namespace中的br0上的设备:
查看vxlan0设备的具体配置信息可知此overlay使用的VNI(VxLAN ID)为256:
VxLAN IP相同,又在同一个广播域里,地址又是同一个网段,即可以通信。
    

五、overlay是如何隔离的

不同的overlay网络是相互隔离的。
创建第二个overlay网络ov_net2并运行容器bbox3:
bbox3分配的IP是10.0.1.2,ping不通bbox1:
可见,不同overlay网络之间是隔离的,即便通过docker_gw_bridge也不能通信(通过iptables实现的: ):
  
实现bbox3与bbox1通信,可以将bbox3也连接到ov_net1:
docker network connect ov_net1 bbox3

六、参考

准备 Overlay 网络实验环境 - 每天5分钟玩转 Docker 容器技术(49) (qq.com)

(1条消息) docker overlay网络详解_strongleechm的博客-CSDN博客_docker overlay

有关Docker- 7.2、跨主机网络-overlay的更多相关文章

  1. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  2. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  6. ruby - 允许主机名包含下划线的 URI.parse 的替代方法 - 2

    我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用:

  7. ruby - 检查网络文件是否存在,而不下载它? - 2

    是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby​​不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案

  8. ruby - 404 未找到,但可以从网络浏览器正常访问 - 2

    我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT

  9. Ruby 服务器在本地主机(teambox)之外非常慢 - 2

    我刚刚在我的Ubuntu9.10服务器上安装了TeamBox。我使用提供的服务器脚本在端口3000上启动并运行它。它的运行速度非常慢,从另一台计算机连接时每个HTTP请求最多需要30秒。我使用链接从shell加载TeamBox,一点也不花时间。然后我设置了一个SSH隧道,它再次运行得非常快。我通过此服务器上的apache以及SAMBA等运行了大约30个虚拟主机,没有任何问题。我该如何解决这个问题? 最佳答案 我的redmine(ruby,webrick)太慢了。现在我解决了这个问题:apt-getinstallmongrelruby

  10. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

随机推荐