无法在Google Cloud Run上部署Ubuntu 20.04的Docker容器

9

我正在尝试通过Google Cloud Run部署一个基于Ubuntu 20.04的简单Python Docker容器。我已经成功构建了镜像,但是当我尝试部署Cloud Run服务时,出现以下错误(省略项目细节):

Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
error: "Invalid command \"/bin/sh\": fil
  e not found"
  e not found"
]....failed
Deployment failed

然而奇怪的是,如果我在本地拉取和运行该镜像,它就可以正常工作。

docker run --rm --publish 5000:5000 -e PORT=5000 -it gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}

我的Dockerfile非常基础:

FROM ubuntu:20.04

COPY . /app
WORKDIR /app

RUN apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y python3 python3-pip \
    && pip3 install gunicorn Flask flask-cors

CMD exec gunicorn --bind :$PORT --worker-tmp-dir /dev/shm --timeout 900 wsgi:app

更加奇怪的是,如果我使用 debian:buster-slim 替换基础映像,它就可以正常工作。

有人有任何想法吗?


额外信息:

status:
  conditions:
  - type: Ready
    status: 'False'
    message: |-
      Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
      error: "Invalid command \"/bin/sh\": file not found"
      ].
    lastTransitionTime: '2020-05-12T07:40:12.804Z'
  - type: ConfigurationsReady
    status: 'False'
    message: |-
      Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
      error: "Invalid command \"/bin/sh\": file not found"
      ].
    lastTransitionTime: '2020-05-12T07:40:12.804Z'
  - type: RoutesReady
    status: 'True'
    lastTransitionTime: '2020-05-12T06:19:12.224Z'

你介意去Cloud Console查看你的Cloud Run服务的YAML选项卡,并将其“status”字段添加到上面的问题中吗?我预计会出现相同的错误,但也许有更多细节。 - ahmet alp balkan
@AhmetB-Google,正如预期的那样,状态区域中的错误与命令行中报告的错误相同。此外,在Cloud Logging控制台中似乎没有任何系统日志条目,因此我认为这不是沙箱问题。 - dstaley
这个命令可以使用吗? gcloud run deploy --image gcr.io/PROJECT-ID/helloworld --platform managed - iker lasaga
1个回答

4

我遇到了相同的问题。似乎是间歇性的:白天我无法将应用部署到Cloud Run上,但在深夜,各种解决方法有一半左右的成功率。

我发现最可靠的解决方法是不依赖于CMD或ENTRYPOINT中的/bin/sh或/bin/bash。在运行时,它看起来存在于/bin/sh,但在Cloud Run部署之前测试容器时,有时并不存在。

换成Dockerfile中的以下内容:

CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 main:app

我使用了这个替代方案:
CMD ["/usr/bin/python3", "/app/run_gunicorn.py", "--workers", "1", "--threads", "4", "main:app"]

接着,我添加了run_gunicorn.py脚本:

import os
import sys
from gunicorn.app.wsgiapp import run
port = os.environ['PORT']
sys.argv[-1:-1] = ['--bind', f':{port}']
print("sys.argv:", sys.argv)
run()

这是一种保持端口号动态的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接