如何通过更新容器镜像将容器部署到gce?

问题描述 投票:0回答:1

我使用以下命令设置我的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个回答
1
投票

我希望这个文档[1]对你有帮助,从这里你可以有步骤更新谷歌云中虚拟机上的容器。

当你想更新运行容器的虚拟机时,计算引擎会执行以下两个步骤。

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

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

[1] https:/cloud.google.comcomputedocscontainersdeploying-containers#updating_a_container_on_a_vm_instance。


1
投票

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

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

但在提取新镜像之前,我总是做一个docker修剪,以避免我的磁盘被镜像填满。

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

对我来说,一个更好的方法是使用一个指向我的仓库的模板,然后从这个模板建立一个Managed-Instance-group。这样一来,你就可以实现零宕机部署,而且99%的时间还是只有一台机器在运行。详细介绍


0
投票

谢谢以上的解答!

我终于想出了自己的办法.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
© www.soinside.com 2019 - 2024. All rights reserved.