GAE上具有不同dockerfiles的多项服务灵活

时间:2018-03-20 15:47:53

标签: google-app-engine docker google-app-engine-python app-engine-flexible

我使用Google AppEngine Flexible python environment。现在我有两个服务:默认和工作人员共享相同的代码库,由app.yamlworker.yaml配置。现在我需要安装本机C ++库,所以我不得不切换到Custom runtime并添加了Dockerfile。

这是由gcloud beta app gen-config --custom命令

生成的Dockerfile
FROM gcr.io/google-appengine/python
LABEL python_version=python3.6

RUN virtualenv --no-download /env -p python3.6

# Set virtualenv environment variables. This is equivalent to running
# source /env/bin/activate
ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH
ADD requirements.txt /app/
RUN pip install -r requirements.txt
ADD . /app/
CMD exec gunicorn --workers=3 --threads=3 --bind=:$PORT aces.wsgi

以前我的app.yamlworker.yaml都有自己的entrypoint:配置,指定了启动服务所需的命令。

所以,我的问题是如何使用两个不同的命令来启动服务?

编辑1

到目前为止,我能够通过在dockerfile中为每个服务的每个部署重写CMD行来解决这个问题。但是,我对此解决方案并不十分满意。

gcloud app deploy命令具有--image-url标志,允许从GCR设置图像URL。我还没有研究过,但似乎我可以上传图像到GCR并使用网址,因为经常不改变这些

3 个答案:

答案 0 :(得分:2)

由于无法更改Dockerfile名称,因此不必修改Dockerfile的唯一方法是将每个服务存储在其自己的单独目录中。清除分离,每个服务都有自己的Dockerfile和/或启动配置。

但这提出了一个问题:如何处理多个服务共享的代码?使用符号链接(非常适合跨标准环境服务共享代码)不适用于灵活的环境服务,请参阅Sharing code between flexible environment modules in a GAE project

我看到了一些可能的方法,没有一个非常理想,但可能比你现在拥有的更吸引人:

  • 硬链接每个共享源代码文件(因为无法链接目录)。有点单调乏味且容易出错,但每个文件只需执行一次
  • 将您的共享代码打包并发布为外部库,并使用它添加到每个服务的requirements.txt文件中
  • 将共享代码拆分到一个单独的存储库中,并使用它在每个服务中拥有该存储库的副本(如果使用git,可能作为git子模块?)。您只需要在服务部署时确保以适当的版本提取共享存储库 - 可以通过自动化非常可靠地完成。如果你在这个仓库中有未经修改的更改,那就有点复杂了 - 你必须在所有服务中修改相同的更改。
  • 拥有多个具有不同名称的Dockerfiles副本,您只需将其复制而不是始终编辑同一文件。 Symlinking而不是复制可能也可以工作,因为符号链接不需要在服务目录之外被跟踪,如果它只是作为符号链接复制它将起作用。

答案 1 :(得分:1)

是的,就像您提到的,我认为在这里使用-image-url 标志是一个不错的选择。

指定自定义运行时。 在本地构建图像,对其进行标记,然后将其推送到Google Container Registry(GCR) 然后,部署服务,指定自定义服务文件,并使用--image-url选项在GCR上指定远程映像。

下面是一个示例,该示例在共享相同代码的2个服务中完成不同的入口点: ...这是假设正在使用“ flex”而非“标准”的应用程序引擎产品。

让我们说您有一个名为 my-proj 的项目 使用不重要的默认服务 第二个服务叫做 queue-processor ,该服务正在使用同一目录中的许多相同代码。 为它创建一个单独的dockerfile,名为 QueueProcessorDockerfile 以及名为 queue-processor-app.yaml 的单独app.yaml来告诉Google App Engine我想要发生什么。

QueueProcessorDockerfile

FROM node:10
# Create app directory
WORKDIR /usr/src/app
COPY package.json ./
COPY yarn.lock ./
RUN npm install -g yarn
RUN yarn
# Bundle app source
COPY . .
CMD [ "yarn", "process-queue" ]

*当然,我的package.json中有一个“ process-queue”脚本 queue-processor-app.yaml

runtime: custom
env: flex
... other stuff...
...
  1. 构建并标记docker映像 在此处查看Google指南-> https://cloud.google.com/container-registry/docs/pushing-and-pulling docker build -t eu.gcr.io/my-proj/queue-processor -f QueueProcessorDockerfile。
  2. 将其推送到GCR docker push eu.gcr.io/my-proj/queue-processor
  3. 部署服务,指定Google应该使用哪个yaml配置文件,以及您推送的图片网址 gcloud应用程序部署queue-processor-app.yaml --image-url eu.gcr.io/my-proj/queue-processor

答案 2 :(得分:0)

所以我的Java应用程序有一个非常相似的问题。我们希望从Heroku迁移到GAE,并尝试使用GAE服务模拟Heroku Procfile。实际上,我们所做的就是在应用程序src/main/appengine/websrc/main/appengine/worker中创建单独的目录,其中每个目录都包含特定于该进程的app.yaml和Dockerfile。然后,使用mvn appengine:deploy功能,分别为我们要部署的每个服务指定-Dapp.stage.dockerDirectory-Dapp.stage.appEngineDirecory。然后,仅使用一些参数,我们就能够从相同的代码库中为每个服务的并行部署编写脚本。不确定这是否适合您的情况,但这对我们非常有用:以下是两个示例命令的全部内容:

Web流程: mvn appengine:deploy -Dapp.stage.dockerDirectory=src/main/appengine/web -Dapp.stage.appEngineDirectory=src/main/appengine/web -Dapp.stage.stagingDirectory=target/appengine-web -Dapp.deploy.projectId=${project-id} -Dapp.deploy.version=${project-version}

工作流程: mvn appengine:deploy -Dapp.stage.dockerDirectory=src/main/appengine/worker -Dapp.stage.appEngineDirectory=src/main/appengine/worker -Dapp.stage.stagingDirectory=target/appengine-worker -Dapp.deploy.projectId=${project-id} -Dapp.deploy.version=${project-version}