You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在推送新镜像至DO容器仓库时触发K8S Deployment滚动更新?

问题描述

我通过控制面板手动创建了一个包含两个节点和K8S负载均衡器的DigitalOcean(DO)Kubernetes集群。使用Gitlab CI构建Docker镜像并推送到已与集群关联的DO容器镜像仓库。遇到的问题是:推送到镜像仓库的新镜像无法触发Deployment滚动更新——原本以为推送带有latest标签的新镜像会自动触发更新,但实际并未生效,应用下方的deployment.yaml文件时系统提示文件未发生变更。

apiVersion: apps/v1
kind: Deployment
metadata:
    name: api
    labels:
        app: api
spec:
    replicas: 2
    strategy:
        type: RollingUpdate
        rollingUpdate:
            maxSurge: 1
            maxUnavailable: 0
    selector:
        matchLabels:
            app: api
    template:
        metadata:
            name: api
            labels:
                app: api
        spec:
            containers:
                -   name: api
                    image: <image>
                    ports:
                        -   containerPort: 80
                            protocol: TCP
                            hostPort: 80
解决方案

1. 使用唯一镜像标签(推荐)

放弃latest标签,每次构建用唯一标识作为镜像标签,比如Git提交哈希、版本号或时间戳。Gitlab CI中可以直接使用内置变量CI_COMMIT_SHA作为标签:

  • 构建镜像时:docker build -t registry.digitalocean.com/your-repo/api:$CI_COMMIT_SHA .
  • 推送镜像后,更新deployment.yaml中的image字段为registry.digitalocean.com/your-repo/api:$CI_COMMIT_SHA
  • 执行kubectl apply -f deployment.yaml,K8S会检测到镜像标签变更,自动触发滚动更新

2. 手动触发滚动更新

如果坚持使用latest标签,可在Gitlab CI的部署阶段执行以下命令强制触发更新:

kubectl rollout restart deployment/api

注意:需确保Deployment中容器的imagePullPolicy设置为Always,否则节点可能使用本地缓存的旧镜像,导致更新后仍运行旧版本。

3. 通过Pod模板注解触发更新

在Deployment的Pod模板中添加动态变更的注解,让K8S检测到Pod模板变化从而触发滚动更新:

kubectl set annotation deployment/api rollout=$(date +%s) --overwrite

每次推送镜像后执行此命令,注解值(当前时间戳)的变更会让K8S重新创建Pod并拉取最新镜像。

补充:为什么latest标签无法自动触发更新

K8S默认的镜像拉取策略是IfNotPresent,即节点本地已有该标签的镜像时,不会重新拉取。即使把拉取策略改为Always,只要Deployment的Pod模板没有任何字段变更,K8S就不会主动重新创建Pod,因此latest标签无法触发自动滚动更新。

内容的提问来源于stack exchange,提问作者Kostas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:43:26