目录
微服务架构模式 服务发现 API 网关 熔断器模式 整体架构 控制平面组件 调度器原理 Pod 生命周期
01

整体架构

背景 为什么需要 K8s?

在容器化时代,将应用打包成 Docker 镜像并运行起来并不难。但当一个系统包含数百个微服务数千个容器时,仅仅依靠 Docker 和脚本是远远不够的。我们需要一个能够自动部署自动伸缩自动恢复的编排系统。Kubernetes 正是为了解决这些大规模容器编排问题而生的。

第一性原理: Kubernetes 的本质是一个「容器调度与编排平台」。它采用控制平面 (Control Plane) 和工作节点 (Node) 的主从架构,通过声明式 API 描述系统的期望状态,由控制平面负责将期望状态转化为实际状态。这种设计将「做什么」(期望状态)与「怎么做」(调度执行)分离,使得用户只需要关心应用的部署意图,而不需要关心具体的实现细节。

原理 控制平面 · 工作节点 · 声明式 API

控制平面组件:

  • kube-apiserver:集群的唯一入口,所有组件通过它通信
  • etcd:分布式键值存储,保存集群所有状态数据
  • kube-scheduler:负责调度 Pod 到具体节点
  • kube-controller-manager:运行控制器,维持期望状态
  • cloud-controller-manager:与云提供商交互

工作节点组件:

  • kubelet:节点代理,负责管理 Pod 和容器
  • kube-proxy:实现 Service 网络规则
  • 容器运行时:如 containerd、CRI-O
Kubernetes 整体架构 控制平面 (Control Plane) apiserver etcd scheduler controller cloud-controller Node 1 kubelet kube-proxy 容器运行时 Node 2 kubelet kube-proxy 容器运行时 Node 3 kubelet kube-proxy 容器运行时 图:Kubernetes 控制平面 + 工作节点架构
图:Kubernetes 控制平面 + 工作节点架构
▸ 查看集群组件状态
# 查看控制平面组件状态 kubectl get --raw='/readyz?verbose' # 查看集群节点 kubectl get nodes # 查看控制平面 Pod (在 kube-system 命名空间) kubectl get pods -n kube-system # 查看 API 服务器版本 kubectl version

演进 Borg → Kubernetes → 云原生标准

  • Borg (2003): Google 内部的大规模容器编排系统,Kubernetes 的前身
  • Kubernetes 1.0 (2015): 开源版本发布,支持 Pod、Service、Replication Controller
  • Kubernetes 1.2 (2016): 引入 DaemonSet、Job、CronJob
  • Kubernetes 1.5 (2016): 引入 StatefulSet,支持有状态应用
  • Kubernetes 1.10 (2018): CRD (自定义资源) 成熟,声明式 API 成为主流
  • Kubernetes 1.20 (2020): 全面支持 CSI、CRI 等标准化接口
"Kubernetes 的架构脱胎于 Google 的 Borg,但它的设计更开放、更标准化。它定义了『什么是容器编排』的标准模式,成为云原生时代的『操作系统』。"
—— 架构设计哲学

取舍 设计中的权衡

⚡ 集中 vs 分散
K8s 采用集中式控制平面,简化了管理但引入了单点故障风险。通过多副本部署和 etcd 高可用来缓解。
🔧 组件化 vs 集成
K8s 的组件都是可替换的(如 CRI、CNI、CSI),这带来灵活性但也增加了配置复杂性。需要平衡标准化和扩展性。
📊 声明式 vs 命令式
声明式 API 让用户关注最终状态,但增加了调试难度。命令式操作更直观,但容易导致状态混乱。
02

控制平面组件

背景 控制平面如何协同工作?

Kubernetes 控制平面由多个组件组成,每个组件负责一个特定的职责。它们相互配合,共同维护集群的期望状态。理解这些组件的功能和交互方式,是掌握 Kubernetes 核心原理的基础。

第一性原理: 控制平面的本质是「一个分布式系统的协调机制」。API 服务器作为唯一权威入口,所有组件通过它进行状态同步;etcd 作为唯一状态存储,保证数据的一致性和持久性;控制器和调度器作为决策和执行组件,从 etcd 读取状态,做出决策,然后通过 API 服务器更新状态。这种「读写分离」「职责分离」的设计,使得每个组件都可以独立优化和扩展。

原理 API 服务器 · etcd · 控制器 · 调度器

