How to call to kubernets grpc services in local

Usually for serivce better performance. we can use GRPC and multiple instance deployment for app, then the GRPC load balancing is challenges

Create Grpc headless service for Grpc app

when multiple instance is enable for GRPC service in order to load balacing the GRPC service, needs create headless service let client load balancing

 1apiVersion: v1
 2kind: Service
 3metadata:
 4  name: grpc-demo-headless
 5  namespace: apps
 6spec:
 7  ports:
 8    - name: tcp-30555
 9      protocol: TCP
10      port: 30555
11      targetPort: 30555
12  selector:
13    app: grpc-demo-app
14  clusterIP: None  
15  type: ClusterIP

Use Envoy proxy the headless service implementation load balancing

  • deploy the envoy proxy
 1apiVersion: apps/v1
 2kind: Deployment
 3metadata:
 4  name: envoy-proxy-grpc-demo
 5  namespace: apps
 6  labels:
 7    app: envoy-proxy-grpc-demo
 8spec:
 9  replicas: 1
10  selector:
11    matchLabels:
12      app: envoy-proxy-grpc-demo
13  template:
14    metadata:
15      labels:
16        app: envoy-proxy-grpc-demo
17        sidecar.istio.io/inject: "false"
18    spec:
19      volumes:
20        - name: envoy-config
21          configMap:
22            name: envoy-proxy-grpc-demo
23      containers:
24        - name: envoy-proxy-grpc-demo
25          image: envoyproxy/envoy:v1.26-latest
26          command: ["envoy", "--config-path", "/etc/envoy/envoy.yaml"]
27          volumeMounts:
28            - name: envoy-config
29              mountPath: /etc/envoy
30          ports:
31            - containerPort: 30555
  • then create the Envoy configmap to proxy to app headless use Envoy builtin load balancing function
 1apiVersion: v1
 2kind: ConfigMap
 3metadata:
 4  name: envoy-proxy-grpc-demo
 5data:
 6  "envoy.yaml": |
 7    admin:
 8      address:
 9        socket_address:
10          protocol: TCP
11          address: 0.0.0.0
12          port_value: 9901
13    static_resources:
14      listeners:
15      - name: listener_0
16        address:
17          socket_address:
18            protocol: TCP
19            address: 0.0.0.0
20            port_value: 30555  
21        filter_chains:
22        - filters:
23          - name: envoy.filters.network.http_connection_manager
24            typed_config:
25              "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
26              codec_type: AUTO
27              add_user_agent: true
28              access_log:
29              - name: envoy.access_loggers.stdout
30                typed_config:
31                  "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
32              stat_prefix: egress_http
33              common_http_protocol_options:
34                idle_timeout: 0.840s
35              use_remote_address: true
36              route_config:
37                name: local_route
38                virtual_hosts:
39                - name: backend
40                  domains:
41                  - "*"
42                  routes:
43                  - match:
44                      prefix: "/"
45                    route:
46                      cluster: grpc-demo-headless
47              http_filters:
48              - name: envoy.filters.http.grpc_web
49                typed_config:
50                  "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
51              - name: envoy.filters.http.cors
52                typed_config:
53                  "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
54              - name: envoy.filters.http.grpc_http1_bridge
55                typed_config:
56                  "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_bridge.v3.Config
57              - name: envoy.filters.http.router
58                typed_config:
59                  "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
60
61      clusters:
62      - name: grpc-demo-headless
63        type: STRICT_DNS
64        lb_policy: LEAST_REQUEST
65        connect_timeout: 30s
66        dns_lookup_family: V4_ONLY
67        http2_protocol_options: {}
68        load_assignment:
69          cluster_name: grpc-demo-headless
70          endpoints:
71            - lb_endpoints:
72                - endpoint:
73                    address:
74                      socket_address:
75                        address: grpc-demo-headless
76                        port_value: 30555    
  • Lastly create the Envoy proxy service to Envoy proxy pod
 1apiVersion: v1
 2kind: Service
 3metadata:
 4  name: envoy-proxy-grpc-demo
 5  namespace: apps
 6spec:
 7  selector:
 8    app: envoy-proxy-grpc-demo
 9  ports:
10    - protocol: TCP
11      port: 30555
12      targetPort: 30555
13  type: ClusterIP

Create local proxy to envoy service in localhost

1kubectl port-forward svc/envoy-proxy-grpc-demo -n apps 60400:30555

Debug in local

1# install grpcurl in local
2go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
3# list service  through proto file
4grpcurl -plaintext -proto example.proto localhost:60400 list
5# list method of services
6grpcurl -plaintext -proto example.proto localhost:60400 list com.ServiceExample
7# invoke the grpc method
8grpcurl -d '{"field1": "value1", "field2": "value2", "id": "1"}' -plaintext -proto example.proto localhost:60400  com.ServiceExample.Get

Awesome the grpc tools and contents