部署

理解 Deployment

请参阅 Kubernetes 官方文档:Deployments

Deployment 是 Kubernetes 中用于声明式管理和更新应用程序 Pod 副本的高级工作负载资源。它提供了一种健壮且灵活的方式来定义应用程序应如何运行,包括需要维持多少副本,以及如何安全地执行滚动更新。

Deployment 是 Kubernetes API 中用于管理 Pod 和 ReplicaSet 的对象。当您创建 Deployment 时,Kubernetes 会自动创建一个 ReplicaSet,随后由该 ReplicaSet 负责维护指定数量的 Pod 副本。

使用 Deployment,您可以

  • 声明式管理:定义应用程序的期望状态,Kubernetes 会自动确保集群的实际状态与期望状态一致。
  • 版本控制和回滚:跟踪 Deployment 的每个修订版本,并在出现问题时轻松回滚到之前的稳定版本。
  • 零停机更新:使用滚动更新策略逐步更新应用程序,而不会中断服务。
  • 自愈:当 Pod 实例崩溃、终止或从节点中移除时,Deployment 会自动替换它们,确保始终有指定数量的 Pod 可用。

工作原理

  1. 您通过 Deployment 定义应用程序的期望状态(例如,使用哪个镜像、运行多少副本)。
  2. Deployment 创建一个 ReplicaSet,以确保运行指定数量的 Pod。
  3. ReplicaSet 创建并管理实际的 Pod 实例。
  4. 当您更新 Deployment 时(例如更改镜像版本),Deployment 会创建一个新的 ReplicaSet,并按照预定义的滚动更新策略逐步用新 Pod 替换旧 Pod,直到所有新 Pod 都运行起来,然后删除旧的 ReplicaSet。

创建 Deployment

使用 CLI 创建 Deployment

前提条件

  • 确保已配置 kubectl,并已连接到您的集群。

YAML 文件示例

# example-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment # Name of the Deployment
  labels:
    app: nginx # Labels for identification and selection
spec:
  replicas: 3 # Desired number of Pod replicas
  selector:
    matchLabels:
      app: nginx # Selector to match Pods managed by this Deployment
  template:
    metadata:
      labels:
        app: nginx # Pod's labels, must match selector.matchLabels
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2 # Container image
          ports:
            - containerPort: 80 # Container exposed port
          resources: # Resource limits and requests
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 200m
              memory: 256Mi

通过 YAML 创建 Deployment

# Step 1: Create Deployment via yaml
kubectl apply -f example-deployment.yaml

# Step 2: Check the Deployment status
kubectl get deployment nginx-deployment # View Deployment
kubectl get pod -l app=nginx # View Pods created by this Deployment

使用 Web 控制台创建 Deployment

前提条件

获取镜像地址。镜像来源可以是由平台管理员通过工具链集成的镜像仓库,也可以是第三方平台的镜像仓库。

  • 对于前者,管理员通常会将镜像仓库分配给您的项目,您可以使用其中的镜像。如果未找到所需的镜像仓库,请联系管理员进行分配。

  • 如果是第三方平台的镜像仓库,请确保当前集群可以直接从该仓库拉取镜像。

  • 如果镜像仓库需要认证,则需要配置相应的镜像拉取 Secret。更多信息,请参见 为 ServiceAccount 添加 ImagePullSecrets

  • 通过 OCI Connector 选择镜像时,还需要为 Connector 代理选择一个镜像拉取 Secret,或者确认工作负载的 ServiceAccount 已经引用了该 Secret。两种引用方式是互斥的。请参见 在 OCI Connector 中使用 ImagePullSecret

使用新的 Web 控制台创建 Deployment

新的 Web 控制台可以从不同视图暴露 Deployment 创建入口。请根据您是从项目范围还是从具体集群中操作来选择入口。

  • 原生应用视图:从当前项目开始。打开 Applications > Applications,选择目标 ClusterNamespace,然后选择会创建 Deployment 的工作负载模型或创建流程。
  • 集群视图:从具体集群开始。先打开目标集群,进入目标命名空间,然后导航到 Workloads > Deployments,点击 Create Deployment

