|
1 | 1 | # gRPC Proxyless Example |
2 | 2 |
|
3 | | -This example demonstrates how to deploy gRPC applications with proxyless service mesh support using Dubbo Kubernetes. |
4 | | - |
5 | | -## Overview |
6 | | - |
7 | | -This sample includes: |
8 | | -- **Provider**: A gRPC server that receives requests (port 17070) and is deployed with multiple versions (v1/v2) to showcase gray release scenarios. |
9 | | -- **Consumer**: A gRPC client that sends requests to the provider service and exposes a test server (port 17171) for driving traffic via `grpcurl`. |
10 | | - |
11 | | -Both services use native gRPC xDS clients to connect to the Dubbo control plane through the `dubbo-proxy` sidecar, enabling service discovery, load balancing, and traffic management without requiring Envoy proxy for application traffic. |
12 | | - |
13 | | -## Prerequisites |
14 | | - |
15 | | -1. Kubernetes cluster with Dubbo Kubernetes control plane installed |
16 | | -2. `kubectl` configured to access the cluster |
17 | | -3. `grpcurl` (optional, for testing) |
18 | | - |
19 | | -## Deployment |
20 | | - |
21 | | -### 1. Create Namespace |
22 | | - |
23 | | -```bash |
24 | | -kubectl create ns grpc-app |
25 | | -kubectl label namespace grpc-app dubbo-injection=enabled |
26 | | -``` |
27 | | - |
28 | | -### 2. Deploy Services |
29 | | - |
30 | | -```bash |
31 | | -kubectl apply -f grpc-app.yaml |
32 | | -``` |
33 | | - |
34 | | -### 3. Test service |
35 | | - |
36 | | -```bash |
37 | | -kubectl port-forward -n grpc-app $(kubectl get pod -l app=consumer -n grpc-app -o jsonpath='{.items[0].metadata.name}') 17171:17171 |
38 | | -``` |
39 | | - |
40 | | -```bash |
41 | | -grpcurl -plaintext -d '{"url": "xds:///provider.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171 echo.EchoTestService/ForwardEcho |
42 | | -``` |
43 | | - |
44 | | -```json |
45 | | -{ |
46 | | - "output": [ |
47 | | - "[0 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
48 | | - "[1 body] Hostname=provider-v1-fbb7b9bd9-l8frj ServiceVersion=v1 Namespace=grpc-app IP=192.168.219.119 ServicePort=17070", |
49 | | - "[2 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
50 | | - "[3 body] Hostname=provider-v1-fbb7b9bd9-l8frj ServiceVersion=v1 Namespace=grpc-app IP=192.168.219.119 ServicePort=17070", |
51 | | - "[4 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070" |
52 | | - ] |
53 | | -} |
54 | | -``` |
55 | | - |
56 | | -## Traffic Management |
57 | | - |
58 | | -### Creating subsets with DestinationRule |
59 | | - |
60 | | -First, create a subset for each version of the workload to enable traffic splitting: |
61 | | - |
62 | | -```bash |
63 | | -cat <<EOF | kubectl apply -f - |
64 | | -apiVersion: networking.dubbo.apache.org/v1alpha3 |
65 | | -kind: DestinationRule |
66 | | -metadata: |
67 | | - name: provider-versions |
68 | | - namespace: grpc-app |
69 | | -spec: |
70 | | - host: provider.grpc-app.svc.cluster.local |
71 | | - subsets: |
72 | | - - name: v1 |
73 | | - labels: |
74 | | - version: v1 |
75 | | - - name: v2 |
76 | | - labels: |
77 | | - version: v2 |
78 | | -EOF |
79 | | -``` |
80 | | - |
81 | | -### Traffic shifting |
82 | | - |
83 | | -Using the subsets defined above, you can send weighted traffic to different versions. The following example sends 10% of traffic to v1 and 90% to v2: |
84 | | - |
85 | | -```bash |
86 | | -cat <<EOF | kubectl apply -f - |
87 | | -apiVersion: networking.dubbo.apache.org/v1alpha3 |
88 | | -kind: VirtualService |
89 | | -metadata: |
90 | | - name: provider-weights |
91 | | - namespace: grpc-app |
92 | | -spec: |
93 | | - hosts: |
94 | | - - provider.grpc-app.svc.cluster.local |
95 | | - http: |
96 | | - - route: |
97 | | - - destination: |
98 | | - host: provider.grpc-app.svc.cluster.local |
99 | | - subset: v1 |
100 | | - weight: 10 |
101 | | - - destination: |
102 | | - host: provider.grpc-app.svc.cluster.local |
103 | | - subset: v2 |
104 | | - weight: 90 |
105 | | -EOF |
106 | | -``` |
107 | | - |
108 | | -Now, send a set of 5 requests to verify the traffic distribution: |
109 | | - |
110 | | -```bash |
111 | | -grpcurl -plaintext -d '{"url": "xds:///provider.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171 echo.EchoTestService/ForwardEcho |
112 | | -``` |
113 | | - |
114 | | -The response should contain mostly `v2` responses, demonstrating the weighted traffic splitting: |
115 | | - |
116 | | -```json |
117 | | -{ |
118 | | - "output": [ |
119 | | - "[0 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
120 | | - "[1 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
121 | | - "[2 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
122 | | - "[3 body] Hostname=provider-v1-fbb7b9bd9-l8frj ServiceVersion=v1 Namespace=grpc-app IP=192.168.219.119 ServicePort=17070", |
123 | | - "[4 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070" |
124 | | - ] |
125 | | -} |
126 | | -``` |
127 | | - |
128 | | -## Enabling mTLS |
129 | | - |
130 | | -Due to the changes to the application itself required to enable security in gRPC, Dubbo Kubernetes's traditional method of automatically detecting mTLS support is unreliable. For this reason, the initial release requires explicitly enabling mTLS on both the client and server. |
131 | | - |
132 | | -### Enable client-side mTLS |
133 | | - |
134 | | -To enable client-side mTLS, apply a `DestinationRule` with `tls` settings: |
135 | | - |
136 | | -```bash |
137 | | -cat <<EOF | kubectl apply -f - |
138 | | -apiVersion: networking.dubbo.apache.org/v1alpha3 |
139 | | -kind: DestinationRule |
140 | | -metadata: |
141 | | - name: provider-mtls |
142 | | - namespace: grpc-app |
143 | | -spec: |
144 | | - host: provider.grpc-app.svc.cluster.local |
145 | | - trafficPolicy: |
146 | | - tls: |
147 | | - mode: DUBBO_MUTUAL |
148 | | -EOF |
149 | | -``` |
150 | | - |
151 | | -Now an attempt to call the server that is not yet configured for mTLS will fail: |
152 | | - |
153 | | -```bash |
154 | | -grpcurl -plaintext -d '{"url": "xds:///provider.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171 echo.EchoTestService/ForwardEcho |
155 | | -``` |
156 | | - |
157 | | -Expected error output: |
158 | | -```json |
159 | | -{ |
160 | | - "output": [ |
161 | | - "ERROR:\nCode: Unknown\nMessage: 5/5 requests had errors; first error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"", |
162 | | - "[0] Error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"", |
163 | | - "[1] Error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"", |
164 | | - "[2] Error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"", |
165 | | - "[3] Error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"", |
166 | | - "[4] Error: rpc error: code = Unavailable desc = connection error: desc = \"transport: authentication handshake failed: tls: first record does not look like a TLS handshake\"" |
167 | | - ] |
168 | | -} |
169 | | -``` |
170 | | - |
171 | | -### Enable server-side mTLS |
172 | | - |
173 | | -To enable server-side mTLS, apply a `PeerAuthentication` policy. The following policy forces STRICT mTLS for the entire namespace: |
174 | | - |
175 | | -```bash |
176 | | -cat <<EOF | kubectl apply -f - |
177 | | -apiVersion: security.dubbo.apache.org/v1alpha3 |
178 | | -kind: PeerAuthentication |
179 | | -metadata: |
180 | | - name: provider-mtls |
181 | | - namespace: grpc-app |
182 | | -spec: |
183 | | - mtls: |
184 | | - mode: STRICT |
185 | | -EOF |
186 | | -``` |
187 | | - |
188 | | -Requests will start to succeed after applying the policy: |
189 | | - |
190 | | -```bash |
191 | | -grpcurl -plaintext -d '{"url": "xds:///provider.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171 echo.EchoTestService/ForwardEcho |
192 | | -``` |
193 | | - |
194 | | -Expected successful output: |
195 | | -```json |
196 | | -{ |
197 | | - "output": [ |
198 | | - "[0 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
199 | | - "[1 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
200 | | - "[2 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
201 | | - "[3 body] Hostname=provider-v2-594b6977c8-5gw2z ServiceVersion=v2 Namespace=grpc-app IP=192.168.219.88 ServicePort=17070", |
202 | | - "[4 body] Hostname=provider-v1-fbb7b9bd9-l8frj ServiceVersion=v1 Namespace=grpc-app IP=192.168.219.119 ServicePort=17070" |
203 | | - ] |
204 | | -} |
205 | | -``` |
206 | | - |
207 | | -## Cleanup |
208 | | - |
209 | | -```bash |
210 | | -kubectl delete -f grpc-app.yaml |
211 | | -kubectl delete ns grpc-app |
212 | | -``` |
| 3 | +This is an example demonstrating a gRPC application. |
0 commit comments