K8S - ReplicaSet 与 Deployment 深度解析与实战

一、引言

1.1 工作负载简介

Kubernetes 工作负载(Workload)是定义应用运行形态的核心对象,决定了 Pod 的部署方式、生命周期管理策略及资源调度规则。深入理解各类工作负载的 设计目标和 适用场景,是构建稳定可靠的容器化应用的基础。

在 Kubernetes 中,Pod 是最小的调度单元,同时也是一种工作负载。但在实际应用中,通常不会直接使用 Pod,而是通过更高级的工作负载对象(如 Deployment、StatefulSet 等)来管理 Pod,以提升可维护性和扩展性。

Kubernetes 提供了多种工作负载类型,包括:

• ReplicaSet

• Deployment(最常用)

• StatefulSet

• DaemonSet

• Job

• CronJob

其中,Deployment 是最常见的工作负载,掌握它即可满足大部分业务需求。

在这里插入图片描述

1.2 副本管理的重要性

在 Kubernetes 集群中,副本管理的核心在于 Pod 副本的生命周期控制,涉及以下三个关键维度:

• 数量控制:确保集群中始终运行指定数量的 Pod(ReplicaSet 的核心职责)。

• 版本控制:支持不同版本的 Pod 交替更新,确保平滑升级与回滚(Deployment 的核心价值)。

• 状态维护:自动检测并修复异常 Pod(如节点故障后触发重建),提高系统稳定性。

副本管理不当会导致以下严重后果:
在这里插入图片描述

二、核心原理解析

2.1 ReplicaSet:副本控制基石

设计目标:确保指定数量的Pod副本始终可用。

三大核心机制:

1.副本保障:持续监控Pod数量,自动补充异常终止的实例。

2.标签选择:通过 selector匹配具有特定标签的Pod。

3.模板控制:使用 podTemplate定义新Pod的创建规范。

配置示例:

apiVersion: apps/v1 
kind: ReplicaSet     # 资源类型,表示 ReplicaSet 工作负载

metadata:
  name: gitops-demo-app-rs  # ReplicaSet 的唯一名称
  labels:
    app: gitops-demo-app    # 标签,用于标识应用

spec:
  replicas: 3  # 副本数,确保有 3Pod 运行
  selector:    # 用于匹配目标 Pod 的标签选择器
    matchLabels:
      app: gitops-demo-app   # 选择具有该标签的 Pod

  template:   # 定义 Pod 的模板
    metadata:
      labels:
        app: gitops-demo-app  # Pod 的标签,确保与 ReplicaSet 匹配

    spec:
      containers:
        - name: app  # 容器名称
          image: your-dockerhub-username/gitops-demo-app:v1  # 容器镜像和版本
          ports:
            - containerPort: 5000  # 容器暴露端口

关键限制:

• 直接修改模板不会触发现有Pod更新。

• 缺乏版本历史记录能力

• 不支持渐进式更新策略

2.2 Deployment:高级部署控制器

设计目标:在ReplicaSet基础上实现 声明式更新与 版本控制。

四大核心能力:

1.滚动更新:通过渐进式替换实现零停机部署

2.版本回滚:保留历史 ReplicaSet,支持快速回退

3.扩缩容:动态调整副本数量应对流量变化

4.暂停/恢复:支持分阶段更新验证

配置示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: python-web-deploy
spec:
  replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: python-web
  template:
    metadata:
      labels:
        app: python-web
    spec:
      containers:
      - name: app
        image: your-dockerhub-username/gitops-demo-app:v1
        ports:
        - containerPort: 5000

滚动更新的架构原理:

Deployment(版本v1)
└─ ReplicaSet-v1(管理3Pod)
   ├─ Pod-v1-abc1f9d2a8
   ├─ Pod-v1-d3f9b9e4d7
   └─ Pod-v1-f2b5c8a3b9

更新镜像后:
Deployment(版本v2)
└─ ReplicaSet-v2(逐步创建)
   ├─ Pod-v2-7a7bda9d3c
   └─ ReplicaSet-v1(逐步终止)
      └─ Pod-v1-d3f9b9e4d7(剩余实例)

2.3 Deployment 与 ReplicaSet 的关系与区别
层级管理关系:

• ReplicaSet 直接管理 Pod:负责创建、删除 Pod 实例,确保副本数(replicas)始终符合预期。

• Deployment 间接管理 Pod:通过创建新的 ReplicaSet 进行版本更新,并逐步缩容旧的 ReplicaSet,实现平滑升级。

