在云计算和容器编排的世界里,Kubernetes(K8s)无疑是核心。它之所以能高效管理复杂的分布式系统,其核心哲学就是采用了声明式API(Declarative API)。理解声明式API的精髓,就是理解为什么我们只需提交YAML文件来描述“期望状态”,而无需编写复杂的指令集去描述“执行步骤”。
1. 声明式 vs. 命令式:本质的区别
要理解声明式API,我们必须先将其与传统的命令式API(Imperative API)进行对比。
命令式API(How to do it):
命令式关注的是过程和步骤。你需要告诉系统如何一步一步地达到目标。例如,在传统系统中,你要部署一个应用,你需要执行一系列脚本:启动VM -> 安装依赖 -> 运行应用。
声明式API(What I want):
声明式关注的是最终结果或期望状态。你只需要描述你希望系统最终是什么样子的,而具体的执行路径和维护工作则交给系统自己去完成。在K8s中,这个“描述”就是YAML配置文件。
一个简单的类比:
- 命令式: 你告诉厨师:“从冰箱里拿出鸡蛋,打碎,加盐,搅拌,倒入热油锅中,煎三分钟,翻面,再煎两分钟,出锅。”(关注步骤)
- 声明式: 你告诉系统:“我需要一份三分熟的煎蛋。”(关注结果)
2. K8s中的核心实践:定义期望状态
在Kubernetes中,所有的资源(如Deployment、Service、Pod)都是通过YAML或JSON文件来定义的。当你编写一个Deployment资源时,你就是在向K8s定义你的期望状态(Desired State)。
例如,我们希望有一个名为 nginx-app 的应用,它必须始终运行 3 个副本(Pod)。
# deployment.yaml: 定义我们的期望状态
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # <--- 关键点:我们声明必须有 3 个副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21.6
ports:
- containerPort: 80
当使用 kubectl apply -f deployment.yaml 提交这个文件时,我们告诉K8s的就是:“请确保集群中始终有 3 个 Nginx Pod 在运行。”
3. 幕后英雄:控制循环与状态同步
K8s之所以能实现声明式管理,依赖于其核心机制:控制循环(Control Loop),或者叫协调循环(Reconciliation Loop)。
K8s的每个核心组件(如Deployment Controller, ReplicaSet Controller)都在不断地执行以下循环:
- 观察(Observe): 查看当前的集群状态(Current State)。
- 分析(Analyze): 将当前状态与用户定义的期望状态(Desired State)进行比较。
- 行动(Act): 如果两者不匹配,则执行必要的动作来弥补差距。
实操演示:自愈性 (Self-Healing)
假设我们成功应用了上述 Deployment,3 个 Nginx Pod 正在运行。然后,由于某种原因(如节点故障或人为删除),其中一个 Pod 意外终止了。
# 1. 提交期望状态 (3个副本)
kubectl apply -f deployment.yaml
# 2. 确认状态
kubectl get pods
# 输出类似于: nginx-xxx-1, nginx-xxx-2, nginx-xxx-3 (3个Running)
# 3. 模拟故障:手动删除一个 Pod
kubectl delete pod <name-of-one-of-the-nginx-pods>
# 4. 观察 K8s 的自愈
kubectl get pods
# 立即查看,你会发现 K8s 启动了一个新的 Pod 来替代被删除的 Pod,
# 确保副本数依然维持在声明的 3 个。
在这个过程中,你没有告诉 K8s “怎么做”(即:如果 Pod 消失了,你应该启动一个新的)。你只告诉了 K8s “你想要什么”(即:我需要 3 个 Nginx 副本)。正是控制循环机制不断对比,才实现了系统的自愈能力。
4. 声明式API的优势:幂等性与可审计性
声明式API带来的核心优势是其幂等性(Idempotence)。无论你提交同一个 YAML 文件多少次,最终的结果(期望状态)都是一样的。如果系统已经达到了期望状态,再次应用配置不会产生副作用。
而在命令式操作中,重复执行相同的创建命令往往会导致错误(例如,“应用已存在”)。
通过专注于定义期望状态,K8s将运维人员从繁琐的“如何做”的步骤中解放出来,专注于架构设计和系统蓝图,从而大大提高了复杂系统的稳定性和可靠性。
汤不热吧