如何在 Docker 和 Google Cloud Builds 中使用 gRPC Python 插件?

Jac*_*ack 5 python docker google-cloud-platform gcloud google-cloud-build

TL,博士;

  • 生成 API 描述符文件时,哪种 Linux Docker 映像运行 Python gRPC 插件最快/最轻?
  • 前面提到的 API 描述符是否应该成为 Cloud Build工件并保存到 Cloud Storage Bucket 中?
    • ...为了用于gcloud将 API 部署到 Cloud Endpoints。

细节

我在Google Compute Engine上运行的 Docker 容器中运行Python gRPC 服务和 ESP 。关于 gRPC > API 管理显示了我的应用程序架构图:

在此处输入图片说明

我的高级构建步骤:


1)使用 protoc 协议缓冲区编译器创建描述符文件, api_descriptor.pb

python -m grpc_tools.protoc \
    --include_imports \
    --include_source_info \
    --proto_path=. \
    --descriptor_set_out=api_descriptor.pb \
    --python_out=generated_pb2 \
    --grpc_python_out=generated_pb2 \
    bookstore.proto
Run Code Online (Sandbox Code Playgroud)

2) 使用 gcloud 命令行工具部署 proto 描述符文件 ( api_descriptor.pb) 和配置文件:

gcloud endpoints services deploy api_descriptor.pb api_config.yaml
Run Code Online (Sandbox Code Playgroud)

3) 使用Python插件生成gRPC代码

python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto
Run Code Online (Sandbox Code Playgroud)

4)构建最终的 Docker 镜像以部署在Google Compute Engine 上。生成的 Docker 映像应包括:

  • 从第 3 步生成的 gRPC 代码)。
  • gRPC 服务器所需的任何其他 Python 包。

第 4 步)使用以下 Dockerfile 构建“gRPC 服务器”(附图中最右侧的蓝色框):

FROM gcr.io/google_appengine/python:latest

WORKDIR .
EXPOSE 8081
ENTRYPOINT ["python", "server.py"]

ADD requirements.txt .
ADD protos ./protos

RUN mkdir out

RUN apt-get update && \
    apt-get install -y python2.7 python-pip && \
    pip install -r requirements.txt


RUN python \
    -m grpc_tools.protoc \
    --python_out=out \
    --grpc_python_out=out \
    --proto_path=. \
    bookstore.proto
Run Code Online (Sandbox Code Playgroud)

我正在将这些构建步骤迁移到 Google 的Cloud Build

AFAICT 我的高级构建步骤应该映射到 Cloud Builder官方构建器镜像

1)???

2) 使用cloud-builders/gcloud/运行gcloud命令。

3)???

4) 使用cloud-builders/ docker 构建 'gRPC Server' Docker 镜像。

步骤 2) 和 3) 已经有可用的云构建器(请参阅GoogleCloudPlatform/cloud-builders)。

但是,我不确定如何将步骤1)3)迁移到 Cloud Build。这两个步骤都需要运行在基本 Linux Docker 映像中不可用的 Python 插件。

AFAICT步骤1)应该产生一个云构建神器api_descriptor.pb,并保存到云存储桶。

  • 生成 API 描述符文件时,哪种 Linux Docker 映像运行 Python gRPC 插件最快/最轻?
  • 前面提到的 API 描述符是否应该成为 Cloud Build工件并保存到 Cloud Storage Bucket 中?
    • ...为了用于gcloud将 API 部署到 Cloud Endpoints。

Jac*_*ack 1

几个月前我就开始工作了。我不知道我是否以“正确”的方式做到了这一点。自己判断吧:p

\n\n

TL,博士;如果您只想protoc与 Google Cloud Build 一起使用,我已向云构建器社区 GitHub 存储库protoc提交了一个构建器,该构建器已被接受。请参阅cloud-builders-community/protoc

\n\n

细节; 我的解决方案依赖于创建protoc Custom Build Step。这将创建一个 Docker 容器映像,供 Cloud Build 工作线程在需要运行时拉取并运行protoc

\n\n

您只需要两个文件来创建自定义构建步骤protoc

\n\n
    \n
  1. cloudbuild.yaml- 告诉 Google Cloud Builder 如何构建 Docker 映像。
  2. \n
  3. Dockerfile- 告诉 Docker 如何构建包含protoc二进制文件的环境。
  4. \n
\n\n

这实际上是我实现步骤 1 的本地目录结构:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cloudbuild.yaml\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Dockerfile\n
Run Code Online (Sandbox Code Playgroud)\n\n

Docker 文件是protoc安装命令的位置,是两个文件中较复杂的一个:

