应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

.net6使用nacos 集群部署,负载均衡调用 。docker swarm 集群部署.net6项目

7592人阅读 2022/12/27 15:45 总访问:5201858 评论:0 收藏:0 手机
分类: 微服务


我们这里的k8s测试环境暂时用不了了,这里先使用docker swarm来进行一下集群部署。


.net6使用nacos实现服务注册与服务发现:
https://www.tnblog.net/aojiancc2/article/details/7931
.net6使用nacos作为配置中心:
https://user.tnblog.net/UpdateArticle/UpdateArticle/7870
docker安装nacos v2.1.2:
https://www.tnblog.net/aojiancc2/article/details/7865

Docker Swarm环境

就两个电脑的一个简单集群,一个主节点,一个子节点

上传发布的项目,打包镜像

上传发布后的项目文件与dockerfile,然后使用命令打包镜像

  1. docker build -t nacoslearn .

打包的时候可以在后面接版本,比如接一个v1版本:

  1. docker build -t nacoslearn:v1 .

创建一个Overlay模式的自定义网络。方便集群容器中的网络管理与容器互通

  1. docker network create -d overlay nacoslearn_net


创建后可以使用docker network ls查看,如上图所示。

也可以使用docker network ls | grep nacoslearn_net查看,这样就只会查看到nacoslearn_net网络了

Overlay网络模式介绍:用于跨主机网络,集群访问,应用层通信的网络。

使用创建的自定义网络部署.net6项目

刚刚镜像已经打好了,可以直接跑服务了

  1. docker service create --replicas 5 --network nacoslearn_net --name nacoslearn -p 8805:8805 nacoslearn


上面创建了一个具有5个副本(—replicas 5 )的nacoslearn服务,nacoslearn,使用网络nacoslearn_net


如果镜像我们是上传到镜像库了的,就可以不需要提前在节点上创建nacoslearn镜像,这个命令执行后会自动下载对应的容器镜像

可以使用下面的命令查看网络的使用详情:

  1. docker network inspect nacoslearn_net

使用 docker service ls 查看正在运行服务的列表

可以看到,刚刚我们创建的5个副本是正常启动起来的

查看服务被运行到什么节点

  1. docker service ps nacoslearn


这里我们可以看到5个副本都跑到了主节点上,因为在node节点没有找到这个镜像去互联网下载又没有成功,所以重试几次后都失败了,就全部运行到主节点了。
测试的时候可以把镜像打包上传到镜像库或者是在子节点在打包一个镜像就可以在子节点跑了。

服务成功跑起来后就可以在nacos查看服务的情况

可以看到一共有5个实例,点击进去查看详情


可以看到5个节点的ip地址等信息,这里要注意这里获取的ip地址格式10.0.0.x和我们查看自定义网络详情的10.0.2.x不一致,是因为nacos获取ip的时候默认是获取第一张网卡的,我们这里容器内部的网卡其实有多张,我们可以去nacos配置以下,获取我们想要的ip。虽然这里的ip也不会影响我们通过docker swarm来进行集群的负债均衡调用,但是我们想要通过nacos服务发现后进去内部调用就要注意了,获取的网卡要对。

动态更新镜像

比如我们修改了一块功能,想要发布新的功能就可以使用动态更新镜像。

先打包一个新的镜像,这里我们取名v2吧

  1. docker build -t nacoslearn:v2 .

我们也可以同时在子节点也去打包一个镜像,方便测试

然后使用命令更新镜像

  1. docker service update --image nacoslearn:v2 nacoslearn

更新之后就可以看到子节点里边也有运行的副本了

我们在子节点也打包了镜像的,所以子节点能找到这个镜像,就能正确的跑起来了

动态扩容与动态缩容

非常简单和k8s类似,使用命令动态指定副本数量即可

通过docker service scale命令动态扩容
  1. docker service scale nacoslearn=9

这样副本数量就从5个变成了9个

通过docker service scale命令动态缩容
  1. docker service scale nacoslearn=2

这样副本数量就降低到了2个

访问集群,负载均衡的访问集群

直接通过两台电脑的ip地址去访问都是没有问题的:

调用一下接口也是没有问题的,这里接口我们获取了一下所有网卡的ip地址

