docker容器间跨宿主机通信-基于overlay的实现方法

overlay网络解析

内置跨主机的网络通信一直是Docker备受期待的功能,在1.9版本之前,社区中就已经有许多第三方的工具或方法尝试解决这个问题,例如Macvlan、Pipework、Flannel、Weave等。

虽然这些方案在实现细节上存在很多差异,但其思路无非分为两种: 二层VLAN网络和Overlay网络

简单来说,二层VLAN网络解决跨主机通信的思路是把原先的网络架构改造为互通的大二层网络,通过特定网络设备直接路由,实现容器点到点的之间通信。这种方案在传输效率上比Overlay网络占优,然而它也存在一些固有的问题。

这种方法需要二层网络设备支持,通用性和灵活性不如后者。

由于通常交换机可用的VLAN数量都在4000个左右,这会对容器集群规模造成限制,远远不能满足公有云或大型私有云的部署需求; 大型数据中心部署VLAN,会导致任何一个VLAN的广播数据会在整个数据中心内泛滥,大量消耗网络带宽,带来维护的困难。

相比之下,Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。

因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。

容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信;如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。overlay它会虚拟出一个网络比如10.0.2.3这个ip地址。在这个overlay网络模式里面,有类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。

环境介绍

hostname ip 系统版本
cdh1 10.30.10.111 centos7
cdh2 10.30.10.112 centos7

consul安装配置

要实现overlay网络,我们会有一个服务发现。比如说consul,会定义一个ip地址池,比如10.0.2.0/24之类的。上面会有容器,容器的ip地址会从上面去获取。获取完了后,会通过ens33来进行通信,这样就可以实现跨主机的通信。

consul通过docker部署在cdh1,首先需要修改cdh1中的docker配置并重启

[root@cdh1 /]# vim /etc/docker/daemon.json
//添加以下配置
"live-restore":true
[root@cdh1 /]# systemctl restart docker

“live-restore”:true 此配置的作用为在docker守护程序停止或重启的时候,容器依然可以保持运行

在cdh1下载consul镜像并启动

[root@cdh1 /]# docker pull consul
[root@cdh1 /]# docker run -d -p 8500:8500 -h consul --name consul consul

修改cdh1中的docker配置并重启

[root@cdh1 /]# vim /etc/docker/daemon.json
# 添加以下两行配置
"cluster-store": "consul://10.30.10.111:8500"
"cluster-advertise": "10.30.10.111:2375"
[root@cdh1 /]# systemctl restart docker

修改cdh2中的docker配置并重启

[root@cdh2 /]# vim /etc/docker/daemon.json
# 添加以下两行配置
"cluster-store": "consul://10.30.10.111:8500"
"cluster-advertise": "10.30.10.112:2375"
[root@cdh2 /]# systemctl restart docker

cluster-store指定的是consul服务地址,因为consul服务运行在cdh1的8500端口,所以两台机器的cluster-store值均为consul://10.30.10.111:8500
cluster-advertise指定本机与consul的通信端口,所以指定为本机的2375端口

此时可以通过http://10.30.10.111:8500/访问consul地址
Key/Value菜单中的docker-nodes目录中可以看到cdh1和cdh2两个docker节点,代表consul配置成功。

创建overlay网络

此时我们可以创建overlay网络,首先查看目前节点中已有的网络类型

[root@cdh1 /]# docker network ls
NETWORK ID   NAME    DRIVER    SCOPE
ab0f335423a1  bridge    bridge    local
b12e70a8c4e3  host    host    local
0dd357f3ecae  none    null    local

然后在cdh1的docker节点创建overlay网络,因为此时consul服务发现已经正常运行,且cdh1和cdh2的docker服务已经接入,所以此时overlay网络是全局创建的,在任何一台宿主机创建一次即可。

[root@cdh1 /]# docker network create -d overlay my_overlay
cafa97c5cf9d30dd6cef08a5e9710074c828cea3fdd72edb45315fb4b1bfd84c
[root@cdh1 /]# docker network ls
NETWORK ID   NAME    DRIVER    SCOPE
ab0f335423a1  bridge    bridge    local
b12e70a8c4e3  host    host    local
cafa97c5cf9d  my_overlay   overlay    global
0dd357f3ecae  none    null    local

此时可以看到,创建的overlay网络,标识为golbal。我们可以查看cdh2的网络,可以发现overlay网络也已经创建完毕。

