跳到主要内容
版本:3.2.16.3

使用 API7 企业版代理 gRPC 服务

Google Remote Procedure Call(gRPC)是基于 HTTP/2 协议的开源高性能远程过程调用(Remote Procedure Call,RPC)框架。gRPC 使用 Protocol Buffers(protobuf)作为接口描述语言(Interface Description Language,IDL)。API7 企业版提供协议转换、负载均衡、身份验证和授权等关键功能,增强了 gRPC 的潜力。

本指南介绍如何使用 API7 企业版代理 gRPC 服务。

下面是一个互动演示,介绍了如何使用 API7 企业版代理 gRPC 流量。

前提条件

  1. 安装 API7 企业版
  2. 安装 gRPCurl,将请求发送到 gRPC 服务器进行验证。

部署示例 gRPC 服务器

API7 提供了一个 gRPC 服务示例,用于测试。你可以使用以下命令在端口 50051 上启动示例 gRPC 服务器的 Docker 实例 grpc-service

docker run -d \
--name grpc-service \
--network=api7-ee_api7 \
-p 50051:50051 \
--restart always api7/grpc-server-example:1.0.0

Start an example gRPC server listening on port 50051:

kubectl run grpc-service \
--image=api7/grpc-server-example:1.0.0 \
--port=50051 \
--restart=Always

你应该能看到类似 pod/grpc-service created 的响应。

### 验证 gRPC 服务器启动成功

暴露应用的 50051 端口:

kubectl expose pod grpc-service --port 50051

你应该看到类似 service/grpc-service exposed 的响应。

将端口50051 转发到 localhost:

kubectl port-forward svc/grpc-service 50051:50051 &

通过列出所有可用的 gRPC 服务和方法来验证 gRPC 服务器是否成功启动:

grpcurl -plaintext 127.0.0.1:50051 list

你应该能看到以下输出:

grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
helloworld.TestImport

列出所有 helloworld.Greeter 服务可用的方法:

grpcurl -plaintext 127.0.0.1:50051 list helloworld.Greeter

你应该能看到以下输出:

helloworld.Greeter.GetErrResp
helloworld.Greeter.Plus
helloworld.Greeter.SayHello
helloworld.Greeter.SayHelloAfterDelay
helloworld.Greeter.SayHelloBidirectionalStream
helloworld.Greeter.SayHelloClientStream
helloworld.Greeter.SayHelloServerStream

创建服务和路由

本示例创建一个名为 grpc-example 的服务和一个名为 helloworld.Greeter 的路由,将请求转发到上面的示例 gRPC 服务。

新增服务

  1. 在左侧菜单选择目标网关组下的 已发布服务 菜单,然后点击 新增服务
  2. 选择 手动新增
  3. 在对话框中执行以下操作:
  • 名称 填写 grpc-example
  • 服务类型 选择 HTTP (七层)
  • 上游 Scheme 选择 gRPC
  • 如何找到上游 选择 使用节点
  • 点击 新增节点
  • 在新增节点对话框中,执行以下操作:
    • 主机 填写你的私有 IP 地址,例如192.168.2.103
    • 端口 填写 50051
    • 权重 填写 100
  1. 点击 新增

创建一条路由

  1. 进入刚才创建好的服务,然后点击 新增路由
  2. 在对话框中,执行以下操作:
  • 名称 填写 helloworld.Greeter
  • 路径 填写 helloworld.Greeter/SayHello
  • HTTP 方法 选择 GETPOST
  • 点击 新增

创建一个 ADC 配置文件:

adc.yaml
services:
- name: grpc-example
upstream:
name: gRPC Upstream
scheme: grpc
type: roundrobin
nodes:
- host: 192.168.2.103
port: 50051
weight: 100
routes:
- uris:
- /helloworld.Greeter/SayHello
name: helloworld.Greeter
methods:
- GET
- POST

将配置同步到 API7 网关:

adc sync -f adc.yaml

使用 ApisixRoute 自定义资源创建一个 Kubernetes mainfest 文件来配置到 gRPC 服务的路由:

