基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Kubernetes 的声明式 API (Declarative API) 与命令式 API 的区别

知识点图片

在 Kubernetes 中,理解命令式 API (Imperative API)声明式 API (Declarative API) 的区别,是掌握 K8s 核心设计哲学的关键。

简单来说:

  • 命令式关注“怎么做”(过程)。
  • 声明式关注“要什么”(结果)。

以下是详细的对比解析:


1. 生活中的类比

为了方便理解,我们可以用打车做菜来类比:

  • 命令式 (打车 - 指挥司机):

    • “师傅,前面左转。”
    • “直走 500 米。”
    • “在那个红绿灯右转。”
    • “停车。”
    • 你必须全程关注每一步,如果一步错了,结果就错了。
  • 声明式 (打车 - 给目的地):

    • “师傅,我要去机场。”
    • 你不需要管司机走哪条路,只要最终到达机场即可。如果中间修路(环境变化),司机自动换路(系统自我修复)。

2. 具体操作对比

命令式 API (Imperative)

你告诉 Kubernetes 具体的动作。通常使用 kubectl 的动词命令(create, run, expose, scale, edit 等)。

  • 操作方式: 面向过程,一步步执行。

  • 例子:

    1. 创建一个 Nginx Pod:
      kubectl run nginx --image=nginx
    2. 将副本数调整为 3:
      kubectl scale deployment nginx --replicas=3
    3. 修改镜像版本:
      kubectl set image deployment/nginx nginx=nginx:1.19
  • 缺点:

    • 不可重复性:如果网络中断,你不知道命令是否执行成功。
    • 非幂等性kubectl create 执行两次会报错(因为资源已存在)。
    • 难以维护:没有文档记录集群当前的状态,只能靠记忆或翻历史命令。

声明式 API (Declarative)

你告诉 Kubernetes 期望的状态 (Desired State)。通常使用 YAML 文件配合 kubectl apply

  • 操作方式: 面向结果,提交配置文件。

  • 例子:

    1. 编写一个 nginx.yaml 文件:
      yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
      spec:
        replicas: 3  # 我期望有3个副本
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.19 # 我期望镜像是 1.19
    2. 应用配置:
      kubectl apply -f nginx.yaml
  • Kubernetes 的工作: 系统会对比“当前状态”和“期望状态”。如果当前没有 Nginx,它就创建;如果当前有 1 个副本,它就再加 2 个;如果镜像不对,它就更新镜像。


3. 核心区别深度解析

特性 命令式 API (Imperative) 声明式 API (Declarative)
关注点 过程 (How) 结果/状态 (What)
典型命令 create, run, scale, edit apply
数据源 命令行参数 配置文件 (YAML/JSON)
幂等性 (重复执行可能报错或产生副作用) (重复执行 apply 结果一致)
事务处理 一次性操作 (Fire and forget) 持续调谐 (Continuous Reconciliation)
审计与协作 困难 (命令记录在个人终端) 容易 (YAML 文件可存入 Git 进行版本控制)
复杂性 简单直观,适合临时调试 学习曲线稍高,适合生产管理

4. 为什么 Kubernetes 推崇声明式 API?

Kubernetes 的核心是 控制器模式 (Controller Pattern),它依赖于声明式 API 来实现自动化运维。

A. 只有声明式才能实现“GitOps”

通过声明式 API,我们可以将 YAML 文件存放在 Git 仓库中。

  • Infrastructure as Code (IaC):基础设施即代码。
  • 版本控制:可以回滚到上一个版本的 YAML。
  • 审计:谁修改了 YAML,Git 都有记录。

B. 自动修复 (Self-Healing)

这是声明式 API 最强大的地方。

  • 场景:你定义了 replicas: 3
  • 命令式:如果你手动删除了一个 Pod,系统不会自动补齐,因为命令已经执行完了。
  • 声明式:Kubernetes 的控制器会不断循环检查(Reconciliation Loop)。它发现“期望是 3,实际只有 2”,于是自动创建一个新的 Pod 来补齐。

C. 智能合并 (Merge Patch)

kubectl apply 不仅仅是覆盖。它会计算 YAML 文件与集群内现有配置的差异(Diff)。

  • 如果有人手动给 Pod 加了一个 Label,而你的 YAML 更新了镜像。apply 会更新镜像,但保留那个手动加的 Label(除非发生冲突)。

5. 总结

  • 如果你只是想快速测试、临时起一个容器看看日志,用命令式 (kubectl run)。
  • 如果你是在管理生产环境、部署应用、需要长期维护,必须使用声明式 (kubectl apply -f yaml)。

Kubernetes 的强大之处在于它不仅仅是一个执行命令的工具,而是一个维持状态的系统,这完全归功于声明式 API 的设计。

00:00
00:00