2. PaaS核心架构:容器编排原理、控制平面与数据平面、Pod与Service模型、Ingress与Gateway
聊到PaaS平台,最核心的其实就是容器编排。说白了,Kubernetes就是目前的事实标准。我最早接触K8s的时候,也被它那一堆概念搞得头大。但后来我发现,只要抓住几个关键模型,整个架构就清晰了。
2.1 容器编排原理:调度器到底在忙什么?
容器编排,本质上就是解决“把容器放在哪台机器上跑”的问题。但实际远比这个复杂。
调度器的工作流程,我习惯把它拆成三步:
- 过滤:先把不满足条件的节点剔除。比如内存不够、CPU不足、端口冲突。
- 打分:对剩下的节点进行评分。资源利用率、亲和性、反亲和性都会影响分数。
- 绑定:选最高分的节点,把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架构就掌握了一半。