【AI 总结】Kubernetes 对象
Kubernetes 对象 | AI 总结
本页说明了在 Kubernetes API 中是如何表示 Kubernetes 对象的,以及如何使用 .yaml 格式的文件表示 Kubernetes 对象。
理解 Kubernetes 对象
在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。具体而言,它们描述了如下信息:
- 哪些容器化应用正在运行(以及在哪些节点上运行)
- 可以被应用使用的资源
- 关于应用运行时行为的策略,比如重启策略、升级策略以及容错策略
Kubernetes 对象是一种 “意向表达(Record of Intent)”。一旦创建该对象,Kubernetes 系统将不断工作以确保该对象存在。通过创建对象,你本质上是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的,这就是 Kubernetes 集群所谓的期望状态(Desired State)。
操作 Kubernetes 对象 —— 无论是创建、修改或者删除 —— 需要使用 Kubernetes API。比如,当使用 kubectl 命令行接口(CLI)时,CLI 会调用必要的 Kubernetes API;也可以在程序中使用客户端库,来直接调用 Kubernetes API。
在 Kubernetes 的语境下,“意向表达(Record of Intent)” 是理解其工作原理的核心概念。简单来说,你可以从以下几个维度来理解:
1. 声明式而非命令式(What vs How)
- 命令式(Imperative):就像给快递员下命令:“直走 500 米,左转,上三楼,敲门”。如果中间路堵了或者门锁了,任务就失败了,你需要重新下令。
- 声明式(Declarative/Intent):就像寄快递:“我要把这个包发给三楼的张三”。你不需要管快递员怎么走,你的 “意向” 是 “包在张三手里”。快递员(Kubernetes)会负责规划路线、处理拥堵,直到达成你的意向。
2. 期望状态(Desired State)
当你创建一个 K8s 对象(比如一个 Deployment 或 Pod)时,你并不是在执行一个一次性的动作,而是在 K8s 的数据库(etcd)中写下了一条持久的 “心愿单”。
- 你的意向:我的应用需要有 3 个副本在运行。
- 记录:这个意向被永久保存在集群中,成为该对象的
spec(规约)。
3. 控制循环(Reconciliation Loop)
一旦你表达了意向,Kubernetes 的各个控制器(Controller)就会开始 “工作”:
- 观察(Observe):发现实际只有 0 个副本在运行。
- 对比(Diff):发现 “实际状态(0)” 不等于 “意向状态(3)”。
- 行动(Act):自动创建 3 个副本,直到两者一致。
4. 持续的保证
“意向表达” 最强大的地方在于它的持续性:
- 如果某个节点挂了,导致副本变成了 2 个,K8s 看到你的 “意向” 仍然是 3,它会立即在别的节点启动一个新的。
- 只要这个 “记录(Record)” 还在,K8s 就会不眠不休地工作,确保现实世界(Status)始终趋向于你描述的理想世界(Spec)。
总结: “意向表达” 意味着你只需要告诉 Kubernetes “你想要什么”(期望状态),剩下的 “怎么做” 以及 “如何维持” 都由系统自动处理。它是 Kubernetes 实现自动化运维和自愈能力的基础。
对象规约(Spec)与状态(Status)
几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec(规约) 和对象 status(状态)。对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征:期望状态(Desired State)。
status 描述了对象的当前状态(Current State),它是由 Kubernetes 系统和组件设置并更新的。在任何时刻,Kubernetes 都一直在积极地管理着对象的实际状态,以使之达成期望状态。
例如,Kubernetes 中的 Deployment 对象能够表示运行在集群中的应用。当创建 Deployment 时,你可能会设置 Deployment 的 spec,指定该应用要有 3 个副本运行。Kubernetes 系统读取 Deployment 的 spec,并启动我们所期望的应用的 3 个实例 —— 更新状态以与规约相匹配。如果这些实例中有的失败了(一种状态变更),Kubernetes 系统会通过执行修正操作来响应 spec 和 status 间的不一致 —— 意味着它会启动一个新的实例来替换。
关于对象 spec、status 和 metadata 的更多信息,可参阅 Kubernetes API 约定。
在 Kubernetes 中,并不是所有对象都遵循 spec 和 status 的结构。虽然绝大多数用于定义资源期望状态的对象(如 Pod、Deployment)都有 spec,但也有一些例外。
以下是具体的分类说明:
1. 拥有 spec 的对象
这些对象通常代表某种需要被控制器维持的持久化状态。你定义 “期望状态”(spec),Kubernetes 系统(控制器)负责将其变为 “实际状态”(status)。
- 工作负载资源:
Pod,Deployment,StatefulSet,ReplicaSet,Job,CronJob。 - 网络资源:
Service,Ingress。 - 存储资源:
PersistentVolume,PersistentVolumeClaim。 - 配置与安全:
NetworkPolicy,ResourceQuota。
2. 没有 spec 的对象
这些对象通常是纯粹的数据容器、元数据集合或瞬时记录,它们不需要控制器去 “实现” 某种状态。
- ConfigMap 和 Secret:它们只有
data(或binaryData/stringData)和metadata。你并不 “期望” 它们变成什么样,它们本身就是你存储的数据。 - Event:事件是系统发生的记录(例如 Pod 启动、拉取镜像失败)。它们是描述性的,没有期望状态,因此没有
spec。 - Namespace:命名空间主要用于逻辑隔离,它有
status(如Active),但其配置通常直接在metadata或通过其他机制处理,虽然在 API 定义中有spec(用于 finalizers),但在日常使用中我们很少像配置 Pod 那样去配置它的spec。 - ComponentStatus:这是一种特殊的只读资源,用于检查 master 组件的状态,没有
spec。 - Node:虽然 Node 有
spec(由系统设置,如unschedulable或podCIDR),但用户通常不直接编写 Node 的spec来创建节点,而是由 Kubelet 注册。
总结 :判断一个对象是否有 spec 的简单方法是看它的角色:
- 如果它是用来 “描述你想要什么” 的(期望状态),它通常有
spec。 - 如果它仅仅是 “提供数据” 或 “记录事实” 的,它通常没有
spec。
在你的文档中,提到 “对于具有 spec 的对象”,正是为了区分像 Pod(有 spec)和 ConfigMap(没有 spec,只有 data)这类不同的资源类型。
描述 Kubernetes 对象
创建规约类 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。当使用 Kubernetes API 创建对象时(直接创建或经由 kubectl 创建),API 请求必须在请求主体中包含 JSON 格式的信息。大多数情况下,你会通过 清单(Manifest) 文件为 kubectl 提供这些信息。按照惯例,清单是 YAML 格式的(你也可以使用 JSON 格式)。像 kubectl 这样的工具在通过 HTTP 进行 API 请求时,会将清单中的信息转换为 JSON 或其他受支持的序列化格式。
这里有一个清单示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec:
与上面使用清单文件来创建 Deployment 类似,另一种方式是使用 kubectl 命令行接口(CLI)的 kubectl apply 命令,将 .yaml 文件作为参数。下面是一个示例:
1 | |
输出类似下面这样:
1 | |
必需字段
在想要创建的 Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:
apiVersion- 创建该对象所使用的 Kubernetes API 的版本kind- 想要创建的对象的类别metadata- 帮助唯一标识对象的一些数据,包括一个name字符串、UID和可选的namespacespec- 你所期望的该对象的状态
对每个 Kubernetes 对象而言,其 spec 之精确格式都是不同的,包含了特定于该对象的嵌套字段。Kubernetes API 参考可以帮助你找到想要使用 Kubernetes 创建的所有对象的规约格式。
例如,参阅 Pod API 参考文档中 spec 字段。对于每个 Pod,其 .spec 字段设置了 Pod 及其期望状态(例如 Pod 中每个容器的容器镜像名称)。另一个对象规约的例子是 StatefulSet API 中的 spec 字段。对于 StatefulSet 而言,其 .spec 字段设置了 StatefulSet 及其期望状态。在 StatefulSet 的 .spec 内,有一个为 Pod 对象提供的模板。该模板描述了 StatefulSet 控制器为了满足 StatefulSet 规约而要创建的 Pod。不同类型的对象可以有不同的 .status 信息。API 参考页面给出了 .status 字段的详细结构,以及针对不同类型 API 对象的具体内容。
请查看配置最佳实践来获取有关编写 YAML 配置文件的更多信息。
服务器端字段验证
从 Kubernetes v1.25 开始,API 服务器提供了服务器端字段验证,可以检测对象中未被识别或重复的字段。它在服务器端提供了 kubectl --validate 的所有功能。
kubectl 工具使用 --validate 标志来设置字段验证级别。它接受值 ignore、warn 和 strict,同时还接受值 true(等同于 strict)和 false(等同于 ignore)。kubectl 的默认验证设置为 --validate=true。
Strict- 严格的字段验证,验证失败时会报错
Warn- 执行字段验证,但错误会以警告形式提供而不是拒绝请求
Ignore- 不执行服务器端字段验证
当 kubectl 无法连接到支持字段验证的 API 服务器时,它将回退为使用客户端验证。Kubernetes 1.27 及更高版本始终提供字段验证;较早的 Kubernetes 版本可能没有此功能。如果你的集群版本低于 v1.27,可以查阅适用于你的 Kubernetes 版本的文档。