【问题标题】:Compute Engine Deploy ContainerCompute Engine 部署容器
【发布时间】:2021-12-23 14:50:09
【问题描述】:

我正在使用 golang 使用 Compute Engine API 以编程方式创建和销毁一次性 Compute Engine 实例。

我可以很好地创建一个实例,但我真正遇到的问题是在启动时启动一个容器。

您可以从控制台 UI 执行此操作:

但据我所知,以编程方式执行此操作非常困难,尤其是使用 Container Optimized OS 作为基础映像时。我尝试做一个启动脚本来执行 docker pull us-central1-docker.pkg.dev/project/repo/image:tag 但它失败了,因为您需要先执行 gcloud auth configure-docker us-central1-docker.pkg.dev 才能使其工作,而 COOS 没有 gcloud 也没有包管理器来获取它。

我所有的变通方法看起来都很老套:

  • 手动创建具有所需容器的 VM 模板并创建模板实例
  • 将容器放入外部注册表,如 docker hub(不可接受)
  • 使用 Ubuntu 而不是 COOS 和包管理器,这样我就可以在启动时以编程方式安装 gcloud、docker 和容器
  • 使用 COOS 从 dockerhub 拉下包含 gcloud 的映像,然后执行某种 docker-in-docker mount 来拉下它

我是否遗漏了什么,或者在不使用 gcloud 或控制台 UI 的情况下将容器部署到计算引擎实例真的很麻烦?

【问题讨论】:

    标签: google-compute-engine google-artifact-registry google-container-optimized-os


    【解决方案1】:

    要让 Compute Engine 在 Compute Engine 启动时启动容器,必须为容器的描述定义元数据。当 COOS 启动时,它似乎运行了一个名为 konlet 的应用程序,可以在这里找到:

    https://github.com/GoogleCloudPlatform/konlet

    如果我们查看文档,它会说:

    代理解析存储在 gce-container-declaration 键下的 VM 实例元数据中的容器声明,并使用声明的配置选项启动容器。

    很遗憾,我还没有找到任何有关此元数据结构的正式文档。虽然我找不到文档,但我确实找到了两种可能的解决方案:

    1. 解密 konlet 的源代码并将其分解,以了解元数据如何映射到 docker 容器启动时传递的内容

    1. 使用所需的容器定义手动创建 Compute Engine,然后启动 Compute Engine。通过 SSH 连接到 Compute Engine,然后检索当前的元数据。我们可以在此处阅读有关检索元数据的信息:

    https://cloud.google.com/compute/docs/metadata/overview

    【讨论】:

    【解决方案2】:

    事实证明,在 Container Optimized OS 中从 Artifact Registry 中拉下一个容器并不难:

    • 运行docker-credential-gcr configure-docker --registries [region]-docker.pkg.dev

    见:https://cloud.google.com/container-optimized-os/docs/how-to/run-container-instance#accessing_private_images_in_or

    所以你可以做的是把上面的行连同docker pull [image]docker run ... 一起放入一个启动脚本中。创建实例时可以使用metadata字段指定启动脚本:https://cloud.google.com/compute/docs/instances/startup-scripts/linux#api

    这似乎是以编程方式为实例配置容器的最简单的方法。

    【讨论】:

    • 您的解决方案看起来效果很好......但是,我想知道它是否是“架构”方式?如果我正确理解 COOS 的故事,如果您有一个加载 COOS 映像的 Compute Engine,并且该 Compute Engine 在其定义的元数据中包含您要运行的映像的身份,那么其他一切(包括启动确定的容器)刚刚发生吗?
    【解决方案3】:

    您提到您使用docker-credential-gcr 来解决您的问题。我在我的启动脚本中尝试了同样的方法:

    docker-credential-gcr configure-docker --registries us-east1-docker.pkg.dev
    

    但它会返回:

    ERROR: Unable to save docker config: mkdir /root/.docker: read-only file system
    

    还需要其他步骤吗?谢谢。

    【讨论】:

    • 它使用HOME 环境变量。你可以做HOME=/tmp docker-credential-gcr configure-docker --registries us-east1-docker.pkg.dev,然后在调用docker时使用docker --config /tmp/.docker ...
    • 如果这不起作用(它应该),您可以随时回退:echo '{"auths":{},"credHelpers":{"us-east1-docker.pkg.dev": "gcr"}}' > /tmp/config.json,然后在调用 docker 时使用 docker --config /tmp ...
    • 谢谢。我刚刚意识到我可以简单地使用gcloud -q auth configure-docker us-east1-docker.pkg.dev,因为我使用的是他们的 Debian 而不是 Container-Optimized VM。这允许我在我的 docker 批处理完成后自动关闭 VM。
    【解决方案4】:

    我最近遇到了这些限制的另一面(并就该主题询问了question)。

    基本上,我想在不启动容器的情况下配置 COOS 实例。我做不到,所以我只是从基础映像启动了一个容器,然后在我的 CI/CD 管道中,对我的应用程序进行 Docker 化,将其上传到 Artifact Registry 并用我新建的应用程序替换 COOS 实例上的基础映像。

    我提供的元数据以将初始基础映像作为容器启动:

    spec:
      containers:
        - image: blairnangle/python3-numpy-ta-lib:latest
          name: containervm
          securityContext:
            privileged: false
          stdin: false
          tty: false
          volumeMounts: []
          restartPolicy: Always
          volumes: []
    

    我是 Terraform fanboi,因此元数据存在于某些 Terraform 配置中。如果你想好好看看,我有一个公共项目的代码可以实现这一点:blairnangle/dockerized-flask-on-gce

    【讨论】:

      猜你喜欢
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2020-01-15
      • 2013-11-07
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      相关资源
      最近更新 更多