You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在GCP上基于docker-compose自动更新多容器实例的Docker镜像

不用Kubernetes实现GCP实例自动拉取GCR新镜像的方案

既然你不想用Kubernetes,又要在GCP实例上用docker-compose管理多容器,同时实现GCR新镜像自动更新,我给你几个靠谱的实战方案:

方案1:CI/CD远程SSH执行docker-compose命令(最直接)

你已经在用GitHub Actions构建推送镜像,那可以把更新实例的步骤直接整合到CI/CD流程里,通过SSH远程连接到实例执行更新命令:

  1. 给实例配置免密SSH访问
    • 把CI/CD服务(比如GitHub Actions)的公钥添加到GCP实例的~/.ssh/authorized_keys里,或者在创建实例时通过metadata注入公钥,这样CI/CD能无密码登录实例。
  2. 在GitHub Actions workflow里添加更新步骤
    推送镜像到GCR后,添加一个步骤,SSH到实例执行:
    ssh username@instance-ip "cd /path/to/docker-compose && docker-compose pull && docker-compose up -d"
    
    如果你只更新某个服务的镜像,可以指定服务名,避免重启所有容器:
    ssh username@instance-ip "cd /path/to/docker-compose && docker-compose pull your-service-name && docker-compose up -d your-service-name"
    

    注意:建议不要用latest标签,改用Git commit哈希或版本号作为镜像标签,这样能精准控制更新,避免本地镜像缓存导致拉取不到新镜像的问题。

方案2:用Pub/Sub + Cloud Functions触发更新(更自动化)

利用GCR的镜像推送事件,自动触发实例更新:

  1. 配置GCR的Pub/Sub事件
    当新镜像推送到GCR时,GCR会自动发送事件到Cloud Pub/Sub。你需要在GCP控制台给对应的镜像仓库配置Pub/Sub通知,指定一个主题。
  2. 编写Cloud Function订阅该主题
    函数的逻辑是:收到镜像推送事件后,通过gcloud compute ssh命令远程连接到实例,执行docker-compose更新命令。比如Python函数核心逻辑(也可以用Node.js/Bash):
    import subprocess
    
    def trigger_update(event, context):
        # 解析事件里的镜像信息(可选,用来判断是否需要更新)
        image_info = event.get('payload', {})
        # 执行SSH命令更新实例
        subprocess.run([
            'gcloud', 'compute', 'ssh', 'instance-name',
            '--zone', 'your-zone',
            '--command', 'cd /path/to/docker-compose && docker-compose pull && docker-compose up -d'
        ])
    
  3. 给Cloud Function配置权限
    确保函数的服务账号有compute.instances.osLogin权限,以及访问实例的SSH权限,同时实例的服务账号能拉取GCR镜像(添加roles/storage.objectViewer权限)。

方案3:实例组滚动更新(适合多实例场景)

如果你有多个相同的实例,用托管实例组来实现滚动更新会更优雅:

  1. 创建包含启动脚本的实例模板
    启动脚本要完成这些操作:安装Docker和docker-compose,从Cloud Storage下载你的docker-compose.yml文件(确保yml里的镜像标签是最新的,或者用唯一标签),然后启动容器。示例启动脚本:
    #!/bin/bash
    # 安装Docker
    apt-get update && apt-get install -y docker.io docker-compose
    # 下载docker-compose.yml
    gsutil cp gs://your-bucket/docker-compose.yml /opt/
    # 启动容器
    cd /opt && docker-compose up -d
    
  2. 创建托管实例组
    用上面的实例模板创建托管实例组,配置好自动扩缩容(如果需要)。
  3. 触发滚动更新
    当新镜像推送后,你可以更新实例模板(比如给启动脚本加个版本注释,触发模板更新),然后执行命令触发滚动更新:
    gcloud compute instance-groups managed rolling-action replace example-group --zone=your-zone
    
    实例组会逐个替换旧实例为新实例,新实例启动时会自动拉取最新的镜像。

一些关键注意事项

  • 镜像标签策略:永远不要依赖latest标签,改用唯一标识符(比如Git commit哈希、语义化版本号),这样能确保你拉取的是预期的新镜像。
  • 权限配置:确保实例的服务账号有roles/storage.objectViewer权限,这样才能拉取GCR里的镜像(GCR底层是Cloud Storage)。
  • 缓存问题:执行docker-compose pull时,如果用了唯一标签,会强制拉取新镜像;如果用了latest,可能需要加--no-cache参数,但还是推荐用唯一标签。

内容的提问来源于stack exchange,提问作者Tiago Gouvêa

火山引擎 最新活动