kube-apiserver: 集群的唯一入口,所有组件通过它通信。它负责认证鉴权准入控制,将请求写入 etcd 并返回结果。

etcd: 分布式键值存储,集群状态的唯一真相来源。支持watch 机制,控制器和调度器可以监听状态变化。

kube-controller-manager: 运行多个控制器,每个控制器关注一种资源(如 Deployment、ReplicaSet),持续将实际状态向期望状态对齐。

kube-scheduler: 负责调度 Pod,通过过滤打分算法选择最合适的节点。

控制平面组件交互流程 用户/CLI API 服务器 etcd 控制器 调度器 kubelet (节点) Pod (容器) 图:控制平面组件的协同工作流程
图:控制平面组件的协同工作流程
▸ 查看控制平面组件健康状态
# 查看 API 服务器健康状态 kubectl get --raw /healthz # 查看 etcd 健康状态 (需在 etcd 容器中执行) kubectl exec -n kube-system etcd-... -- etcdctl endpoint health # 查看控制器管理器状态 kubectl get --raw /healthz/controller-manager # 查看调度器状态 kubectl get --raw /healthz/scheduler

演进 单体 → 多组件 → 可扩展

  • 单体 (早期): 控制平面作为一个进程运行,耦合度高
  • 分离组件 (1.0+): 按功能拆分为多个独立组件,便于维护和扩展
  • CRI/CNI/CSI (1.5+): 定义标准接口,允许第三方实现替换
  • Kubeadm (1.4+): 简化控制平面部署和集群管理
"Kubernetes 控制平面组件的发展体现了『解耦』『标准化』的设计原则。每个组件专注于一个职责,通过 API 进行通信,使得整体系统既稳定又灵活。"
—— 组件设计哲学

取舍 设计中的权衡

⚡ 组件独立性 vs 协调开销
组件独立部署提高了容错性,但增加了组件间的通信开销。API 服务器成为核心瓶颈。
🔧 插件化 vs 一致性
CRI/CNI/CSI 等接口标准化带来灵活性,但不同插件的配置和行为可能不一致,增加了运维复杂度。
📦 控制平面高可用 vs 资源消耗
多副本部署控制平面提高可用性,但增加资源开销。需要根据集群规模和重要性合理配置。
03

调度器原理

背景 如何在多节点中选择最合适的?

当用户创建一个 Pod 时,Kubernetes 需要决定将该 Pod 分配到哪个节点上。调度器就是负责这个决策的组件。它需要综合考虑资源需求(CPU、内存)、约束条件(节点亲和性、污点容忍)、负载均衡等因素,选择一个最优的节点。

第一性原理: 调度器的本质是「一个基于约束的优化问题求解器」。它通过两个阶段完成调度:过滤 (Filtering) 阶段排除不满足硬约束的节点,打分 (Scoring) 阶段对剩余节点进行排序,选出得分最高的节点。这种「先排除后优选」的策略,保证了调度的正确性优化性

原理 过滤 · 打分 · 预测 · 抢占

调度阶段:

  • 过滤阶段 (Filtering): 检查节点是否满足 Pod 的硬约束:资源可用、端口未占用、节点选择器匹配、污点容忍等
  • 打分阶段 (Scoring): 对通过过滤的节点进行打分,考虑因素:资源剩余、镜像缓存、节点亲和性等
  • 绑定阶段 (Binding): 将 Pod 绑定到得分最高的节点,更新 API 服务器
调度器核心流程 输入: 待调度 Pod + 集群节点列表 过滤阶段 (Filtering) • 节点资源充足? • 节点选择器匹配? • 污点容忍? • 端口冲突? 打分阶段 (Scoring) • 资源利用率 (Best Fit) • 镜像缓存 • 节点亲和性 • 负载均衡 输出: 选定节点 → 绑定 Pod 图:调度器的两阶段流程,过滤后打分,选出最优节点
图:调度器的两阶段流程,过滤后打分,选出最优节点
▸ 调度器配置与调试
# 查看 Pod 调度情况 kubectl describe pod my-pod | grep -A 5 Events # 查看调度器日志 kubectl logs -n kube-system kube-scheduler-... -f # 手动调度 (用于调试) kubectl get pod unschedulable-pod -o yaml > pod.yaml # 修改 pod.yaml: 删除 nodeName 字段,设置调度器为 "" kubectl apply -f pod.yaml # 查看调度器性能指标 kubectl get --raw /metrics | grep scheduler