在继续之前,请确认以下差异:

  • 原生应用视图 中,集群选择是项目范围应用工作流的一部分。
  • 集群视图 中,由于您是从具体集群内部开始操作,因此集群已固定。
  • 原生应用视图 中,请确认命名空间是否属于预期的项目范围。
  • 集群视图 中,请确认该集群中命名空间侧的资源是否已为 Deployment 准备就绪。

操作步骤 - 配置基本信息

  1. Container Platform 中,导航到左侧边栏的 Workloads > Deployments

  2. 单击 Create Deployment

  3. 选择输入一个镜像,然后单击Confirm

INFO

说明:当使用集成到 Web 控制台中的镜像仓库镜像时,您可以通过 Already Integrated 过滤镜像。Integration Project Name,例如镜像(registry-projectname),其中包含 Web 控制台中的项目名 projectname,以及镜像仓库中的项目名 containers。

  1. Basic Info 部分,为 Deployment 工作负载配置声明式参数:

    参数说明
    Replicas定义 Deployment 中 Pod 副本的期望数量(默认值:1)。请根据工作负载需求进行调整。
    More > Update Strategy配置用于零停机部署的 rollingUpdate 策略:
    Max surgemaxSurge):
    • 更新期间,允许超过期望副本数的 Pod 最大数量。
    • 接受绝对值(例如 2)或百分比(例如 20%)。
    • 百分比计算:ceil(current_replicas × percentage)
    • 示例:以 10 个副本计算时,4.1 → 5
    Max unavailablemaxUnavailable):
    • 更新期间,允许临时不可用的 Pod 最大数量。
    • 百分比值不能超过 100%
    • 百分比计算:floor(current_replicas × percentage)
    • 示例:以 10 个副本计算时,4.9 → 4
    说明
    1. 默认值:如果未显式设置,则 maxSurge=1maxUnavailable=1
    2. 未运行的 Pod(例如处于 Pending/CrashLoopBackOff 状态)会被视为不可用。
    3. 同时约束
    • maxSurgemaxUnavailable 不能同时为 00%
    • 如果百分比值计算后两个参数都为 0,Kubernetes 会强制将 maxUnavailable=1,以确保更新能够继续推进。
    示例
    对于一个包含 10 个副本的 Deployment:
    • maxSurge=2 → 更新期间的 Pod 总数:10 + 2 = 12
    • maxUnavailable=3 → 最小可用 Pod 数:10 - 3 = 7
    • 这可以在保持可用性的同时,实现受控发布。

操作步骤 - 配置 Pod

说明:在部署单架构镜像的混合架构集群中,请确保已正确配置 Node Affinity 规则,以便进行 Pod 调度。

  1. Pod 部分,配置容器运行时参数和生命周期管理:

    参数说明
    Volumes将持久卷挂载到容器。支持的卷类型包括 PVCConfigMapSecretemptyDirhostPath 等。有关实现细节,请参见 卷挂载指南
    Pull Secret对于私有镜像仓库镜像,请使用包含该仓库凭据的 Secret。对于 OCI Connector 镜像,请选择 Connector 代理镜像拉取 Secret,或者使用已经引用该 Secret 的 ServiceAccount。来自平台集成的镜像仍将继续使用其关联凭据。请参见 在 OCI Connector 中使用 ImagePullSecret
    Close Grace PeriodPod 在收到终止信号后,允许其完成优雅关闭的持续时间(默认值:30s)。
    - 在此期间,Pod 会完成正在处理中的请求并释放资源。
    - 设置为 0 会强制立即删除(SIGKILL),这可能导致请求中断。
  1. Node Affinity 规则
参数说明
More > Node Selector将 Pod 限制调度到带有特定标签的节点上(例如 kubernetes.io/os: linux)。
节点 OS 选择器
More > Affinity基于现有条件定义更细粒度的调度规则。
Affinity 类型
  • Pod Affinity:将新 Pod 调度到承载特定 Pod 的节点上(同一拓扑域)。
  • Pod Anti-affinity:防止新 Pod 与特定 Pod 共置于同一节点。
强制模式
  • requiredDuringSchedulingIgnoredDuringExecution:仅当规则满足时才调度 Pod。
  • preferredDuringSchedulingIgnoredDuringExecution:优先选择满足规则的节点,但允许例外。
