Kubernetes 架构与 API
集群组成
Kubernetes 集群由控制面和工作节点组成。控制面管理全局期望状态,工作节点运行 Pod。
| 组件 | 主要职责 | 生产关注点 |
|---|---|---|
| kube-apiserver | 暴露 REST API,认证、鉴权、准入、校验和对象读写入口 | 多副本、负载均衡、证书、审计、延迟与限流 |
| etcd | 保存 Kubernetes API 状态的强一致键值存储 | 奇数成员、低延迟磁盘、快照、压缩、碎片整理和加密 |
| kube-scheduler | 为未绑定 Pod 过滤与评分节点,写入绑定结果 | 调度延迟、Pending Pod、扩展插件和高可用 |
| kube-controller-manager | 运行 Deployment、Node、Job 等内置控制器 | Leader Election、工作队列、API 限流 |
| cloud-controller-manager | 对接云节点、路由、负载均衡器等 | 云权限、配额、版本兼容;本地集群可能没有 |
| kubelet | 在单个节点实现 PodSpec,管理探针、挂载和容器生命周期 | 节点资源、证书、CRI、重启和驱逐 |
| 容器运行时 | 通过 CRI 拉取镜像、创建 Sandbox 与容器 | 通常为 containerd/CRI-O;Kubernetes 不直接使用 Docker Engine |
| kube-proxy | 实现 Service 数据面规则 | iptables、IPVS 或 nftables 模式;也可能被 eBPF 数据面替代 |
| CNI 插件 | 实现 Pod 网络、IPAM,部分实现 NetworkPolicy | 地址容量、MTU、路由、策略和可观测性 |
| CSI 插件 | 动态制备、挂载、扩容、快照存储 | 拓扑、配额、故障域和数据保护 |
Kubernetes 的可移植性来自标准 API 及 CRI、CNI、CSI 等接口,但“同一 YAML 在所有集群行为完全相同”并不成立。LoadBalancer、默认 StorageClass、Ingress/Gateway Controller、网络策略和云身份都依赖具体环境。
声明式控制循环
控制器反复执行“观察 → 比较 → 行动”:
用户/自动化 → API Server → etcd
↑ ↓
└── 控制器观察实际状态
↓
创建/更新对象
↓
Scheduler → kubelet → 运行时/CNI/CSI关键概念:
- 期望状态:对象
spec描述你想要什么。 - 观察状态:对象
status描述控制器目前看到什么。 - 收敛:控制器不断缩小两者差异,通常是最终一致而非瞬时完成。
- 幂等:重复提交相同期望状态不应产生额外副作用。
- Level-triggered:控制器根据当前状态做决定,而非仅依赖某个事件恰好到达。
因此,API 请求成功通常只表示对象已被接受,不等于应用已经 Ready。发布系统还必须等待条件:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/web --timeout=5m
kubectl wait --for=condition=available deployment/web --timeout=5mAPI 请求链路
一个典型写请求经过:
- 客户端从 kubeconfig 获取 API 地址、身份和 TLS 参数。
- API Server 完成 TLS,并进行认证,得到用户与组。
- 鉴权器判断该身份能否对资源执行 verb。
- Mutating Admission 修改或补全请求。
- 对象默认值填充、字段和版本校验。
- Validating Admission 接受或拒绝请求。
- API Server 持久化到 etcd,并返回对象。
- Watch 客户端和控制器收到变化,异步处理。
只读 List/Get 也经过认证和鉴权;部分准入插件只处理写请求。Webhook 失效策略、超时和网络故障可能阻塞集群写入,因此准入组件本身必须高可用且有明确 failurePolicy。
API Group、Version 与 Resource
REST 路径示例:
/api/v1/namespaces/demo/pods/web
/apis/apps/v1/namespaces/demo/deployments/web- Core Group 使用
/api/v1,包括 Pod、Service、ConfigMap、Secret。 - 命名 API Group 使用
/apis/<group>/<version>,例如apps/v1。 kind是对象类型,REST Resource 通常是小写复数。- 一个资源可同时提供多个 API 版本;存储版本由 API Server 转换。
发现当前集群实际支持的 API:
kubectl api-versions
kubectl api-resources --sort-by=name
kubectl explain deployment
kubectl explain deployment.spec.strategy --recursive
kubectl get --raw /apis/apps/v1 | head不要从旧博客复制已移除版本,如 extensions/v1beta1 Ingress。以目标集群的发现结果和 v1.36 API Reference 为准。
Namespaced 与 Cluster-scoped
kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=falseDeployment、Pod、Service、ConfigMap 等属于命名空间;Node、Namespace、PersistentVolume、StorageClass、ClusterRole 等是集群级资源。命名空间是管理与授权边界,但不是天然的强安全边界;跨租户隔离还需要 RBAC、NetworkPolicy、Pod Security、资源配额和节点隔离。
元数据与身份
每个对象都有:
name:命名空间或集群范围内的名字。namespace:命名空间资源的作用域。uid:对象每次创建时生成的不可复用身份。resourceVersion:用于并发控制和 Watch,不是可排序业务版本。generation:期望状态spec变化时通常递增。labels/annotations:选择与非识别性元数据。ownerReferences/finalizers:垃圾回收和删除前清理机制。managedFields:Server-Side Apply 的字段所有权信息。
控制器的 status.observedGeneration 若追上 metadata.generation,才说明它至少观察到了最新 spec;仍需结合 Ready/Available 条件判断成功。
List、Watch 与缓存
控制器通常先 List 建立本地缓存,再从某个 resourceVersion Watch 增量变化。Watch 可能断开或因版本过旧收到 410 Gone,客户端必须重新 List。写控制器时应使用官方 client-go informer/workqueue 模式,不要轮询整个集群。
kubectl get pods --watch
kubectl get pods --watch-only --output-watch-events大集群查询要使用标签/字段选择器减少返回量;kubectl get pods -A -o yaml 会给 API Server、网络和终端带来不必要负担。
扩展 Kubernetes
| 机制 | 用途 | 风险 |
|---|---|---|
| CRD | 添加自定义 API 资源 | Schema、转换、版本兼容和删除保护 |
| Operator/Controller | 为自定义资源实现控制循环 | 权限过大、热循环、幂等与升级 |
| Admission Webhook / Policy | 校验或修改写请求 | 延迟、可用性和错误拒绝全局写入 |
| API Aggregation | 聚合独立 API Server | 证书、发现与可用性更复杂 |
| Scheduler Plugin | 自定义调度行为 | 影响集群放置结果和升级兼容 |
扩展前先问:是否能用内置对象、CEL 准入策略或现有成熟控制器解决?自定义 API 一旦被业务依赖,就需要像公共 API 一样维护版本和迁移。
高可用边界
控制面多副本不自动等于业务高可用:
- API Server 可水平扩展;controller-manager 和 scheduler 通常多副本 Leader Election。
- etcd 通常部署 3 或 5 个成员;跨高延迟地域扩展会降低写入性能和稳定性。
- 工作负载要跨节点和故障域放置,配置 PDB、拓扑分布与足够容量。
- DNS、CNI、CSI、Ingress/Gateway、证书和镜像仓库也是关键依赖。
- 数据面在控制面短暂不可用时可能继续转发已有流量,但无法可靠调度、扩缩容或更新。
官方组件说明见 Kubernetes Components。
继续阅读
- 命令
- 故障排查
- 故障排查