Docker Swarm 内部服务发现和负载均衡原理

article/2025/10/10 11:44:19

1. 集群环境准备

搭建三台服务器,并安装docker环境,并保证能正常连接互联网,后面会使用其他镜像做负载均衡测试。

  • 192.168.104.79
  • 192.168.104.80
  • 192.168.104.81
    首先修改hostname,便于后面区分当前操作所在机器:
  • 使用 hostname 可以查看当前hostname
  • hostnamectl set-hostname 主机名 修改hostname 打开新的窗口,即可生效,重启仍然有效。
    在这里插入图片描述

其中计划 192.168.104.79 作为集群的 Leader 节点,首先在 79 服务器上执行 docker swarm init 初始化manager节点。
在这里插入图片描述
其中上图打印的:docker swarm join --token SWMTKN-1-32t98682uh3p0cvwe3c0t48a9nj9vzytiglcv1qgaz6em39920-1j4km76o6b3ze2blcppfqtt5y 192.168.104.79:2377
即为其他服务器加入当前集群环境的命令。

依次在docker-80,docker-81 服务器上执行上面的命令。提示当前节点作为worker角色,加入集群环境。
在这里插入图片描述
之后就可以在 79 机器上看到该集群环境的信息了:docker node ls
在这里插入图片描述
其中 docker-79 为Leader节点,其他为work节点。

2. 基于 DNS 的负载均衡

DNS server 内嵌于Docker 引擎。下面创建两个基于DNS负载均衡服务:客户端client和服务端vote, 服务间通过服务名进行调用通信。 Docker DNS 解析服务名“vote” 并返回容器ID地址列表(随机排序)。客户端通常会挑第一个IP访问,因此负载均衡可能发生在不同实例之间。
在这里插入图片描述

  • 2.1 创建network : docker network create --driver overlay overlay1
    在这里插入图片描述
  • 2.2 创建一个名为 client 的服务
docker service create --endpoint-mode dnsrr --replicas 1 --name client --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

在这里插入图片描述
会自动拉取镜像 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ,然后自动启动。

查看服务日志:docker service logs 服务ID
在这里插入图片描述
看下启动痕迹:docker service ps 服务ID
在这里插入图片描述
可以看到,在docker-80机器上运行两次后失败了,最终是运行在docker-79机器上的。

去80机器上看下:docker ps -a 可以看到有两次启动痕迹,状态都为Exist
在这里插入图片描述

  • 2.2 创建 vote 服务
docker service create --endpoint-mode dnsrr --name vote --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

在这里插入图片描述
可以看到创建了两个服务实例,并且自动分配,运行在80和81机器上,如下图 NODE 列所示。
在这里插入图片描述

  • 2.3 进入client 服务内部,查看vote 解析规则
    在这里插入图片描述

从上面的服务运行情况,可以看到client 服务是运行在79机器上的,所以需要从79机器上执行 docker ps,拿到容器ID,然后进入服务内部,使用 dig 来解析服务名 “vote”, 可以看到 vote 会解析到 10.0.1.910.0.1.8,这两个地址是集群内部的网络通信IP。

接着,使用 ping 解析 “vote” 服务,多次执行 ping -c1 vote 如下所示,随机交替解析到 10.0.1.9 和 10.0.1.8
在这里插入图片描述
如果直接执行 ping vote,则一直解析到 同一个IP上。
在这里插入图片描述
接着使用curl测试,可以看到也是可以随机解析到不同的容器上的。
在这里插入图片描述
基于DNS负载均衡存在如下问题:

  • 某些应用程序将DNS主机名缓存 到IP地址映射,这会导致应用程序在映射更改时超时。
  • 具有非零DNS ttl值 会导致DNS条目反映最新的详细信息时,发生延迟。

3. 基于VIP(Virtual IP)的负载均衡

