Skip to content

Kubernetes-工作负载之Deployment

Deployment 核心概念与架构

Deployment 是 Kubernetes 中最常用的工作负载控制器之一,它提供了声明式的更新能力,用于管理无状态应用的部署和更新。作为 Kubernetes 编排体系的核心组件,Deployment 通过控制器模式实现了应用部署的自动化管理。

一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。你负责描述 Deployment 中的目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。

Deployment 工作流程

Deployment 通过管理 ReplicaSet 来实现 Pod 的声明式管理,其典型工作流程包括

  1. 用户创建 Deployment:通过 YAML 文件定义应用所需状态(副本数、容器镜像等)
  2. ReplicaSet 管理副本:Deployment 控制器根据副本数创建对应的 ReplicaSet
  3. Pod 创建与维护:ReplicaSet 负责创建和管理 Pod,确保运行中的 Pod 数量与期望一致
  4. 滚动更新:当 Deployment 配置变更时,系统会逐步替换旧版本 Pod
  5. 健康监测:通过就绪检查(readinessProbe)和存活检查(livenessProbe)确保应用可用性

Deployment、ReplicaSet 和 Pod 的关系

  1. Deployment:负责声明应用的期望状态
  2. ReplicaSet:确保指定数量的 Pod 副本运行
  3. Pod:实际运行应用容器的实体

这种分层设计使得 Kubernetes 能够实现:

  • 版本控制:每个 ReplicaSet 对应一个应用版本
  • 滚动更新:通过协调多个 ReplicaSet 实现平滑过渡
  • 精确回滚:通过保留历史 ReplicaSet 实现版本回溯

Deployment 核心功能

功能说明实现机制
Pod 声明式管理通过 YAML 定义 Pod 模板使用 ReplicaSet 确保 Pod 符合预期状态
滚动更新支持无宕机更新应用版本创建新 ReplicaSet 并逐步替换旧 Pod
版本回滚可回退到历史稳定版本保留更新历史记录,支持快速回退
扩缩容轻松调整 Pod 副本数量修改 replicas 值,ReplicaSet 自动调整
健康检查结合 Readiness/Liveness Probe集成 Kubernetes 健康检查机制

Deployment 的创建与配置

基础 YAML 结构

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3  # Pod副本数
  selector:    # 必须匹配template中的labels
    matchLabels:
      app: nginx
  template:    # Pod模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.10
        ports:
        - containerPort: 80

关键字段说明

  • spec.replicas:期望的 Pod 副本数(默认为1)
  • spec.selector:标签选择器(必须匹配 template.labels)
  • spec.template:Pod 模板定义
  • spec.strategy:更新策略配置

创建与查看 Deployment

创建 Deployment

bash
kubectl apply -f deployment.yaml

查看 Deployment 状态

bash
kubectl get deployments
kubectl describe deployment nginx-deployment

查看关联资源

bash
kubectl get rs -l app=nginx  # 查看关联的ReplicaSet
kubectl get pods --show-labels  # 查看Pod及其标签

kubectl get deployments输出字段解析:

  • NAME:Deployment 名称
  • READY:就绪副本数/期望副本数(如 3/3 表示3个副本全部就绪)
  • UP-TO-DATE:已更新到最新版本的副本数
  • AVAILABLE:当前可供用户使用的副本数
  • AGE:Deployment 运行时间

Deployment 的更新与回滚

滚动更新(RollingUpdate) - 默认策略

yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%  # 可超出replicas的最大Pod数
      maxUnavailable: 25%  # 更新期间不可用Pod比例

更新过程

  • 创建新 ReplicaSet 并逐步扩容
  • 旧 ReplicaSet 逐步缩容
  • 确保始终有可用 Pod 处理请求

重建更新(Recreate)

yaml
spec:
  strategy:
    type: Recreate

特点

  • 先删除所有旧 Pod 再创建新 Pod
  • 会导致短暂服务不可用
  • 适合需要完全替换的场景

查看滚动更新状态

bash
kubectl rollout status deployment/nginx-deployment

更新过程中,Deployment 会创建新的 ReplicaSet,并逐步将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet

tex
6c64d87c8c 老的replicaset 有三个replica pod
59777878f8 新的replicaset 有了一个replica pod
6c64d87c8c 老的replicaset 变成二个replica pod
59777878f8 新的replicaset 有了二个replica pod
...
6c64d87c8c 老的replicaset 变成零个replica pod

版本回滚

查看更新历史

kubectl rollout history deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment --revision=2

执行回滚

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

回滚操作实际上是再次应用历史版本的配置,Kubernetes 会保留 Deployment 的更新历史以便回滚

Deployment 扩缩容

Metrics-Server 监控

Metrics-Server是集群核心监控数据的聚合器。通俗地说,它存储了集群中各节点的监控数据,并且提供了API以供分析和使用。

Metrics-Server在Kubernetes集群中表现为一个Deployment对象。不过准确地说,它是Deployment,Service,ClusterRole,ClusterRoleBinding,APIService,RoleBinding资源对象的综合体。

