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