grpc-route.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: grpc-route
# namespace: api7 # replace with your namespace
spec:
http:
- name: helloworld-greeter
match:
paths:
- /helloworld.Greeter/SayHello
methods:
- GET
- POST
backends:
- serviceName: grpc-service
servicePort: 50051

使用 ApisixUpstream 自定义资源创建另一个 Kubernetes mainfest 文件,将上游配置为 grpc

grpc-upstream.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: grpc-service
# namespace: api7 # replace with your namespace
spec:
scheme: grpc

将配置应用到你的集群:

kubectl apply -f grpc-route.yaml -f grpc-upstream.yaml

更新 API7 网关实例以支持 HTTP/2

默认情况下,API7 网关实例在端口 9443 上支持 TLS 加密的 HTTP/2。在本教程中,你可以添加端口 9081,支持不加密的 HTTP/2,然后将端口 9081 映射到主机上的同一端口。

在本节中,你将更新 API7 网关配置和部署以支持 9081 端口上的非加密 HTTP/2。

由于 Docker 不支持在容器运行时更新端口映射,因此首先请移除 api7-ee-gateway-1 网关容器(随安装一起启动)。

接下来,在 Docker 中启动一个新的网关实例。在运行生成的部署命令之前,添加 -p 9081:9081 标志。修改后的命令应类似于:

docker run -d -e API7_CONTROL_PLANE_ENDPOINTS='["https://<YOUR_IP_ADDR>:7943"]' \
-e API7_GATEWAY_GROUP_SHORT_ID=default \
-e API7_CONTROL_PLANE_CERT="-----BEGIN CERTIFICATE-----
<CERT_CONTENT>
-----END CERTIFICATE-----
" \
-e API7_CONTROL_PLANE_KEY="-----BEGIN PRIVATE KEY-----
<PRIVATE_KEY_VALUE>
-----END PRIVATE KEY-----
" \
-e API7_CONTROL_PLANE_CA="-----BEGIN CERTIFICATE-----
<CERT_CONTENT>
-----END CERTIFICATE-----
" \
-e API7_CONTROL_PLANE_SNI="api7ee3-dp-manager" \
-p 9080:9080 \
-p 9081:9081 \
-p 9443:9443 \
api7/api7-ee-3-gateway:<VERSION>

运行命令启动网关。

网关运行后,更新网关配置以允许 9081 端口上的 HTTP/2:

docker exec <api7-ee-gateway-container-name> /bin/sh -c "echo '
nginx_config:
error_log_level: warn

apisix:
node_listen:
- port: 9080
enable_http2: true
- port: 9081
enable_http2: true
' > /usr/local/apisix/conf/config.yaml"

重新加载容器以使配置更改生效:

docker exec <api7-ee-gateway-container-name> apisix reload

编辑网关 ConfigMap:

kubectl edit cm api7-ee-3-gateway

在 ConfigMap 中添加允许 9081 端口上 HTTP/2 的配置:

apisix:
node_listen:
- port: 9080
enable_http2: false
- port: 9081
enable_http2: true

保存 ConfigMap 并重新启动部署:

kubectl rollout restart deployment api7-ee-3-gateway

要将 9081 添加为服务端口,请编辑服务:

kubectl edit svc/api7-ee-3-gateway-gateway

将以下配置添加到 ports

spec:
ports:
...
- name: http2-non-tls
port: 9081
protocol: TCP
targetPort: 9081
...

保存服务 mainifest 以使更改生效。

验证 gRPC 服务

下载 helloworld.proto 文件

此示例使用 helloworld.proto 文件来确保 gRPCurl CLI 工具使请求和响应格式与 gRPC 服务定义一致。

如果你在 Docker 中安装了网关实例并使用控制台或 ADC 进行配置,请向路由发送请求:

如果你在 Kubernetes 上安装了网关实例并使用 Ingress Controller 进行配置,请先通过端口转发将服务端口暴露给你的本地机器:

kubectl port-forward svc/api7-ee-3-gateway-gateway 9081:9081 &

向路由发送请求:

grpcurl -plaintext \
-proto helloworld.proto \
-d '{"name":"API7"}' \
"127.0.0.1:9081" \
"helloworld.Greeter.SayHello"

你应该能看到如下类似的响应:

{
"message": "Hello API7"
}

相关阅读