基于VIP的负载均衡克服了基于DNS负载均衡的一些问题。在这种方法中,每个服务都有一个虚拟IP地址,并且该IP地址映射到与该服务关联的多个容器的IP地址。在这种情况下,与服务关联的服务IP不会改变,即使与改服务关联的容器死亡并重新启动。
在这里插入图片描述
使用如下命令创建两个新的服务:client_VIPvote_VIP

docker service create --replicas 1 --name client_VIP --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

在这里插入图片描述

docker service create --name vote_VIP --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

在这里插入图片描述
查看这两个服务和他们的IP:docker service inspect --format {{.Endpoint.VirtualIPs}} 服务名称
在这里插入图片描述
client_VIP的容器中,使用 dig vote可以看到 vote 映射同上面一样,映射到到 10.0.1.910.0.1.8
在这里插入图片描述
使用 dig vote可以看到 vote_VIP 映射到到 10.0.1.14
在这里插入图片描述
接着使用 curl 请求 vote_VIP 服务:curl vote_VIP | grep -i "container id",输出结果如下,可以看到时一种轮训分发请求到不同的容器:
在这里插入图片描述
这就有点神奇了,对比之前DNS负载均衡的结果,dig vote; 是两个IP,curl 请求的时候,是随机返回的,而 dig vote_VIP; 返回一个IP,curl的时候,是轮训机制分发的。
在这里插入图片描述
那这个Service IP 10.0.1.14 是怎么分发到两个容器的呢?

实质是使用Linux内核的iptables 和 IPVS 负载均衡到2个容器。IPtables 实现防火墙机制,IPVS 实现负载均衡。这句话是重点,圈起来要考的。

下面带着这个猜想,看下能不能证明一下。

使用nsenter 进入容器网络空间(namespace)。为此我们需要找到网络命名空间。

如下是docker-79上面的网络命名空间:
在这里插入图片描述
进入 /run/docker/netns 目录,可以看到有6个网络命名空间,前两个用于overlay网络,后面用于容器。

接着进去 client_VIP 容器内的网络空间。使用:docker inspect 4664834de94b | grep -i sandbox ,其中 SandboxID 即为 client_VIP 容器的网络空间

同理可以看到 如下是docker-80上面的网络命名空间:
在这里插入图片描述

最后对比下结果:

client_VIP 解析vote_VIP 返回的IP是 10.0.1.14,多次执行仍然是10.0.1.14
在这里插入图片描述
其中 curl vote_VIP | grep "container id" 可以看到轮训到两个不同的容器上去。
在这里插入图片描述
两个容器的IP分别为:10.0.1.1510.0.1.16
在这里插入图片描述在这里插入图片描述
至此,可以看到DNS Server 会将服务名 vote_VIP 解析到 Service IP 10.0.1.14 ,使用iptables和ipvs,实现两个服务端 vote_VIP 容器10.0.1.1510.0.1.16的负载均衡。

4. 路由网格(Routing mesh)

使用路由网络,服务暴露的端口会暴露在集群中的所有的工作节点。Docker 是通过创建“ingress overlay”网络来实现这一点的,所有节点默认使用内在sandbox 网络命名空间成为“ingress” overlay网络的一部分。
在这里插入图片描述

首先,会将Hostname或IP映射到Sandbox IP,Sandbox中的 iptables 和 IPVS 负责将请求负载均衡到2个vote_Routing 容器,Ingress Sandbox网络命名空间驻留在 Docker Swarm 集群中的所有工作节点,它通过主机映射的端口负载均衡到后端容器来协助路由网格功能。

但是我这里测试后发现,只能访问主节点IP才能请求通,其他节点上的容器请求不通。这就很迷。。。。。。

创建服务:vote_Routing

docker service create --name vote_Routing --network overlay1 --replicas 2 -p 8080:80 registry.cn-hangzhou.aliyuncs.com/anoy/vote

在这里插入图片描述
创建服务后,可以看到,服务vote_Routing 分别运行在 docker-80docker-79 两台服务器上。

