news 2026/7/15 6:28:10

一文吃透 K8s Deployment:资源创建、扩缩容与节点自愈实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文吃透 K8s Deployment:资源创建、扩缩容与节点自愈实战

前言

Kubernetes(简称 K8s)作为当前容器编排领域的事实标准,其核心能力之一就是通过多种控制器(Controller)来管理应用的生命周期。在实际生产环境中,我们很少直接操作 Pod —— 因为 Pod 本身不具备自愈、扩缩容、滚动更新等能力。为此,Kubernetes 提供了 Deployment、ReplicaSet、DaemonSet、StatefulSet、Job 等一系列更高层次的对象,其中Deployment是最常用、也最基础的工作负载控制器。

无论是部署一个简单的 Web 服务,还是维护一个复杂的微服务集群,Deployment 都能帮助我们轻松实现声明式管理:你只需要告诉 Kubernetes “我想要运行 3 个实例,使用 httpd 镜像”,它就会自动创建所需的 ReplicaSet 和 Pod,并确保实际状态始终与期望状态一致。此外,Deployment 还天然支持滚动更新、版本回滚、副本扩缩容、节点故障自动迁移等高级功能。

本文将从 Deployment 的基本概念出发,结合实际的命令行输出和 YAML 配置文件,逐步分析 Deployment 的执行流程、创建资源的方式、配置文件编写方法、在线扩缩容操作、节点故障时的自动切换,以及如何通过 Label 控制 Pod 的调度位置。文章内容基于 Kubernetes v1.18.6 环境,所有示例均来自真实操作记录。希望通过这篇详解,能帮助读者从原理到实践全面掌握 Deployment 的使用。


一、Deployment介绍

1. Deployment的概念

为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefulSet、Job 等多种 Controller。其中Deployment是最常用的一种。

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的 Replication Controller,从而更方便地管理应用。

作为最常用的 Kubernetes 对象,Deployment 经常被用来创建 ReplicaSet 和 Pod。我们通常不会直接在集群中使用 ReplicaSet 部署微服务,因为 ReplicaSet 功能不够强大,缺乏更新、扩缩容等常见运维操作。Deployment 的引入正是为了支持这些复杂操作。

2. Deployment执行状态分析

查看 Deployment 的状态,可以使用以下命令:

[root@master k8s]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE http-deployment 3/3 3 3 160m

可以看到,集群中有一个名为http-deployment的 Deployment,它有三个副本且全部正常运行。

要查看某个 Deployment 的详细信息,可以执行:

[root@master k8s]# kubectl describe deployment http-deployment

从输出中发现,存在一个 ReplicaSethttp-deployment-749876cdf4,这说明 Deployment 是通过 ReplicaSet 来管理 Pod 的。

接着查看 ReplicaSet 的状态:

[root@master k8s]# kubectl get replicaset http-deployment-749876cdf4

使用kubectl describe replicaset可以查看更详细的信息:

[root@master ~]# kubectl describe replicaset Name: http-deployment-749876cdf4 Namespace: default Selector: app=http_server, pod-template-hash=749876cdf4 Labels: app=http_server pod-template-hash=749876cdf4 Annotations: deployment.kubernetes.io/desired-replicas: 3 deployment.kubernetes.io/max-replicas: 4 deployment.kubernetes.io/revision: 1 Controlled By: Deployment/http-deployment Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=http_server pod-template-hash=749876cdf4 Containers: http-web: Image: httpd Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 51m replicaset-controller Created pod: http-deployment-749876cdf4-vlfrp Normal SuccessfulCreate 51m replicaset-controller Created pod: http-deployment-749876cdf4-k2xSt Normal SuccessfulCreate 51m replicaset-controller Created pod: http-deployment-749876cdf4-kq9dt

输出中的Controlled By指明该 ReplicaSet 是由 Deploymenthttp-deployment创建的。Events 部分记录了三个副本 Pod 的创建过程。

然后查看 Pod 的状态:

