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

K8S服务发现原理及开发框架的配合

1. K8S 服务发现技术层面底层原理

Kubernetes 的服务发现完全抛弃了传统服务注册中心的模式(如 Eureka, Consul),而是基于其内部的两个核心组件:Service 和 DNS

底层工作流程如下:

  1. 标签选择器 (Label Selector) 是基础:当用户创建一个 Deployment 时,会为其 Pod 模板指定一个标签(例如 app: my-backend)。Deployment 会确保运行的 Pod 都带有这个标签。
  2. Service 创建虚拟 IP (ClusterIP):用户创建一个 Service 资源,并定义一个 selector,使其指向用户在上一步中定义的标签(selector: {app: my-backend})。Kubernetes 会立即为这个 Service 分配一个稳定不变的虚拟 IP,我们称之为 ClusterIP。这个 IP 只在集群内部有效。
  3. Endpoints/EndpointSlices 的自动更新:Kubernetes 控制平面中有一个 Endpoint Controller。它会持续监控带有特定标签的 Pod 的创建、销毁和健康状态。一旦发现 Pod 列表发生变化(比如一个新 Pod 启动并就绪),它就会更新一个与 Service 同名的 Endpoints 或 EndpointSlice 对象,其中包含了所有健康 Pod 的实际 IP 地址和端口列表(例如 [10.1.1.2:8080, 10.1.2.5:8080])。
  4. kube-proxy 实现流量转发
    • 每个 Node 节点上都运行着一个 kube-proxy 进程。
    • kube-proxy 持续 watch Service 和 Endpoints/EndpointSlice 对象的变化。
    • 当它拿到最新的 ClusterIP -> [PodIP1, PodIP2, ...] 的映射关系后,它会在每个 Node 的内核中创建网络规则(通常使用 IPVS 或 iptables)。
    • 这些规则的作用是:“任何发送到 ClusterIP:Port 的流量,都将被拦截,并以负载均衡的方式(如轮询)转发到后端某一个真实的 PodIP:TargetPort”。
  5. CoreDNS 提供域名解析
    • 集群内部署了一套 DNS 服务(通常是 CoreDNS)。
    • Kubernetes 会自动为每个 Service 创建一条 DNS A 记录,格式为:<service-name>.<namespace-name>.svc.cluster.local
    • 当一个 Pod(客户端)想要访问另一个服务时,它不需要知道 ClusterIP,而是直接使用这个 DNS 名称(例如 http://my-backend.default)。
    • Pod 内的 DNS 解析请求会被发送到 CoreDNS,CoreDNS 解析该域名,并返回 Service 的 ClusterIP。
    • 客户端 Pod 拿到 ClusterIP 后,向其发起请求。请求到达 Node 内核时,被 kube-proxy 设置的规则捕获,并转发给后端某个健康的真实 Pod。

K8S 服务发现的本质是 DNS 解析 + VIP (虚拟IP) 路由。它将服务发现的责任从客户端(如 Spring Cloud 的 Ribbon/LoadBalancer)下沉到了 Kubernetes 平台层,对应用完全透明。

2. K8S 自动扩缩容 (HPA) 原理

Kubernetes 的自动扩缩容主要由 Horizontal Pod Autoscaler (HPA) 实现。

工作原理如下:

  1. 指标收集 (Metrics Aggregation)
    • 集群中必须部署 Metrics Server。它是一个轻量级的组件,定期从每个节点的 kubelet 收集 Pod 的 CPU 和内存等基础资源使用情况。
    • kubelet 本身通过 CRI (Container Runtime Interface) 从 cgroup 获取容器的实际资源用量。
    • Metrics Server 将这些指标聚合起来,并通过 Kubernetes Aggregation Layer 以标准的 metrics.k8s.io API 形式暴露出来。
  2. HPA 控制器循环 (Controller Loop)
    • HPA Controller 是 kube-controller-manager 的一部分。
    • 它定期(默认每 15 秒)通过 Metrics API 查询它所管理的 Deployment (或其他可伸缩资源) 的所有 Pod 的指标。
  3. 期望副本数计算
    • HPA Controller 获取到所有 Pod 的当前指标值(如 current_cpu_utilization)后,会与用户在 HPA 中定义的目标值(desired_cpu_utilization)进行比较。
    • 计算公式为:desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
    • 示例:用户设置目标 CPU 为 50%,当前有 3 个副本,测得的平均 CPU 使用率为 75%。那么期望副本数 = ceil[3 * (75 / 50)] = ceil[4.5] = 5
  4. 执行伸缩
    • 计算出期望副本数后,HPA Controller 并不会直接操作 Pod,而是去更新其管理的 Deployment 对象的 spec.replicas 字段
    • Deployment 的控制器(Deployment Controller)检测到 spec.replicas 发生变化,就会执行其本职工作——通过增加或删除 Pod 来使实际副本数与期望值匹配。

注意: HPA 也支持基于内存或自定义指标(如每秒请求数 QPS)进行扩缩容,这需要更复杂的监控设置(如 Prometheus Adapter)。

3. K8S 实现熔断和限流

Kubernetes 本身不直接提供应用级的熔断和限流功能。这些是 L7 的流量治理能力。在 Kubernetes 生态中,主要通过以下两种方式实现:

  1. 服务网格 (Service Mesh) - 推荐方式:
    • 代表技术: Istio, Linkerd
    • 原理: Service Mesh 通过在每个 Pod 中自动注入一个轻量级网络代理(Sidecar Proxy,如 Envoy)来接管所有进出 Pod 的流量。
    • 实现熔断 (Circuit Breaking): 用户可以在 Istio 的 DestinationRule 中配置熔断策略,例如“连续 5 次 5xx 错误,则将该 Pod 实例从负载均衡池中移除 1 分钟”。这些策略会被动态下发到所有客户端的 Envoy Sidecar 中,由 Envoy 来执行熔断逻辑。
    • 实现限流 (Rate Limiting): 可以在 Istio 的 VirtualService 或专门的策略对象中配置全局或局部的速率限制,例如“对某个服务的访问速率不能超过 100 QPS”。
  2. API 网关 (API Gateway):
    • 代表技术: Ambassador, Kong, APISIX 等,它们通常作为 Ingress Controller 运行。
    • 原理: 所有从集群外部进入的流量都会先经过 API 网关。
    • 实现: 用户可以在网关层针对特定路由(API)配置限流和熔断策略。这主要用于管理南北向(Ingress)流量,对于集群内部的东西向流量管理能力较弱。

4. 与 Java Spring 全家桶的配合策略

当把 Spring Cloud 应用迁移到 Kubernetes 时,需要调整思路,将平台能力与框架能力结合,避免冗余。

功能

Spring Cloud 传统方式

Kubernetes + Spring 推荐方式

配合说明

服务注册发现

Eureka Server + @EnableEurekaClient

完全禁用 Eureka

使用 K8S 的 DNS 和 Service 进行服务发现。Spring 应用直接通过 http://service-name 访问,无需任何客户端发现组件。

客户端负载均衡

Ribbon / Spring Cloud LoadBalancer

禁用或简化

负载均衡由 K8S 的 kube-proxy (IPVS/iptables) 在内核层完成。Spring Cloud LoadBalancer 仍可保留,但它只会得到一个 ClusterIP,实际的 Pod 级别负载均衡已由 K8S 处理。

API 网关

Spring Cloud Gateway / Zuul

推荐使用 Ingress Controller (如 Nginx, Traefik) 或 API Gateway (如 Kong)

将网关能力下沉到基础设施层,更高效、更通用。Spring Cloud Gateway 仍然可以用,但通常部署为集群内的一个普通服务。

配置管理

Spring Cloud Config Server

使用 K8S 的 ConfigMap 和 Secret

将配置信息作为 ConfigMap/Secret 挂载到 Pod 中。可以使用 Spring Boot's Kubernetes integration (spring-cloud-starter-kubernetes-client-config) 自动读取这些配置,实现动态刷新。

熔断/降级

Hystrix / Resilience4j

方案一 (推荐): Service Mesh (Istio)

方案二: 应用内实现 (Resilience4j)

方案一:将熔断下沉到 Service Mesh (Envoy),对应用透明,支持多语言,集中管理。方案二:如果不想引入 Service Mesh,继续在 Spring 应用中使用 @CircuitBreaker (Resilience4j) 注解。这提供了更精细的应用内控制(如 Fallback 方法),但配置分散。两者可以共存,形成多层防护。

限流

Sentinel, Resilience4j

方案一 (推荐): Service Mesh / Ingress

方案二: 应用内实现

与熔断类似。方案一:在入口 (Ingress) 或服务间 (Mesh) 进行限流,保护整个服务。方案二:在应用内对某个具体方法或资源进行限流。

最佳实践是: 将网络层和服务治理的通用能力(服务发现、负载均衡、路由、熔断、限流)下沉到 Kubernetes 和服务网格,让 Java 应用更专注于业务逻辑。应用内只保留那些需要业务逻辑感知的、非常精细的熔断降级策略。

5. 其他语言微服务框架与 K8S 的配合

  • Go:
    • 框架: Go-Kit, Go-Micro, gRPC。
    • 配合: Go 语言开发的微服务天生轻量,非常适合 K8S。它们同样不再需要自己的服务发现机制,直接通过 K8S DNS 访问其他服务。熔断限流等可以通过引入服务网格(如 Istio)来解决,或者使用 Go 语言的库(如 gobreaker, ratelimit)在代码中实现。
  • Python:
    • 框架: Flask, Django, FastAPI。
    • 配合: 与 Go 类似。通过 Gunicorn/uWSGI 部署后,打包成容器镜像。服务发现依赖 K8S DNS。东西向流量治理依赖服务网格,南北向依赖 Ingress。
  • Node.js:
    • 框架: Express, NestJS。
    • 配合: 模式完全一致。利用 K8S 进行部署、扩缩容和服务发现。通过 Nginx Ingress Controller 处理入口流量和 TLS。服务间通信通过 K8S Service 名称。
http://www.xdnf.cn/news/1234135.html

相关文章:

  • 利用AI渲染技术提升元宇宙用户体验的技术难点有哪些?
  • 语义分割--deeplabV3+
  • Navicat连接远程服务器上的mysql
  • ubuntu24.04安装selenium、chrome、chromedriver
  • elk快速部署、集成、调优
  • [Oracle] TO_DATE()函数
  • 二叉树算法之【前序遍历】
  • GitOps:云原生时代的革命性基础设施管理范式
  • 每日五个pyecharts可视化图表-bars(2)
  • Python Seaborn【数据可视化库】 全面讲解
  • 基于图像识别与分类的中国蛇类识别系统
  • k8s日志收集
  • zookeeper常见命令和常见应用
  • SpringBoot学习总结
  • python学智能算法(三十一)|SVM-Slater条件理解
  • Vim编辑器详解:从入门到高效使用
  • 【Unity】背包系统 + 物品管理窗口 (上)
  • 【一天一个知识点】RAG遇见推理
  • 谷歌开源Agent框架ADK快速入门
  • 前端应用权限设计面面观
  • 防御综合实验
  • 【0基础PS】PS工具详解--图案图章工具
  • 安灯系统(Andon System)
  • 【昇腾推理PaddleOCR】生产级部署方式
  • SpringBoot与TurboGears2跨栈、整合AI服务、智能客服路由系统整合实战
  • FreeRTOS源码分析二:task启动(RISCV架构)
  • 单位长度上的RC参数
  • Codeforces Round 1039 (Div. 2) A-C
  • sifu mod制作 相关经验
  • LangGraph认知篇-Command函数