在 docker-80 服务器上可以正常请求的通,并且是轮训的机制负载均衡到两台服务器的容器上。
在这里插入图片描述
但是尝试在docker-79机器上请求:curl 192.168.104.80:8080 | grep -i "container id" 却一直没有响应回来。。。。。。。
在这里插入图片描述
也不报错,其中上图的Time列 开始计时,计时能一直走下去,直到提示连接超时。。。。。。。。。。
在这里插入图片描述
此时确保防火墙也是关闭状态的,连接超时这个就很坑。。。。。。。。

后面换成别的镜像测试后再补充。

文章实践参考:https://www.jb51.net/article/139411.htm


http://chatgpt.dhexx.cn/article/ac4OyLi2.shtml

相关文章

Spring Cloud - Ribbon 负载均衡原理、负载策略、懒加载

目录 ​编辑 一、Ribbon 负载均衡原理 1.1、前言 1.2、负载均衡的工作流程 二、负载均衡策略 2.1、策略原理 2.2、负载均衡自定义方式 三、Ribbon 加载方式 一、Ribbon 负载均衡原理 1.1、前言 ps:案例是上一章所讲的 “根据订单id查询订单的同时&#xff0…

Ribbon-负载均衡原理

负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。 那么我们发出的请求明明是http://userservice/user/1,怎么变成了http://localhost:8081的呢? 源码跟踪 为什么我们只输入了service名称就可以访问了…

Nginx负载均衡原理与实战

Nginx 负载均衡原理与实践 本篇摘自《亿级流量网站架构核心技术》第二章 Nginx 负载均衡与反向代理 部分内容。 当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台。然而,用户访问时是通过如的…

Nginx负载均衡原理

Nginx简介 Nginx是通过反向代理实现的负载均衡。 什么是正向代理与反向代理? 正向代理就是,客户端通过一台代理服务器访问服务端。 反向代理就是,服务端通过代理服务器为客户端提供服务。 看起来似乎没有什么区别,举个例子。 …

负载均衡原理及算法