用户 → 操作 Deployment → 生成 ReplicaSet(版本N) → 管理 Pod(副本组)
                          │
                          └─ 保留 ReplicaSet(版本N-1)→ 历史 Pod 记录

更新机制:

ReplicaSet:修改配置(如镜像版本)后,需手动删除旧 Pod 才能创建新版本 Pod。

Deployment:修改配置后,自动创建新 ReplicaSet,并逐步替换旧 Pod(旧 ReplicaSet 缩容,新 ReplicaSet 扩容)。

核心区别对照表

在这里插入图片描述

三、实战环境准备

1. 安装必要工具

Mac/Linux 用户

# 安装 Docker 并启动服务
brew install --cask docker
open /Applications/Docker.app
# 安装 kubectl 命令行工具
brew install kubectl
# 安装 Kind(本地K8S集群工具)
brew install kind
# 验证安装
docker --version          # 预期输出: Docker version 24.x+
kubectl version --client  # 预期输出: Client Version: v1.28.x
kind version              # 预期输出: kind v0.20.x

Windows 用户

下载Docker Desktop

安装 Chocolatey(包管理器):

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
通过 Chocolatey 安装工具:
choco install kind kubernetes-cli

2. 创建本地 Kubernetes 集群

# 创建单节点集群(命名为 k8s-lab)
kind create cluster --name k8s-lab

# 验证集群状态
kubectl cluster-info
# 预期输出:Kubernetes control plane is running at https://127.0.0.1:xxxxx

四、实战:ReplicaSet vs Deployment

4.1 ReplicaSet 实验

实验目的:验证ReplicaSet 仅管理 Pod 数量。在Pod数未变的情况下,不做pod 更新。

步骤1:创建 ReplicaSet并部署到集群

使用第四章 实例中的镜像。也可直接使用 nginx:1.25镜像,它是 Docker 官方提供的公开镜像。

# 保存为 replicaset-app.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: gitops-demo-app-rs  
  labels:
    app: gitops-demo-app    # 与 Deployment 一致
spec:
  replicas: 3  
  selector:
    matchLabels:
      app: gitops-demo-app  # 必须与 template 中的 labels 匹配
  template:
    metadata:
      labels:
        app: gitops-demo-app  # 统一标签
    spec:
      containers:
      - name: app
        image: your-dockerhub-username/gitops-demo-app:v1  # 与第四章一致
        ports:
        - containerPort: 5000
       
 应用配置并验证pods
# 应用配置
kubectl apply -f replicaset-app.yaml
# 查看 Pod(等待所有 Pod 状态为 Running)
kubectl get pods -l app=python-web -w
输出(所有 Pod 进入 Running 状态):

NAME                           READY   STATUS    RESTARTS   AGE
gitops-demo-app-rs-abc1f9d2a8   1/1     Running   0          5m
gitops-demo-app-rs-d3f9b9e4d7   1/1     Running   0          5m
gitops-demo-app-rs-f2b5c8a3b9   1/1     Running   0          5m

说明:

• ReplicaSet 负责维持 spec.replicas指定的 Pod 副本数(这里是 3个)。

• Kubernetes 自动创建 Pod,并确保它们运行正常。

• -w选项用于实时观察 Pod 状态变化。

步骤2:更新 ReplicaSet 镜像(v2 )并应用到集群
在包含Dockerfile的项目目录下运行以下命令,将新版本镜像构建并推送至 Docker Hub:

docker build -t your-dockerhub-username/gitops-demo-app:v2 .
docker login
docker push your-dockerhub-username/gitops-demo-app:v2

修改replicaset-app.yaml 的 镜像版本为 v2,并应用更新:

containers:
  - name: app
    image: your-dockerhub-username/gitops-demo-app:v2
# 重新应用到集群
kubectl apply -f replicaset-app.yaml

步骤3: 验证Pod镜像未自动更新

kubectl get pods -l app=python-web -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
输出(镜像未变):

gitops-demo-app-rs-abc1f9d2a8   your-dockerhub-username/gitops-demo-app:v1
gitops-demo-app-rs-d3f9b9e4d7   your-dockerhub-username/gitops-demo-app:v1
gitops-demo-app-rs-f2b5c8a3b9   your-dockerhub-username/gitops-demo-app:v1

步骤4:删除旧 Pod,验证Pod 总数不变。

删除pod gitops-demo-app-rs-abc1f9d2a8 

kubectl delete pod gitops-demo-app-rs-abc1f9d2a8
输出:
pod "gitops-demo-app-rs-abc1f9d2a8" deleted
观察新 Pod 重建过程

