k8s容器编排技术实践——K8s对象deployment应用详解

k8s容器编排技术实践------OpenEuler的k8s高可用集群构建实战https://blog.csdn.net/xiaochenXIHUA/article/details/161345015k8s容器编排技术实践------k8s的介绍及其整体运行架构https://coffeemilk.blog.csdn.net/article/details/161011629

一、Deployment简介

为满足不同业务场景,k8s开发了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多种Controller。Deployment 为Pod和ReplicaSet提供了一个声明式定义 (declarative) 方法,用来替代以前的 Replication Controller更方便的管理应用。Deployment作为最常用的Kubernetes对象,经常会用来创建 ReplicaSet和Pod,但不会直接在集群中使用ReplicaSet部署一个新的微服务(是因为ReplicaSet 的功能其实不够强大,一些常见的更新、扩容和缩容运维操作都不支持)Deployment的引入就是为了支持这些复杂的操作 。

1.1、Deployment是什么

Deployment 是 Kubernetes(K8s)最核心、使用最广泛的工作负载控制器 ,专门用于管理无状态应用的 Pod 集群。

K8s 不会让 Deployment 直接管理 Pod,而是采用多层封装DeploymentReplicaSet(副本集) → Pod

核心层级关系 说明
Deployment 在上层管理 ReplicaSet,提供发布、回滚、更新、版本控制等高级能力,是面向开发者 / 运维的入口。
ReplicaSet 负责保证集群中始终运行指定数量的正常 Pod。
Pod K8s 最小运行单元,真正运行业务的容器。

可简单理解为:Deployment 是 Pod 集群的「大管家」,帮你批量管理、运维一组功能完全相同的应用实例。

1.2、Deployment有啥用

Deployment几乎覆盖了线上无状态服务的全生命周期运维,核心能力如下:

Deployment核心作用 说明
✅副本保活 & 故障自愈 通过 replicas 字段指定期望运行的 Pod 副本数量(比如 3 个)。 * 若 Pod 崩溃、容器异常、所在节点宕机; * Deployment 会通过 ReplicaSet 自动新建 Pod 补足数量; 从根源上解决单实例单点故障,保障服务高可用。
✅应用扩缩容 * 手动扩缩 :直接修改 replicas 数值,即可快速增加 / 减少实例数,应对流量变化; * 自动扩缩 :无缝对接 K8s HPA(水平Pod自动扩缩器),根据 CPU、内存、QPS 等指标自动增减副本,适配流量峰谷(如电商大促、活动流量)。
✅零停机滚动更新(最核心) 默认使用 RollingUpdate(滚动更新) 策略发布新版本:逐步销毁旧版本 Pod、同时创建新版本 Pod,整个发布过程服务不中断。 还可精细控制更新节奏: * maxUnavailable:更新过程中允许最大不可用 Pod 数; * maxSurge:更新过程中允许临时多出的 Pod 数。 另有 Recreate 策略(先删全部旧 Pod,再建新 Pod),会造成服务中断,仅测试环境使用
✅版本记录 & 一键回滚 Deployment 会自动记录每一次配置 / 镜像变更,生成历史版本(Revision): * 新版本上线出现 Bug、性能问题、报错时; * 可一键回滚到任意历史稳定版本,快速止损,降低线上故障影响。
✅发布暂停 / 恢复 支持临时暂停发布,批量修改配置、镜像、环境变量后再统一生效,避免多次触发更新。
✅标签解耦管理 依靠 Label(标签)和 Selector(选择器)关联 Pod,控制器与 Pod 完全解耦,调度、运维更加灵活。

1.3、Deployment的适用场景与不适用场景

明确前提:Deployment 主打「无状态应用」 (无状态应用:Pod 之间完全等价、无身份区分,不依赖本地磁盘存储数据,销毁 / 重建 Pod 不会影响业务,数据统一存放在外部组件(MySQL、Redis、对象存储等))

