Kubernetes 架构
本章将深入介绍 Kubernetes 集群的架构设计和核心组件,帮助你理解 Kubernetes 是如何工作的。
Kubernetes 架构概述
Kubernetes 采用主从架构,主要由**控制平面(Control Plane)和工作节点(Worker Nodes)**两部分组成。控制平面负责集群的全局决策和事件响应,工作节点负责运行实际的工作负载。
这种设计实现了关注点分离:控制平面专注于集群管理和调度决策,工作节点专注于执行工作负载。这种分离也让高可用部署变得更加灵活。
控制平面组件
控制平面负责整个集群的管理和控制,是 Kubernetes 的"大脑"。控制平面的组件可以在集群中的任何节点上运行,但在生产环境中,通常会部署在专用节点上以提供更好的稳定性和隔离性。
1. kube-apiserver
API 服务器是 Kubernetes 控制平面的核心组件,也是整个集群的入口点。所有组件都通过它进行通信,它提供 RESTful API 让用户和组件创建、读取、更新和删除资源。
主要功能:
- 认证(Authentication):验证请求者的身份,支持多种认证方式:客户端证书、静态 Token、服务账户 Token、OpenID Connect 等
- 授权(Authorization):验证请求者是否有权限执行操作,支持 RBAC、ABAC、Node 授权等多种模式
- 准入控制(Admission Control):在请求被持久化之前进行验证或修改,例如 LimitRanger、ResourceQuota、NamespaceLifecycle 等
- 数据验证和持久化:验证请求的有效性,并将数据存储到 etcd
# 查看 API 服务器信息
kubectl get pod -n kube-system -l component=kube-apiserver
# 查看 API 端点
kubectl api-resources
# 查看 API 版本
kubectl api-versions
工作原理:
高可用部署:
在生产环境中,通常会部署多个 API 服务器实例,前面通过负载均衡器分发请求。每个 API 服务器实例都是无状态的,状态存储在 etcd 中。
2. etcd
etcd 是一个分布式键值存储,用于保存集群的所有数据。它是 Kubernetes 的"数据库",存储了集群的完整状态。
核心特点:
- 一致性保证:使用 Raft 共识算法,确保数据在多个节点之间一致
- 高可用:支持多节点部署,容忍节点故障
- 持久化存储:数据持久化到磁盘,重启后不丢失
- 监听机制:支持 Watch API,客户端可以监听数据变化
# 查看 etcd Pod
kubectl get pods -n kube-system -l component=etcd
# 使用 etcdctl 查看数据(需要配置)
etcdctl get /registry --prefix -keys-only
# 检查 etcd 健康状态
etcdctl endpoint health
# 查看集群成员
etcdctl member list
存储的内容:
| 数据类型 | 说明 |
|---|---|
| Pod | Pod 定义和状态 |
| Service | Service 定义 |
| ConfigMap | 配置数据 |
| Secret | 敏感信息 |
| Node | 节点信息 |
| RBAC | 角色和权限配置 |
| Custom Resources | 自定义资源 |
生产环境建议:
- 部署 3、5 或 7 个节点的 etcd 集群(奇数个节点)
- 使用 SSD 存储以提高性能
- 定期备份 etcd 数据
- 监控 etcd 的健康状态和性能指标
3. kube-scheduler
调度器负责为新创建的 Pod 选择最合适的工作节点。这是一个复杂的决策过程,需要考虑多种因素。
调度流程:
kube-scheduler 的工作分为两个主要阶段:过滤(Filtering) 和 打分(Scoring)。
过滤阶段:
过滤阶段找出所有可以运行 Pod 的节点。调度器会评估一系列谓词(Predicates),排除不满足条件的节点:
| 过滤条件 | 说明 |
|---|---|
| PodFitsResources | 节点是否有足够的 CPU、内存资源 |
| PodFitsHostPorts | 节点是否有可用的端口 |
| PodMatchNodeSelector | 节点是否匹配 Pod 的节点选择器 |
| PodToleratesNodeTaints | Pod 是否容忍节点的污点 |
| CheckNodeCondition | 节点是否处于 Ready 状态 |
| CheckNodeUnschedulable | 节点是否可调度(是否有 node.kubernetes.io/unschedulable 污点) |
打分阶段:
打分阶段对通过过滤的节点进行评分,选择最优节点。调度器会评估一系列优先级(Priorities):
| 评分因素 | 说明 |
|---|---|
| LeastRequestedPriority | 优先选择资源使用率低的节点 |
| BalancedResourceAllocation | CPU 和内存使用率均衡的节点得分更高 |
| NodeAffinityPriority | 节点亲和性权重 |
| InterPodAffinityPriority | Pod 亲和性权重 |
| TaintTolerationPriority | 污点容忍权重 |
| ImageLocalityPriority | 节点已有镜像的优先(减少镜像拉取) |
调度示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
# 节点选择器:只调度到有 SSD 标签的节点
nodeSelector:
disktype: ssd
# 节点亲和性:更复杂的调度规则
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-west-2a
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
# 污点容忍
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx
调度器扩展:
Kubernetes 支持自定义调度器。你可以:
- 编写自己的调度器,与默认调度器并行运行
- 使用调度框架(Scheduling Framework)扩展默认调度器
- 使用调度器配置文件(Scheduler Configuration)自定义调度行为
4. kube-controller-manager
控制器管理器运行各种控制器来维护集群状态。每个控制器是一个独立的控制循环,持续监控集群状态并将其调整到期望状态。
控制器模式:
控制器遵循"期望状态 vs 当前状态"的模式:
内置控制器:
| 控制器 | 功能 |
|---|---|
| Node Controller | 监控节点状态,当节点不可用时响应 |
| Replication Controller | 确保指定数量的 Pod 副本运行 |
| Deployment Controller | 管理 Deployment,处理滚动更新 |
| StatefulSet Controller | 管理 StatefulSet,处理有状态应用 |
| DaemonSet Controller | 确保每个节点运行指定的 Pod |
| Job Controller | 管理 Job,确保任务完成 |
| EndpointSlice Controller | 管理 Service 的后端 Pod 端点 |
| Service Account Controller | 为新命名空间创建默认 ServiceAccount |
| Token Controller | 为 ServiceAccount 创建 API 访问令牌 |
| Namespace Controller | 删除命名空间时清理资源 |
| ResourceQuota Controller | 资源配额管理 |
| Garbage Collector | 清理不再使用的资源 |
# 查看控制器管理器
kubectl get pods -n kube-system -l component=kube-controller-manager
# 查看控制器管理器日志
kubectl logs -n kube-system -l component=kube-controller-manager
控制器协作示例:
当创建一个 Deployment 时,多个控制器协同工作:
- Deployment Controller:创建 ReplicaSet
- ReplicaSet Controller:创建 Pod
- Scheduler:为 Pod 分配节点
- EndpointSlice Controller:更新 Service 的端点
5. cloud-controller-manager
云控制器管理器负责与云提供商交互,管理云资源。它将云相关的控制逻辑与 Kubernetes 核心分离,使 Kubernetes 核心更加独立于云平台。
主要控制器:
| 控制器 | 功能 |
|---|---|
| Node Controller | 检查节点是否在云中存在 |
| Route Controller | 配置云路由 |
| Service Controller | 创建、更新、删除云负载均衡器 |
| Volume Controller | 创建、附加、卸载云存储卷 |
分离的好处:
- Kubernetes 核心不需要云平台特定的代码
- 云提供商可以独立发布控制器更新
- 使 Kubernetes 在非云环境中也能运行
工作节点组件
工作节点是实际运行 Pod 的机器,负责执行计算任务。每个节点都运行必要的组件来维护 Pod 的运行。
1. kubelet
kubelet 是运行在每个节点上的代理,负责管理该节点上的 Pod。它是控制平面和工作负载之间的桥梁。
主要职责:
- Pod 生命周期管理:创建、启动、停止、删除 Pod 中的容器
- 健康检查:执行存活探针和就绪探针,报告容器状态
- 资源监控:监控节点和容器的资源使用情况
- 卷管理:挂载和卸载存储卷
- 与 API Server 通信:注册节点、报告状态、接收 Pod 规范
# 查看 kubelet 状态
systemctl status kubelet
# 查看 kubelet 日志
journalctl -u kubelet -n 100
# 查看节点信息
kubectl describe node <node-name>
kubelet 工作流程:
2. kube-proxy
kube-proxy 是节点上的网络代理,负责实现 Service 的负载均衡。它维护节点上的网络规则,将到达 Service 的流量转发到后端 Pod。
工作模式:
| 模式 | 说明 | 特点 |
|---|---|---|
| iptables | 使用 iptables 规则转发(Linux 默认) | 效率高,但规则更新有延迟 |
| IPVS | 使用 IPVS 负载均衡 | 支持更多算法,适合大规模 |
| nftables | 使用 nftables 规则 | 新一代 Linux 防火墙,iptables 继任者 |
| userspace | 用户空间代理(已弃用) | 性能差,仅用于兼容 |
# 查看 iptables 规则
sudo iptables -t nat -L KUBE-SERVICES -n
# 查看 IPVS 规则
ipvs -L -n
# 查看 kube-proxy Pod
kubectl get pods -n kube-system -l k8s-app=kube-proxy
Service 流量转发过程:
3. 容器运行时
容器运行时负责拉取镜像和运行容器。Kubernetes 支持多种容器运行时,只要实现了 CRI(Container Runtime Interface)接口即可。
支持的运行时:
| 运行时 | 说明 |
|---|---|
| containerd | 最常用,Docker 的核心组件独立出来 |
| CRI-O | 专为 Kubernetes 设计的轻量级运行时 |
| Docker Engine | 通过 cri-dockerd 适配器支持 |
| gVisor | 增强安全性的沙箱运行时 |
| Kata Containers | 基于虚拟机的容器运行时 |
# 查看容器运行时
kubectl describe node <node-name> | grep -A 5 "Container Runtime"
# 使用 crictl 查看容器
crictl ps
crictl pods
crictl images
容器运行时接口(CRI):
CRI 定义了 kubelet 和容器运行时之间的接口,使 Kubernetes 可以与任何实现了该接口的运行时配合工作:
控制器模式详解
Kubernetes 使用控制器模式来管理集群状态。理解这个模式对于掌握 Kubernetes 至关重要。
控制循环
每个控制器通过"控制循环"来确保期望状态与实际状态一致。这是一个永不停止的过程:
- 获取期望状态:从 Kubernetes API 读取资源的 spec 字段
- 观察当前状态:读取资源实际的 status 字段
- 计算差异:比较期望状态和当前状态
- 执行动作:执行必要的操作使当前状态接近期望状态
- 更新状态:将新的状态写回 status 字段
- 重复:继续下一轮循环
声明式 API
Kubernetes 使用声明式 API,用户只需声明期望状态,控制器负责实现:
# 声明期望状态:3 个 Pod 副本
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # 期望状态:3 个副本
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
当你修改这个配置(例如将 replicas 改为 5),控制器会自动检测到变化并创建额外的 Pod。
控制器的独立性
Kubernetes 的控制器是独立运行的,每个控制器专注于自己的职责:
- 如果某个控制器崩溃,其他控制器继续工作
- 控制器之间通过 API Server 间接通信,避免了紧耦合
- 可以添加新的控制器而不影响现有的控制器
通信机制
理解 Kubernetes 组件之间的通信方式有助于排查问题和设计安全的网络架构。
控制平面内部通信
控制平面组件之间的通信:
- API Server ↔ etcd:所有数据通过 API Server 存储到 etcd
- Scheduler ↔ API Server:Scheduler 通过 API Server 获取未调度的 Pod,并更新绑定信息
- Controller Manager ↔ API Server:控制器通过 API Server 监听和更新资源
控制平面与节点通信
通信特点:
- API Server 到 kubelet:获取日志、执行命令、端口转发
- kubelet 到 API Server:注册节点、报告状态、获取 Pod 规范
- kube-proxy 到 API Server:获取 Service 和 Endpoint 信息
节点间通信
- Pod 可以直接与其他 Pod 通信(不需要 NAT)
- 每个 Pod 都有唯一的 IP 地址
- Service 提供稳定的虚拟 IP
集群高可用
生产环境通常部署高可用集群,确保控制平面故障时集群仍可正常运行。
高可用架构
高可用要点
API Server 高可用:
- 部署多个 API Server 实例
- 使用负载均衡器分发请求
- 每个实例都是无状态的
etcd 高可用:
- 部署奇数个节点(推荐 3、5、7)
- 使用 Raft 共识算法保证一致性
- 可以容忍 (N-1)/2 个节点故障
控制器和调度器高可用:
- 通过 Leader Election 实现
- 同一时刻只有一个实例处于活跃状态
- 活跃实例故障时自动切换
高可用部署示例
# 使用 kubeadm 创建高可用集群
# 首先创建负载均衡器,然后初始化第一个控制平面节点
kubeadm init --control-plane-endpoint "lb.example.com:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16
# 在其他控制平面节点加入
kubeadm join lb.example.com:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
# 工作节点加入
kubeadm join lb.example.com:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
节点状态
了解节点状态有助于监控和排查问题。
节点状态字段
| 状态 | 说明 |
|---|---|
| Ready | 节点健康且可接受 Pod |
| MemoryPressure | 节点内存不足 |
| DiskPressure | 节点磁盘空间不足 |
| PIDPressure | 节点进程 ID 不足 |
| NetworkUnavailable | 节点网络配置错误 |
# 查看节点状态
kubectl get nodes -o wide
# 查看节点详细信息
kubectl describe node <node-name>
# 查看节点条件
kubectl get nodes -o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[-1].type,REASON:.status.conditions[-1].reason
节点控制器
节点控制器负责管理节点的生命周期:
- 节点注册时分配 CIDR
- 监控节点健康状态
- 节点不可达时更新节点状态
- 驱逐不可达节点上的 Pod
小结
本章我们学习了:
- Kubernetes 架构概述:控制平面 + 工作节点的分层设计
- 控制平面组件:
- API Server:集群入口,认证授权准入控制
- etcd:分布式键值存储,保存集群状态
- Scheduler:Pod 调度,过滤和打分机制
- Controller Manager:运行控制器,维护期望状态
- Cloud Controller Manager:云平台集成
- 工作节点组件:
- kubelet:Pod 生命周期管理
- kube-proxy:Service 负载均衡
- 容器运行时:容器执行
- 控制器模式:控制循环和声明式 API
- 高可用设计:多实例部署和 Leader Election
练习
- 使用
kubectl get componentstatuses查看控制平面组件状态 - 使用
kubectl describe node <node-name>查看节点详情,理解节点条件 - 使用
kubectl get pods -n kube-system查看系统组件 Pod - 分析一个 Pod 的调度过程,使用
kubectl describe pod查看事件 - 检查 etcd 数据,了解存储结构
准备好继续学习了吗?点击下一章了解如何配置 Kubernetes 环境!