代理 gRPC 流量
gRPC(Google Remote Procedure Call)是一个基于 HTTP/2 协议的开源、高性能的远程过程调用(RPC)框架。它使用 Protocol Buffers(protobuf)作为接口描述语言(IDL)。API7 企业版提供了包括协议转换、负载均衡、身份验证和授权等关键功能,极大地提升了 gRPC 的应用潜能。
本指南介绍了如何使用 API7 企业版代理 gRPC 服务的流量。
下面是一个交互式演示,提供了使用 API7 企业版代理 gRPC 流量的实际上手介绍。
前提条件
- 安装 API7 企业版。
- (可选)如有需要,完成在 Kubernetes 上部署 API7 Ingress Controller。
- 安装 gRPCurl,用于向 gRPC 服务发送请求以进行验证。
部署一个示例 gRPC Server
API7 提供了一个用于测试的示例 gRPC 服务。你可以根据你的 API7 安装环境,选择在 Docker 或 Kubernetes 中启动该服务。
启动服务
- Docker
- Kubernetes
在 Docker 中启动一个示例 gRPC 服务,监听 50051 端口:
docker run -d \
--name grpc-service \
--network=api7-ee_api7 \
-p 50051:50051 \
--restart always api7/grpc-server-example:1.0.0
为 gRPC 的 Deployment 和 Service 创建一个 Kubernetes 资源清单文件:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: api7
name: grpc-service
spec:
replicas: 1
selector:
matchLabels:
app: grpc-service
template:
metadata:
labels:
app: grpc-service
spec:
containers:
- name: grpc-service
image: api7/grpc-server-example:1.0.0
ports:
- containerPort: 50051
---
apiVersion: v1
kind: Service
metadata:
namespace: api7
name: grpc-service
spec:
type: ClusterIP
selector:
app: grpc-service
ports:
- name: grpc
port: 50051
targetPort: 50051
将配置应用到你的集群:
kubectl apply -f grpc-server.yaml
验证安装
- Docker
- Kubernetes
将服务的 50051 端口转发到你本地机器的端口上:
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 服务。
- 控制台(Dashboard)
- ADC
- Ingress Controller
创建服务
- 从侧边导航栏选择你的网关组下的 已发布服务(Published Services),然后点击 添加服务(Add Service)。
- 选择 手动添加(Add Manually)。
- 在对话框中,执行以下操作:
- 在 名称(Name) 字段中,输入
grpc-example。 - 在 服务类型(Service Type) 字段中,选择
HTTP(七层代理)。 - 在 上游协议(Upstream Scheme) 字段中,选择
gRPC。 - 在 如何寻找上游(How to find the upstream) 字段中,选择
使用节点(Use Nodes)。 - 点击 添加节点(Add Node)。
- 在 添加节点(Add Node) 对话框中,执行以下操作:
- 在 主机(Host) 字段中,输入你的私有 IP 地址,如
192.168.2.103。 - 在 端口(Port) 字段中,输入
50051。 - 在 权重(Weight) 字段中,使用默认值
100。
- 在 主机(Host) 字段中,输入你的私有 IP 地址,如
- 点击 添加(Add)。
创建路由
- 在你刚才创建的服务中,点击 添加路由(Add Route)。
- 在对话框中,执行以下操作:
- 在 名称(Name) 字段中,输入
helloworld.Greeter。 - 在 路径(Path) 字段中,输入
helloworld.Greeter/SayHello。 - 在 方法(Methods) 字段中,选择
GET和POST。 - 点击 添加(Add)。
创建一个 ADC 配置文件,配置一个通往 gRPC 服务的路由:
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
- Gateway API
- APISIX CRD
创建一个 Kubernetes 资源清单文件,以配置通往 gRPC 服务的 GRPCRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
namespace: api7
name: grpc-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- method:
service: helloworld.Greeter
method: SayHello
backendRefs:
- name: grpc-service
port: 50051
创建一个 Kubernetes 资源清单文件,配置通往 gRPC 服务的路由,并将上游协议(scheme)配置为 grpc:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: api7
name: grpc-service
spec:
ingressClassName: apisix
scheme: grpc
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: api7
name: grpc-route
spec:
ingressClassName: apisix
http:
- name: helloworld-greeter
match:
paths:
- /helloworld.Greeter/SayHello
methods:
- GET
- POST
backends:
- serviceName: grpc-service
servicePort: 50051
将配置应用到你的集群:
kubectl apply -f grpc-route.yaml
更新 API7 网关以允许 HTTP/2
默认情况下,API7 网关实例支持 9443 端口上基于 TLS 加密的 HTTP/2。对于未加密的 HTTP/2 流量,你可以在网关配置中新增一个端口。
在本节中,你将更新 API7 网关的配置和部署,使其能够在 9081 端口上支持未加密的 HTTP/2。
- Docker
- Kubernetes
由于 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
要更新网关的 HTTP/2 配置,首先导出所有变量值(包括默认值):
helm get values -n api7 api7-ee-3-gateway --all > values.yaml
在 values 文件中,如下所示更新以下配置:
gateway:
http:
enabled: true
ip: 0.0.0.0
servicePort: 80
containerPort: 9080
additionalContainerPorts:
- port: 9081
enable_http2: true
升级 Release:
helm upgrade --install -n api7 api7-ee-3-gateway api7/gateway -f values.yaml
验证配置
从这里下载 helloworld.proto 文件。
本示例使用 helloworld.proto 文件来确保 gRPCurl CLI 工具的请求和响应格式与 gRPC 服务定义一致。
- Docker
- Kubernetes
如果你已经在 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"
}