扩缩容操作

手动扩缩容

bash
kubectl scale deployment/nginx-deployment --replicas=5

自动扩缩容(HPA)

bash
kubectl autoscale deployment nginx-deployment \
  --min=2 --max=10 --cpu-percent=80

健康检查配置

Deployment 可以结合 Readiness 和 Liveness Probe 实现应用健康检查

yaml
spec:
  template:
    spec:
      containers:
      - name: nginx
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5

资源限制与调度

资源限制

yaml
resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "200m"
    memory: "256Mi"

亲和性调度

yaml
 affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values: [ssd]

暂停与恢复更新

暂停 Deployment 更新

bash
kubectl rollout pause deployment/nginx-deployment

恢复 Deployment 更新

bash
kubectl rollout resume deployment/nginx-deployment

暂停期间,Deployment 不会应用任何新的更新,直到恢复

Deployment 状态解析

Deployment 状态类型

Progressing (进行中):

  • 正在创建新的 ReplicaSet
  • 正在扩容/缩容 ReplicaSet
  • 有新的 Pod 已经就绪

Complete (完成)

  • 最小可用副本数已满足
  • 所有副本都已更新到指定版本
  • 没有旧 Pod 存在

Failed (失败)

  • 配额不足
  • 就绪探测失败
  • 镜像拉取错误
  • 权限不足
  • 配置错误

监控状态

bash
kubectl rollout status deployment/nginx-deployment

经典案例

yaml
---
# 定义命名空间资源
apiVersion: v1
kind: Namespace
metadata:
  name: demo-study  # 命名空间名称

---
# 定义 Deployment 资源
apiVersion: apps/v1  # Kubernetes API 版本
kind: Deployment     # 资源类型为 Deployment
metadata:
  name: demo-deployment  # Deployment 名称
  namespace: demo-study  # 所属命名空间
  labels:
    app: demo-study      # 标签用于资源识别
spec:
  replicas: 1  # 期望的 Pod 副本数
  selector:    # 选择器,用于匹配 Pod
    matchLabels:
      app: demo-study
  template:    # Pod 模板
    metadata:
      name: demo-deployment
      namespace: demo-study
      labels:
        app: demo-study
    spec:
      volumes:  # 定义存储卷
        - name: demo-html
          hostPath:  # 使用主机路径作为存储
            path: /data/html  # 主机上的目录路径
      containers:
        - name: demo-deployment  # 容器名称
          image: nginx           # 使用 nginx 镜像
          imagePullPolicy: Never # 镜像拉取策略(本地已有镜像)
          ports:
            - name: demo-deployment
              containerPort: 80  # 容器暴露的端口
          volumeMounts:          # 挂载卷到容器
            - name: demo-html
              mountPath: /usr/share/nginx/html/  # 容器内的挂载路径
          # 启动探针配置
          startupProbe:
            httpGet:             # 使用 HTTP GET 检查
              port: 80           # 检查的端口
              scheme: HTTP       # 使用 HTTP 协议
            initialDelaySeconds: 3  # 容器启动后等待时间
            periodSeconds: 1        # 检查间隔
            timeoutSeconds: 1       # 检查超时时间
            failureThreshold: 3    # 失败阈值
          # 就绪探针配置
          readinessProbe:
            exec:                  # 使用命令执行检查
              command: ["/bin/sh","-c","ls -la /usr/share/nginx/html/index.html"]
            initialDelaySeconds: 3
            periodSeconds: 1
            timeoutSeconds: 1
            failureThreshold: 1
          # 存活探针配置
          livenessProbe:
            httpGet:
              port: 80
              scheme: HTTP
            initialDelaySeconds: 3
            periodSeconds: 3
            timeoutSeconds: 3
            failureThreshold: 3
          # 资源限制和请求
          resources:
            limits:    # 资源上限
              cpu: 200m  # 200 毫核
              memory: 200Mi  # 200 MB
            requests:  # 资源请求
              cpu: 200m
              memory: 200Mi

---
# 定义 Service 资源
apiVersion: v1
kind: Service
metadata: 
  name: demo-service    # Service 名称
  namespace: demo-study # 所属命名空间
  labels:
    app: demo-study
spec:
  selector:    # 选择器,匹配要暴露的 Pod
    app: demo-study
  type: NodePort  # Service 类型为 NodePort
  ports:
    - name: demo-deployment
      port: 80           # Service 端口
      targetPort: 80     # 目标容器端口
      nodePort: 30010    # 节点暴露的端口
      protocol: TCP      # 使用 TCP 协议

Kubernetes Deployment 参数解析

Deployment 是 Kubernetes 中最常用的工作负载控制器之一,它提供了声明式的更新能力,用于管理无状态应用的部署和更新。以下是对 Deployment 参数的详细解析。

Deployment 基础结构

Deployment 的 YAML 配置文件通常包含以下几个主要部分:

yaml
apiVersion: apps/v1  # API 版本
kind: Deployment     # 资源类型
metadata:            # 元数据
  name: my-deployment
  namespace: default
  labels:
    app: my-app
