本教程介绍如何构建自定义 Cloud Run 服务,以将图表说明输入参数转换为 PNG
图片格式的图表。本教程使用已作为系统软件包安装在服务容器环境中的 Graphviz。您可以通过命令行实用程序使用 Graphviz 来处理请求。
目标
- 使用 Dockerfile 编写并构建一个自定义容器
- 编写、构建和部署 Cloud Run for Anthos 服务
- 使用 Graphviz dot 实用程序生成图表
- 通过使用 DOT 语法发布集合中的图表或您自己创建的图表来测试服务
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
准备工作
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- 启用 Cloud Run for Anthos API
- 安装并初始化 gcloud CLI。
- 安装
kubectl
组件:gcloud components install kubectl
- 更新组件:
gcloud components update
- 安装 curl 以试用该服务
- 按照设置 Cloud Run for Anthos 中的说明创建一个新集群。
设置 gcloud 默认值
如需为您的 Cloud Run for Anthos 服务配置 gcloud 默认值,请执行以下操作:
设置默认项目:
gcloud config set project PROJECT_ID
将 PROJECT_ID 替换为您在本教程中使用的项目名称。
为您的集群配置 gcloud:
gcloud config set run/platform gke gcloud config set run/cluster CLUSTER-NAME gcloud config set run/cluster_location REGION
您需要将其中的:
- 将 CLUSTER-NAME 替换为您使用的集群名称。
- 将 REGION 替换为您选择的受支持的集群位置。
检索代码示例
如需检索可用的代码示例,请执行以下操作:
将示例应用代码库克隆到本地机器:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
或者,您也可以下载该示例的 zip 文件并将其解压缩。
Python
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
或者,您也可以下载该示例的 zip 文件并将其解压缩。
Go
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
或者,您也可以下载该示例的 zip 文件并将其解压缩。
Java
git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
或者,您也可以下载该示例的 zip 文件并将其解压缩。
切换到包含 Cloud Run for Anthos 示例代码的目录:
Node.js
cd nodejs-docs-samples/run/system-package/
Python
cd python-docs-samples/run/system-package/
Go
cd golang-samples/run/system_package/
Java
cd java-docs-samples/run/system-package/
直观呈现架构
基本架构如下所示:
用户向 Cloud Run for Anthos 服务发出 HTTP 请求,然后该服务执行 Graphviz 实用程序来将请求转换为图片,并将得到的图片以 HTTP 响应形式传递给用户。
了解代码
使用 Dockerfile
定义您的环境配置
您的 Dockerfile
取决于服务将使用的语言和基础运营环境,例如 Ubuntu。
此服务还需要一个或多个其他系统软件包,但这些软件包不会默认提供。
在编辑器中打开
Dockerfile
。查找
Dockerfile
RUN
语句。该语句允许运行任意 shell 命令来修改环境。如果Dockerfile
包含多个阶段(可通过找到多条FROM
语句来确定),则您将会在最后一个阶段找到这条语句。所需的特定软件包及其安装机制因容器内声明的操作系统而异。
如需获取有关所用操作系统或基础映像的说明,请点击相应的标签页。
Debian/Ubuntu Alpine Alpine 还需要一个用于支持字体的软件包。要确定容器映像的操作系统,请检查
FROM
语句中的名称或与基础映像关联的 README 文件。例如,如果您的 Dockerfile 从node
扩展而来,则可以在 Docker Hub 上找到文档和父级Dockerfile
。使用
docker build
(本地)或 Cloud Build 构建映像,以对您的自定义内容进行测试。
处理传入请求
示例服务使用来自传入 HTTP 请求的参数进行系统调用,以此执行相应的 dot
实用程序命令。
以下 HTTP 处理程序从 dot
查询字符串变量中提取图表说明输入参数。
图表说明包含的字符必须采用网址编码,以便用于查询字符串。
Node.js
Python
Go
Java
您需要区分内部服务器错误和无效用户输入。此示例服务会为所有 dot 命令行错误都返回一个内部服务器错误,除非错误消息包含指示用户输入问题的 syntax
字符串。
生成图表
图表生成的核心逻辑是使用 dot 命令行工具将图表说明输入参数处理为 PNG 图片格式的图表。
Node.js
Python
Go
Java
设计安全的服务
dot
工具中的任何漏洞都会成为 Web 服务的潜在漏洞。通过定期重新构建容器映像,您可以使用 graphviz
软件包的最新版本来缓解这种情况。
如果您将当前示例扩展为接受用户输入作为命令行参数,则应防范命令注入攻击。以下是可以防范此类注入攻击的一些方法:
- 将输入映射到由受支持参数组成的字典
- 验证输入是否匹配一系列已知安全的值(可能使用正则表达式)
- 对输入进行转义,以确保不对 shell 语法进行评估
交付代码
要交付代码,请先使用 Cloud Build 进行构建,然后上传到 Container Registry,最后再部署到 Cloud Run for Anthos:
运行以下命令来构建容器并将其发布到 Container Registry 上。
Node.js
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
其中 PROJECT_ID 是您的 GCP 项目 ID,
graphviz
是您要为服务指定的名称。成功完成后,您将看到一条包含 ID、创建时间和映像名称的 SUCCESS 消息。映像存储在 Container Registry 中,并可根据需要重复使用。
Python
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
其中 PROJECT_ID 是您的 GCP 项目 ID,
graphviz
是您要为服务指定的名称。成功完成后,您将看到一条包含 ID、创建时间和映像名称的 SUCCESS 消息。映像存储在 Container Registry 中,并可根据需要重复使用。
Go
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
其中 PROJECT_ID 是您的 GCP 项目 ID,
graphviz
是您要为服务指定的名称。成功完成后,您将看到一条包含 ID、创建时间和映像名称的 SUCCESS 消息。映像存储在 Container Registry 中,并可根据需要重复使用。
Java
此示例使用 Jib 利用常见 Java 工具构建 Docker 映像。无需编写 Dockerfile 或安装 Docker,Jib 便可以优化容器构建。详细了解如何使用 Jib 构建 Java 容器。使用 Dockerfile,配置并构建已安装系统软件包的基本映像,以覆盖 Jib 的默认基本映像:
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz-base
其中 PROJECT_ID 是您的 GCP 项目 ID。
使用 Jib 构建最终容器并在 Container Registry 上发布:
mvn compile jib:build \ -Dimage=gcr.io/PROJECT_ID/graphviz \ -Djib.from.image=gcr.io/PROJECT_ID/graphviz-base
其中 PROJECT_ID 是您的 GCP 项目 ID。
使用以下命令进行部署:
gcloud run deploy graphviz-web --create-if-missing --image gcr.io/PROJECT_ID/graphviz
其中 PROJECT_ID 是您的 GCP 项目 ID,
graphviz
是上述容器的名称,graphviz-web
是服务的名称。等待部署完成,这可能需要半分钟左右的时间。
如果要将代码更新部署到该服务,请重复执行上述步骤。向服务执行的每次部署都会创建一个新的修订版本,该修订版本准备就绪后会自动开始处理流量。
试试看
要试用您的服务,您可以发送 HTTP POST
请求,并使用 DOT 语法在请求负载中添加说明。
向您的服务发送 HTTP 请求。
您可以将图表嵌入到网页中:
- 如需获取 Istio 入站网关的外部 IP,请执行以下操作:
生成的输出类似如下所示:kubectl get svc istio-ingress -n gke-system
负载平衡器的 EXTERNAL-IP 是您必须使用的 IP 地址。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingress LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
通过在网址中使用此
EXTERNAL-IP
地址,运行 curl 命令。 请不要将协议(例如:http://
)添加到SERVICE_DOMAIN
中。curl -G -H "Host: SERVICE_DOMAIN" http://EXTERNAL-IP/diagram.png \ --data-urlencode "dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }" \ > diagram.png
- 如需获取 Istio 入站网关的外部 IP,请执行以下操作:
在任何支持
PNG
文件的应用(如 Chrome)中,打开生成的diagram.png
文件。该属性应如下所示:
您可以浏览一小部分现成的图表说明。
- 复制所选
.dot
文件的内容 将其粘贴到
curl
命令中:curl -G -H "Host: SERVICE_DOMAIN" http://EXTERNAL-IP/diagram.png \ --data-urlencode "dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }" \ > diagram.png
清除数据
如果您为本教程创建了一个新项目,请删除项目。 如果您使用的是现有项目,希望保留此项目且不保留本教程中添加的任何更改,请删除为教程创建的资源。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
如需删除项目,请执行以下操作:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
删除教程资源
删除您在本教程中部署的 Cloud Run for Anthos 服务:
gcloud run services delete SERVICE-NAME
其中,SERVICE-NAME 是您选择的服务名称。
您还可以在 Google Cloud 控制台中删除 Cloud Run for Anthos 服务。
移除您在教程设置过程中添加的 gcloud 默认配置:
gcloud config unset run/platform gcloud config unset run/cluster gcloud config unset run/cluster_location
移除项目配置:
gcloud config unset project
删除在本教程中创建的其他 Google Cloud 资源:
后续步骤
- 对您的 graphviz 应用进行实验:
- 添加对其他 graphviz 实用程序的支持,以便运用不同算法来生成图表。
- 将图表保存到 Cloud Storage。要保存该图片或 DOT 语法吗?
- 使用 Cloud Natural Language API 实现内容滥用防护。
- 参阅图片处理中的另一个系统软件包示例。
- 探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud Architecture Center。