Multiple GRPC Service Routing in Kong
Into
这里演示了利用 kong 对多个 grpc 服务进行路由的方法。
1.在 kubernetes 安装 kong
kubecstl apply -f https://bit.ly/kong-ingress-dbless
2.安装完查看 kong 服务情况
$ kubectl -n kong get all
NAME READY STATUS RESTARTS AGE
pod/ingress-kong-1122334455-mzfnx 2/2 Running 0 23h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kong-proxy LoadBalancer 172.20.179.34 a111222333444555666777888999000f-1122334455667788.elb.cn-northwest-1.amazonaws.com.cn 80:30004/TCP,443:32418/TCP 23h
service/kong-validation-webhook ClusterIP 172.20.59.181 <none> 443/TCP 23h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-kong 1/1 1 1 23h
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-kong-1122334455 1 1 1 23h
将 AWS ELB 保存在变量 ELB
中
ELB=$(kubectl -n kong get svc -o=jsonpath="{.items[0].status.loadBalancer.ingress[0].hostname}")
echo $ELB
# a111222333444555666777888999000f-1122334455667788.elb.cn-northwest-1.amazonaws.com.cn
3.安装 grpcbin 服务
kubectl apply -f https://bit.ly/grpcbin-service
给 service 打 patch,让 kong 使用 gRPC 协议来和 upstram 通信,grpcbin 9001 服务需要指定 protocol 为 grpcs
kubectl patch svc grpcbin -p '{"metadata":{"annotations":{"konghq.com/protocol":"grpcs"}}}'
安装 ingress
kubectl apply -f ingress.yaml
ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: grpcbin-grpc
annotations:
konghq.com/protocols: grpc,grpcs
spec:
rules:
- http:
paths:
- path: /hello.HelloService
backend:
serviceName: grpcbin
servicePort: 9001
下面进行测试。
测试前需要准备 protobuf 文件
hello.proto
// based on https://grpc.io/docs/guides/concepts.html
syntax = "proto2";
package hello;
service HelloService {
rpc SayHello(HelloRequest) returns (HelloResponse);
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}
message HelloRequest {
optional string greeting = 1;
}
message HelloResponse {
required string reply = 1;
}
通过 grpcurl 来测试
$ grpcurl -v -d '{"greeting": "Kong Hello world!"}' -proto hello.proto -insecure $ELB:443 hello.HelloService.SayHello
Resolved method descriptor:
rpc SayHello ( .hello.HelloRequest ) returns ( .hello.HelloResponse );
Request metadata to send:
(empty)
Response headers received:
content-type: application/grpc
date: Wed, 13 May 2020 02:29:43 GMT
server: openresty
trailer: Grpc-Status
trailer: Grpc-Message
trailer: Grpc-Status-Details-Bin
via: kong/2.0.4
x-kong-proxy-latency: 1
x-kong-upstream-latency: 13
Response contents:
{
"reply": "hello Kong Hello world!"
}
Response trailers received:
(empty)
Sent 1 request and received 1 response
4.安装 helloworld-grpc 服务
kubectl apply -f helloworld-grpc.yaml
helloworld-grpc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
spec:
selector:
matchLabels:
app: helloworld
replicas: 1
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: "quay.io/dylankyc/grpc-examples-helloworld-server"
resources:
limits:
cpu: 64m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
annotations:
konghq.com/protocol: grpc
spec:
# type: ClusterIP
selector:
app: helloworld
ports:
- port: 50051
targetPort: 50051
name: grpc
# protocol: TCP
给 service 打 patch,让 kong 使用 gRPC 协议来和 upstram 通信,因为 helloworld 采用非 TLS 方式,这里指定 protocol 为 grpc
kubectl patch svc helloworld -p '{"metadata":{"annotations":{"konghq.com/protocol":"grpc"}}}'
安装 ingresss
kubectl apply -f ingress.yaml
ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: helloworld-grpc
annotations:
konghq.com/protocols: grpc,grpcs
spec:
rules:
- http:
paths:
- path: /helloworld.Greeter
backend:
serviceName: helloworld
servicePort: 50051
下面进行测试。
测试前需要准备 protobuf 文件
helloworld.proto
// protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
syntax = "proto3";
// option go_package = "github.com/dylankyc/grpc-examples/helloworld/internal/pb/helloworld";
// option go_package = "../pb/helloworld;helloworld";
// OK
option go_package = "pb/helloworld;helloworld";
// NOT OK
// option go_package = "helloworld";
package helloworld;
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
通过 grpcurl 来测试
$ grpcurl -v -d '{"name": "Kong Hello world!"}' -insecure -proto helloworld.proto $ELB:443 helloworld.Greeter.SayHello
Resolved method descriptor:
// Sends a greeting
rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply );
Request metadata to send:
(empty)
Response headers received:
content-type: application/grpc
date: Wed, 13 May 2020 02:55:01 GMT
server: openresty
via: kong/2.0.4
x-kong-proxy-latency: 0
x-kong-upstream-latency: 2
Response contents:
{
"message": "Hello Kong Hello world!"
}
Response trailers received:
(empty)
Sent 1 request and received 1 response