演进 默认调度器 → 多调度器 → 调度框架

  • 默认调度器 (1.0): 仅支持基础过滤和打分
  • 多调度器 (1.6): 支持自定义调度器,允许不同的 Pod 使用不同的调度策略
  • 调度框架 (1.19): 提供插件化调度框架,允许自定义调度阶段(如 Queue 排序、PreFilter、PostFilter)
  • 并行调度 (1.20+): 支持并行调度,提高大规模集群的调度效率
"调度器的演进是一个从『硬编码』『可编程』的过程。调度框架的引入使得用户可以编写自定义调度插件,满足特定业务场景的需求,而不再需要替换整个调度器。"
—— 调度设计哲学

取舍 设计中的权衡

⚡ 调度速度 vs 调度质量
快速的调度需要减少过滤和打分阶段的检查数量,但可能降低调度质量。需要根据集群规模平衡调度性能和效果。
🔧 配置 vs 扩展
调度框架提供了高度可扩展性,但配置复杂。需要在易用性和灵活性之间权衡。
📈 硬件约束 vs 软优化
硬约束(如资源需求、端口冲突)必须满足,软优化(如负载均衡、亲和性)提高整体效率但不能违背硬约束。
04

Pod 生命周期

背景 Pod 是如何被管理的?

Pod 是 Kubernetes 中的最小部署单元,它可以包含一个或多个容器。Pod 的生命周期包括从创建删除的整个过程。理解 Pod 的生命周期,有助于我们更好地设计应用的启动健康检查优雅关闭机制。

第一性原理: Pod 生命周期的本质是「容器状态机」。它定义了容器在不同阶段的状态和转换规则,包括初始化容器(完成预启动任务)、主容器(运行应用)、探针(健康检查)、终止钩子(优雅关闭)。这种设计使得 Pod 可以自描述自管理,kubelet 根据这些声明执行相应的操作。

原理 Pod 阶段 · 初始化容器 · 探针 · 终止

Pod 阶段 (Phase):

  • Pending:Pod 已创建但尚未调度完成
  • Running:Pod 已调度到节点,至少一个容器正在运行
  • Succeeded:所有容器成功退出
  • Failed:至少一个容器以非零状态退出
  • Unknown:无法获取 Pod 状态
Pod 生命周期状态机 Pending Running Succeeded Failed Unknown 生命周期事件 • 初始化容器 (initContainers) • 启动探针 (startupProbe) • 存活探针 (livenessProbe) • 就绪探针 (readinessProbe) • 终止钩子 (lifecycle.preStop) 图:Pod 生命周期状态转换与关键事件
图:Pod 生命周期状态转换与关键事件
▸ Pod 生命周期配置示例
# Pod 定义中包含初始化容器、探针和终止钩子 apiVersion: v1 kind: Pod metadata: name: my-pod spec: initContainers: - name: init image: busybox command: ['sh', '-c', 'echo "Initializing..."'] containers: - name: app image: my-app:latest ports: - containerPort: 8080 startupProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 5 livenessProbe: httpGet: path: /health port: 8080 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 lifecycle: preStop: exec: command: ['sh', '-c', 'echo "Shutting down..."']

演进 初始化容器 → 探针 → 终止钩子

  • Pod (1.0): 基本容器管理,不支持探针和钩子
  • 初始化容器 (1.6): 提供 initContainers,在应用启动前执行初始化任务
  • 存活/就绪探针 (1.1): 引入健康检查机制,自动重启不健康的容器
  • 启动探针 (1.16): 用于慢启动容器,避免存活探针过早失败
  • 终止钩子 (1.4): preStop 钩子,实现优雅关闭
"Pod 生命周期的完善,使得 Kubernetes 具备了『自愈』『优雅』的能力。通过探针,Pod 可以自动恢复故障;通过钩子,Pod 可以优雅处理终止信号。这些设计让 Kubernetes 的 Pod 管理达到了生产级的成熟度。"
—— Pod 设计哲学

取舍 设计中的权衡

⚡ 探针频率 vs 开销
频繁的探针检查增加系统开销,可能影响应用性能。需要合理设置探针的 periodSecondstimeoutSeconds
🔧 初始化容器 vs 主容器
初始化容器在主容器之前运行,完成初始化任务。但过度使用会导致 Pod 启动时间延长,需要平衡启动速度和初始化需求。
📊 启动探针 vs 存活探针
启动探针用于慢启动应用,避免存活探针在启动阶段错误触发。两者的配合需要根据应用启动特性精心设计。
05

