博主头像

人間になりたい!!!!!


皖ICP备2025096275号

Kubernets 学习: 一文理解 K8s Deployment 清单文件的含义及作用

前言

在接触 Kubernets 运维后, 我们需要将我们编写的程序交付给 Kubernets 进行集群化部署. 这么做的前提需要您充分的理解 Kubernets Deployment 清单文件的含义及各个配置的作用. 本文将会带你进行了解


清单文件的四大结构

每个 Kubernets 清单文件都有四个必填的顶层字段:

apiVersion: ...
kind: ...
metadata:
  ...
spec:
  ...

它们的含义分别为:

  • apiVersion 使用的 Kubernets API 版本
  • kind 要创建的资源类型
  • metadata 资源的元数据
  • spec 资源的期望状态 (规约)

这是一个具体的清单文件示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myapp:v1.0.0
        ports:
        - containerPort: 8080

apiVersionkind: 资源的唯一标识

  • apiVersion 指定了要使用的 Kubernetes API 的版本和 API 组.

    • 核心组 (Core Group) : 如 v1 (用于 Pod, Service 等), 它们是最基础的资源, 路径是 /api/v1.
    • 命名组 (Named Groups) : 如 apps/v1 (用于 Deployment, StatefulSet), 它们的路径是 /apis/apps/v1.
    • 架构知识: 这反映了 kube-apiserver 的 API 分组和版本演进策略 - apiserver 负责暴露这些 RESTful API endpoint, 并提供不同版本之间的转换.
  • kind 明确指定你要创建的资源对象类型,例如 Pod, Service, Deployment, ConfigMap.

    • 架构知识: 每个 kind 在 Kubernetes 内部都对应一个资源类型定义 (Resource Definition). 当 kubectl apply -f 时, 客户端会将 YAML 序列化为 JSON 并发送到对应的 API 端点.

metadata: 为资源附加的身份信息与 Tag

metadata:
  name: myapp-deployment
  labels:
    app: myapp
    version: v1
  annotations:
    build-number: "123"

metadata 资源的身份信息与标签

metadata:
  name: myapp-deployment
  labels:
    app: myapp
    version: v1
  annotations:
    build-number: "123"
  • metadata.name 唯一标识符, 在同一个 namespace 下必须唯一
  • labels 键值对标签, 用于组织和筛选资源
  • annotations 用于存储非标识性信息, 例如构建信息, 开发者联系方式等
  • 架构知识:

    • namenamespace 共同构成了资源在集群中的唯一键. apiserver 将资源数据最终存储在 etcd 中, 键类似于 /registery/deployments/defaults/myapp-deployment.
    • labels 是 Kubernets 中核心的组织与选择机制. ServiceDeployment 通过 Label Selector (标签选择器) 来发现并管理一组 Pod. kube-scheduler 也是用标签来将 Pod 调度到具有特定标签的 Node 上.

spec 定义期望状态的规约

spec 的内容完全由 kind 决定. 我们这里详细拆解 Deploymentspec.

spec:
  replicas: 3
  selector: 
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myapp:v1.0.0
        ports:
        - containerPort: 8080
  • spec.replicas 期望的 Pod 副本数量
  • spec.selector 定义如何找到该 Deployment 管理的 Pod
  • spec.matchLabels 必须与 template 中的 labels 匹配
  • spec.template Pod 模板, 定义了如何创建新的 Pod
  • spec.template.labels Pod 的标签, 必须被上面的 selector 选中
  • spec.spec Pod 的 spec

控制器如何工作

这是理解 Kubernets 运行机制的关键

  1. 用于提交清单 -> kubectl 将 YAML 发送给 api-server
  2. apisever 验证并存储 -> 验证格式和字段合法性, 然后作为期望状态存入 etcd
  3. Deployment Controller 监听到变化 -> 它是 kube-controller-manager 的一部分. 它发现期望的 replicas 是 3, 但是当前没有任何 Pod.
  4. Deployment Controller 创建 ReplicaSet -> 它会创建一个中间资源 ReplicaSet, 其 spec 中包含了 Pod 模板和 replicas: 3
  5. ReplicaSet Controller 创建 Pod -> 它发现 Pod 的期望数量为 3, 实际是 0, 于是会创建 3 个 Pod 对象, 这些对象的定义完全来自 template
  6. Scheduler 介入 -> 新建的 Pod 对象此时处于 Pending 状态. kube-scheduler 会持续监听 api-server, 发现这些未被调度的 Pod, 然后根据资源请求与亲和性规则等, 为它们选择一个最优的 Worker Node
  7. Scheduler 更新 Pod 对象 -> 将选定的节点名称写入 Pod 的 spec.nodeName 字段
  8. 目标节点上的 kubelet 监听到 -> 每个节点上的 kubelet 只关注 spec.nodeName 等于自己主机名的 Pod. 它发现有一个 Pod 分配给了自己
  9. kubelet 创建容器 -> kubelet 调用容器 runtime (在 K3s 中为 containerd), 拉取 myapp:v1.0.0 镜像并启动容器
  10. 状态上报 -> kubelet 不断将 Podcast 的运行状态 (如 Running) 上报给 apiserver, 更新到 etcd

    整个流程是异步且最终一致的, 各个组件通过 apiserver 进行协作, 共同推进集群状态向期望状态收敛

至此, Kubernets 的部署清单已经完全介绍完成. 如果你已经了解了 Kubernets 的控制器如何工作, 且明白了其中的一些核心概念, 那么就可以去尝试手写配置文件, 启动你的第一个集群了!


后记

本人非专业 Kubernets 运维人员, 如有错误或疏漏欢迎支持. 如果觉得文章不错, 请将其分享给有需要的人, 感谢阅读!

Kubernets 学习: 一文理解 K8s Deployment 清单文件的含义及作用
https://blog.nanami.tech/archives/282/
本文作者 Madobi Nanami
发布时间 2026-04-11
许可协议 CC BY-NC-SA 4.0
发表新评论