Deployment的适用场景 说明
✅Web / 微服务 / API 接口(最主流) 如 SpringBoot/Dubbo 微服务、Nginx 反向代理、前端静态服务、网关、RESTful API 等。这类服务多副本负载均衡、迭代频繁,是 Deployment 标准使用场景。
✅需要 7×24 在线、零停机发布的业务 互联网核心业务、C 端用户服务,不允许停机维护,依赖滚动更新实现无感发布。
✅流量波动大、需要弹性伸缩的服务 活动页面、秒杀接口、推送服务等,搭配 HPA(Horizontal Pod Autoscaler,Pod 水平自动扩缩器) 实现自动扩缩容,节约资源同时扛住峰值流量。
✅无状态中间件 & 消费端 如 MQ 消费端、日志转发程序、监控采集客户端、无状态 Redis 节点等。
✅测试 / 演示环境批量部署 快速拉起多套测试实例,一键重建、销毁,提升测试效率。
绝对不推荐使用 Deployment 的场景 说明
❌有状态应用(核心禁区) 如 MySQL、PostgreSQL、MongoDB、ZooKeeper、etcd、主从架构组件。 特点:Pod 有固定身份、有序启停、需要稳定域名 / 网络标识、依赖本地持久化存储。 替代方案:StatefulSet
❌节点级守护进程 要求每个集群节点上必须运行一个 Pod,如日志采集器 Filebeat、节点监控 Agent、网络组件。 替代方案:DaemonSet
❌一次性定时 / 离线批处理任务 如数据备份、离线计算、脚本任务(任务跑完就主动退出)。 Deployment 会不断重启已完成任务的 Pod,造成资源浪费。 替代方案:Job(一次性任务)、CronJob(定时任务)
❌需要主从选主、固定角色的集群 所有 Pod 完全等价,无法区分主节点、备节点,不适合集群选主架构。

1.4、Deployment的优缺点

Deployment的优点 说明
✅上手简单、生态成熟 配置语法简洁,是 K8s 入门首选控制器,社区工具、监控、CI/CD 流水线均深度适配。
✅高可用 & 自愈能力强 容器、节点故障自动重建 Pod,从底层规避单点故障,大幅降低运维压力。
✅发布体验优秀 原生支持零停机滚动更新 + 版本回滚,线上发布、故障应急流程标准化。
✅弹性能力完善 原生支持手动扩缩,无缝对接 HPA 实现全自动弹性,适配各类流量场景。
✅资源复用性高 应用模板可在开发、测试、生产多环境复用,统一部署规范。
✅调度灵活 基于标签管理 Pod,配合节点亲和、污点、容忍等调度策略,灵活分配资源。
Deployment的缺点 说明
❌仅支持无状态应用 天生不具备有状态服务所需的能力:无法提供固定主机名、稳定网络标识、有序启停、Pod 与存储一对一绑定,不能用于数据库、集群类有状态组件。
❌所有 Pod 身份完全一致 无法区分主 / 备、不同角色的实例,不适合需要节点角色划分的架构。
❌存储绑定能力弱 Pod 重建后可能被调度到其他节点,无法固定 Pod 与本地存储 / 磁盘的对应关系,容易造成数据丢失。
❌复杂灰度发布能力不足 原生仅支持标准滚动更新,金丝雀发布、按比例流量灰度、地域灰度等复杂发布,需要额外配合 Service、Ingress、流量网关实现。
❌滚动更新存在小幅流量波动 更新过程中 Pod 数量动态变化,副本数极少时可能出现短暂负载不均;且发布耗时长于蓝绿发布。
❌历史版本有上限 默认最多保留 10 个历史 Revision,版本过多会占用集群 etcd 存储,需要手动清理或调整保留数量。
❌不适合短生命周期任务 一旦 Pod 正常执行完毕退出,Deployment 会反复重启 Pod,资源利用率极低。

二、Deployment

2.1、Deployment的执行状态解析

