This is an automated email from the ASF dual-hosted git repository.
zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git
The following commit(s) were added to refs/heads/master by this push:
new 8011927a Update grpc sample readme (#827)
8011927a is described below
commit 8011927a2177a2ae2e25edf0b077ffb0e20bb1e1
Author: mfordjody <[email protected]>
AuthorDate: Sat Nov 22 23:55:51 2025 +0800
Update grpc sample readme (#827)
* Update sample readme
* Update sample readme v2
---
samples/grpc-app/README.md | 163 +++++++++++----------------------------------
1 file changed, 39 insertions(+), 124 deletions(-)
diff --git a/samples/grpc-app/README.md b/samples/grpc-app/README.md
index 67383db3..7432ae70 100644
--- a/samples/grpc-app/README.md
+++ b/samples/grpc-app/README.md
@@ -31,117 +31,28 @@ kubectl label namespace grpc-app dubbo-injection=enabled
kubectl apply -f grpc-app.yaml
```
-### 3. Verify Deployment
+### 3. Call the test service
```bash
-# Check pods are running
-kubectl get pods -n grpc-app
-
-# Check services
-kubectl get svc -n grpc-app
-```
-
-## Configuration
-
-### Key Annotations
-
-- `proxyless.dubbo.apache.org/inject: "true"` - Enables proxyless injection
-- `inject.dubbo.apache.org/templates: grpc-agent` - Uses the grpc-agent
template
-- `proxy.dubbo.apache.org/config: '{"holdApplicationUntilProxyStarts": true}'`
- Ensures proxy starts before application
-
-### Security requirements
-
-When mTLS is enabled (`SubsetRule` with `ISTIO_MUTUAL` or `PeerAuthentication
STRICT`), **both the producer and consumer application containers must**:
-
-1. Mount the certificate output directory that `dubbo-proxy` writes to:
- ```yaml
- volumeMounts:
- - name: dubbo-data
- mountPath: /var/lib/dubbo/data
- ```
- The `grpc-agent` template already provides the `dubbo-data` volume;
mounting it from the app container makes the generated `cert-chain.pem`,
`key.pem`, and `root-cert.pem` visible to gRPC.
-
-2. Set `GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT=true` so the gRPC runtime
actually consumes the xDS security config instead of falling back to plaintext.
The sample manifest in `grpc-app.yaml` shows the required environment variable.
-
-3. When testing with `grpcurl`, export the same variable before issuing TLS
requests:
- ```bash
- export GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT=true
- grpcurl -d
'{"url":"xds:///producer.grpc-app.svc.cluster.local:7070","count":5}'
localhost:17171 echo.EchoTestService/ForwardEcho
- ```
-
-## Testing
-
-### Test with grpcurl
-
-1. Port forward to the consumer test server:
-
-```bash
-kubectl port-forward -n grpc-app \
- $(kubectl get pod -l app=consumer -n grpc-app -o
jsonpath='{.items[0].metadata.name}') \
- 17171:17171 &
+kubectl port-forward -n grpc-app $(kubectl get pod -l app=consumer -n grpc-app
-o jsonpath='{.items[0].metadata.name}') 17171:17171
```
-2. Send test request:
-
```bash
-grpcurl -plaintext -d '{
- "url": "xds:///producer.grpc-app.svc.cluster.local:7070",
- "count": 5
-}' localhost:17171 echo.EchoTestService/ForwardEcho
+grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171
echo.EchoTestService/ForwardEcho
```
-Expected output:
```json
{
"output": [
- "[0 body] Hostname=producer-xxx",
- "[1 body] Hostname=producer-yyy",
- "[2 body] Hostname=producer-xxx",
- "[3 body] Hostname=producer-yyy",
- "[4 body] Hostname=producer-xxx"
+ "[0 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[1 body] Hostname=producer-v1-fbb7b9bd9-l8frj ServiceVersion=v1
Namespace=grpc-app IP=192.168.219.119 ServicePort=17070",
+ "[2 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[3 body] Hostname=producer-v1-fbb7b9bd9-l8frj ServiceVersion=v1
Namespace=grpc-app IP=192.168.219.119 ServicePort=17070",
+ "[4 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070"
]
}
```
-### Check Logs
-
-```bash
-# Producer logs
-kubectl logs -f -l app=producer -n grpc-app -c app
-
-# Consumer logs
-kubectl logs -f -l app=consumer -n grpc-app -c app
-
-# Proxy sidecar logs
-kubectl logs -f -l app=producer -n grpc-app -c dubbo-proxy
-```
-
-## Troubleshooting
-
-### Application fails to start
-
-If the application fails with "grpc-bootstrap.json: no such file or directory":
-- The `dubbo-proxy` sidecar may not have generated the bootstrap file yet
-- Check proxy logs: `kubectl logs <pod-name> -c dubbo-proxy -n grpc-app`
-- Ensure `holdApplicationUntilProxyStarts: true` is set in annotations
-
-### Connection issues
-
-1. Verify xDS proxy is running:
-```bash
-kubectl exec <pod-name> -c dubbo-proxy -n grpc-app -- ls -la /etc/dubbo/proxy/
-```
-
-2. Check bootstrap file:
-```bash
-kubectl exec <pod-name> -c app -n grpc-app -- cat
/etc/dubbo/proxy/grpc-bootstrap.json
-```
-
-3. Verify control plane connectivity:
-```bash
-kubectl logs <pod-name> -c dubbo-proxy -n grpc-app | grep -i xds
-```
-
## Traffic Management
### Creating subsets with SubsetRule
@@ -169,7 +80,7 @@ EOF
### Traffic shifting
-Using the subsets defined above, you can send weighted traffic to different
versions. The following example sends 20% of traffic to v1 and 80% to v2:
+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:
```bash
cat <<EOF | kubectl apply -f -
@@ -186,33 +97,32 @@ spec:
- destination:
host: producer.grpc-app.svc.cluster.local
subset: v1
- weight: 20
+ weight: 10
- destination:
host: producer.grpc-app.svc.cluster.local
subset: v2
- weight: 80
+ weight: 90
EOF
```
Now, send a set of 10 requests to verify the traffic distribution:
```bash
-grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070", "count": 10}'
localhost:17171 echo.EchoTestService/ForwardEcho | jq -r '.output | join("")' |
grep ServiceVersion
+grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171
echo.EchoTestService/ForwardEcho
```
The response should contain mostly `v2` responses, demonstrating the weighted
traffic splitting:
-```plain
-[0 body] ServiceVersion=v2
-[1 body] ServiceVersion=v2
-[2 body] ServiceVersion=v1
-[3 body] ServiceVersion=v2
-[4 body] ServiceVersion=v1
-[5 body] ServiceVersion=v2
-[6 body] ServiceVersion=v2
-[7 body] ServiceVersion=v2
-[8 body] ServiceVersion=v2
-[9 body] ServiceVersion=v2
+```json
+{
+ "output": [
+ "[0 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[1 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[2 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[3 body] Hostname=producer-v1-fbb7b9bd9-l8frj ServiceVersion=v1
Namespace=grpc-app IP=192.168.219.119 ServicePort=17070",
+ "[4 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070"
+ ]
+}
```
## Enabling mTLS
@@ -241,15 +151,20 @@ EOF
Now an attempt to call the server that is not yet configured for mTLS will
fail:
```bash
-grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070"}' localhost:17171
echo.EchoTestService/ForwardEcho | jq -r '.output | join("")'
+grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171
echo.EchoTestService/ForwardEcho
```
Expected error output:
```json
{
- "output": [
- "ERROR:\nCode: Unknown\nMessage: 1/1 requests had errors; first error: rpc
error: code = Unavailable desc = all SubConns are in TransientFailure"
- ]
+ "output": [
+ "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\"",
+ "[0] Error: rpc error: code = Unavailable desc = connection error: desc
= \"transport: authentication handshake failed: tls: first record does not look
like a TLS handshake\"",
+ "[1] Error: rpc error: code = Unavailable desc = connection error: desc
= \"transport: authentication handshake failed: tls: first record does not look
like a TLS handshake\"",
+ "[2] Error: rpc error: code = Unavailable desc = connection error: desc
= \"transport: authentication handshake failed: tls: first record does not look
like a TLS handshake\"",
+ "[3] Error: rpc error: code = Unavailable desc = connection error: desc
= \"transport: authentication handshake failed: tls: first record does not look
like a TLS handshake\"",
+ "[4] Error: rpc error: code = Unavailable desc = connection error: desc
= \"transport: authentication handshake failed: tls: first record does not look
like a TLS handshake\""
+ ]
}
```
@@ -273,19 +188,19 @@ EOF
Requests will start to succeed after applying the policy:
```bash
-grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070"}' localhost:17171
echo.EchoTestService/ForwardEcho | jq -r '.output | join("")'
+grpcurl -plaintext -d '{"url":
"xds:///producer.grpc-app.svc.cluster.local:7070","count": 5}' localhost:17171
echo.EchoTestService/ForwardEcho
```
Expected successful output:
```json
{
- "output": [
- "[0 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
- "[1 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
- "[2 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
- "[3 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
- "[4 body] Hostname=producer-v1-fbb7b9bd9-l8frj ServiceVersion=v1
Namespace=grpc-app IP=192.168.219.119 ServicePort=17070"
- ]
+ "output": [
+ "[0 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[1 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[2 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[3 body] Hostname=producer-v2-594b6977c8-5gw2z ServiceVersion=v2
Namespace=grpc-app IP=192.168.219.88 ServicePort=17070",
+ "[4 body] Hostname=producer-v1-fbb7b9bd9-l8frj ServiceVersion=v1
Namespace=grpc-app IP=192.168.219.119 ServicePort=17070"
+ ]
}
```