K8s 架构总览与核心概念

导读
Kubernetes 解决的核心问题是:如何在多台机器上可靠地运行数百个容器,并在节点故障时自动恢复。理解它的架构设计和核心对象模型,是后续所有实操的基础。本篇将拆解控制平面与数据平面的组件职责,厘清 Pod、Node、Namespace 三者的关系,并解释声明式 API 为何改变了运维的思维方式。
核心概念
什么是 Kubernetes
Kubernetes(简称 K8s)是一个开源的容器编排系统,负责自动化容器的部署、扩缩容和运维。如果你用 Docker 跑过容器,就已经解决了"单机运行"的问题;K8s 解决的是"多机运行"的问题——跨节点调度、故障自愈、滚动更新、服务发现,这些在单机 Docker 中都需要手动处理。
K8s 的设计哲学围绕三个关键词:声明式 API、自愈、弹性伸缩。你告诉系统"我要 3 个 Nginx 副本",而不是"启动一个 Nginx 容器"。系统会持续比对期望状态与实际状态,发现偏差时自动纠正——某个 Pod 崩溃了,调度器会在其他节点重新拉起一个;流量突增时,水平扩缩器自动增加副本数。
集群与节点模型
一个 K8s 集群由至少一个控制平面节点(Control Plane Node,也称 Master)和若干工作节点(Worker Node)组成。控制平面是集群的"大脑",负责全局决策和事件响应;工作节点是"手脚",负责运行实际的容器负载。
Node 是 K8s 中对物理机或虚拟机的抽象。每个 Node 包含 CPU、内存等资源容量,调度器根据这些容量决定将 Pod 放在哪个节点上。Node 有两种角色:control-plane(同时承担控制职责)和 <none>(纯工作节点)。生产环境通常将控制平面与工作节点分离部署,控制平面至少 3 个节点以实现高可用。
Node 的状态通过 Conditions 字段报告,关键的几项包括 Ready(节点健康可调度)、MemoryPressure(内存不足)、DiskPressure(磁盘不足)、PIDPressure(进程数过多)。当 Ready 为 False 时,调度器不再往该节点分配新 Pod。
核心对象模型
K8s 通过一组核心对象来描述集群中运行的一切:
- Pod —— K8s 的最小调度单元。一个 Pod 包含一个或多个紧密耦合的容器,它们共享网络命名空间和存储卷。Pod 是临时的,IP 会随重建而变化,因此不应直接依赖 Pod IP。
- Namespace —— 集群内的逻辑隔离边界。不同 Namespace 下的资源名称可以重复,RBAC 权限和资源配额都以 Namespace 为作用域。生产环境通常按团队或环境(dev/staging/prod)划分 Namespace。
- Label 与 Selector —— K8s 的关联机制。Label 是挂在资源上的键值对(如
app=nginx, tier=frontend),Selector 通过 Label 筛选资源。Service 通过 Selector 找到后端 Pod,Deployment 通过 Selector 管理它创建的 Pod。
下面的架构图展示了控制平面与工作节点的组件拓扑,以及核心对象在其中的位置。
图 1 展示了 K8s 集群的组件拓扑。所有组件只与 kube-apiserver 通信,不直接读写 etcd,这保证了状态变更的一致性。kubelet 在每个工作节点上运行,负责向 apiserver 上报节点状态并管理本节点的 Pod 生命周期。kube-proxy 负责将 Service 的虚拟 IP 规则写入节点 iptables 或 IPVS,使流量能正确路由到后端 Pod。
图解原理
控制平面组件职责
控制平面包含五个核心组件,各司其职:
- kube-apiserver —— 集群统一的 API 入口,所有组件和 kubectl 命令都通过它读写集群状态。它负责认证、授权和准入控制,是唯一直接操作 etcd 的组件。
- etcd —— 分布式键值存储,保存集群的全部状态数据(Pod、Service、ConfigMap 等所有资源定义)。etcd 的一致性直接决定集群的可靠性,生产环境必须以集群方式部署。
- kube-scheduler —— 监听新建但未调度的 Pod,根据资源请求、亲和性规则、污点容忍等策略,为 Pod 选择最合适的节点。
- kube-controller-manager —— 运行一组控制器,每个控制器负责一种资源对象的调和循环。例如 Deployment Controller 确保副本数符合期望,Node Controller 监控节点健康状态。
- cloud-controller-manager —— 将云厂商特定的逻辑(如负载均衡器创建、节点路由配置)与 K8s 核心代码解耦,使各云厂商只需实现自己的插件。
声明式与命令式的本质区别
命令式操作是"告诉系统做什么":docker run nginx 直接启动一个容器。声明式操作是"告诉系统想要什么":提交一段 YAML 描述"我要 3 个 Nginx 副本",系统自行决定如何达到这个状态。
声明式的核心优势在于可恢复性。当节点故障导致 Pod �丢失时,Deployment Controller 检测到实际副本数低于期望值,自动在其他节点创建新 Pod。这个过程不需要人工干预,也不需要记录"之前做了什么操作"——系统只需要比对当前状态与期望状态的差异。
下面的流程图展示了从 kubectl 命令到 Pod 调度运行的完整链路。
图 2 描述了从提交 YAML 到 Pod 运行的完整链路。注意 scheduler 和 controller-manager 都通过监听 apiserver 的事件来驱动工作,而不是直接被调用。这种事件驱动架构是 K8s 控制平面的核心设计模式——每个组件自治地响应状态变化,形成多层调和循环。
动手实操
以下命令使用 kubectl 与集群交互,验证本篇涉及的架构概念。
查看集群节点及其角色和状态:
kubectl get nodes -o wide输出示例:
NAME STATUS ROLES AGE VERSION
control-plane Ready control-plane 10d v1.30.0
worker-1 Ready <none> 10d v1.30.0
worker-2 Ready <none> 10d v1.30.0查看某个节点的详细状态,包括 Conditions 和资源容量:
kubectl describe node worker-1关注输出中的 Conditions 部分(Ready、MemoryPressure 等)和 Capacity 部分(CPU、内存总量),这些是调度器决策的依据。
查看控制平面组件状态:
kubectl get componentstatuses创建一个 Namespace 并部署一个简单 Pod,观察 Label 和 Selector 的关联:
# 创建 Namespace
kubectl create namespace demo
# 部署带 Label 的 Pod
kubectl run nginx --image=nginx:1.27 --labels=app=nginx,tier=frontend -n demo
# 通过 Label Selector 查找 Pod
kubectl get pods -l app=nginx -n demo查看 Pod 的详细信息,注意其所在节点和 IP:
kubectl describe pod nginx -n demo常见问题与避坑
控制平面组件不可在同一节点混用——在生产环境中,etcd 与工作负载混部会导致资源争抢,etcd 写延迟升高会直接影响整个集群的响应速度。建议控制平面节点仅运行控制组件,不调度业务 Pod(通过污点实现)。
Pending 状态的 Pod 通常不是调度器故障,而是资源不足。先用 kubectl describe pod <name> 查看 Events 部分,如果出现 FailedScheduling 并提示 Insufficient cpu,说明没有节点能满足 Pod 的资源请求。此时应检查资源请求值是否合理,或扩容集群节点。
Pod IP 是易变的。如果你在代码或配置中硬编码了 Pod IP,当 Pod 重建后 IP 变化会导致连接失败。始终通过 Service 的稳定 ClusterIP 或 DNS 名称访问服务。
小结与进阶
K8s 通过控制平面(apiserver/etcd/scheduler/controller-manager)集中决策、工作节点(kubelet/kube-proxy/容器运行时)分散执行的架构,实现了容器负载的自动化管理。Pod 是最小调度单元,Namespace 提供逻辑隔离,Label/Selector 建立资源间的关联。声明式 API 让系统持续向期望状态收敛,这是 K8s 自愈能力的根基。
下一篇将从零搭建一个本地集群,用 kubectl 命令实际操作这些概念。