当前位置: 首页 > news >正文

一文吃透 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 学习之路上的一块坚实垫脚石。如果你有任何疑问或建议,欢迎在评论区留言交流。

http://www.cnnetsun.cn/news/3390862.html

相关文章:

  • 2、射频功率放大器设计之偏置电路稳定性考量与仿真优化
  • BMS设计实战:bq4050电流保护与SMBus通信时序配置详解
  • Claude 大模型核心应用场景与落地指南
  • Python网络CSV直读:从HTTP请求到DataFrame的工程化实践
  • 如何在 Pipeline 中使用 GridSearchCV 进行超参数调优?
  • Unity天空盒实战指南:从原理到动态天气系统实现
  • 微信小程序云函数实战:从零到一构建后端逻辑
  • 模板驱动型文档自动化:零代码实现合规PDF批量生成
  • 哈雷摩托车头罩溃缩断裂修复技术:成本仅为更换的零头
  • C++构建高性能期货CTA策略系统:架构、实现与优化
  • RC舵机蓝牙调参技术:从原理到实践的无线PID参数优化方案
  • W25Q256写保护机制深度解析:从状态寄存器到解锁实战
  • <宇将军AI>深度拆解Claude 4.8思维链:透明化推理机制的技术内幕与工程实现
  • Qt信创|联合收割机操作员智能作业管控系统
  • 【SpringBoot篇】登录校验 — JWT令牌的实战进阶:从生成到失效的全链路设计
  • Android Audio音量曲线与分贝映射机制深度解析
  • FPGA之JESD204B接口——链路建立与确定性延迟实战解析
  • MSP430i20xx架构解析:CPU、指令集与低功耗模式实战指南
  • 告别杂乱格式困扰,Gemini 输出的内容粘贴有符号好烦交给 AI 导出鸭
  • 【iOS】优先级反转
  • <宇将军AI>Claude Opus 4.8:AI代码协作的精准革命
  • C++20协程实战:从生成器到异步任务,告别回调地狱
  • 米家72LW-PL30/N1A1立柜空调评测:巨省电与大风口技术解析
  • 深入理解C++ STL算法库:从核心分类到实战应用
  • C++字体库选型指南:从FreeType到HarfBuzz的实战解析
  • Docker部署ClickHouse时序数据库
  • ping命令无效时,我们可以使用工具tcping取而代之
  • C++实现箱线图异常值检测:从算法原理到工程实践
  • ChatGPT Codex与工作模式:AI辅助开发实战指南
  • ChatGPT桌面版:AI工具从网页到工作流的无缝集成变革