无法运行Google App Engine自定义托管VM: - 必须设置--custom-entrypoint错误

时间:2015-11-17 18:42:41

标签: python google-app-engine google-app-engine-python gae-module google-managed-vm

问题说明

我正在尝试为Google App Engine创建自定义托管VM,其行为与Google提供的标准python27托管VM完全相同。 (我这样做是将C ++库添加到运行时的第一步。)

从谷歌documentation,以下Dockerfile指定标准的python27运行时:

FROM gcr.io/google_appengine/python-compat
ADD . /app

通过检查gcloud preview app run在使用标准python27运行时生成的那个时,我已经验证了这是正确的Dockerfile。它与此相同。

但是当我使用dev_appserver.pygcloud preview app run使用此Dockerfile运行我的应用程序时,我收到错误消息:

The --custom_entrypoint flag must be set for custom runtimes

我使用的是最新版本的gcloud(1.9.86,app-engine-python组件版本1.9.28)和独立的python app引擎SDK(1.9.28)。我在早期版本中遇到了同样的问题,所以我更新到了最新版本。

我做过的尝试:

gcloud preview app run --help有以下关于--custom-entrypoint

的说法
 --custom-entrypoint CUSTOM_ENTRYPOINT
    Specify an entrypoint for custom runtime modules. This is required when
    such modules are present. Include "{port}" in the string (without
    quotes) to pass the port number in as an argument. For instance:
    --custom_entrypoint="gunicorn -b localhost:{port} mymodule:application"

我不知道该怎么做。码头图像是否尚未包含ENTRYPOINT?为什么我被要求另外提供一个?此外,gcr.io/google_appengine/python-compat图像的入口点应该是什么? Google没有为此提供任何文档。

我尝试过无意义的--custom-entrypoint="echo",它会使错误无效,但应用程序不响应任何HTTP请求。

我发现的另外两个相关的stackoverflow问题没有帮助。接受的答案似乎表明这是已解决的SDK中的错误。但是我已经在SDK的两个版本中尝试了它,包括最新版本,我仍然有问题。

重申的步骤:

为了突出我的问题,我创建了一个生成错误的简单应用程序。它只包含三个文件:

app.yaml

module: default
version: 1
runtime: custom
api_version: 1
threadsafe: true
vm: true

handlers:
- url: /.*
  script: wsgi.app

Dockerfile

FROM gcr.io/google_appengine/python-compat
ADD . /app

这个Dockerfile与用于python27运行时的gcloud preview app run相同(事实上,当使用python27运行时,实际上是从runtime: python27生成的Dockerfile中复制粘贴的),所以这应该是相同的设置wsgi.py

import webapp2 class Hello(webapp2.RequestHandler): def get(self): self.response.write(u'Hello') app = webapp2.WSGIApplication([('/Hello', Hello)], debug=True)

dev_appserver.py app.yaml

当我在包含这三个文件的目录中运行Traceback (most recent call last): File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 83, in <module> _run_file(__file__, globals()) File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 79, in _run_file execfile(_PATHS.script_file(script_name), globals_) File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1033, in <module> main() File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1026, in main dev_server.start(options) File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 818, in start self._dispatcher.start(options.api_host, apis.port, request_data) File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 194, in start _module.start() File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1555, in start self._add_instance() File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1707, in _add_instance expect_ready_request=True) File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/custom_runtime.py", line 73, in new_instance assert self._runtime_config_getter().custom_config.custom_entrypoint File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 383, in _get_runtime_config raise ValueError('The --custom_entrypoint flag must be set for ' ValueError: The --custom_entrypoint flag must be set for custom runtimes 时,我收到以下错误:

phash

3 个答案:

答案 0 :(得分:10)

<强>更新

这可能不会更准确。看看尼克的答案。

(虽然我无法做到这一点。但我并没有非常努力)

有一个完全没有记载但绝对必要的信息w.r.t.自定义托管VM:

他们无法在开发服务器上运行!

如果您认为这个关键事实会在任何地方提及,例如自定义托管VM的文档页面,或dev_appserver.py,或者甚至在运行dev_appserver.py时作为错误消息提及,那么您谷歌给予了太多的信任。

我能找到任何关于此问题的任何声明的唯一地方是github上appengine-java-vm-guestbook-extras demo的自述文件(严重):

  

当a时,Cloud SDK不再支持运行自定义运行时   提供了Dockerfile。您必须将应用程序部署到App   发动机