Service 与 CNI 网络模型

背景 如何在动态环境中提供稳定的网络服务?

Pod 是易失性的——它们随时可能被重建、迁移、伸缩。直接使用 Pod 的 IP 地址作为服务入口是不可靠的。Kubernetes Service 提供了一种抽象,将一组 Pod 暴露为一个稳定的网络服务。CNI (Container Network Interface) 则定义了容器网络的标准接口,允许不同的网络插件替换实现。

第一性原理: Service 的本质是「一个稳定的 VIP(虚拟 IP)和负载均衡器」kube-proxy 不直接转发流量,只负责下发 iptables/IPVS 规则到节点,实际流量转发由内核 netfilter 组件完成。这种设计将服务发现负载均衡的功能从应用中剥离出来,使得应用可以无感知地面对 Pod 的变化。

原理 Service · kube-proxy · iptables · CNI

Service 类型:

  • ClusterIP:集群内部 IP,仅集群内可访问
  • NodePort:在每个节点上开放一个端口,通过节点 IP 访问
  • LoadBalancer:云提供商支持的负载均衡器
  • ExternalName:映射到外部域名
Service 与 CNI 网络模型 用户 Service (VIP) kube-proxy Node 1 Pod A (10.244.1.2) Pod B (10.244.1.3) eth0: veth... Node 2 Pod C (10.244.2.2) Pod D (10.244.2.3) eth0: veth... Node 3 Pod E (10.244.3.2) Pod F (10.244.3.3) eth0: veth... 图:Service 通过 kube-proxy 将流量转发到后端 Pod
图:Service 通过 kube-proxy 将流量转发到后端 Pod
▸ Service 与 CNI 配置示例
# 创建 ClusterIP Service apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - port: 80 targetPort: 8080 # 查看 Service 端点 kubectl get endpoints my-service # 查看 iptables 规则 (在节点上) sudo iptables -t nat -L -n | grep my-service # 使用 NodePort 暴露服务 apiVersion: v1 kind: Service metadata: name: my-nodeport spec: type: NodePort selector: app: my-app ports: - port: 80 targetPort: 8080 nodePort: 30080

演进 用户空间 → iptables → IPVS → eBPF

  • 用户空间 (早期): kube-proxy 在用户空间转发,性能差
  • iptables (1.1+): 使用 iptables 规则,性能提升,但规则链过长时更新慢
  • IPVS (1.8+): 使用 IPVS 内核模块,支持更大的规模和更高的吞吐量
  • eBPF (Cilium): 通过 eBPF 实现高性能网络和可观测性
"Service 网络的演进是『从软件转发』『内核加速』的过程。iptables 和 IPVS 利用内核功能大幅提升了转发性能,eBPF 则进一步将网络功能与可观测性结合,代表了新一代网络技术的方向。"
—— 网络设计哲学

取舍 设计中的权衡

⚡ iptables vs IPVS
iptables 简单但规则多时更新慢;IPVS 性能好但配置复杂。需要根据集群规模和服务数量选择。
🔧 CNI 插件选择
CNI 插件如 Flannel(简单)、Calico(性能好)、Cilium(eBPF)各有优劣。需要在性能、复杂度、功能之间权衡。
📦 ClusterIP vs Headless
ClusterIP 提供负载均衡但引入 VIP 额外层;Headless Service 直接返回 Pod IP,适合需要直接访问 Pod 的场景。
06

PV/PVC 存储

背景 如何为 Pod 提供持久化存储?

Pod 是临时性的,它的存储会随着 Pod 的删除而消失。但对于数据库、消息队列等有状态应用,需要持久化存储。Kubernetes 通过 PV (PersistentVolume)PVC (PersistentVolumeClaim) 实现存储的供应消费分离。

第一性原理: PV/PVC 设计的本质是「存储资源的抽象与解耦」。PV 代表物理存储资源(由管理员提供),PVC 代表用户对存储的需求。两者通过绑定 (Binding) 机制配对,实现了存储的声明式管理。这种设计使得应用开发者不需要关心底层存储的具体实现(如 NFS、Ceph、EBS),只需要声明需要多少存储什么类型即可。

原理 PV · PVC · StorageClass · CSI

持久卷 (PV): 集群中的存储资源,由管理员预先创建或通过 StorageClass 动态供应。

