当前位置: 首页 > news >正文

图解Kubernetes的服务(Service)

pod 准备:

不要直接使用和管理Pods:

  • 当使用ReplicaSet水平扩展scale时,Pods可能被terminated
  • 当使用Deployment时,去更新Docker Image Version,旧Pods会被terminated,然后创建新Pods

0 啥是服务(Service)

Kubernetes 中 Service 是 将运行在一个或一组 [Pod]上的网络应用程序公开为网络服务的方法。

Kubernetes 中 Service 的一个关键目标是让你无需修改现有应用以使用某种不熟悉的服务发现机制。 你可以在 Pod 集合中运行代码,无论该代码是为云原生环境设计的,还是被容器化的老应用。 你可以使用 Service 让一组 Pod 可在网络上访问,这样客户端就能与之交互。

如果你使用 [Deployment]运行应用, Deployment 可动态创建和销毁 Pod。 在任何时刻,你都不知道有多少个这样的 Pod 正在工作以及它们健康与否; 你可能甚至不知道如何辨别健康的 Pod。 Kubernetes Pod 的创建和销毁是为了匹配集群的预期状态。 Pod 是临时资源(你不应期待单个 Pod 可靠又耐用)。

每个 Pod 会获得属于自己的 IP 地址(Kubernetes 期待网络插件来保证这一点)。 对集群中给定的某个 Deployment,这一刻运行的 Pod 集合可能不同于下一刻运行该应用的 Pod 集合。

这就带来问题:若某组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”) 集合提供功能,前端要如何发现并跟踪要连接的 IP 地址,以便其使用负载的后端组件呢?

1 Kubernetes 中的 Service

Service API 是 Kubernetes 的组成部分,它是一种抽象,帮助你将 Pod 集合在网络上公开。 每个 Service 对象定义端点的一个逻辑集合(通常这些端点就是 Pod)以及如何访问到这些 Pod 的策略。

如考虑一个无状态的图像处理后端,其中运行 3 个副本(Replicas)。 这些副本是可互换的 —— 前端不需要关心它们调用的是哪个后端。 即便构成后端集合的实际 Pod 可能会发生变化,前端客户端不应该也没必要知道这些, 而且它们也不必亲自跟踪后端的状态变化。

Service 抽象使这种解耦成为可能。

Service 所对应的 Pod 集合通常由你定义的选择算符来确定。 若想了解定义 Service 端点的其他方式,查阅不带选择算符的 Service。

如果你的工作负载使用 HTTP 通信,你可能选用 Ingress 来控制 Web 流量如何到达该工作负载。Ingress 不是一种 Service,但它可用作集群的入口点。 Ingress 能让你将路由规则整合到同一个资源内,这样你就能将工作负载的多个组件公开出去, 这些组件使用同一个侦听器,但各自独立地运行在集群中。

用于 Kubernetes 的 Gateway API 能够提供 Ingress 和 Service 所不具备的一些额外能力。 Gateway 是使用 CustomResourceDefinitions 实现的一系列扩展 API。 你可以添加 Gateway 到你的集群中,之后就可以使用它们配置如何访问集群中运行的网络服务。

1.1 云原生服务发现

如果你想要在自己的应用中使用 Kubernetes API 进行服务发现,可以查询 APIServer, 寻找匹配的 EndpointSlice 对象。 只要 Service 中的 Pod 集合发生变化,Kubernetes 就会为其更新 EndpointSlice。

对于非本地应用,Kubernetes 提供了在应用和后端 Pod 之间放置网络端口或负载均衡器的方法。

无论采用那种方式,你的负载都可以使用这里的服务发现机制找到希望连接的目标。

对比Spring Cloud

Spring Cloud 中的微服务也通常使用服务名称进行通信,而不需要关心具体的IP地址。这是通过服务发现机制实现的,其中服务注册中心维护了服务名称与实际服务实例的映射关系。

在Spring Cloud中,服务通常会注册到服务注册中心(例如Eureka、Consul等),并且客户端通过服务名称来发现和调用服务,而不是直接使用硬编码的IP地址。这种做法使得微服务的位置可以更加灵活地变化,而不影响客户端的调用方式。

在这方面,Kubernetes 中的 Service 与 Spring Cloud 中的服务注册中心的角色有些相似。Kubernetes Service 提供了一种将一组 Pod 暴露为一个网络服务的机制,通过 Service 名称来访问这组 Pod,而不需要关心具体的 Pod IP 地址。这有助于实现微服务架构中的服务发现和解耦。

因此,无论是在Kubernetes中的Service还是Spring Cloud中的微服务,服务的抽象层级都允许更灵活、可扩展和解耦的服务通信。

2 Service类型

kubectl expoese给我们的pod创建一个Service,供外部访问。

2.1 ClusterIP

默认Service类型,它将Pods公开为k8s集群内部的服务。要创建ClusterIP Service,可用kubectl expose指定–type=ClusterIP。