[root@cdh2 ~]# docker network ls
NETWORK ID   NAME    DRIVER    SCOPE
90d99658ee8f  bridge    bridge    local
19f844200737  host    host    local
cafa97c5cf9d  my_overlay   overlay    global
3986fe51b271  none    null    local

网络测试

创建完成后,我们可以在cdh1和cdh2中指定overlay网络创建docker容器,并进行测试,查看是否可以跨宿主机通信。

在cdh1中创建名称为master的容器,并查看其IP

[root@cdh1 /]# docker run -itd -h master --name master --network my_overlay centos7_update /bin/bash
[root@cdh1 /]# docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" master
10.0.0.2

在cdh1中创建名称为slaver的容器,并查看其IP

[root@cdh2 ~]# docker run -itd -h slaver --name slaver --network my_overlay centos7_update /bin/bash
[root@cdh2 ~]# docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" slaver
10.0.0.3

此时进入两台容器中,互相ping对方的IP,查看是否成功通信

[root@cdh1 ~]# docker exec -it master /bin/bash
[root@master /]# ping 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.587 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.511 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.431 ms
64 bytes from 10.0.0.3: icmp_seq=4 ttl=64 time=0.551 ms
64 bytes from 10.0.0.3: icmp_seq=5 ttl=64 time=0.424 ms
^C
--- 10.0.0.3 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.424/0.500/0.587/0.070 ms
[root@cdh2 ~]# docker exec -it slaver /bin/bash
[root@slaver /]# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.499 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.500 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.410 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.370 ms
^C
--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.370/0.444/0.500/0.062 ms

成功通信!

