跳到主要内容

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

存储的内容

数据类型说明
PodPod 定义和状态
ServiceService 定义
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 的节点选择器
PodToleratesNodeTaintsPod 是否容忍节点的污点
CheckNodeCondition节点是否处于 Ready 状态
CheckNodeUnschedulable节点是否可调度(是否有 node.kubernetes.io/unschedulable 污点)

打分阶段

打分阶段对通过过滤的节点进行评分,选择最优节点。调度器会评估一系列优先级(Priorities):

评分因素说明
LeastRequestedPriority优先选择资源使用率低的节点
BalancedResourceAllocationCPU 和内存使用率均衡的节点得分更高
NodeAffinityPriority节点亲和性权重
InterPodAffinityPriorityPod 亲和性权重
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 支持自定义调度器。你可以:

  1. 编写自己的调度器,与默认调度器并行运行
  2. 使用调度框架(Scheduling Framework)扩展默认调度器
  3. 使用调度器配置文件(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 时,多个控制器协同工作:

  1. Deployment Controller:创建 ReplicaSet
  2. ReplicaSet Controller:创建 Pod
  3. Scheduler:为 Pod 分配节点
  4. 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 至关重要。

控制循环

每个控制器通过"控制循环"来确保期望状态与实际状态一致。这是一个永不停止的过程:

  1. 获取期望状态:从 Kubernetes API 读取资源的 spec 字段
  2. 观察当前状态:读取资源实际的 status 字段
  3. 计算差异:比较期望状态和当前状态
  4. 执行动作:执行必要的操作使当前状态接近期望状态
  5. 更新状态:将新的状态写回 status 字段
  6. 重复:继续下一轮循环

声明式 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

节点控制器

节点控制器负责管理节点的生命周期:

  1. 节点注册时分配 CIDR
  2. 监控节点健康状态
  3. 节点不可达时更新节点状态
  4. 驱逐不可达节点上的 Pod

小结

本章我们学习了:

  1. Kubernetes 架构概述:控制平面 + 工作节点的分层设计
  2. 控制平面组件
    • API Server:集群入口,认证授权准入控制
    • etcd:分布式键值存储,保存集群状态
    • Scheduler:Pod 调度,过滤和打分机制
    • Controller Manager:运行控制器,维护期望状态
    • Cloud Controller Manager:云平台集成
  3. 工作节点组件
    • kubelet:Pod 生命周期管理
    • kube-proxy:Service 负载均衡
    • 容器运行时:容器执行
  4. 控制器模式:控制循环和声明式 API
  5. 高可用设计:多实例部署和 Leader Election

练习

  1. 使用 kubectl get componentstatuses 查看控制平面组件状态
  2. 使用 kubectl describe node <node-name> 查看节点详情,理解节点条件
  3. 使用 kubectl get pods -n kube-system 查看系统组件 Pod
  4. 分析一个 Pod 的调度过程,使用 kubectl describe pod 查看事件
  5. 检查 etcd 数据,了解存储结构

准备好继续学习了吗?点击下一章了解如何配置 Kubernetes 环境!