持久卷声明 (PVC): 用户对存储的请求,描述需要的大小、访问模式(ReadWriteOnce、ReadOnlyMany、ReadWriteMany)。

存储类 (StorageClass): 定义存储的类型、性能、回收策略等,用于动态供应 PV。

PV/PVC 存储模型 PVC (用户声明) 大小: 5Gi · 访问模式: RWO 绑定 PV (存储资源) 5Gi · NFS / EBS / Ceph StorageClass (动态供应) fast-ssd · 回收策略: Delete Pod (使用 PVC) volumeMounts: /data CSI (容器存储接口) 存储插件标准化 图:PV/PVC 存储模型,PVC 绑定 PV,StorageClass 动态供应
图:PV/PVC 存储模型,PVC 绑定 PV,StorageClass 动态供应
▸ PV/PVC 配置示例
# 创建 StorageClass apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-ssd provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer # 创建 PVC apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: fast-ssd # 在 Pod 中使用 PVC apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: app image: nginx volumeMounts: - name: my-storage mountPath: /data volumes: - name: my-storage persistentVolumeClaim: claimName: my-pvc

演进 静态供应 → 动态供应 → CSI 标准

  • 静态供应 (早期): 管理员预先创建 PV,用户申请使用,灵活性差
  • 动态供应 (1.2+): 通过 StorageClass 自动创建 PV,提高存储利用率
  • CSI 标准 (1.9+): 容器存储接口,统一不同存储系统的接入方式
  • CSI 快照 (1.12+): 支持存储快照功能,用于备份和恢复
"PV/PVC 的发展使得 Kubernetes 的存储管理从『静态』走向『动态』,从『专有』走向『标准』。CSI 的引入让任意存储系统都可以通过标准接口接入 Kubernetes,极大地丰富了存储生态。"
—— 存储设计哲学

取舍 设计中的权衡

📦 动态供应 vs 静态供应
动态供应提高存储利用率,但需要 StorageClass 和 CSI 插件的支持。静态供应控制力强,但资源利用率低。
⚡ 访问模式 vs 应用需求
ReadWriteMany 支持多 Pod 同时读写,但大多数存储系统不支持。需要根据应用选择合适的访问模式。
🔧 回收策略 vs 数据安全
Delete 策略在 PVC 删除时自动清理数据,安全但易误删;Retain 策略保留数据但需要手动清理。需根据数据重要程度选择。
07

控制器与声明式设计

背景 如何维护系统的期望状态?

Kubernetes 的核心设计哲学是声明式 (Declarative) 的。用户通过 YAML 文件描述期望状态(如 Deployment 的副本数、镜像版本),Kubernetes 控制器负责将实际状态调整为期望状态。控制器模式是 Kubernetes 实现自动化的基础。

第一性原理: 控制器的本质是「一个永不停止的协调循环 (Reconcile Loop)」。它持续观察实际状态(从 API 服务器获取),与期望状态(从资源定义获取)进行对比,然后执行相应的操作(如创建 Pod、更新副本数)使两者一致。这种「观察 → 对比 → 行动」的循环模式,保证了系统的自愈自管理能力。

原理 协调循环 · 控制器工作模式 · 自定义控制器

控制器核心模式:

  1. 观察 (Observe): 监听 API 服务器的事件(创建、更新、删除)
  2. 对比 (Compare): 将实际状态与期望状态进行对比
  3. 行动 (Act): 执行所需操作,使实际状态趋近期望状态
控制器协调循环 (Reconcile Loop) 期望状态 (YAML) replicas: 3 · image: v1 控制器 (Controller) 观察 → 对比 → 行动 实际状态 (Pod) replicas: 2 控制器持续协调,直至实际状态等于期望状态 示例: Deployment 控制器 → 创建/更新 ReplicaSet → 管理 Pod 副本 图:控制器协调循环,持续将实际状态调整为期望状态
图:控制器协调循环,持续将实际状态调整为期望状态
▸ 声明式操作示例
# 声明式创建资源 (推荐) kubectl apply -f deployment.yaml # 命令式更新 (不推荐) kubectl scale deployment my-deploy --replicas=5 # 查看控制器状态 kubectl get deployment my-deploy -o yaml # 查看控制器协调日志 kubectl logs -n kube-system kube-controller-manager-... -f # 创建自定义控制器 (使用 Operator SDK) operator-sdk create --domain mydomain --repo mydomain/my-operator

