【问题标题】:How to deploy container to gce by updating container image?如何通过更新容器镜像将容器部署到 gce?
【发布时间】:2020-09-18 01:12:49
【问题描述】:

我使用以下命令设置我的 CD 以将容器部署到 gce:

gcloud compute instances stop my-awesome-app
gcloud compute instances update my-awesome-app --no-shielded-integrity-monitoring
gcloud beta compute instances update-container my-awesome-app --container-image=docker.io/my-docker-hub-user/my-awesome-app:${IMAGE_TAG}
gcloud compute instances start my-awesome-app

然后实例将停止,替换容器映像并启动。

如果我使用最新图像创建新实例,一切正常。

如果我使用我的 CD 管道进行部署,实例总是会永远挂起(在接收到启动事件后,不会出现新的日志记录),永远不会拉取新映像,也永远不会启动和运行。

谁能告诉我这是什么问题?

【问题讨论】:

    标签: docker google-cloud-platform google-compute-engine


    【解决方案1】:

    我不会启动和停止我的实例来更新容器。我只是:

    gcloud compute instances update-container $instanceName2 --zone $instanceZone --container-image $registry:$BUILD_ID
    

    但是在拉取一个新图像之前,我总是做一个 docker prune 以避免我的磁盘被图像填满:

    gcloud compute ssh $instanceName2 --zone $instanceZone --command 'docker system prune -f -a'
    

    对我来说,更好的方法是使用指向我的存储库的模板,并从该模板构建一个托管实例组。通过这种方式,您可以实现零停机部署,并且在 99% 的时间里仍然只有一台机器运行。 Details

    【讨论】:

      【解决方案2】:

      我希望文档 [1] 对您有所帮助,您可以从中获取在 Google Cloud 中更新 VM 上的容器的步骤。

      当您想要更新运行容器的虚拟机时,Compute Engine 会执行以下两个步骤:

      1. 更新实例上的容器声明。 Compute Engine 将更新的容器声明存储在 gce-container-declaration 元数据键下的实例元数据中。
      2. 如果实例正在运行,则停止并重新启动实例以启动更新的配置。如果实例停止,则更新容器声明并保持实例停止。 VM 实例下载新映像并在 VM 启动时启动容器。

      请按照文档 [1] 中的 1 到 5 个步骤进行操作,Compute Engine 会保存更改并自动重启实例以进行更新。 VM 重新启动后,它会下载新映像并使用更新的配置启动容器。

      [1]https://cloud.google.com/compute/docs/containers/deploying-containers#updating_a_container_on_a_vm_instance

      【讨论】:

        【解决方案3】:

        感谢以上回答!

        我终于找到了自己的方法。 1. 每次部署都会使用容器创建一个新的托管实例。 2.然后我的保留IP地址指向新的实例。 (所以我不需要更新 DNS) 3. 最后,尽可能关闭旧部署。

        缺点显然是在部署期间会有停机时间,但我认为部署管道对于我当前的项目来说已经足够了。

        # install dependencies
        apt-get --yes install jq
        
        # Create new instance
        NEW_INSTANCE="$INSTANCE_NAME_PREFIX-build-$CIRCLE_BUILD_NUM"
        gcloud beta compute instances create-with-container "$NEW_INSTANCE" \
            --machine-type=f1-micro \
            --container-image=docker.io/xxx/yyy:$IMAGE_TAG \
            --container-env="ANSIBLE_VAULT_PASSWORD=${ANSIBLE_VAULT_PASSWORD}" \
            --tags http-server,https-server \
            --zone ${GOOGLE_COMPUTE_ZONE}
        
        IP_ADDRESS=$(gcloud compute addresses list --filter="name=('$RESERVED_IP_NAME')" --format=json | jq '.[0].address' --raw-output)
        OLD_INSTANCE=$(gcloud compute instances list --filter="EXTERNAL_IP=('$IP_ADDRESS')" --zones asia-east1-a --format=json | jq '.[0].name' --raw-output)
        
        # Remove ephemeral IP address from new instance
        echo "Removing ephemeral IP address from instance: $NEW_INSTANCE"
        gcloud compute instances delete-access-config "$NEW_INSTANCE" \
            --access-config-name "external-nat" \
            --zone ${GOOGLE_COMPUTE_ZONE}
        
        # Remove reserved IP address from old instance
        # Ignore error if there is no access config present
        if [ "$OLD_INSTANCE" != "null" ]; then
            echo "Removing reserved IP address from instance: $OLD_INSTANCE"
            gcloud compute instances delete-access-config "$OLD_INSTANCE" \
                --access-config-name "external-nat" \
                --zone ${GOOGLE_COMPUTE_ZONE} || true
        fi
        
        # Assign reserved IP address to new instance
        gcloud compute instances add-access-config "$NEW_INSTANCE" \
            --access-config-name "external-nat" --address "$IP_ADDRESS" \
            --zone ${GOOGLE_COMPUTE_ZONE}
        
        # Shutdown old instance
        if [ "$OLD_INSTANCE" != "null" ]; then
            gcloud compute instances stop "$OLD_INSTANCE" --zone ${GOOGLE_COMPUTE_ZONE}
        fi
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-30
          • 2020-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多