如myapp Deployment暴露为ClusterIP Service:

kubectl expose deployment myapp --port=80 --target-port=8080 --type=ClusterIP

2.2 NodePort

将Pods公开为k8s集群外部的服务。它会在每个节点上打开一个端口,并将请求转发到后端Pods。

创建NodePort Service,使用kubectl expose命令,并指定–type=NodePort选项。

如将myapp Deployment暴露为NodePort Service:

[root@javaedge-k8s-node-1 ~]#  kubectl expose deployment javaedge-nginx  --port=90 --target-port=80 --type=NodePortservice/javaedge-nginx exposed

这个命令的作用是在 k8s 集群中将名为 javaedge-nginx 的 Deployment 暴露为一个 Service,该 Service 使用 NodePort 类型,并将容器端口 80 映射到 Service 的端口 90。这个命令的完整语法为:

kubectl expose deployment <deployment-name> --port=<service-port> --target-port=<container-port> --type=NodePort

其中,<deployment-name> 是要暴露的 Deployment 的名称,<service-port> 是要创建的 Service 的端口,<container-port> 是要映射到 Service 端口的容器端口,--type=NodePort 表示创建的 Service 类型为 NodePort。

2.3 外部的LoadBalancer

LoadBalancer Service将Pods公开为k8s集群外部的服务,并使用云提供商的公网的负载均衡器(固定的公网ip)来将请求路由到后端Pods。要创建Load Balancer Service,可用kubectl expose命令,并指定–type=LoadBalancer。

如将myapp Deployment暴露为LoadBalancer Service:

kubectl expose deployment myapp --port=80 --target-port=8080 --type=LoadBalancer

这些命令将创建一个名为myapp的Deployment,并将其公开为LoadBalancer Service。

使用LoadBalancer Service,需在云提供商的环境中运行Kubernetes集群,并且需要正确配置云提供商的负载均衡器。也可使用DNS,但需要DNS的add-on。

3 实战

kubectl create -f pod_nginx.yml
kubectl create -f pod_busybox.yml
[root@javaedge-monitor-platform-dev k8s]# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
busybox-pod                         1/1     Running   0          49s     10.244.0.24   minikube   <none>           <none>
nginx-pod                           1/1     Running   0          6s      10.244.0.25   minikube   <none>           <none>
[root@javaedge-monitor-platform-dev k8s]# kubectl expose pods nginx-pod
service/nginx-pod exposed

4 外部的LoadBalancer 模式的缺点

  • LoadBalancer+一个 ip 只能暴露一个服务。若需暴露多个服务,就需要申请多个LoadBalancer加上IP,成本剧增
  • 如果将K8s内部服务直接暴露给外网的客户,就会导致前端和后端耦合

于是,k8s 引入 Ingress。

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都国企技术专家兼架构,多家大厂后台研发和架构经验,负责复杂度极高业务系统的模块化、服务化、平台化研发工作。具有丰富带团队经验,深厚人才识别和培养的积累。

参考:

  • 编程严选网

相关文章:

  • 高并发场景系统设计的时候应该怎么考虑?
  • python入门,数据容器:set集合
  • mybatis核心配置文件介绍
  • 作业:通过两台linux主机配置ssh实现互相免密登陆
  • 大模型背景下计算机视觉年终思考小结(一)
  • 【计算机组成原理】高速缓冲存储器 Cache 的写策略(Writing Policy)
  • 【教学类-43-20】20240113 数独(二)4宫格、9宫格 无空行A4模板
  • 【REST2SQL】05 GO 操作 达梦 数据库
  • 代码随想录算法训练营第八天|344.反转字符串 ,541. 反转字符串II ,151.翻转字符串里的单词,55.右旋转字符串
  • Python中如何简化if...else...语句
  • SSH远程访问与控制
  • Python 密码设置输入掩码的方法
  • linux 网络设置
  • C#监听Dictionary、List的写入操作
  • windows下如何搭建Yapi环境
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Java 多线程编程之:notify 和 wait 用法
  • 飞驰在Mesos的涡轮引擎上
  • 后端_ThinkPHP5
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 力扣(LeetCode)21
  • 微信小程序--------语音识别(前端自己也能玩)
  • 我是如何设计 Upload 上传组件的
  • 新书推荐|Windows黑客编程技术详解
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • Spring第一个helloWorld
  • 交换综合实验一
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #Linux(权限管理)
  • #NOIP 2014#Day.2 T3 解方程
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (全注解开发)学习Spring-MVC的第三天
  • (十)T检验-第一部分
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)Mysql的优化设置
  • ..回顾17,展望18
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .net 中viewstate的原理和使用
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .net打印*三角形
  • ?.的用法
  • @Autowired注解的实现原理
  • @ConditionalOnProperty注解使用说明
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [17]JAVAEE-HTTP协议
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [AutoSar]BSW_Com02 PDU详解
  • [codeforces]Recover the String