Deployment执行状态 说明
查看deployment状态 kubectl get deployment 该命令可查看到k8s集群中的所有deployment内容,且可知道每个deployment的副本情况(即:共指定了几个副本,几个副本在线,几个副本可用)
查看指定deployment的详情 kubectl describe deployment http-deployment 该命令可直接查看名为【http-deployment】内容的详情,在命令倒数第二行可以看到【NewReplicaSet: http-deployment-6d6d5f65c9 (3/3 replicas created)】内容,因此可以知道Deployment是通过 ReplicaSet 来管理 Pod 的
查看指定ReplicaSet状态 kubectl get replicaset http-deployment-6d6d5f65c9 该命令可直接查看名为【http-deployment-6d6d5f65c9】的replicaset的状态信息
查看指定ReplicaSet的详情 kubectl describe replicaset http-deployment-6d6d5f65c9 该命令可直接查看名为【http-deployment-6d6d5f65c9】的replicaset的详细信息,从输出可以看出,Controlled By指明此 ReplicaSet 是由 Deployment http-deployment创建。Events记录了3个副本 Pod的创建。
查看pod的状态 kubectl get pod 该命令可查看到所有pod节点及其相应的基础状态信息 kubectl get pod -o wide 该命令可查看到所有pod节点及其相应的详细状态信息
查看指定pod的详情 kubectl describe pod http-deployment-6d6d5f65c9-2zfwn 该命令可查看到指定pod的详细信息(输出结果中Controlled By指明此Pod 是由ReplicaSet/http-deployment-6d6d5f65c9创建。最后的Events记录了Pod的启动过程) 注意:若操作失败(如 image 不存在),也能从这里也能查看到失败的原因。
查看指定pod的日志排查问题 kubectl logs http-deployment-6d6d5f65c9-2zfwn

总结一下deployment实现的过程:

  1. 首先用户通过 kubectl 创建 deployment。
  2. 接着,deployment 创建 ReplicaSet。
  3. 然后,ReplicaSet 创建 Pod
  4. 最后,pod在每个节点上通过kubelet调用docker完成容器创建。

可以看出,对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。

2.2、k8s中创建资源的方式

2.2.1、基于命令行方式创建

  1. 简单直观快捷,上手快;
  2. 适合临时测试或实验;

注意:从1.18版本之后,k8s已经不支持在命令行中通过参数指定资源的属性。这种方式已经基本废弃(--replicas参数已弃用,k8s推荐用deployment创建 pods)。

bash 复制代码
#直接用kubectl命令直接创建资源
kubectl run nginx-deployment --image=library/nginx --port=80

#查看当前所有的pod
kubectl get pod

#删除指定名称的pod
kubectl delete pod nginx-deployment

2.2.2、通过配置文件和kubectl apply命令创建资源【推荐使用】

bash 复制代码
#通过配置文件和kubectl apply命令创建资源
#1-创建资源文件
cat > httpd.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
   name: httpd-deployment
spec:
  replicas: 3
  selector:
   matchLabels:
     app: httpd_server
  template:
   metadata:
     labels:
       app: httpd_server
   spec:
    containers:
    - name: httpd-web
      image: library/httpd:2.4.67
EOF


#2-创建指定资源
kubectl apply -f httpd.yml

#查看当前所有pod状态
kubectl get pod

#3-删除指定资源
kubectl delete -f httpd.yml

kubectl apply不但能够创建 Kubernetes资源,也能对资源进行更新,非常方便。不过Kubernets还提供了几个类似的命令(如:kubectl create、kubectl replace、kubectl edit 和 kubectl patch。但 kubectl apply命令已经能够应对超过 90% 的场景)。

deployment资源文件内容 说明
apiVersion 当前配置格式的版本(先执行kubectl api-resources找到所有的资源,再执行命令 kubectl explain deploy即可获取到版本和类型信息)
kind 要创建的资源类型,这里是Deployment
metadata 该资源的元数据,name是必需的元数据项,后面名字任意起一个即可。
第一个spec 第一个spec部分是该Deployment的规格说明
replicas 指明副本数量,默认为 1,这里指定为3。
selector 是个选择器, matchLabels是个匹配标签, 在发布Service时,selector需要和这里对应。
template 定义Pod的模板,这是配置文件的重要部分。
metadata 定义Pod的元数据,至少要定义一个label。label的key和value可以任意指定。
第二个spec 第二个spec描述Pod的规格,此部分定义Pod中每一个容器的属性,name和image是必需的。 注意:最后name前面需要加个中杠,是因为container后面是一个列表。

2.2.3、增加pod副本数

修改httpd.yml文件,将副本数从3增加到6,然后查看pod状态,如下图所示:

2.2.4、减少pod副本数

