当你第一次面对一个 Kubernetes 集群时,可能会被一堆组件名称淹没——API Server、etcd、Scheduler、Controller Manager、kubelet、kube-proxy……它们各自做什么?为什么需要这么多组件?Pod 和容器有什么区别?Namespace 到底隔离了什么?
理解这些核心概念是使用 Kubernetes 的前提。本章从架构总览出发,逐一拆解控制面和工作节点的组件职责,再深入 Pod、Node、Namespace、Label 与 Selector 的设计哲学,最后揭示 Kubernetes 的核心编程范式——声明式 API 与控制器模式。
一、Kubernetes 架构总览
Kubernetes 集群由两类节点组成:**控制面(Control Plane)**负责全局决策,**工作节点(Worker Node)**负责运行实际负载。
这个架构的核心思想是中心化决策 + 分布式执行。所有集群状态存储在 etcd 中,所有操作通过 API Server 进行,调度和控制器在控制面运行,而实际的容器创建和管理由每个节点上的 kubelet 独立完成。
1.1 控制面组件
| 组件 | 职责 | 关键特性 |
|---|---|---|
| kube-apiserver | 集群唯一入口,所有组件通过它交互 | REST API、认证/鉴权/准入控制、Watch 机制 |
| etcd | 分布式键值存储,保存所有集群状态 | 强一致性(Raft 协议)、Watch 支持、持久化 |
| kube-scheduler | 为未调度 Pod 选择目标 Node | 预选/优选算法、亲和性/反亲和性、优先级/抢占 |
| kube-controller-manager | 运行多个控制器,驱动集群向期望状态收敛 | Deployment/ReplicaSet/Node/Job/Endpoint 等控制器 |
API Server 是集群的”大脑”,etcd 是”记忆”,Scheduler 是”调度员”,Controller Manager 是”执行监督员”。所有组件只与 API Server 通信,不直接访问 etcd——这保证了 etcd 的访问路径唯一,便于审计和安全控制。
1.2 工作节点组件
| 组件 | 职责 | 关键特性 |
|---|---|---|
| kubelet | 节点代理,管理 Pod 生命周期 | Pod 创建/销毁、健康检查、资源上报、CRI 调用 |
| kube-proxy | 网络代理,实现 Service 负载均衡 | iptables/IPVS 模式、Service VIP 代理 |
| 容器运行时 | 运行容器 | containerd(默认)、CRI-O、Docker(已弃用) |
kubelet 是节点上最关键的组件。它通过 Watch 机制监听 API Server 上分配到本节点的 Pod,然后调用容器运行时(通过 CRI 接口)创建容器、配置网络(通过 CNI)、挂载存储(通过 CSI)。
二、Pod:Kubernetes 的最小调度单元
Pod 是 Kubernetes 中最小的可调度单元。一个 Pod 包含一个或多个紧密耦合的容器,它们共享网络和存储,始终运行在同一个 Node 上。
2.1 为什么不是容器?
直接以容器为调度单元会面临几个问题:
- 容器之间需要共享资源:很多应用由主进程和辅助进程组成(如 Nginx + log sidecar),它们需要共享网络端口空间和文件系统
- 容器生命周期管理复杂:容器是一个相对底层的概念,缺乏”一组容器共同协作”的抽象
- 调度粒度不合理:如果以容器为调度单元,同一应用的多个容器可能被调度到不同节点,网络延迟和通信成本增加
Pod 解决了这些问题。Pod 内的所有容器共享同一个 Network Namespace(同一个 IP 和端口空间)、同一个 Volume,可以通过 localhost 直接通信。
每个 Pod 都有一个 Pause 容器(也叫 infra 容器)。它是最先启动的容器,负责持有 Pod 的 Network Namespace。其他容器通过共享 Pause 容器的 Namespace 加入 Pod 网络。Pause 容器几乎不做任何事情——它的存在只是为了”占住”Namespace,确保 Pod 中任何容器退出都不会破坏网络配置。
2.2 Pod 的关键属性
apiVersion: v1kind: Podmetadata: name: my-app namespace: production labels: app: web tier: frontendspec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi restartPolicy: Always nodeSelector: disktype: ssd| 属性 | 说明 |
|---|---|
metadata.labels | 键值对标签,用于筛选和分组 |
spec.containers | Pod 内的容器列表 |
spec.resources.requests | 调度时的最低资源需求 |
spec.resources.limits | 容器可使用的最大资源 |
spec.restartPolicy | 容器失败时的重启策略(Always/OnFailure/Never) |
spec.nodeSelector | 简单的节点选择约束 |
2.3 Pod 的生命周期
Pod 的状态(Phase)有以下几种:
| Phase | 说明 |
|---|---|
| Pending | Pod 已创建,但容器尚未启动(正在调度或拉取镜像) |
| Running | Pod 已绑定到节点,所有容器已创建且至少一个正在运行 |
| Succeeded | Pod 中所有容器成功退出,不会重启 |
| Failed | Pod 中至少一个容器失败退出 |
| Unknown | 无法获取 Pod 状态(通常是与节点通信失败) |
Pod 还有更细粒度的Conditions,用来描述 Pod 处于当前 Phase 的具体原因:
| Condition | 说明 |
|---|---|
| PodScheduled | Pod 已被调度到某个 Node |
| ContainersReady | Pod 中所有容器都已就绪 |
| Initialized | 所有 Init 容器已成功完成 |
| Ready | Pod 可以接收请求(Service 可将其加入 Endpoints) |
三、Node:工作节点与资源管理
Node 是 Kubernetes 的工作节点,每个 Node 运行 kubelet、kube-proxy 和容器运行时。
3.1 Node 的状态信息
apiVersion: v1kind: Nodemetadata: name: node-1 labels: kubernetes.io/os: linux node.kubernetes.io/instance-type: n1-standard-4status: capacity: # 节点总资源 cpu: "4" memory: "15Gi" pods: "110" allocatable: # 可分配资源(扣除系统预留) cpu: "3.8" memory: "14.5Gi" pods: "110" conditions: - type: Ready status: "True" # 节点健康 - type: DiskPressure status: "False" # 磁盘无压力 - type: MemoryPressure status: "False" - type: PIDPressure status: "False" - type: NetworkUnavailable status: "False"capacity 和 allocatable 的区别很重要:capacity 是节点的硬件总资源,allocatable 是扣除 kubelet 系统预留和 eviction 预留后可供 Pod 使用的资源。调度器使用 allocatable 进行决策。
3.2 Node 的心跳与驱逐
kubelet 定期向 API Server 上报 Node 状态。如果 kubelet 停止上报,节点会被标记为 NotReady。超过 pod-eviction-timeout(默认 5 分钟)后,Controller Manager 会驱逐该节点上的所有 Pod。
驱逐策略基于资源压力——当节点磁盘或内存不足时,kubelet 会主动终止优先级最低的 Pod,保护节点稳定运行。
四、Namespace:多租户隔离
Kubernetes Namespace 提供逻辑隔离,不是物理隔离。它将集群划分为多个虚拟集群,每个 Namespace 内的资源名称唯一,但跨 Namespace 可以重复。
# 查看所有 Namespacekubectl get namespaces
# 创建 Namespacekubectl create namespace production
# 在指定 Namespace 中操作kubectl get pods -n production| 默认 Namespace | 用途 |
|---|---|
| default | 未指定 Namespace 时的默认空间 |
| kube-system | Kubernetes 系统组件 |
| kube-public | 公开可读的集群信息 |
| kube-node-lease | Node 租约(心跳机制) |
Namespace 的隔离范围:
| 维度 | 是否隔离 | 说明 |
|---|---|---|
| 资源名称 | 是 | 同一 Namespace 内资源名唯一 |
| 资源配额 | 是 | 每个 Namespace 可设置 ResourceQuota |
| RBAC 权限 | 是 | RoleBinding 按 Namespace 授权 |
| 网络 | 否 | 默认 Pod 可跨 Namespace 通信(需 NetworkPolicy 阻断) |
| Node | 否 | 所有 Namespace 的 Pod 共享同一组 Node |
Namespace 不提供网络隔离。默认情况下,任何 Namespace 的 Pod 都可以与其他 Namespace 的 Pod 通信。要实现网络隔离,需要配置 NetworkPolicy。
五、Label 与 Selector:万物皆可筛选
Label 是附加在 Kubernetes 对象上的键值对,用于分类、筛选和组织资源。Selector 是基于 Label 的查询条件。
# Pod 上的 Labelmetadata: labels: app: nginx tier: frontend env: production version: v1.25# Service 通过 Selector 选择 Podspec: selector: app: nginx tier: frontend# kubectl 通过 Label 筛选资源kubectl get pods -l app=nginxkubectl get pods -l 'tier in (frontend,backend)'kubectl get pods -l env!=stagingLabel 的设计哲学是松耦合——Pod 不知道自己会被哪个 Service 选中,Service 也不关心 Pod 的具体名称。它们通过 Label 这个”中间层”建立关联,使得系统高度灵活:更换 Pod 只需确保 Label 匹配,无需修改 Service 配置。
5.1 Label vs Annotation
| 维度 | Label | Annotation |
|---|---|---|
| 用途 | 标识和筛选对象 | 存储非标识性元数据 |
| 长度限制 | 63 字符 | 无限制 |
| 字符限制 | 字母、数字、-、_、. | 任意字符 |
| 是否可查询 | 是(Selector) | 否 |
| 典型场景 | app=nginx, tier=frontend | build-date, contact-email, rollback-reason |
Annotation 适合存储”人看但不用于筛选”的信息,如构建时间、负责人邮箱、变更原因等。
六、声明式 API 与控制器模式
Kubernetes 的核心编程范式是声明式 API + 控制器模式。理解这个范式,就理解了 Kubernetes 的设计灵魂。
6.1 声明式 vs 命令式
| 模式 | 思路 | 示例 |
|---|---|---|
| 命令式 | ”做什么” | docker run nginx → 直接创建容器 |
| 声明式 | ”期望什么状态” | replicas: 3 → 告诉 K8s 我要 3 个副本 |
声明式 API 不告诉系统”怎么做”,只描述”期望状态”。系统自己决定如何从当前状态收敛到期望状态。这种模式的优势:
- 自愈能力:Pod 崩溃后,控制器会自动重建,无需人工干预
- 可重复:同一 YAML 多次提交,结果一致(幂等性)
- 可审计:所有变更通过 API Server,便于追踪
6.2 控制器模式
控制器是声明式 API 的执行者。每个控制器遵循同一个循环:
观察当前状态 → 对比期望状态 → 执行动作使当前状态趋近期望状态 → 回到观察以 Deployment 控制器为例:
- 观察:Watch API Server,发现 Deployment 对象的
replicas字段从 2 变为 3 - 对比:当前 ReplicaSet 只有 2 个 Pod,期望 3 个
- 执行:创建 1 个新 Pod
- 更新:新 Pod 状态写入 etcd
这个循环持续运行,确保集群始终向期望状态收敛。即使有人手动删除了一个 Pod,控制器也会立即发现并重建——这就是 Kubernetes 的”自愈”能力。
6.3 控制器层级
Kubernetes 的控制器不是扁平的,而是嵌套的层级结构:
Deployment 不直接管理 Pod——它管理 ReplicaSet,ReplicaSet 再管理 Pod。这种分层设计使得滚动更新成为可能:Deployment 创建新 ReplicaSet(新版本),逐步扩容新 ReplicaSet、缩容旧 ReplicaSet,实现平滑过渡。
总结
| 概念 | 核心要点 |
|---|---|
| 控制面 | API Server + etcd + Scheduler + Controller Manager,中心化决策 |
| 工作节点 | kubelet + kube-proxy + 容器运行时,分布式执行 |
| Pod | 最小调度单元,容器共享网络和存储,Pause 容器持有 Namespace |
| Node | 工作节点,capacity/allocatable 区分总资源和可分配资源 |
| Namespace | 逻辑隔离(资源名、配额、RBAC),不隔离网络 |
| Label/Selector | 松耦合关联,万物皆可筛选 |
| 声明式 API | 描述期望状态,系统自动收敛 |
| 控制器模式 | 观察→对比→执行→更新,持续循环 |
下一章将深入 Kubernetes 的工作负载类型——从 Pod 到 Deployment、StatefulSet、DaemonSet,理解每种工作负载的设计意图和使用场景。
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






