Невозможно запустить настраиваемую управляемую виртуальную машину Google App Engine: должна быть установлена ошибка --custom-entrypoint
ОПИСАНИЕ ПРОБЛЕМЫ
Я пытаюсь создать настраиваемую управляемую виртуальную машину для Google App Engine, которая работает аналогично стандартной управляемой виртуальной машине python27, предоставленной Google. (Я делаю это как первый шаг к добавлению библиотеки C++ во время выполнения).
Из документации Google следующий Dockerfile определяет стандартную среду выполнения python27:
FROM gcr.io/google_appengine/python-compat
ADD . /app
Я проверил, что это правильный Dockerfile, изучив файл, сгенерированный gcloud preview app run
при использовании стандартной среды выполнения python27. Это идентично этому.
Но когда я запускаю свое приложение с этим Dockerfile, используя dev_appserver.py
или с gcloud preview app run
Я получаю сообщение об ошибке:
The --custom_entrypoint flag must be set for custom runtimes
Я использую последние версии gcloud (1.9.86, с компонентом app-engine-python версии 1.9.28) и SDK автономного движка приложений python (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-запросы.
Два других релевантных вопроса о стековом потоке, которые я нашел, не помогли. Принятые ответы, похоже, указывают на то, что это ошибка в SDK, которая была устранена. Но я попробовал это в двух версиях SDK, включая последнюю, и у меня все еще есть проблема.
- Как исправить "
The --custom_entrypoint flag must be set for custom runtimes
"? - Ошибка управляемой виртуальной машины Google - пользовательская точка входа
ШАГИ ПЕРЕПИСАТЬ:
Чтобы подчеркнуть мою проблему, я создал тривиальное приложение, которое генерирует ошибку. Он состоит всего из трех файлов:
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 (и фактически буквально копируется из файла Dockerfile, сгенерированного gcloud preview app run
при использовании среды выполнения Python27), поэтому это должно совпадать с настройкой 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)
Когда я бегу 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
3 ответа
ОБНОВИТЬ
ЭТО НЕ МОЖЕТ БЫТЬ ТОЛЬКО ТОЧНЫМ. ПОСМОТРЕТЬ НИК ОТВЕТ.
(Хотя я не мог заставить это работать. Но я не очень старался)
Существует совершенно недокументированная, но абсолютно необходимая информация о виртуально управляемых ВМ:
ОНИ НЕ МОГУТ БЫТЬ НА СЕРВЕРЕ РАЗВИТИЯ!
Если вы думаете, что этот важный факт будет упомянут в любом месте, например, на странице документации для настраиваемых управляемых виртуальных машин или для dev_appserver.py
или даже как сообщение об ошибке при запуске dev_appserver.py
, тогда вы даете Google слишком много кредитов.
Единственное место, где я могу найти какое-либо утверждение по этому поводу, находится в файле Readme https://github.com/GoogleCloudPlatform/appengine-java-vm-guestbook-extras на github (серьезно):
Cloud SDK больше не поддерживает запуск пользовательских сред выполнения, когда предоставляется Dockerfile. Вам придется развернуть приложение в App Engine.
Google не заботится о том, чтобы:
- Реализуйте эту основную и важную функцию.
- Документ, что на сервере разработки отсутствует такая важная функция.
- Дайте любое разумное сообщение об ошибке, когда пользователь устает выполнять действие.
Я надеюсь, что этот ответ спасет какого-нибудь извиняющегося разработчика от мучительных дней, которые я пережил из-за этого
РЕДАКТИРОВАТЬ 1: Решение, опубликованное user862857, использует сам Docker для создания образов из Dockerfile и запуска их в контейнерах. Это также хороший подход к запуску управляемых виртуальных машин и пользовательских сред выполнения в контексте разработки.
Принятый ответ не кажется правильным. Github README не должен превзойти официальные документы в авторитетности при работе с быстро развивающимся бета-продуктом. Это вполне возможно для runtime: custom
приложение в среде разработчика, используя Dockerfile, упомянутый в посте OP,
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=stackru.com
чтобы увидеть это в действии.
NB
Если они хотят полностью отделиться от среды исполнения python-compat и просто развернуть / протестировать приложение Python WSGI через них, они также могут использовать --custom_entrypoint
flag, пока у них есть команда, которая запускает соответствующее приложение WSGI на подходящем порту (такой командой будет uwsgi или gunicorn).
После попытки заставить мою собственную виртуальную машину работать с dev_appserver большую часть дня, принятый ответ на этот пост стал довольно неприятным сюрпризом. Но я подумал, что развертывание сервера разработки не может быть такой большой проблемой, потому что, в конце концов, виртуальная машина - это стандартный образ Docker.
Что ж, оказалось, что есть несколько проблем, которые мешают правильному развертыванию. Ниже я представил сводку этих проблем, а также то, как я их решил. Возможно, я упустил некоторые несовместимости между средами Docker и App Engine (особенно со многими аспектами App Engine, которые мой проект не использовал), но, надеюсь, этого достаточно, чтобы люди работали.
Источники неприятностей
Во-первых, я обнаружил, что среда Python, запускаемая на виртуальных машинах Compute Engine, более мягкая, чем обычная среда виртуальных машин (например, пакеты типа webapp2
всегда доступны). Следовательно, развертывание в менее щадящей среде контейнера Docker выявило некоторые скрытые ошибки в моем проекте.
Тем не менее, существуют некоторые различия в средах, которые требуют некоторых настроек, даже если ваш проект безупречен:
Проблема: gunicorn (или сервер по вашему выбору) должен быть установлен на пути контейнера Docker.
- Хотя это может показаться очевидным, я столкнулся с проблемой, потому что я включил
gunicorn
в моем проектеrequirements.txt
файл. К сожалению, я устанавливал все эти зависимости, используяpip install -t ...
который может только установить источник. В результате не былоgunicorn
двоичный на изображении, не говоря уже оPATH
,
- Хотя это может показаться очевидным, я столкнулся с проблемой, потому что я включил
Решение: явно
pip install gunicorn
- Проблема:
google.appengine.*
пакеты недоступны из базового образа Docker App Engine и не доступны через pip (AFAICT).- Это может быть общим источником проблем, потому что
google.appengine.ext.vendor
рекомендуемый интерфейс для импорта сторонних библиотек в приложение App Engine.
- Это может быть общим источником проблем, потому что
- Решение: я справился с этим, загрузив всю иерархию пакетов Google App Engine и поместив его в путь приложения.
Как получить скрипт
Сценарий для создания и развертывания образа Docker VM в контейнере Docker, работающем локально, доступен здесь.
Для рабочего примера, проверьте мой проект.
Дайте мне знать, если у вас есть комментарий, запрос на добавление функции или если вы пишете более симпатичный bash, чем я (я чувствую, что установил комфортно низкую планку на этом счетчике).