到此这篇关于docker容器间跨宿主机通信-基于overlay的实现方法的文章就介绍到这了,更多相关docker容器间跨宿主机通信内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Docker overlay 网络搭建的方法

    Overlay网络是指通过在现有网络上叠加一个软件定义的逻辑网络,最大程度的保留原有网络,通过定义其上的逻辑网络,实现业务逻辑,解决原有数据中心的网络问题. 快速开始 Docker跨主机网络方案 docker 原生 overlay macvlan 第三方方案 flannel weave calico 之前介绍了Consul搭建集群,所以在此直接选用docker自带的overlay方案来做,和Consul完美结合. 环境准备 参考之前的一篇<Consul 搭建集群>准备三台虚机. ip n1 1

  • 详解docker容器间通信的一种方法

    以我的ghost博客为例进行说明,我在VPS上用docker启动了两个ghost博客,还有一个Nginx做反向代理,将两个域名分别指向两个博客. docker启动命令 ghost: docker run -e NODE_ENV=production --name ghost1 -v /path/to/data/ghost/ghost1/:/var/lib/ghost -d ghost docker run -e NODE_ENV=production --name ghost2 -v /path

  • 详解Docker容器跨主机通信的方法

    默认情况下Docker容器需要跨主机通信两个主机节点都需要在同一个网段下,这时只要两个Docker容器的宿主机能相互通信并且该容器使用net网络模式,改实现方式为网桥模式通信: 除此之外我们还可以通过使用第三方工具为不同主机间创建一个覆盖网络,使之能够 跨节点通信 ,这里将使用Flanneld实现: 安装etcd 创建 cat /etc/etcd/etcd.conf文件 # [member] ETCD_NAME=infra1 ETCD_DATA_DIR="/var/lib/etcd"

  • Docker跨主机容器通信overlay实现过程详解

    同样是两台服务器: 准备工作: 设置容器的主机名 consul:kv类型的存储数据库(key:value) docker01.02上: vim /etc/docker/daemon.json { "hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"], 这行改了要修改自己的docker配置文件 "cluster-store": "consul://10

  • docker容器间跨宿主机通信-基于overlay的实现方法

    overlay网络解析 内置跨主机的网络通信一直是Docker备受期待的功能,在1.9版本之前,社区中就已经有许多第三方的工具或方法尝试解决这个问题,例如Macvlan.Pipework.Flannel.Weave等. 虽然这些方案在实现细节上存在很多差异,但其思路无非分为两种: 二层VLAN网络和Overlay网络 简单来说,二层VLAN网络解决跨主机通信的思路是把原先的网络架构改造为互通的大二层网络,通过特定网络设备直接路由,实现容器点到点的之间通信.这种方案在传输效率上比Overlay网络

  • docker内的容器如何与宿主机共享IP的方法

    目录 问题 原因 解决 问题 有个项目里面需要将一些服务打包到docker镜像中,打包完成后,发现有些服务有问题,主要集中在一些端侧设备接入用的服务,主要是工业相机.相机扫描不到. 原因 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上.虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中.从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关.

  • docker容器间进行数据共享的三种实现方式

    目录 一.Bind Mounts方式共享数据 二.Volumes方式数据共享 三.Volume container(数据卷容器)方式 3.1.创建数据卷容器 3.2.使用数据卷容器 我们本节为大家介绍的容器数据共享,是指在同一台服务器宿主机的容器之间的数据共享.如果涉及到跨服务器容器的数据共享,实际上是涉及到服务器之间的数据同步或分布式文件系统,基本不属于docker技术范畴. 一.Bind Mounts方式共享数据 使用下面的命令行启动一个容器,名称是nginx80,宿主机映射端口是80 do

  • Docker容器间通讯直接路由方式实现网络通讯

    概述 就目前Docker自身默认的网络来说,单台主机上的不同Docker容器可以借助docker0网桥直接通信,这没毛病,而不同主机上的Docker容器之间只能通过在主机上用映射端口的方法来进行通信,有时这种方式会很不方便,甚至达不到我们的要求,因此位于不同物理机上的Docker容器之间直接使用本身的IP地址进行通信很有必要.再者说,如果将Docker容器起在不同的物理主机上,我们不可避免的会遭遇到Docker容器的跨主机通信问题.本文就来尝试一下. 此时两台主机上的Docker容器如何直接通过

  • 解决Mac下 docker 无法 ping 通宿主机的问题

    解决方案 抛弃docker for mac自带的linux虚拟机(尽管轻量,但其与OSX通信采用socket文件的方式),使用docker-machine 安装virtualbox.virtualbox创建后,会添加一个虚拟网卡,可以通过ifconfig命令查看.我们实现的方式,就是利用这个虚拟网卡. 使用docker-machine创建默认linux虚拟机,命令docker-machine create 切换docker环境,使用eval $(docker-machine env)命令 查看创

  • docker容器无法访问宿主机端口的解决

    最近在工作时遇到一个问题,docker容器无法访问宿主机的redis,telent6379端口不通. 经排查发现,该服务器启用了防火墙,防火墙把6379的端口的访问授权给docker0网卡访问即可. 操作如下: firewall-cmd --permanent --zone=trusted --change-interface=docker0 firewall-cmd --reload 补充知识:docker 启动mysql 容器出错Ports are not available: listen

  • docker内服务访问宿主机服务的实现

    目录 1. 场景 2. 解决 3. 总结 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数据使用开源组件synch 同步到clickhouse 这个工作. 测试所需组件 postgres kafka zookeeper redis synch容器 最开始测试时,选择的方案是, 将上述五个服务使用 docker-compose 进行编排, network_modules使用ho

  • Docker MySQL无法被宿主机访问的问题解决

    目录 1 问题描述 2 原因 3 解决方案 1 问题描述 Docker启动MySQL容器后,创建一个localhost访问的用户: create user test@localhost identified by 'test'; 但是在宿主机中无法通过该用户登录: mycli -u test 2 原因 在Docker中的MySQL创建localhost的用户只能在Docker内部访问,而不能通过外部访问. 至于为什么能在宿主机访问root,是因为默认存在两个root,分别是: root@loca

  • 在Docker容器中使用iptables时的最小权限的开启方法

    在Docker容器中使用iptables时的最小权限的开启方法 Dcoker容器在使用的过程中,有的时候是需要使用在容器中使用iptables进行启动的,默认的docker run时都是以普通方式启动的,没有使用iptables的权限,那么怎样才能在容器中使用iptables呢?要如何开启权限呢? 那么在docker进行run的时候如何将此容器的权限进行配置呢?主要是使用--privileged或--cap-add.--cap-drop来对容器本身的能力的开放或限制.以下将举例来进行说明: 例如

  • Docker容器间通信与外网通信的操作

    一 容器间通信 1.容器的网络共享 处于这个模式下的docker容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信. 使用于web服务器与应用服务器之间的通信. ##清空实验环境 [root@server1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ##默认网络创建容器 [root@server1 ~]# docker run -it --name vm1 ubuntu

随机推荐