2026/2/12 21:14:27
网站建设
项目流程
网站的空间是什么意思,移动互联网开发,淄博网站备案公司,足球世界排名一览表. Service概念引入k8s之部署Deployment章节我们介绍RS以及Deployment#xff0c;Deployment提供了pod的管理方式#xff0c;以及通过副本控制器RC保证集群中pod的数量保持为指定数量。同时Deployment还提供了相关升级、回滚、更新速度、灰度发布等功能。那么pod之间怎么进行访…. Service概念引入k8s之部署Deployment章节我们介绍RS以及DeploymentDeployment提供了pod的管理方式以及通过副本控制器RC保证集群中pod的数量保持为指定数量。同时Deployment还提供了相关升级、回滚、更新速度、灰度发布等功能。那么pod之间怎么进行访问呢在之前我们提过k8s之间的node网络是互通的同时它里面的pod网络也是互通的相关结构如下图所示暂时可以不需要理解里面的service看得懂通过curl ip即可NodeB (192.168.1.11)NodeA (192.168.1.10)✅直接访问 Pod IPcurl Unsupported markdown: link✅推荐通过 Servicecurl Unsupported markdown: link自动负载均衡❌通常无效curl Unsupported markdown: link✅显式设置curl Unsupported markdown: linkPodAIP: 10.244.1.5Port: 8080PodxIP: 10.244.1.xPort: xxPodBIP: 10.244.2.8Listens: 8080Service: podB-serviceClusterIP: 10.96.xx.xxPort: 80 → targetPort: 8080在集群中pod可以通过指定podB的ip以及端口进行访问。比如说应用A访问应用B我们可以配置应用A中请求地址便可以进行访问但是如果pod挂了呢通过上一章节的介绍我们知道pod挂了之后会重新启动一个新的pod但问题是ip也变了这样便没法访问了。这时候肯定会有人说Java boy不惧怕任何事情俺有nacosnacos可以进行自动负载均衡以及服务发现不需要配置ip只需要配置服务名。是的如果是使用nacos集群内部的访问便变得简单了其实nacos的作用跟今天所介绍的service很相似但问题又来了如果别人的应用没有注册到nacos上面去呢万一我是一个phper呢又或者说我集群内部的某个pod需要对外提供服务呢这时候便需要k8s中的Service来帮忙了。2. 什么是ServiceKubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法[注]。我们可以这样理解Service 是 Kubernetes 中定义的一组 Pod 的稳定网络入口抽象用于实现服务发现与负载均衡。 在我们部署应用的时候为了服务的高可用性一般来说我们会将应用X部署在多个pod上例如podApodBpodC他们各自有自己的ip地址。k8s的service将这三个pod给包装起来了包装为了一个服务service,其他的应用需要访问应用X的时候不再需要通过通过ip地址来访问而是直接通过服务名来访问。例如这个服务名叫做my-svc.my-ns.svc.cluster.local那么其他应用直接通过http://my-svc.my-ns.svc.cluster.local便可以访问应用X了。这是因为当你请求这个域名的时候k8会为你自动转发到对应的pod上去。通过上面可以解释我们可以知道k8s的service主要有如下作用解耦服务消费者与提供者客户端只需访问 Service 名称无需知道后端 Pod IPPod 是临时的IP 会变自动负载均衡将流量分发到所有健康的后端 Pod提供稳定的网络端点即使 Pod 重建、扩缩容Service 的 ClusterIP 和 DNS 名称保持不变这个之后解释。3. Service的分类根据Service的作用不同可以分为如下的4种Service。3.1 ClusterIPClusterIP的作用主要是在集群内部暴露服务仅集群内可访问。举个列子我用python写了一个算法服务这个算法服务提供了一个http请求接口然后我java应用想要调用这个算法服务我便可以将这个算法服务包装为一个ClusterIP类型的Service专门提供给java应用调用。那么他的原理是怎样的呢如下的代码便是构建一个ClusterIP类型的serviceapiVersion: v1kind: Servicemetadata:name: backend-svcspec:type: ClusterIPselector:app: backend # 匹配的podports:- port: 80targetPort: 8080其中port80代表这个service对外暴露的端口也就是另一个pod需要访问backend这个后端pod服务需要通过http://backend-svc:80来进行访问。targetPort8080代表service会将流量转移到后端pod的哪个端口。ClusterIP 类型的 Service 会被分配一个集群内部的专有且唯一的虚拟 IP 地址由 Kubernetes 的控制平面从 --service-cluster-ip-range 指定的 CIDR 范围中分配。这个 IP 不是真实网卡上的 IP而是一个“虚拟 IPClusterIP”。它只在 Kubernetes 集群内部可达外部无法直接访问。然后k8s内置的dns服务会为该service创建一个dns记录将例子中的backend-svc解析为这个虚拟ip。这样集群中的pod都会在访问backend-svc这个域名的时候就会自动解析到这个ClusterIP中。同时k8s的控制平面也会创建一个同名的Endpoints 对象记录对应Service当前实际可用的后端pod IP地址和端口列表。image在前面的知识中我们知道kube-proxy运行在每一个Node节点中监听Service和Endpoints的变化。当他发现有一个clusterIP service变化的时候就会用小本本记录下来然后生成相关的ip映射规则建立cluster IP和pod IP的映射规则。这样当节点中的某个pod访问Service的时候节点中的Kube-Proxy就可以根据ip映射规则将流量转发到对应的服务上去。当然一个cluster IP会对应多个pod IP具体访问哪一个就根据kube-proxy设置的算法来进行执行。PlantUML Diagram3.2 NodePort在每个节点的 IP 上开放一个固定端口外部可通过 NodeIP:NodePort 访问服务NodePort 范围默认为 30000-32767。什么意思呢在Cluster IP类型的service中集群内部访问当然没问题但是如果是集群外部呢集群外部如何访问集群内部的服务呢这时候我们就需要创建一个NodePort类型的service了。当创建一个 type: NodePort 的 Service 时Kubernetes 实际上做了两件事创建一个ClusterIP的Service比如 ClusterIP是10.96.123.45在每个节点上监听一个端口比如 31234。当外部流量通过 NodeIP:31234 进入节点时kube-proxy 会将该流量转发到 Service 的 ClusterIP然后再由 ClusterIP 的规则转发到后端 Pod。外部请求 → NodeIP:NodePort → (kube-proxy 转发) → ClusterIP → 后端 Pod这个时候我们再看k8s官网的这句话应该就能理解了吧。通过每个节点上的 IP 和静态端口NodePort公开 Service。 为了让 Service 可通过节点端口访问Kubernetes 会为 Service 配置集群 IP 地址 相当于你请求了 type: ClusterIP 的 Service。3.3 LoadBalancer前面的NodePort类型的service解决了集群外部访问集群内部服务的问题那么又有一个问题来了我要是公网想访问集群内部的服务呢在k8s集群中node的节点ip都是分配的内网ip我们肯定是无法在公网上使用node ip来访问对应的服务。这时候就需要借助LoadBalancer Service了。LoadBalancer 是 k8s中最“面向外部”的 Service 类型之一它建立在 NodePort 和 ClusterIP 之上专为云环境设计用于自动创建一个外部负载均衡器将流量从互联网直接导入你的服务。也就是说当创建一个LoadBalancer的service时Kubernetes 会自动分配一个 ClusterIP内部使用自动分配一个 NodePort每个节点开放该端口云控制器管理器cloud-controller-manager 会检测到这个 Service自动向云平台 API 请求创建一个外部负载均衡器。该负载均衡器会被配置为前端分配一个公网 IP或 DNS 名称后端将流量转发到所有节点的 NodePortPlantUML Diagram3.4 ExternalName前面介绍的几种Service都是将自己暴露出去将pod的服务以更加便捷形式提供给外界使用。那么反过来呢如何让外界服务更加便捷给内部使用呢那么便是ExternalName Service提供的功能了。ExternalName Service 会在集群内部创建一个 DNS 别名CNAME指向你指定的外部服务地址如 api.example.com让 Pod 可以像访问内部服务一样访问外部服务。本质上来说就是给外部服务取了一个DNS层