kubectl get pods -l app=python-web -w
输出:新建1个pod,恢复到总副本数 3个pod

NAME                           READY   STATUS        RESTARTS   AGE
gitops-demo-app-rs-7a7bda9d3c   1/1     Running       0          3m
gitops-demo-app-rs-d3f9b9e4d7   1/1     Running       0          30m
gitops-demo-app-rs-f2b5c8a3b9   1/1     Running       0          30m

步骤 5:验证所有Pod 镜像版本

kubectl get pods -l app=gitops-demo-app -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
输出(新 Pod 采用 v2 ,其他 Pod 仍是 v1):

gitops-demo-app-rs-7a7bda9d3c   your-dockerhub-username/gitops-demo-app:v2
gitops-demo-app-rs-d3f9b9e4d7   your-dockerhub-username/gitops-demo-app:v1
gitops-demo-app-rs-f2b5c8a3b9   your-dockerhub-username/gitops-demo-app:v1

说明:

• gitops-demo-app-rs-7a7bda9d3c是新创建的 Pod,镜像为 v2。

• gitops-demo-app-rs-d3f9b9e4d7和 gitops-demo-app-rs-f2b5c8a3b9是之前的 Pod,镜像为 v1。

结论:

ReplicaSet 仅维持 Pod 数量,不自动更新镜像。

ReplicaSet 适用于维持副本数,但不支持自动升级,需结合其他机制实现版本管理。

4.2 Deployment 实验

实验目的:验证Deployment 支持滚动更新,通过创建多个replicaset实现。

步骤 1:创建 Deployment 并应用配置

保存以下内容为deployment-app.yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: python-web-deploy
spec:
  replicas: 3  # 指定 Pod 副本数,即期望同时运行的 Pod 数量为 3
  strategy:
    rollingUpdate:
      maxSurge: 1  # 允许在滚动更新过程中额外创建 1 个新 Pod,以保证可用性
      maxUnavailable: 0  # 滚动更新时不会减少现有的可用 Pod,确保始终有 3Pod 在运行
  selector:
    matchLabels:
      app: python-web
  template:
    metadata:
      labels:
        app: python-web
    spec:
      containers:
      - name: app
        image: your-dockerhub-username/gitops-demo-app:v1  # 这里定义了应用的初始镜像版本
        ports:
        - containerPort: 5000  # 指定容器对外暴露的端口

注:请将your-dockerhub-username替换为您的 Docker Hub 用户名。

应用配置并查看 Deployment 状态:

# 应用配置
kubectl apply -f deployment-app.yaml

# 查看部署状态
kubectl get deployments python-web-deploy
输出:
NAME                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
python-web-deploy   3         3         3            3           2m
验证 Pod 状态

kubectl get pods -l app=python-web
输出:(3个pods 已被创建并运行)
NAME                                 READY   STATUS    RESTARTS   AGE
python-web-abcde-xyz01               1/1     Running   0          5m
python-web-abcde-xyz02               1/1     Running   0          5m
python-web-abcde-xyz03               1/1     Running   0          5m

步骤2:触发滚动更新

更新镜像版本到 v2

执行以下命令更新镜像版本:

kubectl set image deployment/python-web-deploy app=your-dockerhub-username/gitops-demo-app:v2

输出

deployment.apps/python-web-deploy image updated

步骤3:验证滚动更新状态

(1)实时观察 ReplicaSet 变化

在滚动更新过程中,Kubernetes 通过ReplicaSet控制 Pod 的逐步替换。执行以下命令查看 ReplicaSet 变化:

kubectl get replicaset -l app=python-web -w

输出:

NAME                            DESIRED   CURRENT   READY   AGE
python-web-deploy-abcde         3         2         2       10m
python-web-deploy-fghij         1         1         0       10s

说明:

• python-web-deploy-abcde为旧版本 ReplicaSet,副本数逐渐减少。

• python-web-deploy-fghij为新版本 ReplicaSet,副本数逐渐增加。

(2)实时观察 Pod 变化

使用以下命令查看 Pod 逐步被替换的状态:

kubectl get pods -l app=python-web -w

输出:

NAME                                 READY   STATUS              RESTARTS   AGE
python-web-abcde-xyz01               1/1     Running             0          10m
python-web-abcde-xyz02               1/1     Running             0          10m
python-web-abcde-xyz03               1/1     Running             0          10m
python-web-fghij-uvw01               0/1     ContainerCreating   0          5s
python-web-fghij-uvw02               1/1     Running             0          10s