目录 背景概述原理分类按照软硬件分类硬件负载均衡软件负载均衡 按照地理结构分类本地负载均衡全局负载均衡 按照实现技术DNS负载均衡IP负载均衡链路层负载均衡混合型负载均衡 按照OSI层次二层负载均衡(数据链路层)三层负载均衡(网络层&#…

Ribbon负载均衡原理

Ribbon restTemplate相结合实现负载均衡,具体原理图详见以下截图: LoadBalancerClient 类执行具体的负载均衡,其继承于 LoadBalancerBase。LoadBalancerInterceptor 中注入了 LoadBalancerClient 对象,LoadBalancerClient执行具…

什么是负载均衡,负载均衡的原理解析是怎么样的

负载均衡对于很多大型企业来说,不管网游,商城,金融等业务,他的重要性无需多说,今天带来负载均衡的原理解析。 开头先理解一下所谓的“均衡”。 不能狭义地理解为分配给所有实际服务器一样多的工作量,因为…

负载均衡工作原理详解

负载均衡是由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。通过某种负载分担技术,将外部发送来的请求均匀分配到对称结构中的某一台服务器上,而接收到请求的服务器独立地回应客户的请求。 均衡负…

负载均衡原理及实现

什么是负载均衡? 负载均衡( LoadBalance ),顾名思义就是把任务压力进行平衡的分摊到集群中各个操作单元(或机器)上,使得避免集群中部分机器压力过大而部分机器过于空闲。经过负载均衡,使得每个机器获取适合自己的处理能力负载。 …

Android 获取手机已安装的应用列表(适配)

权限 <uses-permissionandroid:name"android.permission.QUERY_ALL_PACKAGES"tools:ignore"QueryAllPackagesPermission" /> 加上权限才能获取到所有的应用 获取代码 public static boolean hasApplication(Context context, String packageName) …

如何在没有微软商店的情况下在Windows 10上安装应用程序

如何在没有微软商店的情况下在Windows 10上安装应用程序 通过微软商店&#xff0c;你可以轻松地在Windows 10设备上安装应用程序&#xff0c;就像使用Google Play或AppleStore一样。IT部门经常从设备上删除微软商店&#xff0c;或设置组策略禁用Windows更新&#xff0c;以防止…

“打开文件所在位置“失败,提示“该文件没有与之关联的应用来执行操作。请安装应用,若已经安装应用...““

问题点:装了某个软件,卸载后出现"打开文件所在位置"失败,出现以下提示: 该文件没有与之关联的应用来执行操作。请安装应用&#xff0c;若已经安装应用&#xff0c;请在“默认应用设置"页面中创建关联 解决办法: 打开注册表,找到HKEY_CLASSES_ROOT\Folder\shell,…

Win 11 打开未知文件/打开方式 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。

问题 鼠标右键选中文件 - 打开方式&#xff0c;或者选择其他应用 弹窗提示&#xff1a; 该文件没有与之关联的应用来执行该操作。请安装应用&#xff0c;若已经安装应用&#xff0c;请在“默认应用设置”页面中创建关联。 打开注册表&#xff0c;查看是否存在以下路径 HKEY_C…

该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置“页面中创建关联

在任意文件上鼠标右键&#xff0c;选择打开方式或者选择其他应用时报错“该文件没有与之关联的应用来执行该操作。请安装应用&#xff0c;若已经安装应用&#xff0c;请在"默认应用设置"页面中创建关联”&#xff0c;错误现象如下&#xff1a; 打开注册表&#xf…

安装软件程序

包管理基础 在深入了解Linux软件包管理之前&#xff0c;本章将先介绍一些基础知识。各种主流Linux发行版都采用了某种形式的包管理系统来控制软件和库的安装。 PMS利用一个数据库来记录各种相关内容&#xff1a;  Linux系统上已安装了什么软件包&#xff1b;  每个包安装了…

android 获取已安装应用(App)列表

效果图 获取手机上已安装应用列表&#xff0c;将获取到的信息用集合返回&#xff0c;可以自己定义是否过滤系统应用&#xff0c;Appinfo是一个实体类&#xff0c;包含应用的名称 包名 图标icon等等 /*** 获取手机已安装应用列表* param ctx* param isFilterSystem 是否过滤系统…

应用程序安装流程

https://maoao530.github.io/2017/01/18/package-install/ 本文介绍APK的安装流程。 一、安装流程图 APK安装流程&#xff0c;总体可以下图流程&#xff0c;用ProcessOn画的&#xff0c;凑合看&#xff1a; 从上图我们可以看到apk安装到最后都会调用到这个flow&#xff1a; PM…

app 安装方式

APK的安装方式主要有以下几种&#xff1a; 通过adb命令安装&#xff1a;adb 命令包括adb push/install用户下载的Apk&#xff0c;通过系统安装器PackageInstaller安装该Apk。PackageInstaller是系统内置的应用程序&#xff0c;用于安装和卸载应用程序。系统开机时安装系统应用…

安卓手机怎样安装apk应用

以华为手机为例 首先手机要关闭纯净模式&#xff0c;方法&#xff1a; 设置–系统和更新–纯净模式–关闭 然后下载/接收apk文件 &#xff08;如果是从浏览器下载的&#xff0c;可以直接安装&#xff0c;如果是从其他渠道下载&#xff0c;则安装方法如下&#xff09; 打开手机…

大体了解Android应用安装过程及原理

Android应用安装的流程及路径&#xff1a; 应用安装涉及到如下几个目录&#xff1a; system/app 系统自带的应用程序&#xff0c;无法删除 data/app 用户程序安装的目录&#xff0c;有删除权限。安装时把apk文件复制到此目录 data/data …