这里接口我们获取了一下所有网卡的ip地址

  1. [HttpGet]
  2. public IEnumerable<string> Get()
  3. {
  4. //获取配置中心nacos的DbConfig节点
  5. var dbConfig = _configuration.GetSection("DbConfig");
  6. //读取连接字符串配置
  7. string connectionString = dbConfig["ConnectionString"];
  8. //读取配置
  9. string isAutoCloseConnection = _configuration["DbConfig:IsAutoCloseConnection"];
  10. //读取common里边的配置
  11. string UserName = _configuration["UserName"];
  12. string Password = _configuration["Password"];
  13. //获取服务器上所有网卡的IP地址
  14. NetworkInterface[] networks = NetworkInterface.GetAllNetworkInterfaces();
  15. string serverIpAddresses = string.Empty;
  16. foreach (var network in networks)
  17. {
  18. var ipAddress = network.GetIPProperties().UnicastAddresses.Where(p => p.Address.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(p.Address)).FirstOrDefault()?.Address.ToString();
  19. serverIpAddresses += network.Name + ":" + ipAddress + "|";
  20. }
  21. return new List<string>() { connectionString, isAutoCloseConnection, serverIpAddresses };
  22. }

这个时候我们访问接口本身就是直接负债均衡了的
通过swagger请求接口有缓存,我们直接使用curl测试,可以看到每次请求返回的ip地址都不一样,所以每次请求的都是不通的容器

所以这里我们直接请求接口就已经是支持了负债均衡了的,不需要在通过nacos去进行一次服务发现后调用,因为docker swarm其实是内置了服务注册,服务发现了的,好像是用的consul,而且也是内置了vip以及dns这些。

大概的原理如下:


在结构图可以看出 Docker Client使用Swarm对 集群(Cluster)进行调度使用。
上图可以看出,Swarm是典型的master-slave结构,通过发现服务来选举manager。manager是中心管理节点,各个node上运行agent接受manager的统一管理,集群会自动通过Raft协议分布式选举出manager节点,无需额外的发现服务支持,避免了单点的瓶颈问题,同时也内置了DNS的负载均衡和对外部负载均衡机制的集成支持

其中Node的图解:

可以通过命令查询Swarm中服务的详细信息

  1. docker service inspect --pretty nacoslearn

可以看到绑定的ip,使用的模式vip,对外提供服务ingress,使用的网络nacoslearn_net等。

这里用到了inggress。Swarm 管理节点会利用 ingress 负载均衡以将服务公布至集群之外。

集群的容器之间,也是可以通过ip或者容器名,容器id进行访问的
比如我们随便进入一个容器内部

  1. docker exec -it 53a6dc1cfc3a /bin/bash

然后可以ping一下其他容器的ip:


没有问题

通过容器名称去访问也是没有问题的:

访问一下接口:


没有问题

如果docker内部的ping命令与curl无法访问的情况下,就在docker内部装一下

  1. apt-get update
  2. ## 安装ping命令
  3. apt install iputils-ping
  4. ## 安装curl命令
  5. apt install curl -y

通过nacos服务发现,负载均衡的访问集群。多网卡下nacos获取ip的配置

虽然这里直接访问接口本身就是支持负债均衡了的,不需要在使用nacos的服务发现了,但是如果我们需要使用也是完全可以的。

通过SelectInstances方法就可以发现多个服务了,然后在随机调用即可

  1. /// <summary>
  2. /// 通过nacos的服务发现来调用接口
  3. /// </summary>
  4. /// <returns></returns>
  5. [HttpGet("test")]
  6. public async Task<string> Test()
  7. {
  8. // 通过分组与服务名获取
  9. //var instance = await _svc.SelectOneHealthyInstance("BaseApi", "DEFAULT_GROUP");
  10. try
  11. {
  12. //获取多个实例,可以进行负载均衡等方式调用服务
  13. var instanceList = await _svc.SelectInstances("TNBLOG.BaseApi", "DEFAULT_GROUP", true);
  14. if (instanceList.Count == 0)
  15. return "未找到相关接口信息";
  16. //使用随机数模拟一下负载均衡
  17. Random random = new Random();
  18. var instance = instanceList[random.Next(0, instanceList.Count)];
  19. var host = $"{instance.Ip}:{instance.Port}";
  20. var baseUrl = instance.Metadata.TryGetValue("secure", out _)
  21. ? $"https://{host}"
  22. : $"http://{host}";
  23. if (string.IsNullOrWhiteSpace(baseUrl))
  24. {
  25. return "empty";
  26. }
  27. //测试调用一下上面那个接口
  28. var url = $"{baseUrl}/api/WeatherForecast";
  29. using (HttpClient client = new HttpClient())
  30. {
  31. var result = await client.GetAsync(url);
  32. return await result.Content.ReadAsStringAsync();
  33. }
  34. }
  35. catch (Exception ex)
  36. {
  37. return ex.Message;
  38. }
  39. }