Google并不关心:

  1. 实施这一基本而重要的功能。
  2. 说明开发服务器缺少这么重要的功能。
  3. 当用户厌倦执行操作时,提供任何合理的错误消息。
  4. 我希望这个答案可以帮助那些因为这个而遭受折磨的日子里一些令人遗憾的开发者。

答案 1 :(得分:6)

编辑1 user862857 发布的解决方案利用Docker本身从Dockerfile构建图像并在容器中运行它们。这也是在开发环境中运行托管虚拟机和自定义运行时的好方法。

接受的答案似乎不正确。在处理快速发展的Beta产品时,github自述文件不应该胜过official docs的权威性。使用OP帖子中提到的Dockerfile,在开发环境中使用runtime: custom应用程序是完全可能的,

FROM gcr.io/google_appengine/python-compat
ADD . /app

使用--runtime=python-compat标志。但是,他们需要捕获/_ah/start/_ah/health的请求。在给定以下文件的情况下尝试运行以下命令,并亲自查看:

devserver command

$ dev_appserver.py app.yaml --runtime=python-compat

app.yaml

runtime: custom
vm: true
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: main.app

Dockerfile

FROM gcr.io/google_appengine/python-compat

RUN apt-get update

RUN apt-get install -y gwhois

ADD . /app

main.py

import logging
import webapp2
from subprocess import Popen, PIPE

class OkHandler (webapp2.RequestHandler):
    def get (self): 
        self.response.write ('ok')

class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        domain = self.request.get ('domain')
        cmd = ["gwhois", domain]
        process = Popen (cmd, stdout=PIPE, stderr=PIPE)
        output, err = process.communicate()
        exit_code = process.wait()
        self.response.write('stdout: %s' % output)
        logging.info ('stderr: %s' % err)

app = webapp2.WSGIApplication([
    ('/', MainPage),
    ('/_ah/start', OkHandler),
    ('/_ah/health', OkHandler)
], debug=True)

/?domain=stackoverflow.com发送请求以查看此操作。

<强> N.B。

如果他们希望完全脱离python-compat运行时并简单地部署/测试python WSGI应用程序,他们也可以使用--custom_entrypoint标志,只要他们有一个命令可以开始运行在合适的端口上使用适当的WSGI应用程序(这样的命令可以是uwsgigunicorn)。

答案 2 :(得分:0)

尝试让我的自定义虚拟机与dev_appserver一起工作更好 部分时间,这篇文章的accepted answer来自于 非常不愉快的惊喜。但我认为部署一个开发服务器无法 这很麻烦,因为毕竟VM是标准的Docker镜像。

确实存在一些妨碍直接部署工作的问题。我已经在下面提供了这些问题的摘要以及我如何解决它们。我可能已经错过了Docker和App Engine环境之间的一些不兼容性(特别是我的项目没有使用的App Engine的许多方面),但希望它足以让人们启动并运行。

麻烦来源

首先,我发现在Compute Engine VMs中运行的python环境是一个 比普通VM环境更宽松(例如webapp2之类的包总是可用的)。因此,部署到较不宽容的Docker 容器环境在我的项目中浮现了一些潜在的错误。

话虽如此,但环境存在一些差异 即使您的项目完美无瑕,也需要进行一些调整:

  • 问题:必须在上面安装gunicorn(或您选择的服务器) Docker容器的路径。

    • 虽然这看起来很明显,但我遇到了麻烦,因为我包括了 我的项目gunicorn文件中的requirements.txt。不幸的是,我是 使用pip install -t ...安装所有这些依赖项,只能安装源代码。因此,图片上没有gunicorn二进制文件,更不用说PATH了。
  • 解决方案:明确pip install gunicorn

  • 问题: google.appengine.*软件包无法从中获取 App Engine基础Docker镜像也不是通过pip(AFAICT)提供的。
    • 这可能是常见的问题来源,因为google.appengine.ext.vendor是将第三方库导入App Engine应用程序的推荐界面。
  • 解决方案:我通过下载整个Google App Engine程序包层次结构并将其放在应用程序的路径上来解决这个问题。

如何获取脚本

用于构建VM docker镜像并将其部署到docker容器的脚本 在当地运行是可用的 here

有关工作示例,请查看my project

如果您有评论,功能请求,或者您编写更漂亮的bash,请告诉我 比我(我觉得我在这个数字上设置了低得多的棒)。