演进 ReplicationController → ReplicaSet → Deployment → Operator

  • ReplicationController (1.0): 基础的副本管理器,功能简单
  • ReplicaSet (1.2): 替代 ReplicationController,支持标签选择器
  • Deployment (1.2): 声明式部署管理,支持滚动更新、回滚
  • Operator (1.3+): 使用 CRD 和控制器实现自定义业务逻辑
"控制器的演进是 Kubernetes 从『平台』走向『生态』的关键。从 ReplicationController 到 Operator,Kubernetes 的控制能力从基础资源延伸到任意业务资源,实现了真正的『声明式』自动化。"
—— 控制器设计哲学

取舍 设计中的权衡

⚡ 实时性 vs 一致性
控制器是最终一致性的,状态变更有一定延迟。对于需要强实时性的场景,需要额外的同步机制。
🔧 通用控制器 vs 自定义控制器
通用控制器(Deployment、ReplicaSet)覆盖面广但功能有限;自定义控制器(Operator)功能强大但开发复杂。
📊 协调频率 vs 系统负载
频繁的协调循环能够快速响应变化,但会增加 API 服务器和控制器的负载。需要平衡响应速度和系统开销。
08

etcd

背景 Kubernetes 的数据库

etcd 是一个分布式、高可用的键值存储,是 Kubernetes 的唯一状态存储。所有集群状态都保存在 etcd 中,包括 Pod、Service、ConfigMap 等资源对象。etcd 基于 Raft 共识算法 保证数据的一致性和高可用。

第一性原理: etcd 的本质是「一个基于 Raft 协议的分布式键值数据库」。它通过领导者选举日志复制实现高可用,通过快照日志压缩保证效率。Kubernetes 选择 etcd 作为存储引擎,是因为它提供了强一致性高可用watch 机制——这些正是控制器模式所需的特性。

原理 Raft 共识 · 键值存储 · Watch 机制

etcd 核心特性:

  • Raft 共识: 确保所有节点数据一致,容忍部分节点故障
  • 键值存储: 基于 BoltDB 的持久化存储,支持事务
  • Watch 机制: 客户端可以监听键的变化,实现事件驱动
  • 租约 (Lease): 实现 TTL 和心跳机制
etcd 高可用架构 Leader 处理所有写请求 Follower 1 只读 · 日志复制 Follower 2 只读 · 日志复制 Follower 3 只读 · 日志复制 日志复制 (Append Entries) 客户端请求 图:etcd 通过 Raft 协议实现高可用,Leader 处理写请求并复制到 Follower
图:etcd 通过 Raft 协议实现高可用,Leader 处理写请求并复制到 Follower
▸ etcd 操作与维护
# 访问 etcd 容器 (在控制平面上) kubectl exec -n kube-system etcd-master-... -- sh # 查看 etcd 集群成员 etcdctl member list # 查看所有键 (注意: Kubernetes 大量数据) etcdctl get / --prefix # 手动创建备份 etcdctl snapshot save /tmp/etcd-backup.db # 从备份恢复 etcdctl snapshot restore /tmp/etcd-backup.db --data-dir /var/lib/etcd-restore # 查看 etcd 状态 etcdctl endpoint status --write-out=table

演进 etcd v2 → v3 → 性能优化

  • etcd v2 (2013): 基于 HTTP+JSON 的键值存储,支持 TTL,但性能和可扩展性有限
  • etcd v3 (2016): 使用 gRPC 和 BoltDB 存储,支持事务、观察者模式,大幅提升性能
  • etcd v3.4 (2019): 引入并发控制、租约优化,支持大规模集群
  • etcd v3.5 (2021): 优化快照和压缩策略,降低存储占用
"etcd 是 Kubernetes 的『单一事实来源』。它的可靠性和一致性直接决定了整个集群的稳定性。etcd v3 的引入是 Kubernetes 性能提升的关键里程碑。"
—— 存储设计哲学

取舍 设计中的权衡

📦 数据量 vs 性能
etcd 不适合存储大量数据(如日志、文件),Kubernetes 只存储元数据。需要定期进行压缩和快照,控制存储大小。
⚡ 写吞吐量 vs 读性能
etcd 的写性能受 Raft 限制,适合低频写、高频读的场景。对于写入密集型应用,需要合理控制 Kubernetes 的资源变更频率。
🔧 高可用 vs 成本
3 节点 etcd 集群可以容忍 1 个节点故障,5 节点集群可以容忍 2 个节点故障。更多的节点提高可用性但增加成本。