配置字段
  • topologyKey:定义拓扑域的节点标签(默认值:kubernetes.io/hostname)。
  • labelSelector:使用标签查询筛选目标 Pod。
  1. 网络配置
    • Kube-OVN

      参数说明
      Bandwidth Limits为 Pod 网络流量实施 QoS:
      • Egress rate limit:最大出站流量速率(例如 10Mbps)。
      • Ingress rate limit:最大入站流量速率。
      Subnet从预定义的子网池中分配 IP。如果未指定,则使用命名空间的默认子网。
      Static IP Address为 Pod 绑定持久 IP 地址:
      • 跨 Deployment 的多个 Pod 可以声明同一个 IP,但同一时刻只能有一个 Pod 使用它。
      • 重要:静态 IP 数量必须大于或等于 Pod 副本数。
    • Calico

      参数说明
      Static IP Address分配固定 IP,并且要求严格唯一:
      • 集群中的每个 IP 只能绑定到一个 Pod
      • 重要:静态 IP 数量必须大于或等于 Pod 副本数。

操作步骤 - 配置容器

  1. Container 部分,请参考以下说明配置相关信息。

    参数说明
    Resource Requests & Limits
    • Requests:容器运行所需的最小 CPU/内存。
    • Limits:容器运行期间允许使用的最大 CPU/内存。有关单位定义,请参见 资源单位
    命名空间超售比
    • 未使用超售比
      如果存在命名空间资源配额:容器 requests/limits 继承命名空间默认值(可修改)。
      没有命名空间配额:无默认值;使用自定义 Request。
    • 使用超售比
      Requests 自动计算为 Limits / Overcommit ratio(不可修改)。
    约束
    • Request ≤ Limit ≤ 命名空间配额最大值。
    • 更改超售比后需要重新创建 Pod 才会生效。
    • 超售比会禁用手动 request 配置。
    • 没有命名空间配额 → 没有容器资源约束。
    Extended Resources配置集群可用的扩展资源(例如 vGPU、pGPU)。
    Volume Mounts持久化存储配置。请参见 存储卷挂载说明
    操作
    • 已有 pod 卷:单击 Add
    • 没有 pod 卷:单击 Add & Mount
    参数
    • mountPath:容器文件系统路径(例如 /data
    • subPath:卷内的相对文件/目录路径。
      对于 ConfigMap/Secret:选择特定键
    • readOnly:以只读方式挂载(默认值:读写)
    请参见 Kubernetes 卷
    Ports暴露容器端口。
    示例:暴露名为 redis 的 TCP 端口 6379
    字段
    • protocol:TCP/UDP
    • Port:暴露的端口(例如 6379
    • name:符合 DNS 规范的标识符(例如 redis
    Startup Commands & Arguments覆盖默认的 ENTRYPOINT/CMD:
    示例 1:执行 top -b
    - Command["top", "-b"]
    - 或者 Command:["top"],Args:["-b"]
    示例 2:输出 $MESSAGE
    /bin/sh -c "while true; do echo $(MESSAGE); sleep 10; done"
    请参见 定义命令
    More > Environment Variables
    • 静态值:直接键值对
    • 动态值:引用 ConfigMap/Secret 键、pod 字段(fieldRef)、资源指标(resourceFieldRef
    说明:环境变量会覆盖镜像/配置文件设置。
    More > Referenced ConfigMaps将整个 ConfigMap/Secret 作为环境变量注入。支持的 Secret 类型:Opaquekubernetes.io/basic-auth
    More > Health Checks
    • Liveness Probe:检测容器健康状态(失败时重启)
    • Readiness Probe:检测服务可用性(失败时从端点中移除)
    请参见 健康检查参数
    More > Log Files配置日志路径:
    - 默认:收集 stdout
    - 文件模式:例如 /var/log/*.log
    要求
    • 存储驱动 overlay2:默认支持
    • devicemapper:需手动将 EmptyDir 挂载到日志目录
    • Windows 节点:确保已挂载父目录(例如 c:/a/b/c/*.log 需要挂载 c:/a
    More > Exclude Log Files排除特定日志不被收集(例如 /var/log/aaa.log)。
    More > Execute before Stopping在容器终止前执行命令。
    示例echo "stop"
    说明:命令执行时间必须短于 pod 的 terminationGracePeriodSeconds
  2. 单击 Add Container(右上角)或 Add Init Container

    请参见 Init Containers。 Init Container:

    1. 在应用容器之前启动(按顺序执行)。
    2. 完成后释放资源。
    3. 允许删除的条件:
      • Pod 包含 >1 个应用容器且 ≥1 个 init container。
      • 单应用容器 Pod 不允许删除。
  3. 单击 Create

参考信息

存储卷挂载说明
类型用途
Persistent Volume Claim将现有 PVC 绑定起来,以请求持久化存储。

说明:只有已绑定的 PVC(已关联 PV)才可选择。未绑定的 PVC 会导致 Pod 创建失败。
ConfigMap将完整/部分 ConfigMap 数据挂载为文件:
  • 完整 ConfigMap:在挂载路径下创建以键命名的文件
  • 子路径选择:挂载特定键(例如 my.cnf
Secret将完整/部分 Secret 数据挂载为文件:
  • 完整 Secret:在挂载路径下创建以键命名的文件
  • 子路径选择:挂载特定键(例如 tls.crt
Ephemeral Volumes集群预配的临时卷,特性包括:
  • 动态预配
  • 生命周期与 pod 绑定
  • 支持声明式配置
使用场景:临时数据存储。请参见 Ephemeral Volumes
Empty Directory在同一 pod 内的容器之间共享临时存储:
  • pod 启动时在节点上创建
  • 随 pod 删除而删除
使用场景:容器间文件共享、临时数据存储。请参见 EmptyDir
Host Path挂载主机机器上的目录(必须以 / 开头,例如 /volumepath)。

健康检查

何时在原生应用视图中使用 Deployment

当工作负载主要是无状态的,并且应通过复制的 Pod 替换而不是稳定标识或每个副本的持久状态来更新时,请使用 Deployment。

以下场景通常更适合使用 Deployment:

  • 副本标识在替换后不需要保持稳定
  • 工作负载应通过可互换的 Pod 进行水平扩展
  • 应用交付更倾向于使用滚动更新行为

如果工作负载依赖稳定的序号标识或每个副本的持久存储,请改为查看 StatefulSets

提交前的 Deployment 审查要点

在原生应用视图中创建或更新 Deployment 之前,请仔细检查以下内容:

  • 所选项目、集群和命名空间是否是预期的运行范围
  • 副本数是否与预期的可用性目标一致
  • 所选镜像和拉取凭据在目标集群中是否有效
  • 引用的 ConfigMap、Secret、PVC 或 ServiceAccount 是否已存在于同一命名空间中
  • 资源 requests、limits 和探针是否与应用的真实启动和健康行为一致
  • 滚动发布策略是否适合该工作负载和流量模式

管理 Deployment

使用 CLI 管理 Deployment

查看 Deployment

  • 检查 Deployment 是否已创建。

    kubectl get deployments
  • 获取 Deployment 的详细信息。

    kubectl describe deployments

更新 Deployment

请按以下步骤更新您的 Deployment:

  1. 将 nginx Pod 更新为使用 nginx:1 .16.1 镜像。

    kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

    或者使用以下命令:

    kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

    另外,您也可以编辑 Deployment,并将 .spec.template.spec.containers[0].imagenginx:1.14.2 更改为 nginx:1.16.1

    kubectl edit deployment/nginx-deployment
  2. 要查看发布状态,请运行:

    kubectl rollout status deployment/nginx-deployment

    运行 kubectl get rs 可看到 Deployment 通过创建新的 ReplicaSet 并将其扩容到 3 个副本,同时将旧 ReplicaSet 缩容到 0 个副本,从而更新了 Pod。

    kubectl get rs

    运行 get pods 现在应只显示新的 Pod:

    kubectl get pods

当更改镜像或 OCI Connector 时,也请检查 Pod 模板中的 Pull SecretserviceAccountName 和令牌有效期。更新后,请验证新的 ReplicaSet 和 Pod:检查 Connector 注解,确认实际 Pod 镜像已重写为 Connector 代理,等待 Pod 进入 Running,并查看 Events。

扩缩 Deployment

您可以使用以下命令扩缩 Deployment:

kubectl scale deployment/nginx-deployment --replicas=10

回滚 Deployment

  • 假设您在更新 Deployment 时输入错误,把镜像名称写成了 nginx:1.161,而不是 nginx:1.16.1

    kubectl set image deployment/nginx-deployment nginx=nginx:1.161
  • 发布会卡住。您可以通过检查发布状态来验证这一点:

    kubectl rollout status deployment/nginx-deployment

删除 Deployment

删除 Deployment 也会删除其管理的 ReplicaSet 和所有关联的 Pod。

kubectl delete deployment <deployment-name>

使用 Web 控制台管理 Deployment

查看 Deployment

您可以查看 deployment 以获取应用程序信息。

  1. Container Platform 中,导航到 Workloads > Deployments
  2. 找到您要查看的 Deployment。
  3. 单击 deployment 名称查看 DetailsTopologyLogsEventsMonitoring 等。

更新 Deployment

  1. Container Platform 中,导航到 Workloads > Deployments
  2. 找到您要更新的 Deployment。
  3. Actions 下拉菜单中,选择 Update 以查看 Edit Deployment 页面。

更新操作会使 Deployment 保持在当前集群和命名空间中。如果工作负载必须运行在不同的集群或命名空间中,请在目标范围内创建或应用单独的 Deployment,而不是将更新视为迁移操作。

在提交更新之前,请确认镜像、探针、环境变量、端口、卷挂载或资源设置的更改不会破坏正在运行的工作负载。

对 Pod 模板的更改可能会触发新的发布。更新请求成功并不代表发布本身就是健康的。只有当新的 Pod 修订版本正确调度、进入就绪状态,并在不使工作负载不可用的情况下替换先前修订版本时,实际效果才会显现出来。

在 Web 控制台中更改镜像或 OCI Connector 时,也请检查 Pull Secret、工作负载 ServiceAccount 和令牌有效期。确认生成的 Pod 使用 Connector 代理镜像并完成发布;仅更新请求成功并不能验证镜像拉取是否成功。

删除 Deployment

  1. Container Platform 中,导航到 Workloads > Deployments
  2. 找到您要删除的 Deployment。
  3. Actions 下拉菜单中,单击操作列中的 Delete 按钮并确认。

删除后,请验证列表中不再显示该 Deployment,并且任何需要保留的独立 Service、ConfigMap、Secret 或 PVC 仍然存在。

使用 CLI 进行故障排查

当 Deployment 出现问题时,可以使用以下常见排查方法。

对于 OCI Connector 镜像拉取失败,请按以下顺序检查路径:

  1. 检查 Pod 模板中的 connectors.<baseDomain>/connectors 注解。
  2. 检查 spec.imagePullSecrets 以及工作负载 ServiceAccount 的 imagePullSecrets
  3. 检查实际 Pod 镜像是否已重写为 Connector 代理。
  4. 检查 Pod 状态和 Events。

如果 Events 显示原始 HTTP 仓库出现 HTTPS 错误,则该工作负载可能没有进入 Connector 代理路径。在更改仓库运行时设置之前,请检查 Connector 代理 Secret、ServiceAccount 和令牌。请参见 在 OCI Connector 中使用 ImagePullSecret

检查 Deployment 状态

kubectl get deployment nginx-deployment
kubectl describe deployment nginx-deployment # View detailed events and status

检查 ReplicaSet 状态

kubectl get rs -l app=nginx
kubectl describe rs <replicaset-name>

检查 Pod 状态

kubectl get pods -l app=nginx
kubectl describe pod <pod-name>

查看日志

kubectl logs <pod-name> -c <container-name> # View logs for a specific container
kubectl logs <pod-name> --previous         # View logs for the previously terminated container

进入 Pod 进行调试

kubectl exec -it <pod-name> -- /bin/bash # Enter the container shell

检查健康配置

确保 livenessProbe 和 readinessProbe 已正确配置,并且应用程序的健康检查端点能够正常响应。排查探针失败

检查资源限制

确保容器资源 requests 和 limits 设置合理,并且容器不会因资源不足而被终止。