云原生俱乐部-k8s知识点归纳(4)
其实由于平时会写笔记(网站上的StackEdit),所以完全可以从那里搬过来,不过就没有这么多话和解释性的文字了。这个k8s知识点归纳系列我写的还算快,争取能够尽快写完。
其中有些未能理解的也是借助AI来看,有些说法也纯粹是个人理解,大家可以帮忙指正。至于码字的话,也就是个人爱好了。之前的文章很大部分都是AI写的复制粘贴过来,格式也乱七八糟,但是内容都是精选的,后面会进行修改的。
至于文章的格式,没有很精美,因为排版的话需要花更多的时间了!这一个章节主要讲讲k8s中的service服务发现。
Kubernetes 的 Service 是一个抽象层,用于定义访问 Pod 的规则(如负载均衡、服务发现),本身不具备 Pod 的创建和管理能力。
Service服务发现
service是k8s中为抽象化后端pod提供的稳定访问入口的组件,主要是通过service资源来配置,通过标签来选择。主要有headless service、clusterIP、NodeIP、LoadBalancer、Ingress、GateWay API等六种类型。
首先要说的是pod本身虽然有IP,但是pod是动态的,并且只有IP而没有DNS名称。应用服务之间不可能通过变化的podIP来进行通信的。并且集群可能需要允许外部访问,因此service起着很重要的作用。
headless service
这种模式配合statefulSet使用非常合适,headless service并不提供clusterIP,也就是集群IP,但是提供DNS名称呀。
并且更好的是,headless service提供的DNS名称和statefulSet中的pod名称息息相关。准确来说,pod会生成固定地 DNS 名称:<pod-name>.<svc-name>.<ns>.svc.cluster.local
。
# headless-service.yaml
apiVersion: v1
kind: Service
metadata:name: nginx
spec:clusterIP: None # Headless Serviceselector:app: nginxports:- port: 80
---
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:serviceName: "nginx" # 关联 Headless Servicereplicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80
这和常规的service资源定义不一样,平时都是在service中通过标签选择pod,但这里通过statefulSet的yml文件中的spec.serverName来绑定headless service的。
这样能保证pod的DNS记录持久化,即使pod重建或者调度到其他节点,但是由于pod的名称不变,因此能够保证稳定的DNS记录。
不过也有缺点,就是访问这种DNS记录无法实现负载均衡。每个pod都是有着自己的DNS,意味着访问DNS,解析的是唯一确定的podIP。
除非访问headless service的DNS记录,虽然它并没有提供集群IP,但是提供了DNS记录,也就是<service-name>.<namespace>.svc.cluster.local。
这个DNS能够解析到所有的podIP,并返回所有后端pod的IP列表。
ClusterIP
既然上面说了headless service+statefulSet的DNS记录<service-name>.<namespace>.svc.cluster.local,那么肯定要说说clusterIP了。
其实这种类型的service也是使用以上命名格式的DNS,但这个不像上面的一样,每个pod都有DNS记录,而仅仅只有service有DNS记录。
还有就是提供了clusterIP,并且解析DNS记录的行为,上面说的是返回所有的podIP,但是clusterIP类型只会返回集群IP。
这种类型的service通过定义yml文件,在文件中通过标签选择默认命名空间(如果没有给service指定namespace的话)中的pod。(注意和headless service+statefulSet的区别)
Nodeport
这种方式会在所有的节点都暴露一个端口,让外部能够通过节点IP+端口访问集群内部的服务。
尽管有的节点没有运行对应的pod,但是无论 Pod 实际运行在哪个节点,访问任意节点的的 `NodePort`都会自动将流量路由到后端 Pod。
loadBalancer
LoadBalancer 是 Kubernetes 的一种 Service 类型,用于将服务暴露到集群外部(公有云环境),MetalLB 是一个开源工具,为 裸金属(Bare Metal)或本地集群 提供类似云平台的 LoadBalancer 功能,自动分配外部 IP 并实现负载均衡。
MetaILB包含两个核心组件,一个是controller(为loadBalancer类型的service分配IP并管理IP地址池),另一个是speaker,通过 ARP(Layer 2)或 BGP(Layer 3)协议宣告 IP 的可达性。
注意分配IP的其实是和master/worker主机同网段的IP,用于暴露集群内部服务(其实也只有同网段的才能访问)。但是这是Layer2才需要遵守的,如果使用BGP,那么任意网段的IP都可以。
Ingress
这是k8s中用于管理外部访问API的对象,通过定义规则将HTTP/HTTPS流量路由到集群的service。
注意的是虽然定义了路由规则,比如“/index”路由,但是也只是将该路由转发给后端的pod,让pod去处理该路由,如果pod无法处理该路由则会失败。因为ingress仅申明规则,不处理流量。
GateWay API
这一部分的内容倒是不多,不过却被单独放在了一个章节,我在这里提前介绍一下。
Gateway API 是 Kubernetes 中新一代的流量管理 API,旨在解决传统 Ingress 的局限性(如功能单一、扩展性差),提供更灵活、模块化的服务暴露方式。
Gateway API定义了三层资源模型,有gatewayclass、gateway、httproute/tcproute。
这一部分内容或许在学了CRD之后能够更清楚地理解,主要就是通过gatewayclass指定控制器,然后控制器会去监控对应的资源(这里是gateway)
gatewayclass
gatewayclass必须关联一个 控制器(Controller),该控制器负责实际实现gateway和路由规则的功能。例如安装 Nginx Gateway Controller 或 Istio Gateway Operator。
gateway
主要是声明网关监听的端口和协议等,并且需要将gateway关联到gatewayclass上。
因为gatewalclass使用的控制器会根据gateway创建实际的负载均衡器,这也就是deployment和pod的关系。控制器会根据gateway的定义创建对应的pod资源。
控制器本质:一个运行在集群中的 Pod 或 Operator,持续监听 Kubernetes API 资源(如gateway、route)。
httproute/tcproute
这并不创建pod资源,而是引用service定义的访问规则。route将定义的路由规则转发流量到service(由负载均衡器实现),service再将流量转发给后端pod。