修改httpd.yml文件,将副本数从6减少到3,然后查看pod状态,如下图所示:

2.2.5、node节点故障时pod切换

现在有3 个 httpd副本分别运行在node2 上,如下图所示:

现在模拟 node2故障(即:关闭该节点服务器),然后查看pod状态,如下图所示:

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

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

三、通过label 控制 Pod 的位置

默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node。不过有些情况希望将 Pod 部署到指定的 Node(如:将有大量磁盘I/O的Pod部署到配置了SSD的Node节点上;或者Pod需要GPU,需要运行在配置了GPU的节点上)。k8s是通过label来实现这个功能的。label是key-value 对,各种资源都可以设置label,灵活添加各种自定义属性。

bash 复制代码
#将pod指定到对应的node节点上
#标注k8s-node1是配置了SSD磁盘的节点
kubectl label node k8s-node1  disk=ssd2

#查看所有节点的全部标签
kubectl get node --show-labels

#查看指定节点的标签
kubectl get node k8s-node1 --show-labels

#通过标签筛选节点(如:只列出带有disk=ssd2标签的节点)
kubectl get node -l disk=ssd2

#修改已存在的标签(如:将disk标签值改为ssd3)
kubectl label node k8s-node1 disk=ssd3 --overwrite

#删除指定节点标签(如:删除k8s-node1节点上的disk标签)
#标签删除之后,Pod 并不会重新部署,依然会在node1上运行。要改变Pod运行的节点,需要修改nodeSelector设置,然后通过 kubectl apply 重新部署即可。
kubectl label node k8s-node1 disk-

#一条命令添加多个标签(使用空格分隔多个key=value)
kubectl label node k8s-node1 disk=ssd2 env=prod arch=x86
kubectl label node k8s-node1 disk=ssd2命令解析 说明
kubectl Kubernetes 官方命令行客户端,集群操作入口
label kubectl 子命令,专门用来新增 / 修改 / 删除 资源标签 (Label)
node 操作的资源类型,此处目标是集群节点 (Node)
k8s-node1 目标节点名称(需与 kubectl get nodes 查到的节点名完全一致)
disk=ssd2 标签键值对 * 标签键:disk * 标签值:ssd2 注意: 《1》集群节点多、业务复杂时,提前约定规则( * 格式:磁盘类型_容量_编号 * 示例:nvme_1t_01ssd_2t_02 ); 《2》保持格式统一,不要混用多种写法(如:不要同一类磁盘一会儿写 ssd2、一会儿写 ssd_2,避免标签筛选失效); 《3》结合标签用途(磁盘类型、硬件、环境、角色等)取语义清晰、格式统一的值,不要随意写无意义字符。 《4》标签值不能使用大写、空格、中文、特殊符号。
bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: httpd_server
  template:
    metadata:
      labels:
        app: httpd_server
    spec:
      containers:
      - name: httpd-web
        image: library/httpd:2.4.67
      # 节点选择器:绑定 disk=ssd2 标签节点
      nodeSelector:
        disk: ssd2
相关推荐
bukeyiwanshui19 小时前
20260626 k8sControllers介绍
云原生·容器·kubernetes
能有时光20 小时前
] K8s 核心组件使用指南
云原生·容器·kubernetes
云烟成雨TD21 小时前
Kubernetes 系列【13】控制器:可视化操作 Deployment
云原生·容器·kubernetes
运维老郭1 天前
【K8s运维实战】Kubernetes临时存储卷实战:emptyDir核心用法与gitRepo弃用迁移指南
运维·云原生·kubernetes
gs801402 天前
记一次多 Agent 架构在单节点 K8s 触发的 PID 耗尽与 Pod 驱逐(Evicted)大摸排
容器·架构·kubernetes
bukeyiwanshui2 天前
20260701 k8s Metric Server
容器·贪心算法·kubernetes
Zhu7582 天前
在k8s集群部署ApacheHadoop单节点单数据副本
云原生·容器·kubernetes
摇滚侠2 天前
云原生 Java 架构师的第一课 K8s+Docker+KubeSphere+DevOps 51-60
java·云原生·kubernetes
bukeyiwanshui2 天前
20260703 K8s ECShop商城项目
云原生·容器·kubernetes