但是这里要注意nacos获取ip默认是第一个网卡的,我们这里其实应该是eth1网卡的ip才是我们需要的那个ip地址,通过它才能正确的在容器间调用:

多网卡下nacos可以通过配置PreferredNetworks=10.0.2,使服务获取内网中前缀为10.0.2的IP。

修改配置后我们可以重新打包一个v3的镜像,然后动态升级一下镜像

可以看到nacos获取的就是10.0.2开头的了

当然这里其实只是修改了配置不一定需要重新打开镜像,重启一下原有的服务也是可以的,我这里使用更新镜像的方式测试。

然后我们就可以通过nacos的服务发现去调用接口

多点几下,会发现会随机调用我们跑的5个副本,因为我们获取到服务实例后,生成的随机数去随机调用的,效果如下:

上面我们是使用的指定前缀的方式在多网卡下获取需要的ip地址,当然还有一些其他配置方法比如指定网卡什么的,多在网上搜一下就知道了,不过.net的资料真的很少哇,java的倒是很多-。-

比如指定网卡可以类似这样配置:

  1. "NetworkInterface": "eth1"

我测试好像这样指定网卡并不是非常准确,还是有部分服务获取到的是10.0.0.x这种第一个网卡的地址,估计是这里配置.net下的写法有点小区别,找一下确认一下就行了,思路就是这样,.net下的文档也是非常少。

还可以配置忽略网卡什么的,比如

  1. IgnoredInterfaces[0]=eth0 # 忽略网卡,eth0
  2. IgnoredInterfaces=eth.* # 忽略网卡,eth.*,正则表达式

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

.net6 Ocelot 与 Kubernetes

.Net6 Ocelot 与 Kubernetes[TOC] 前言这玩意太坑人了。浪费了我一天的时间。先看我们想实现的效果流程: 首先我们请求sv...

.net core发布出来swagger无法访问。docker 发布.net6 webapi swagger访问不到

因为代码里边设置swagger的代码是: if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.Use...

.net6 指定时区

.Net6 指定时区[TOC] 最近相当忙!忙着学这学那的,各种考试。以及项目上也有很多改动。还有这恶心的时间问题(特别注意当...

.net6 AsyncEx 异步锁

.Net6 AsyncEx[TOC] 简单来讲就是可以通过异步方式实现锁。安装&lt;PackageReference Include=&quot;Nito.AsyncEx&quot; V...

Kubernetes .net6 集群管理(一)

Kubernetes .Net6 集群管理(一)[TOC] 对于Kubernetes集群的管理,.net提供了KubernetesClient库,可以对k8s集群通过简单...

Kubernetes .net6 Webhook

Kubernetes .Net6 Webhook[TOC] 本文主要是学习陈计节大佬讲的 使用 .NET Core 开发 Kubernetes 基础组件记录的笔记。 Ad...

.net6 设置信任自签证书(浏览器可信任)

.Net6 设置信任自签证书(浏览器可信任)[TOC] 先决条件确保本地windows上拥有openssl,没有的自己去:http://slproweb.com...

Kubernetes .net6 CRD

Kubernetes .Net6 CRD[TOC] CRD介绍简单来说就是自定义资源,像Pod、Service、Deployment一样。创建自定义资源的资源类型...

linux批量执行命令脚本。linux脚本执行docker镜像打包运行.net6项目

linux批量执行命令脚本1:创建一个.sh后缀的文件vi run.sh 2:在文件开头添加内容#!/bin/bash 3:在文件里边输入想要执行...

docker发布.net6项目。制作发布的批量脚本一键发布脚本

docker 发布.net core项目可以参考:https://www.tnblog.net/aojiancc2/article/details/5030 docker发布.net6项目简单的d...

.net6 连接mysql报错Unable to connect to any of the specified MySQL hosts.

.net5/6 连接mysql报错Unable to connect to any of the specified MySQL hosts. 不能使用点.连接 server=.;uid=root;pwd...

.net6使用nacos作为配置中心

consul+.net core实现配置中心:https://www.tnblog.net/aojiancc2/article/details/6815nacos的安装参考:https://www.tnbl...

.net6使用session

先在Program.cs中引入 使用存储 HttpContext.Session.SetString(&quot;nickname&quot;,&quot;test&quot;); 读取 string...

.net6使用nacos实现服务注册与服务发现

.net6使用nacos作为配置中心:https://www.tnblog.net/aojiancc2/article/details/7870docker安装nacos v2.1.2:https://www...

.net6.net core获取服务器上所有网卡的IP地址

代码如下: //获取服务器上所有网卡的IP地址 NetworkInterface[] networks = NetworkInterface.GetAllNetworkInterfaces(...