Enable gRPC support using the NetScaler Ingress Controller
gRPC is a high performance, open-source universal RPC framework created by Google. In gRPC, a client application can directly call methods on a server application from a different server in the same way you call local methods. You can easily create distributed applications and services using GRPC.
Enable gRPC support
Perform the following steps to enable GRPC support using HTTP2.
-
Create a YAML file
cic-configmap.yaml
and enable the global parameter for HTTP2 server side support using the following entry in the ConfigMap. For more information on using ConfigMap, see the ConfigMap documentation.NS_HTTP2_SERVER_SIDE: 'ON'
-
Apply the ConfigMap using the following command.
kubectl apply -f cic-configmap.yaml
-
Edit the
cic.yaml
file for deploying the NetScaler Ingress Controller to support ConfigMap.args: - --ingress-classes citrix - --configmap default/cic-configmap
-
Deploy the NetScaler Ingress Controller as a stand-alone pod by applying the edited YAML file.
kubectl apply -f cic.yaml
-
To test the gRPC traffic, you may need to install
grpcurl
. Perform the following steps to installgrpcurl
on a Linux machine.go get github.com/fullstorydev/grpcurl go install github.com/fullstorydev/grpcurl/cmd/grpcurl
-
Apply the gRPC test service YAML file (
grpc-service.yaml
).kubectl apply -f grpc-service.yaml
Following is a sample content for the
grpc-service.yaml
file.apiVersion: apps/v1 kind: Deployment metadata: name: grpc-service spec: replicas: 1 selector: matchLabels: app: grpc-service template: metadata: labels: app: grpc-service spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest imagePullPolicy: Always name: grpc-service ports: - containerPort: 50051 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: grpc-service spec: ports: - port: 50051 protocol: TCP targetPort: 50051 selector: app: grpc-service sessionAffinity: None type: NodePort
-
Create a certificate for the gRPC Ingress configuration.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=grpc.example.com/O=grpc.example.com" kubectl create secret tls grpc-secret --key tls.key --cert tls.crt secret "grpc-secret" created
-
Enable HTTP2 using Ingress annotations. See HTTP/2 support for steps to enable HTTP2 using the NetScaler Ingress Controller.
-
Create a YAML file for the front-end Ingress configuration and apply it to enable HTTP/2 on the content switching virtual server.
kubectl apply -f frontend-ingress.yaml
The content of the
frontend-ingress.yaml
file is provided as follows:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: ingress.citrix.com/frontend-httpprofile: '{"http2":"enabled", "http2direct" : "enabled"}' ingress.citrix.com/frontend-ip: 192.0.2.1 ingress.citrix.com/secure-port: "443" kubernetes.io/ingress.class: citrix name: frontend-ingress spec: rules: - {} tls: - {}
-
Create a YAML file for the back-end Ingress configuration with the following content and apply it to enable HTTP2 on back-end (service group).
kubectl apply -f backend-ingress.yaml
The content of the
backend-ingress.yaml
file is provided as follows:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: ingress.citrix.com/backend-httpprofile: '{"grpc-service":{"http2": "enabled", "http2direct" : "enabled"}}' ingress.citrix.com/frontend-ip: 192.0.2.2 ingress.citrix.com/secure-port: "443" kubernetes.io/ingress.class: citrix name: grpc-ingress spec: rules: - host: grpc.example.com http: paths: - backend: service: name: grpc-service port: number: 50051 path: / pathType: Prefix tls: - hosts: - grpc.example.com secretName: grpc-secret
-
-
Test the gRPC traffic using the
grpcurl
command.grpcurl -v -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
The output of the command is shown as follows:
Resolved method descriptor: rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply ); Request metadata to send: (empty) Response headers received: content-type: application/grpc Response contents: { "message": "Hello gRPC" } Response trailers received: (empty) Sent 1 request and received 1 response
Validate the rate limit CRD
Perform the following steps to validate the rate limit CRD.
-
Apply the rate limit CRD using the ratelimit-crd.yaml file.
kubectl create -f ratelimit-crd.yaml
-
Create a YAML file (ratelimit-crd-object.yaml) with the following content for the rate limit policy.
apiVersion: citrix.com/v1beta1 kind: ratelimit metadata: name: throttle-req-per-clientip spec: servicenames: - grpc-service selector_keys: basic: path: - "/" per_client_ip: true req_threshold: 5 timeslice: 60000 throttle_action: "RESPOND"
-
Apply the YAML file using the following command.
kubectl create -f ratelimit-crd-object.yaml
-
Test gRPC traffic using the
grpcurl
command.grpcurl -v -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
The command returns the following error in response after the rate limit is reached:
Error invoking method "helloworld.Greeter.SayHello": failed to query for service descriptor "helloworld.Greeter": rpc error: code = Unavailable desc = Too Many Requests: HTTP status code 429; transport: missing content-type field
Validate the Rewrite and Responder CRD with gRPC
Perform the following steps to validate the Rewrite and Responder CRD.
-
Apply the Rewrite and Responder CRD using the rewrite-responder-policies-deployment.yaml file.
kubectl create -f rewrite-responder-policies-deployment.yaml
-
Create a YAML file (rewrite-crd-object.yaml) with the following content for the rewrite policy.
apiVersion: citrix.com/v1 kind: rewritepolicy metadata: name: addcustomheaders spec: rewrite-policies: - servicenames: - grpc-service rewrite-policy: operation: insert_http_header target: 'sessionID' modify-expression: '"48592th42gl24456284536tgt2"' comment: 'insert SessionID in header' direction: RESPONSE rewrite-criteria: 'http.res.is_valid'
-
Apply the YAML file using the following command.
kubectl create -f rewrite-crd-object.yaml
-
Test the gRPC traffic using the
grpcurl
command.grpcurl -v -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
This command adds a session id in the gRPC request response.
Resolved method descriptor: rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply ); Request metadata to send: (empty) Response headers received: content-type: application/grpc sessionid: 48592th42gl24456284536tgt2 Response contents: { "message": "Hello gRPC" } Response trailers received: (empty) Sent 1 request and received 1 response