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

时间:2018-08-14 13:28:55

标签: python docker google-cloud-platform gcloud google-cloud-build

TL,DR;

  • 在生成API描述符文件时,哪种Linux Docker映像运行Python gRPC插件最快/最轻?
  • 上述API描述符是否应成为Cloud Build artifact并保存到Cloud Storage Bucket?
    • ...以便使用gcloud将API部署到Cloud Endpoints。

详细信息

我在Python gRPC service上运行的Docker容器中运行了Google Compute Engine和ESP。 About gRPC > API management显示了我的应用程序体系结构图:

enter image description here

我的高级构建步骤:


1),使用协议协议缓冲区编译器创建描述符文件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

2) Deploy the proto descriptor文件(api_descriptor.pb)和使用gcloud命令行工具的配置文件:

gcloud endpoints services deploy api_descriptor.pb api_config.yaml

3) Generate gRPC code使用Python插件:

python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto

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

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

AFAICT我的高级构建步骤应映射到Cloud Builder official builder images

1) ???

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

3) ???

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

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

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

AFAICT步骤1)应该为api_descriptor.pb生成一个Cloud Build artifact,然后保存到Cloud Storage Bucket。

  • 在生成API描述符文件时,哪种Linux Docker映像运行Python gRPC插件最快/最轻?
  • 上述API描述符是否应成为Cloud Build artifact并保存到Cloud Storage Bucket?
    • ...以便使用gcloud将API部署到Cloud Endpoints。

1 个答案:

答案 0 :(得分:1)

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

TL,DR; :如果您仅想将protoc与Google Cloud Build一起使用,我已经向cloud builders community GitHub repository提交了protoc构建器公认。参见cloud-builders-community/protoc

详细信息;我的解决方案依赖于创建protoc Custom Build Step。这将创建一个Cloud Build工作者在需要运行protoc时提取并运行的Docker容器映像。

您只需要两个文件即可创建Custom Build Stepprotoc

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

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

.
├── cloudbuild.yaml
└── Dockerfile

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

FROM ubuntu

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

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

RUN echo "${PROTOC_VERSION}/${ASSET_NAME}"

RUN wget https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip && \
unzip ${ASSET_NAME} -d protoc && rm ${ASSET_NAME}

ENV PATH=$PATH:/protoc/bin/
ENTRYPOINT ["protoc"]
CMD ["--help]

打破这一点:

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

FROM ubuntu

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

ARG PROTOC_VERSION=3.6.1

ARG PROTOC_TARGET=linux-x86_64

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

  1. 运行apt-get -qy update以“从其源重新同步包索引文件”。 q省略了进度指示器,y认为是,是对遇到的任何提示的答案:

RUN apt-get -qy update

  1. 安装 Python Wget (从Web服务器检索内容)和解压缩

RUN apt-get -qy install python wget unzip

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

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

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

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

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

ENV PATH=$PATH:/protoc/bin/

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

ENTRYPOINT ["protoc"]

  1. 使用CMD指令,以便如果在运行protoc映像时未提供任何选项,则protoc --help将运行:

CMD ["--help]

这就是我们定义可执行文件protoc的Docker映像的全部。但是,尚不能在Custom Build Step环境中使用Google's Cloud Build。我们必须使用cloudbuild.yaml定义自定义构建步骤:

steps:
  - name: 'gcr.io/cloud-builders/docker'
    args:
      [
        'build',
        '--tag',
        'gcr.io/$PROJECT_ID/protoc',
        '--cache-from',
        'gcr.io/$PROJECT_ID/protoc',
        '.',
      ]
images: ['gcr.io/$PROJECT_ID/protoc']

此文件将生成伪像gcr.io/my-cloud-project-id/protoc,可用于在Google Cloud Build中运行protoc。此自定义构建步骤的示例用法:

steps:
  - name: 'gcr.io/$PROJECT_ID/protoc'
    args:
      [
        '--include_imports',
        '--include_source_info',
        '--proto_path',
        '.',
        '--descriptor_set_out',
        'api_descriptor.pb',
        'v1/my-api-proto.proto',
      ]

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

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

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