\n\n
FROM ubuntu\n\nARG PROTOC_VERSION=3.6.1\nARG PROTOC_TARGET=linux-x86_64\nARG ASSET_NAME=protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip\n\nRUN apt-get -qy update && apt-get -qy install python wget unzip && rm -rf /var/lib/apt/lists/*\n\nRUN echo "${PROTOC_VERSION}/${ASSET_NAME}"\n\nRUN wget https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip && \\\nunzip ${ASSET_NAME} -d protoc && rm ${ASSET_NAME}\n\nENV PATH=$PATH:/protoc/bin/\nENTRYPOINT ["protoc"]\nCMD ["--help]\n
Run Code Online (Sandbox Code Playgroud)\n\n

分解一下:

\n\n
    \n
  1. 定义我们想要的最终“protoc”图像的第一个只读层。我选择 Ubuntu 因为它是我在本地运行的。任何最小的 Linux“基础映像”都可以,但它必须安装以下二进制文件:apt-getwgetunziprm
  2. \n
\n\n

FROM ubuntu

\n\n
    \n
  1. 设置一些变量,用户可以使用以下标志通过 docker build 命令在构建时传递给构建器--build-arg <varname>=<value>
  2. \n
\n\n

ARG PROTOC_VERSION=3.6.1

\n\n

ARG PROTOC_TARGET=linux-x86_64

\n\n

ARG ASSET_NAME=protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip

\n\n
    \n
  1. 运行apt-get -qy update“从源重新同步包索引文件”。q省略进度指示器,y假设对遇到的任何提示的回答是“是”:
  2. \n
\n\n

RUN apt-get -qy update

\n\n
    \n
  1. 安装PythonWget(从 Web 服务器检索内容)和Unzip
  2. \n
\n\n

RUN apt-get -qy install python wget unzip

\n\n
    \n
  1. 删除在前面的步骤中创建的所有文件(并且不再需要):
  2. \n
\n\n

RUN rm -rf /var/lib/apt/lists/*

\n\n

前面的三个RUN指令可以合并为一个:

\n\n

RUN apt-get -qy update && apt-get -qy install python wget unzip && rm -rf /var/lib/apt/lists/*

\n\n
    \n
  1. 使用ENV指令更新环境以包含最终环境(映像)中二进制文件PATH的位置。protoc
  2. \n
\n\n

ENV PATH=$PATH:/protoc/bin/

\n\n

设置映像的ENTRYPOINT,以便映像作为protoc可执行文件运行。不,因为上一步添加protoc$PATH,我们只需要指定要运行的二进制文件(而不是完整路径):

\n\n

ENTRYPOINT ["protoc"]

\n\n
    \n
  1. 使用CMD指令,这样如果运行镜像时没有提供任何选项protocprotoc --help将运行:
  2. \n
\n\n

CMD ["--help]

\n\n

这就是我们定义可执行protocDocker 镜像所需的全部内容。但是,它还不是可在Google 的 Cloud Build环境中使用的自定义构建步骤。我们必须使用定义自定义构建步骤cloudbuild.yaml

\n\n
steps:\n  - name: \'gcr.io/cloud-builders/docker\'\n    args:\n      [\n        \'build\',\n        \'--tag\',\n        \'gcr.io/$PROJECT_ID/protoc\',\n        \'--cache-from\',\n        \'gcr.io/$PROJECT_ID/protoc\',\n        \'.\',\n      ]\nimages: [\'gcr.io/$PROJECT_ID/protoc\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

该文件将生成一个gcr.io/my-cloud-project-id/protoc可用于protocGoogle Cloud Build中运行的工件。此自定义构建步骤的示例用法:

\n\n
steps:\n  - name: \'gcr.io/$PROJECT_ID/protoc\'\n    args:\n      [\n        \'--include_imports\',\n        \'--include_source_info\',\n        \'--proto_path\',\n        \'.\',\n        \'--descriptor_set_out\',\n        \'api_descriptor.pb\',\n        \'v1/my-api-proto.proto\',\n      ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

Cloud Build 会自动将 $PROJECT_ID 替换为您的项目 ID,因此,该名称将引用工件:gcr.io/my-cloud-project-id/protoc。由于这是一个可执行的 Docker 映像(使用 定义ENTRYPOINT ["protoc"]),因此它相当于在本地运行:

\n\n

protoc --include_imports --include_source_info --proto_path . --descriptor_set_out api_descriptor.pb v1/my-api-proto.proto

\n\n

因此,在回答我的问题时,1) 和 3) 都可以使用protoc自定义构建步骤在 Google Cloud Build 中运行。

\n