spec:                # 规格定义
  replicas: 3        # 副本数
  selector:          # 选择器
    matchLabels:
      app: my-app
  template:          # Pod 模板
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image:latest
        ports:
        - containerPort: 80

核心参数详解

metadata 部分

  • name: Deployment 的名称,在命名空间内必须唯一
  • namespace: 指定部署的命名空间,默认为 default
  • labels: 键值对标签,用于组织和选择资源
  • annotations: 存储附加的非标识性信息,不影响资源选择

spec 部分

副本管理

  • replicas: 指定 Pod 的副本数量,默认值为 1

    yaml
    replicas: 3  # 运行3个Pod副本
  • revisionHistoryLimit: 保留的历史 ReplicaSet 数量,用于回滚,默认值为 10

    yaml
    revisionHistoryLimit: 5  # 只保留5个历史版本

选择器(selector)

  • matchLabels: 必须与 template.metadata.labels 匹配,用于确定 Deployment 管理的 Pod

    yaml
    selector:
      matchLabels:
        app: my-app
  • matchExpressions: 更复杂的标签选择表达式

    yaml
    matchExpressions:
      - {key: app, operator: In, values: [my-app, your-app]}

    支持的操作符:In, NotIn, Exists, DoesNotExist

更新策略(strategy)

  • type: 更新策略类型,支持 RollingUpdate(默认) 和 Recreate

    yaml
    strategy:
      type: RollingUpdate
      rollingUpdate:
        maxSurge: 25%
        maxUnavailable: 25%
  • RollingUpdate 滚动更新参数:

    • maxSurge: 更新过程中允许超出 replicas 的最大 Pod 数(可以是数字或百分比)
    • maxUnavailable: 更新过程中允许的最大不可用 Pod 数(可以是数字或百分比)
  • Recreate: 先删除所有旧 Pod 再创建新 Pod,会导致服务短暂中断

其他参数

  • minReadySeconds: Pod 就绪后被认为可用的最小秒数,影响旧 Pod 的终止时间
  • progressDeadlineSeconds: 部署超时时间(秒),默认600秒
  • paused: 暂停部署更新,默认为 false

template 部分(Pod模板)

容器定义(containers)

  • name: 容器名称

  • image: 容器镜像及版本

  • ports: 容器暴露的端口

    yaml
    ports:
    - containerPort: 80
      protocol: TCP
  • env: 环境变量

    yaml
    env:
    - name: ENV_VAR
      value: "production"
  • resources: 资源请求和限制

    yaml
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "200m"
        memory: "256Mi"

健康检查

  • livenessProbe: 存活检查,失败会重启容器

  • readinessProbe: 就绪检查,失败会从Service端点移除Pod

    yaml
    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
      initialDelaySeconds: 3
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 10

调度策略

  • affinity: 亲和性调度规则

    yaml
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: disktype
              operator: In
              values: [ssd]
  • tolerations: 污点容忍

  • nodeSelector: 节点选择器

Deployment 生命周期管理

创建与查看

yaml
# 创建Deployment
kubectl apply -f deployment.yaml

# 查看状态
kubectl get deployments
kubectl describe deployment <deployment-name>

# 查看关联的ReplicaSet和Pod
kubectl get rs -l app=my-app
kubectl get pods -l app=my-app

更新操作

yaml
# 镜像更新
kubectl set image deployment/my-deployment my-container=my-image:new-version

# 或通过编辑配置
kubectl edit deployment my-deployment

# 查看更新过程
kubectl rollout status deployment/my-deployment

扩缩容

yaml
# 手动扩缩
kubectl scale deployment/my-deployment --replicas=5

# 基于CPU自动扩缩(HPA)
kubectl autoscale deployment/my-deployment --min=2 --max=10 --cpu-percent=80

回滚操作

yaml
# 查看历史版本
kubectl rollout history deployment/my-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/my-deployment

# 回滚到指定版本
kubectl rollout undo deployment/my-deployment --to-revision=2

最佳实践

  1. 标签一致性: 确保 selector.matchLabels 与 template.metadata.labels 完全匹配
  2. 更新策略选择:
    • 生产环境使用 RollingUpdate
    • 开发环境可使用 Recreate 加快更新速度
  3. 资源限制: 为容器设置合理的 requests 和 limits
  4. 健康检查: 配置适当的 liveness 和 readiness 探针
  5. 版本控制: 保留足够的 revisionHistoryLimit 以便回滚
  6. 监控与告警: 监控 Deployment 状态和 Pod 健康状况

常见问题排查

  1. Pod 未创建:

    yaml
    kubectl describe deployment <name>  # 查看事件
    kubectl get rs  # 检查ReplicaSet
  2. 更新卡住:

    yaml
    kubectl rollout undo deployment/<name>  # 先回滚
    kubectl describe deployment/<name>  # 分析原因
  3. 资源不足:

    yaml
    kubectl describe nodes  # 查看节点资源
    kubectl top pods  # 查看Pod资源使用