能否在GCE上部署容器优化OS虚拟机时不预先指定部署镜像?
解决方案
你的需求可以实现,无需在Terraform的gce-container-declaration中填写真实业务镜像,也可以避免基础设施变更时误覆盖部署镜像的问题。
底层限制说明
gcloud compute instances update-container命令的底层逻辑依赖实例的gce-container-declaration元数据标识实例为可管理的容器VM,因此完全省略该元数据会触发报错,这是GCP的预设限制,无法绕过。
最优实现方案
你只需要在Terraform配置中做两处调整即可:
- 保留
gce-container-declaration配置,镜像地址填写任意无意义的占位值即可 - 为
google_compute_instance资源添加生命周期规则,忽略后续对gce-container-declaration元数据的变更检测
修改后的完整Terraform配置如下:
data "google_compute_image" "cos" { family = "cos-stable" project = "cos-cloud" } resource "google_compute_instance" "container_optimized_os_vm" { name = "container-optimized-os-vm" machine_type = "f1-micro" allow_stopping_for_update = true network_interface { network = "default" } boot_disk { initialize_params { image = data.google_compute_image.cos.self_link } } metadata = { google-logging-enabled = "true" # 此处镜像为占位值,无需修改,后续CI部署时会自动覆盖 gce-container-declaration =<<EOT spec: containers: - image: placeholder/placeholder:latest name: containervm securityContext: privileged: false stdin: false tty: false volumeMounts: [] restartPolicy: Always volumes: [] EOT } # 新增生命周期规则,忽略gce-container-declaration的变更检测 lifecycle { ignore_changes = [ metadata["gce-container-declaration"] ] } }
效果说明
- 实例初始化时会拉取占位镜像,即使拉取失败也不影响,只要CI在实例启动后立即执行
gcloud compute instances update-container命令替换为真实镜像即可 - 后续CI执行更新命令修改元数据后,Terraform再执行
apply操作时不会检测到该字段的变更,也不会用占位镜像覆盖你已经部署的业务镜像,完全避免了你担心的误部署问题
注意事项
如果你后续需要修改容器的通用配置(如权限、卷挂载、重启策略等),可以临时移除ignore_changes规则,更新Terraform配置后执行apply,完成后再把规则加回即可。
内容的提问来源于stack exchange,提问作者Blair Nangle
相关产品推荐
相关产品推荐

