2. PaaS核心架构:容器编排原理、控制平面与数据平面、Pod与Service模型、Ingress与Gateway

聊到PaaS平台,最核心的其实就是容器编排。说白了,Kubernetes就是目前的事实标准。我最早接触K8s的时候,也被它那一堆概念搞得头大。但后来我发现,只要抓住几个关键模型,整个架构就清晰了。

2.1 容器编排原理:调度器到底在忙什么?

容器编排,本质上就是解决“把容器放在哪台机器上跑”的问题。但实际远比这个复杂。

调度器的工作流程,我习惯把它拆成三步:

  1. 过滤:先把不满足条件的节点剔除。比如内存不够、CPU不足、端口冲突。
  2. 打分:对剩下的节点进行评分。资源利用率、亲和性、反亲和性都会影响分数。
  3. 绑定:选最高分的节点,把Pod绑定上去。

核心要点:调度不是一次性的。Pod运行后,如果节点挂了,控制器会重新调度。这就是声明式API的魅力。

我记得有一次线上集群,调度器突然变慢。排查后发现,有个团队创建了上千个带有nodeSelector的Pod,而且这些标签在集群里根本不存在。调度器每次都要遍历所有节点,发现都不匹配,然后重试。嗯,这就是典型的“调度风暴”。

2.2 控制平面与数据平面:大脑和手脚

Kubernetes的架构,说白了就是两个平面:

  • 控制平面:负责决策。包括API Server、Scheduler、Controller Manager、etcd。
  • 数据平面:负责执行。就是各个节点上的kubelet、kube-proxy、容器运行时。

你想想看,控制平面就像公司的管理层,只做决策不下场干活。数据平面就是一线员工,接到指令就执行。

组件 所属平面 核心职责
API Server 控制平面 所有请求的入口,认证授权
etcd 控制平面 集群状态存储
Scheduler 控制平面 Pod调度决策
Controller Manager 控制平面 维护期望状态
kubelet 数据平面 管理节点上的Pod
kube-proxy 数据平面 网络代理与负载均衡

避坑指南:我曾经遇到一个案例,etcd的磁盘IO被打满,导致整个控制平面响应超时。所有kubelet都以为控制平面挂了,开始进入“节点自愈”模式,结果集群直接脑裂。所以,etcd的磁盘性能一定要用SSD,并且做好监控。

2.3 Pod与Service模型:最小单元与稳定入口

Pod是K8s里最小的调度单元。一个Pod可以包含一个或多个容器。为什么这么设计?

我个人的理解是:有些进程需要紧密协作,共享网络栈和存储卷。比如一个日志采集容器和一个业务容器,放在同一个Pod里,它们可以通过localhost通信,效率最高。

但Pod的IP是动态的。Pod挂了重建,IP就变了。这时候就需要Service出场了。

Service提供了一个稳定的虚拟IP和DNS名称。不管后端Pod怎么变,客户端只要访问Service就行。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

这段配置的意思是:所有带有app: my-app标签的Pod,都会收到发往80端口的流量。kube-proxy会在每个节点上维护iptables或IPVS规则,实现流量转发。

小技巧:如果你对性能有要求,建议把kube-proxy的模式从iptables改成IPVS。IPVS使用哈希表,在大规模服务下性能更稳定。我在一个5000+节点的集群里验证过,切换后CPU开销降低了约30%。

2.4 Ingress与Gateway:南北流量的入口

Service解决了集群内部的流量问题。但外部流量怎么进来?

早期方案是NodePort或LoadBalancer。但NodePort端口有限,LoadBalancer成本高。于是有了Ingress。

Ingress说白了就是一个七层反向代理。它根据域名和路径,把请求转发到不同的Service。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

但Ingress有个问题:它只定义了规则,具体实现要靠Ingress Controller。比如Nginx Ingress Controller、Traefik、HAProxy等。

后来社区推出了Gateway API。它比Ingress更灵活,支持更细粒度的流量管理,比如流量拆分、Header修改、重试策略等。

我的建议:新项目直接上Gateway API。虽然Ingress目前还是主流,但Gateway API是未来方向。我在一个金融客户的项目里用了Gateway API,配合服务网格,实现了灰度发布和故障注入,效果非常好。

为什么会推荐Gateway API?因为它把流量管理分成了三个角色:

  • 基础设施提供者:定义GatewayClass,比如“使用Nginx还是Envoy”
  • 集群管理员:创建Gateway实例,绑定证书、配置监听端口
  • 应用开发者:创建HTTPRoute,定义路由规则

这种分层设计,说白了就是职责分离。各管各的,互不干扰。

避坑指南:我曾经遇到一个Ingress配置问题。团队在同一个Ingress里配置了多个域名,结果某个域名的TLS证书过期,导致其他域名的请求也被拒绝。这是因为Nginx Ingress Controller在处理多域名时,如果某个证书无效,会直接返回错误。解决方案是每个域名单独创建Ingress资源,或者使用Gateway API的独立监听器。

好了,这一章的核心内容就是这些。记住:控制平面管决策,数据平面管执行。Pod是原子单元,Service是稳定入口。Ingress和Gateway是外部流量的守门员。把这些模型理解透,PaaS架构就掌握了一半。