如何用Golang调用Compute Engine API在COOS实例启动时自动部署容器
解决方案
方案1:使用GCE原生容器部署能力(推荐)
Console UI上的「部署容器到VM实例」功能,底层是通过实例元数据的gce-container-declaration字段实现的,Container Optimized OS(COOS)原生支持该配置的自动解析执行,无需手动编写启动脚本、处理镜像认证逻辑。
你只需要在Golang调用Compute Engine API创建实例时,补充对应配置即可:
- 给实例绑定的服务账号授予目标Artifact Registry仓库的
roles/artifactregistry.reader权限 - 实例元数据中添加
gce-container-declaration字段,填入容器配置信息 - 配置实例服务账号的scope,开放镜像拉取所需的权限
Golang代码示例:
package main import ( compute "google.golang.org/api/compute/v1" ) func ptr[T any](v T) *T { return &v } func main() { // 容器配置,遵循COOS支持的yaml格式 containerDecl := `spec: containers: - name: business-container image: us-central1-docker.pkg.dev/你的项目ID/仓库名/镜像名:版本标签 restartPolicy: Always ` instance := &compute.Instance{ Name: "临时实例名称", MachineType: "zones/你要用的可用区/machineTypes/机器规格", Disks: []*compute.AttachedDisk{ { Boot: true, AutoDelete: true, InitializeParams: &compute.AttachedDiskInitializeParams{ SourceImage: "projects/cos-cloud/global/images/family/cos-stable", // 官方COOS稳定版镜像 }, }, }, NetworkInterfaces: []*compute.NetworkInterface{ { AccessConfigs: []*compute.AccessConfig{ { Name: "External NAT", }, }, }, }, Metadata: &compute.Metadata{ Items: []*compute.MetadataItems{ { Key: "gce-container-declaration", Value: &containerDecl, }, // 可选:开启容器日志投递到Cloud Logging { Key: "google-logging-enabled", Value: ptr("true"), }, }, }, // 实例绑定的服务账号配置 ServiceAccounts: []*compute.ServiceAccount{ { Email: "你的服务账号邮箱", Scopes: []string{ "https://www.googleapis.com/auth/cloud-platform", }, }, }, } // 后续调用API创建实例即可 }
该方案完全符合GCP最佳实践,和Console UI操作的底层逻辑完全一致,无需额外自定义逻辑,实例启动后会自动拉取私有镜像、启动容器。
方案2:启动脚本直接获取认证凭证(无需安装gcloud)
如果你确实需要自定义启动脚本逻辑,也不需要安装gcloud,可以直接通过COOS预装的工具从实例元数据服务器获取访问凭证,完成docker认证:
#!/bin/bash # 从元数据服务器获取服务账号访问令牌 TOKEN=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq -r '.access_token') # 写入docker认证配置 mkdir -p /root/.docker cat > /root/.docker/config.json << EOF { "auths": { "us-central1-docker.pkg.dev": { "auth": "$(echo -n "oauth2accesstoken:${TOKEN}" | base64 -w 0)" } } } EOF # 拉取并启动容器 docker pull us-central1-docker.pkg.dev/你的项目ID/仓库名/镜像名:版本标签 docker run -d us-central1-docker.pkg.dev/你的项目ID/仓库名/镜像名:版本标签
COOS默认预装了curl和jq工具,无需额外安装任何依赖即可运行上述脚本。
你之前提到的预制模板、切换Ubuntu、DinD等方案均存在维护成本高、启动速度慢、逻辑冗余的问题,上述两个方案都可以更轻量化的解决你的需求。
内容的提问来源于stack exchange,提问作者Gillespie
相关产品推荐
相关产品推荐