注: 在滚动更新过程中,新旧pod 共享,最多保持 4个pod 运行,符合
maxSurge=1 允许临时多 1 个 Pod。

(3)验证 Pod 版本

watch -n 1 "kubectl get pods -l app=python-web -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'"

输出:(更新进行中,新旧版本 pod 共处)

python-web-abcde-xyz01     your-dockerhub-username/gitops-demo-app:v1  # 旧 Pod
python-web-fghij-uvw01     your-dockerhub-username/gitops-demo-app:v2  # 新 Pod
python-web-fghij-uvw02     your-dockerhub-username/gitops-demo-app:v2  # 新 Pod
python-web-abcde-xyz02     your-dockerhub-username/gitops-demo-app:v1  # 旧 Pod

最终输出:镜像更新到V2版,保持3个pod

python-web-fghij-uvw01     your-dockerhub-username/gitops-demo-app:v2
python-web-fghij-uvw02     your-dockerhub-username/gitops-demo-app:v2
python-web-fghij-uvw03     your-dockerhub-username/gitops-demo-app:v2

(4)验证旧replicaset 继续保留,但副本为0。

kubectl get rs -l app=python-web

输出:

NAME                          DESIRED   CURRENT   READY   AGE
python-web-deploy-abcde        0         0         0       1h    # 旧版本 RS(缩容至 0)
python-web-deploy-fghij        3         3         3       5m    # 新版本 RS

核心结论:

• 旧 RS 保留:Deployment 默认保留历史 ReplicaSet,便于回滚。

• 副本数归零:旧 RS 的 DESIRED和 CURRENT均为 0,表示已停止管理 Pod。

步骤4:横向扩容实验

(1)更新 Deployment 副本数到5个

kubectl scale命令直接修改 Deployment 的副本数,并立即生效。

kubectl scale deployment/python-web-deploy --replicas=5

(2)验证扩容结果

kubectl get deployments python-web-deploy

输出:

NAME                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
python-web-deploy   5         5         5            5           10m

(3)验证 Pod 数量

kubectl get pods -l app=python-web

输出:

NAME                                 READY   STATUS    RESTARTS   AGE
python-web-fghij-uvw01               1/1     Running   0          15m
python-web-fghij-uvw02               1/1     Running   0          15m
python-web-fghij-uvw03               1/1     Running   0          15m
python-web-fghij-uvw04               1/1     Running   0          1m
python-web-fghij-uvw05               1/1     Running   0          1m

pod数横向扩容到 5个。

结论:

  • Deployment 通过控制多个 ReplicaSet 实现版本管理,而非直接操作 Pod。

  • Deployment 支持滚动更新和回滚,逐步替换 Pod,确保无中断升级。

  • Deployment 通过保留旧 ReplicaSet 以便回滚。同时,支持动态扩容,适用于持续部署(CD)。

  • Deployment更新镜像图解

[用户][更新 Deployment 镜像][创建新 ReplicaSet(v2)][扩容新 Pod][缩容旧 ReplicaSet(v1)][保留历史版本][完成零停机更新]

五、生产决策指南

5.1 核心决策矩阵
在这里插入图片描述

注:生产推荐指数栏, 第一排 代表replicaset,第二排代码Deployment。

5.2 选型黄金法则

1.必须使用 Deployment 的场景

Web 服务 / API 网关

• 需频繁更新版本(如每日多次部署)

• 7×24 小时不间断服务

CI/CD 流水线集成

• 与 Jenkins / Argo CD 等工具深度集成

• 支持金丝雀发布和蓝绿部署策略

多版本并行验证

• A/B 测试流量分割

• Feature Toggle(特征开关)动态切换

2.可考虑 ReplicaSet 的特殊场景

硬件设备固件升级

• 需完全控制每个 Pod 的更新顺序和时间

• 更新逻辑与业务强耦合

临时调试集群

• 快速拉起一次性测试环境

• 无需版本管理的短期任务

边缘计算场景

• 资源受限设备上的极简部署

• 需绕过 K8s 默认更新策略

5.3 运维红宝书:关键场景命令速查
在这里插入图片描述

六、总结

6.1 深度知识图谱
Kubernetes 工作负载体系

├── 无状态服务
│   ├── ReplicaSet(基础副本控制)
│   └── Deployment(生产级部署)
├── 有状态服务
│   └── StatefulSet(下期重点)
├── 节点级任务
│   └── DaemonSet(下期重点)
└── 短期任务
    ├── Job
    └── CronJob
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小马不敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值