【问题标题】:Google Cloud Deploying Containers VM "Command" option谷歌云部署容器虚拟机“命令”选项
【发布时间】:2022-01-27 13:01:15
【问题描述】:

我想在 Google Cloud 上创建一个运行我的 docker 容器的虚拟机。我的图像位于 Google 的 Artifact Registry 中,我可以将其部署到 VM,但它不允许网络请求,即使在本地也是如此(我在本地尝试了来自 SSH 的curl,但它不起作用)。该容器是一个简单的 Node.js 应用程序,它会向任何请求返回“Hi there”。

我认为问题在于在创建容器/运行映像时指定端口。在本地命令行上创建容器时,我只需使用 -p 运算符将端口发布到容器。但由于 Google 的虚拟机从 Artifact Registry 中获取映像,并在构建虚拟机时自动创建一个容器,因此我无法运行-p 标记。

我认为解决方案可能与 Cloud Console 中的“命令”选项有关(见下文),但 docs 使它看起来与应用程序的“入口点”有关,而不是与创建容器。如何自定义容器创建以允许在将映像部署到 Google Cloud VM 时发布端口?

编辑:日志

好的,日志比我想象的更有趣。 我是对的,最初创建了一个 docker 容器。

但是这个容器很快就被删除了,新的容器出现了一个不同的 id,并且每隔一段时间就会重新启动。

编辑 2:

Dockerfile:

FROM node:latest
WORKDIR /untitled
COPY package.json .
RUN npm install
EXPOSE 3000
COPY . ./
CMD node server.js

我的项目名为“未命名”。这是一个测试图像,只是为了让一切正常。

实际的 Node.js 代码是这样的:

const express = require("express");

const app = express();

const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.send("Hi there!")
})

app.listen(port, () => console.log("Listening On Port 3000"))

我的 Package.json 是

{
  "name": "untitled",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.2"
  }
}

我确定我正在做的事情有问题,但我怀疑它是源代码 - 当我运行本地 docker 容器时它不会退出。

【问题讨论】:

  • 您的容器不应退出。 COS 会重启容器。这意味着您的容器有问题。编辑您的问题并显示 Dockerfile 和应用程序。您的容器应用程序应设计为无需退出即可运行。如果它正在退出,请记录原因以便您可以调试问题。另外,请阅读关于 COS 的文档,以便了解 COS 运行容器的方式与 Docker 的运行方式之间的区别。
  • 什么是 COS,它的文档在哪里?
  • COS 是您正在运行的 - 计算引擎容器优化操作系统。在使用任何云服务之前,请查看定价和服务文档。
  • 退出问题是否与 Google 控制台中的“命令”选项有关?我尝试在该字段中输入不同的内容,例如“docker run node-test-image”(我的图像)和“docker run -p 80:3000 node-test-image”,所以我认为错误是
  • 编辑您的问题,详细说明您是如何运行容器的。对于 COS,您通常不使用“docker run”,并且绝对不使用 -p(端口)选项。对于常规的 Compute Engine,您可以。编辑您的问题以清楚地定义您在做什么以及问题是什么。花 30 分钟阅读有关如何部署容器的文档。

标签: docker google-cloud-platform virtual-machine


【解决方案1】:

IIRC 使用 gcloud compute create-with-container 将容器绑定到主机的网络。因此,容器公开的任何端口都应该在主机上的(相同)端口上可用。

您能否确认您的容器正在虚拟机上运行? SSH 进入,然后 docker container ls(就像您在本地一样)。

您能否提供有关您的curl 命令和响应的更多信息。

您应该能够sudo journalctl VM 来检查它的启动并确定它在启动容器时遇到的任何问题。您可能需要专门查看 konlet-startupdocker 单位,例如sudo journalctl --unit=konlet-startup 并关注它是否启动了一个容器(希望是你的容器 [ID])。

要尝试的另一件事是ss VM 的(tcp 侦听)端口。其中之一应与您的容器匹配:

sudo ss --tcp --listening --processes
更新
PROJECT=...
ZONE=...

gcloud compute instances create-with-container test \
--container-image=gcr.io/kuar-demo/kuard-amd64:blue \
--image-family=cos-stable \
--image-project=cos-cloud \
--machine-type=f1-micro \
--zone=${ZONE} \
--project=${PROJECT}

gcloud compute ssh ${INSTANCE} \
--zone=${ZONE} \
--project=${PROJECT}

在虚拟机上:

docker container ls --format="{{.ID}}\t{{.Image}}"
521d11ace93b    gcr.io/kuar-demo/kuard-amd64:blue
11ae194b354e    gcr.io/stackdriver-agents/stackdriver-logging-agent:1.8.9

curl \
--silent \
--output /dev/null \
--write-out '%{response_code}' \
localhost:8080
200 # Success

# Matches `kuard` container
sudo journalctl --unit=konlet-startup
Starting a container with ID: 521d11ace93b...

# http-alt == 8080
sudo ss --tcp --listening --processes
Local Address:Port         Process                              
*:http-alt                 users:(("kuard",pid=893,fd=3))

# Using pid from ss command
ps aux | grep 893
893  /kuard

【讨论】:

  • 但是谷歌获取图像而不是容器的重点不是吗?我docker push将我的图像添加到 Artifact Registry 并使用它来形成我的 VM。我使用-p 暴露的端口位于我在本地机器上创建的测试容器上——我不想将它传递给虚拟机
  • 我稍后会为您提供确切的详细信息,但是是的,我使用 docker ps 确认在我的 VM 上运行了一个容器
  • 我的假设是虚拟机正在围绕我传入的图像创建一个容器——我想自定义它是如何做到的
  • 如果不是这样,请纠正我。显然我在做的事情是错误的
  • 你可以做所有这些事情。您不需要--publish 端口,因为这些等效的docker 命令将是docker run --net=host ...,因此您的容器的端口会自动绑定。如果您需要运行不同的命令和/或参数,可以使用 --container-command--container-arg 标志。
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多