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

use*_*609 5 python google-app-engine gae-module google-app-engine-python google-managed-vm

问题描述

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

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

FROM gcr.io/google_appengine/python-compat
ADD . /app
Run Code Online (Sandbox Code Playgroud)

我通过检查gcloud preview app run使用标准python27运行时生成的那个来验证这是正确的Dockerfile .它与此完全相同.

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

The --custom_entrypoint flag must be set for custom runtimes
Run Code Online (Sandbox Code Playgroud)

我使用的是最新版本的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"
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做.泊坞窗图像是否尚未包含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
Run Code Online (Sandbox Code Playgroud)

Dockerfile:

FROM gcr.io/google_appengine/python-compat
ADD . /app
Run Code Online (Sandbox Code Playgroud)

Dockerfile与用于python27运行时的相同(实际上从使用python27 gcloud preview app run运行时生成的Dockerfile中复制粘贴),因此这应该与设置相同runtime: python27.

wsgi.py:

import webapp2

class Hello(webapp2.RequestHandler):
    def get(self):
        self.response.write(u'Hello')

app = webapp2.WSGIApplication([('/Hello', Hello)], debug=True)
Run Code Online (Sandbox Code Playgroud)

当我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
Run Code Online (Sandbox Code Playgroud)

use*_*609 10

UPDATE

这可能不会更准确.看看尼克的回答.

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


自定义托管VM有一个完全没有记录但绝对必要的信息:

它们不能在开发服务器上运行!

如果你认为这个关键事实会在任何地方被提及,比如说,自定义托管虚拟机的文档页面 dev_appserver.py,或者甚至作为运行时的错误消息dev_appserver.py,那么你给予谷歌过多的信任.

我可以在github(严重)上的appengine-java-vm-guestbook-extras演示的自述文件中找到关于此的任何声明的唯一地方:

提供Dockerfile时,Cloud SDK不再支持运行自定义运行时.您必须将应用程序部署到App Engine

谷歌不关心:

  1. 实现这一基本而重要的功能.
  2. 记录开发服务器缺少这样一个重要的功能.
  3. 当用户厌倦执行操作时,给出任何合理的错误消息.

我希望这个答案可以避免一些令人遗憾的开发人员因为这个而遭受折磨的日子.


Nic*_*ick 6

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


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

FROM gcr.io/google_appengine/python-compat
ADD . /app
Run Code Online (Sandbox Code Playgroud)

使用--runtime=python-compat国旗.他们将需要捕捉的请求/_ah/start/_ah/health,虽然.在给定以下文件的情况下尝试运行以下命令,并亲自查看:

devserver command

$ dev_appserver.py app.yaml --runtime=python-compat
Run Code Online (Sandbox Code Playgroud)

app.yaml

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

handlers:
- url: /.*
  script: main.app
Run Code Online (Sandbox Code Playgroud)

Dockerfile

FROM gcr.io/google_appengine/python-compat

RUN apt-get update

RUN apt-get install -y gwhois

ADD . /app
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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


NB

如果他们希望完全从Python-compat的运行时间解耦和简单的部署/通过测试一个python WSGI应用程序,他们还可以使用--custom_entrypoint标志,只要他们有这将启动一个合适的端口上运行相应的WSGI应用程序的命令(这样的命令将是uwsgigunicorn).