[root@master k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE http-deployment-749876cdf4-k2x5t 1/1 Running 0 101s http-deployment-749876cdf4-kq9dt 1/1 Running 0 101s http-deployment-749876cdf4-vlfrp 1/1 Running 0 101s

可以看到三个副本 Pod 都处于 Running 状态。

使用kubectl describe pod查看更详细的信息:

Controlled By: ReplicaSet/http-deployment-749876cdf4 Containers: http-web: Container ID: docker://3043f79fa114... Image: httpd Image ID: docker-pullable://httpd@sha256:2a9ae199b5... State: Running Started: Fri, 24 Jul 2020 16:53:17 +0800 Ready: True Restart Count: 0 Environment: <none> ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/http-deployment-749876cdf4-89c29 to node2 Normal Pulling 67s kubelet, node2 Pulling image "httpd" Normal Pulled 52s kubelet, node2 Successfully pulled image "httpd" Normal Created 52s kubelet, node2 Created container http-web Normal Started 52s kubelet, node2 Started container http-web

输出中Controlled By指明此 Pod 是由 ReplicaSethttp-deployment-749876cdf4创建。最后的 Events 记录了 Pod 的启动过程。如果操作失败(比如镜像不存在),也可以从这里查看到失败原因。

3. Deployment执行流程总结

Deployment 的实现过程可以总结为以下几步:

  1. 用户通过kubectl创建 Deployment。

  2. Deployment 创建 ReplicaSet。

  3. ReplicaSet 创建 Pod。

  4. Pod 在每个节点上通过 kubelet 调用容器运行时(如 docker)完成容器创建。

对象的命名方式为:子对象的名字 = 父对象名字 + 随机字符串或数字

二、K8s中创建资源的方式

1. 基于命令的方式

  • 优点:简单直观快捷,上手快。

  • 适用场景:适合临时测试或实验。

2. 基于配置文件的方式

  • 优点:资源的属性写在 YAML 配置文件中,描述了最终要达到的状态。配置文件提供了创建资源的模板,能够重复部署,可以像管理代码一样管理部署。

  • 适用场景:适合正式的、跨环境、规模化部署。

  • 注意:这种方式要求熟悉配置文件的语法,有一定难度。后续我们主要采用这种方式,需要尽快熟悉和掌握。

3. 用 kubectl 命令直接创建资源(已部分废弃)

[root@master k8s]# kubectl run nginx-deployment --image=nginx --port=80 [root@master k8s]# kubectl get pod nginx-deployment 1/1 Running 0 31s

从 Kubernetes 1.18 版本开始,已经不支持在命令行中通过参数指定资源的属性(例如--replicas参数已弃用),推荐使用 Deployment 配置文件方式创建 Pod。

4. 通过配置文件和kubectl apply创建资源

[root@master k8s]# more http.yml apiVersion: apps/v1 kind: Deployment metadata: name: http-deployment spec: replicas: 3 selector: matchLabels: app: http_server template: metadata: labels: app: http_server spec: containers: - name: http-web image: httpd

kubectl apply不仅可以创建 Kubernetes 资源,还能对资源进行更新,非常方便。虽然 Kubernetes 还提供了kubectl createkubectl replacekubectl editkubectl patch等命令,但kubectl apply已经能够应对超过 90% 的场景。

三、通过 YAML 文件编写 Deployment 配置

Deployment 的配置格式详解

http.yml为例进行说明:

字段说明
apiVersion当前配置格式的版本。可以通过kubectl api-resources找到所有资源,再用kubectl explain deploy获取版本和类型信息。
kind要创建的资源类型,这里是Deployment
metadata该资源的元数据,name是必需的,可任意指定。
spec(第一层)Deployment 的规格说明。
replicas副本数量,默认为 1,这里指定为 3。
selector选择器,matchLabels用于匹配标签。发布 Service 时,selector需要与此处对应。
template定义 Pod 的模板,是配置文件的重点部分。
template.metadata定义 Pod 的元数据,至少要定义一个label,key/value 可任意指定。
template.spec描述 Pod 的规格,定义 Pod 中每个容器的属性,nameimage是必需的。

注意:containers后面是一个列表,所以每项前面需要加一个短横线-

四、在线增加或减少 Pod 的副本数

1. 增加 Pod 副本数

修改http.yml文件,将replicas从 3 增加到 5,然后重新应用配置:

[root@master k8s]# kubectl apply -f http.yml deployment.apps/http-deployment configured [root@master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE http-deployment-749876cd4f-89c29 1/1 Running 0 76m 10.244.2.5 node2 http-deployment-749876cd4f-bj7v9 1/1 Running 0 76m 10.244.1.7 node1 http-deployment-749876cd4f-gv8cw 1/1 Running 0 22s 10.244.1.8 node1 http-deployment-749876cd4f-hxkks 1/1 Running 0 76m 10.244.1.6 node1 http-deployment-749876cd4f-ldq8q 1/1 Running 0 22s 10.244.2.8 node2

可以看到 Pod 数量由 3 个增加到了 5 个。

2. 减少 Pod 副本数

修改http.yml文件,将replicas从 5 减少到 3(或 2),重新应用即可。Kubernetes 会自动终止多余的 Pod。

五、Node 节点故障时的 Pod 切换

假设当前有 3 个 httpd 副本分别运行在 node1 和 node2 上:

[root@master k8s]# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 8h v1.18.6 node1 Ready <none> 8h v1.18.6 node2 Ready <none> 8h v1.18.6 [root@master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE http-deployment-749876cdf4-brmt7 1/1 Running 0 16s 10.244.1.12 node1 http-deployment-749876cdf4-jt4bd 1/1 Running 0 16s 10.244.1.11 node1 http-deployment-749876cdf4-p56tb 1/1 Running 0 16s 10.244.2.9 node2

现在模拟 node1 故障,关闭该节点,然后查看状态:

[root@master k8s]# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 8h v1.18.6 node1 NotReady <none> 8h v1.18.6 node2 Ready <none> 8h v1.18.6 [root@master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE http-deployment-749876cd4-rmt7 1/1 Terminating 0 7m56s 10.244.1.12 node1 http-deployment-749876cd4-jt4bd 1/1 Terminating 0 7m56s 10.244.1.11 node1 http-deployment-749876cd4-17jkd 1/1 Running 0 83s 10.244.2.11 node2 http-deployment-749876cd4-ndb9g 1/1 Running 0 83s 10.244.2.10 node2 http-deployment-749876cd4-p56tb 1/1 Running 0 7m56s 10.244.2.9 node2

可以看到,node1 状态变为NotReady。等待一段时间,Kubernetes 会检测到 node1 不可用,将 node1 上的 Pod 标记为Terminating状态,并在 node2 上新建两个 Pod,使总副本数维持在 3 个。

当 node1 恢复后,Terminating的 Pod 会被删除,但已经在 node2 上运行的 Pod 不会重新调度回 node1。

六、通过 Label 控制 Pod 的位置

默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node。但有时我们希望将 Pod 部署到指定的 Node(例如将大量磁盘 I/O 的 Pod 部署到配置了 SSD 的节点,或需要 GPU 的 Pod 部署到 GPU 节点)。

Kubernetes 通过Label实现这个功能。Label 是 key-value 对,各种资源都可以设置 Label,灵活添加自定义属性。

1. 给 Node 添加 Label

执行如下命令,标注 node1 是配置了 SSD 磁盘的节点:

[root@master k8s]# kubectl label node node1 disk=ssd [root@master k8s]# kubectl get node --show-labels

注意:disk=ssddisk是 key,ssd是 value,都是自定义的。除了自定义 label,Node 上还有几个 Kubernetes 自己维护的 label。

2. 编写带 nodeSelector 的 Deployment

编写一个nginx.yml文件,内容如下:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx_server template: metadata: labels: app: nginx_server spec: containers: - name: nginx-web image: nginx nodeSelector: disk: ssd

在 Pod 模板的spec中通过nodeSelector指定将此 Pod 部署到具有 labeldisk=ssd的 Node 上。

注意:nodeSelector需要与containers保持同级,且其中的S必须大写。

3. 删除 Label

要删除 label,执行:

[root@master k8s]# kubectl label node node1 disk-

删除之后,已存在的 Pod 并不会重新部署,依然会在原节点上运行。要改变 Pod 运行的节点,需要修改nodeSelector设置,然后通过kubectl apply重新部署。


结语

通过本文的详细介绍,我们系统性地学习了 Kubernetes Deployment 的方方面面:从它作为 ReplicaSet 和 Pod 上层控制器的基本定位,到实际的创建、查看、更新操作;从 YAML 配置文件的逐字段解析,到在线扩缩容、节点故障自愈等强大特性;最后还掌握了如何通过 Label 和 nodeSelector 精准控制 Pod 的调度位置。

Deployment 的设计思想体现了 Kubernetes 声明式 API 的精髓 —— 用户只需要描述“想要什么”,系统会持续不断地将实际状态调整为期望状态。这种模式极大地降低了运维复杂度,也为自动化运维和 GitOps 实践奠定了坚实基础。

在实际生产环境中,Deployment 通常还会结合 Service、Ingress、ConfigMap、Secret 等对象共同工作,形成一个完整的应用部署方案。作为 Kubernetes 学习的起点,深入理解 Deployment 的使用方法和原理,将帮助你更轻松地掌握 StatefulSet(有状态应用)、DaemonSet(守护进程)、Job/CronJob(任务型应用)等其它控制器,从而从容应对各种复杂业务场景。

希望本文能成为你 Kubernetes 学习之路上的一块坚实垫脚石。如果你有任何疑问或建议,欢迎在评论区留言交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 6:26:27

2、射频功率放大器设计之偏置电路稳定性考量与仿真优化

1. 射频功率放大器偏置电路稳定性挑战射频功率放大器&#xff08;PA&#xff09;的偏置电路设计是整个系统稳定性的关键所在。在实际工程中&#xff0c;我们经常会遇到三个"杀手级"问题&#xff1a;温度漂移、电源电压波动和版图寄生效应。这些问题会导致放大器增益波…

作者头像 李华
网站建设 2026/7/15 6:25:51

BMS设计实战:bq4050电流保护与SMBus通信时序配置详解

1. 项目概述&#xff1a;为什么电流保护与通信时序是BMS设计的命门在嵌入式电池管理系统&#xff08;BMS&#xff09;的设计中&#xff0c;有两项看似基础却至关重要的任务常常让工程师头疼&#xff1a;一是如何确保电池在异常大电流冲击下能毫秒级响应并安全关断&#xff0c;二…

作者头像 李华
网站建设 2026/7/15 6:24:35

Claude 大模型核心应用场景与落地指南

在处理日常开发任务时&#xff0c;我们常常被海量的文档淹没&#xff0c;从几百页的技术规范到错综复杂的遗留代码库&#xff0c;单纯依靠人工阅读和梳理不仅效率低下&#xff0c;还极易遗漏关键细节。很多时候&#xff0c;团队花费数天时间整理会议纪要或清洗数据&#xff0c;…

作者头像 李华
网站建设 2026/7/15 6:23:54

Python网络CSV直读:从HTTP请求到DataFrame的工程化实践

1. 项目概述&#xff1a;为什么“直接读取网络CSV”是每个数据从业者绕不开的基本功你有没有遇到过这样的场景&#xff1a;早上刚收到运营同事发来的链接&#xff0c;说“最新用户行为数据在这儿&#xff0c;快跑个分析”&#xff0c;点开一看是https://data.example.com/repor…

作者头像 李华
网站建设 2026/7/15 6:23:45

如何在 Pipeline 中使用 GridSearchCV 进行超参数调优?

文章目录一、核心规则&#xff08;必须记住&#xff09;二、最简可运行完整代码三、详细拆解&#xff1a;每一步怎么写&#xff1f;1. 先给 Pipeline 步骤起名2. 搜索参数必须用&#xff1a;步骤名__参数3. 传入 GridSearchCV四、超常用模板&#xff08;直接复制&#xff09;模…

作者头像 李华
网站建设 2026/7/15 6:23:41

Unity天空盒实战指南:从原理到动态天气系统实现

1. 项目概述&#xff1a;为什么天空盒是Unity场景的灵魂做Unity开发这么多年&#xff0c;我越来越觉得&#xff0c;一个项目的“第一眼”印象&#xff0c;很大程度上取决于天空。新手可能会把大量精力放在主角模型、场景搭建上&#xff0c;但往往忽略了一个最基础也最影响氛围的…

作者头像 李华