如何将 gRPC Python 插件与 Docker 和 Google 云构建一起使用?
How to use the gRPC Python Plugin with Docker and Google Cloud Builds?
TL,DR;
- 在生成 API 描述符文件时,Linux Docker 图像对于 运行 Python gRPC 插件来说最快/最轻?
- 前面提到的 API 描述符是否应该成为 Cloud Build artifact 并保存到 Cloud Storage Bucket?
- ...为了使用
gcloud
将 API 部署到 Cloud Endpoints。
详情
I 运行 a Python gRPC service and ESP in Docker containers running on Google Compute Engine. About gRPC > API management 显示了我的应用程序架构图:
我的高级构建步骤:
1) 使用 protoc protocol buffers 编译器创建 描述符文件、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) 使用以下 Docker 文件构建 'gRPC Server'(附图中最右边的蓝色框):
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。
我几个月前就开始工作了。我不知道我是不是按照 "right" 的方式做的。自己判断 :p
TL,DR; 如果您只想将 protoc
与 Google Cloud Build 一起使用,我已经提交了一个 protoc
构建器到cloud builders community GitHub repository which has been accepted. See cloud-builders-community/protoc.
详细信息; 我的解决方案依赖于创建 protoc
Custom Build Step。这会创建一个 Docker 容器镜像,Cloud Build worker 在需要 运行 protoc
.
时拉取和 运行s
您只需要两个文件即可创建 Custom Build Step、protoc
:
cloudbuild.yaml
- 告诉 Google Cloud Builder 如何构建 Docker 图像。
Dockerfile
- 告诉 Docker 如何构建包含 protoc
二进制文件的环境。
这实际上是我实现步骤 1 的本地目录结构:
.
├── cloudbuild.yaml
└── Dockerfile
Docker 文件是安装 protoc
命令的地方,是两个文件中较复杂的一个:
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]
分解:
- 定义我们想要结束的最终 "protoc" 图像的第一个只读层。我选择 Ubuntu 因为它是我在本地 运行 的内容。任何最小 Linux "base image" 都可以,但必须安装以下二进制文件:
apt-get
、wget
、unzip
和 rm
:
FROM ubuntu
- 设置一些变量,用户可以在构建时使用 docker 使用
--build-arg <varname>=<value>
标志的构建命令将这些变量传递给构建器:
ARG PROTOC_VERSION=3.6.1
ARG PROTOC_TARGET=linux-x86_64
ARG ASSET_NAME=protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip
- 运行
apt-get -qy update
到 "resynchronize the package index files from their sources"。 q
省略进度指示器,y
假定对遇到的任何提示的回答是“是”:
RUN apt-get -qy update
- 安装Python、Wget(从网络服务器检索内容),然后解压缩.
RUN apt-get -qy install python wget unzip
- 删除作为前面步骤的一部分创建的所有文件(不再需要):
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/*
- 使用 ENV 指令更新
PATH
环境以在最终环境(图像)中包含 protoc
二进制文件的位置。
ENV PATH=$PATH:/protoc/bin/
设置映像的 ENTRYPOINT,使映像 运行 成为 protoc
可执行文件。不是,由于上一步将protoc
添加到$PATH
,我们只需要将二进制指定为运行(不是完整路径):
ENTRYPOINT ["protoc"]
- 使用CMD指令,这样如果运行宁
protoc
图像时没有提供选项,protoc --help
将运行:
CMD ["--help]
这就是定义可执行文件 protoc
Docker 映像所需的全部内容。但是,它还不是可以在 Google 的 Cloud Build 环境中使用的 Custom Build Step。我们必须使用 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 会自动将 $PROJECT_ID 替换为您的项目 ID,因此名称将引用工件:gcr.io/my-cloud-project-id/protoc
。由于这是一个可执行的 Docker 映像(用 ENTRYPOINT ["protoc"]
定义),它等同于 运行ning 在本地:
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 中的 运行。
TL,DR;
- 在生成 API 描述符文件时,Linux Docker 图像对于 运行 Python gRPC 插件来说最快/最轻?
- 前面提到的 API 描述符是否应该成为 Cloud Build artifact 并保存到 Cloud Storage Bucket?
- ...为了使用
gcloud
将 API 部署到 Cloud Endpoints。
- ...为了使用
详情
I 运行 a Python gRPC service and ESP in Docker containers running on Google Compute Engine. About gRPC > API management 显示了我的应用程序架构图:
我的高级构建步骤:
1) 使用 protoc protocol buffers 编译器创建 描述符文件、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) 使用以下 Docker 文件构建 'gRPC Server'(附图中最右边的蓝色框):
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。
- ...为了使用
我几个月前就开始工作了。我不知道我是不是按照 "right" 的方式做的。自己判断 :p
TL,DR; 如果您只想将 protoc
与 Google Cloud Build 一起使用,我已经提交了一个 protoc
构建器到cloud builders community GitHub repository which has been accepted. See cloud-builders-community/protoc.
详细信息; 我的解决方案依赖于创建 protoc
Custom Build Step。这会创建一个 Docker 容器镜像,Cloud Build worker 在需要 运行 protoc
.
您只需要两个文件即可创建 Custom Build Step、protoc
:
cloudbuild.yaml
- 告诉 Google Cloud Builder 如何构建 Docker 图像。Dockerfile
- 告诉 Docker 如何构建包含protoc
二进制文件的环境。
这实际上是我实现步骤 1 的本地目录结构:
.
├── cloudbuild.yaml
└── Dockerfile
Docker 文件是安装 protoc
命令的地方,是两个文件中较复杂的一个:
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]
分解:
- 定义我们想要结束的最终 "protoc" 图像的第一个只读层。我选择 Ubuntu 因为它是我在本地 运行 的内容。任何最小 Linux "base image" 都可以,但必须安装以下二进制文件:
apt-get
、wget
、unzip
和rm
:
FROM ubuntu
- 设置一些变量,用户可以在构建时使用 docker 使用
--build-arg <varname>=<value>
标志的构建命令将这些变量传递给构建器:
ARG PROTOC_VERSION=3.6.1
ARG PROTOC_TARGET=linux-x86_64
ARG ASSET_NAME=protoc-${PROTOC_VERSION}-${PROTOC_TARGET}.zip
- 运行
apt-get -qy update
到 "resynchronize the package index files from their sources"。q
省略进度指示器,y
假定对遇到的任何提示的回答是“是”:
RUN apt-get -qy update
- 安装Python、Wget(从网络服务器检索内容),然后解压缩.
RUN apt-get -qy install python wget unzip
- 删除作为前面步骤的一部分创建的所有文件(不再需要):
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/*
- 使用 ENV 指令更新
PATH
环境以在最终环境(图像)中包含protoc
二进制文件的位置。
ENV PATH=$PATH:/protoc/bin/
设置映像的 ENTRYPOINT,使映像 运行 成为 protoc
可执行文件。不是,由于上一步将protoc
添加到$PATH
,我们只需要将二进制指定为运行(不是完整路径):
ENTRYPOINT ["protoc"]
- 使用CMD指令,这样如果运行宁
protoc
图像时没有提供选项,protoc --help
将运行:
CMD ["--help]
这就是定义可执行文件 protoc
Docker 映像所需的全部内容。但是,它还不是可以在 Google 的 Cloud Build 环境中使用的 Custom Build Step。我们必须使用 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 会自动将 $PROJECT_ID 替换为您的项目 ID,因此名称将引用工件:gcr.io/my-cloud-project-id/protoc
。由于这是一个可执行的 Docker 映像(用 ENTRYPOINT ["protoc"]
定义),它等同于 运行ning 在本地:
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 中的 运行。