Merge pull request #89 from haoyann/dubbo-xds-route
Proposals: dubbo support xds route
diff --git a/proposals/D13-dubbo-xds-route.md b/proposals/D13-dubbo-xds-route.md
new file mode 100644
index 0000000..e7f050f
--- /dev/null
+++ b/proposals/D13-dubbo-xds-route.md
@@ -0,0 +1,410 @@
+## 目录
+
+* [背景](#背景)
+
+* [目标](#目标)
+
+* [XDS 路由协议解析](#xds-路由协议解析)
+
+ * [XDS 服务发现流程](#xds-服务发现流程)
+
+ * [LDS ](#lds-)
+
+ * [RDS](#rds)
+
+ * [CDS](#cds)
+
+ * [EDS](#eds)
+
+ * [总结](#总结)
+
+ * [VirtualService 对 RDS 的影响](#virtualservice-对-rds-的影响)
+
+ * [DestinationRule 对 CDS的影响](#destinationrule-对-cds的影响)
+
+ * [Pod 打标对EDS的影响](#pod-打标对eds的影响)
+
+ * [XDS 路由总结](#xds-路由总结)
+
+* [Dubbo 路由适配](#dubbo-路由适配)
+
+# Dubbo 对接 XDS 路由
+
+## 背景
+
+Dubbo 框架使用 proxyless 的方式接入控制中心,对接 XDS 协议。将 XDS 的路由功能与 Dubbo 的路由功能适配。
+
+## 目标
+
+完成基本路由功能,其他服务治理功能如负载均衡、权重、超时等后续添加
+
+* 解析 VirtualService 规则,uri、head 的规则匹配
+
+* 解析 DestinationRule 规则适配 subsets
+
+## XDS 路由协议解析
+
+先部署一个 Pod 注入 sidecar,借助 `istioctl` 工具进行 xds 协议分析。
+
+```bash
+kubectl get pod
+NAME READY STATUS RESTARTS AGE
+productpage-v1-65b75f6885-cb7d5 2/2 Running 0 9h
+```
+
+将 demo `dubbo-samples-xds` 部署在集群中,以下将对此 demo 进行分析。
+
+### XDS 服务发现流程
+
+#### LDS 
+
+获取LDS数据,获取 `dubbo-samples-xds-provide`监听端口为 50051
+
+```bash
+istioctl proxy-config listener productpage-v1-65b75f6885-cb7d5
+
+ADDRESS PORT MATCH DESTINATION
+......
+10.102.128.210 15443 ALL Cluster: outbound|15443||istio-ingressgateway.istio-system.svc.cluster.local
+10.102.128.210 31400 ALL Cluster: outbound|31400||istio-ingressgateway.istio-system.svc.cluster.local
+0.0.0.0 50051 Trans: raw_buffer; App: http/1.1,h2c Route: 50051
+0.0.0.0 50051 ALL PassthroughCluster
+```
+
+查看具体数据,获取 routeConfigName 名称为 `50051`
+
+```bash
+istioctl proxy-config listener productpage-v1-65b75f6885-cb7d5 --port=50051 -o json
+```
+
+```json
+.....
+"typedConfig": {
+ "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
+ "statPrefix": "outbound_0.0.0.0_50051",
+ "rds": {
+ "configSource": {
+ "ads": {},
+ "initialFetchTimeout": "0s",
+ "resourceApiVersion": "V3"
+ },
+ "routeConfigName": "50051"
+ }
+...
+```
+
+#### RDS
+
+通过路由名称 `50051` 查询 RDS ,获取到 cluster `outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 
+
+```bash
+istioctl proxy-config route productpage-v1-65b75f6885-cb7d5 --name=50051 -o json
+```
+
+```json
+[
+ {
+ "name": "50051",
+ "virtualHosts": [
+ ...,
+ {
+ "name": "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local:50051",
+ "domains": [
+ "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local:50051",
+ "dubbo-samples-xds-provider.dubbo-demo",
+ "dubbo-samples-xds-provider.dubbo-demo:50051",
+ "dubbo-samples-xds-provider.dubbo-demo.svc",
+ "dubbo-samples-xds-provider.dubbo-demo.svc:50051",
+ "10.104.227.50",
+ "10.104.227.50:50051"
+ ],
+ "routes": [
+ {
+ "name": "default",
+ "match": {
+ "prefix": "/"
+ },
+ "route": {
+ "cluster": "outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "timeout": "0s",
+ "retryPolicy": {
+ "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
+ "numRetries": 2,
+ "retryHostPredicate": [
+ {
+ "name": "envoy.retry_host_predicates.previous_hosts"
+ }
+ ],
+ "hostSelectionRetryMaxAttempts": "5",
+ "retriableStatusCodes": [
+ 503
+ ]
+ },
+ "maxStreamDuration": {
+ "maxStreamDuration": "0s",
+ "grpcTimeoutHeaderMax": "0s"
+ }
+ },
+ "decorator": {
+ "operation": "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local:50051/*"
+ }
+ }
+ ],
+ "includeRequestAttemptCount": true
+ }
+ ],
+ "validateClusters": false
+ }
+]
+```
+
+#### CDS
+
+通过 `outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 查询 cluster,获取 EDS。
+
+```json
+istioctl proxy-config cluster productpage-v1-65b75f6885-cb7d5 --fqdn=dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local -o json
+```
+
+```json
+ .....
+ "name": "outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "type": "EDS",
+ "edsClusterConfig": {
+ "edsConfig": {
+ "ads": {},
+ "initialFetchTimeout": "0s",
+ "resourceApiVersion": "V3"
+ },
+ "serviceName": "outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local"
+ },
+ "connectTimeout": "10s",
+ "circuitBreakers": {
+ "thresholds": [
+ {
+ "maxConnections": 4294967295,
+ "maxPendingRequests": 4294967295,
+ "maxRequests": 4294967295,
+ "maxRetries": 4294967295,
+ "trackRemaining": true
+ }
+ ]
+ },
+ ....
+```
+
+#### EDS
+
+通过 `outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local`获取 endpoint 
+
+```bash
+istioctl proxy-config endpoint productpage-v1-65b75f6885-cb7d5 --cluster="outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local"
+
+ENDPOINT STATUS OUTLIER CHECK CLUSTER
+10.244.1.58:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.2.55:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.2.56:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+```
+
+#### 总结
+
+整个服务发现的流程由 LDS —> RDS —> CDS —> EDS。
+
+### VirtualService 对 RDS 的影响
+
+提交 VirtualService 规则
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: dubbo-samples-xds-provider
+ namespace: dubbo-demo
+spec:
+ hosts:
+ - dubbo-samples-xds-provider
+ http:
+ - match:
+ - uri:
+ prefix: /user/v1
+ route:
+ - destination:
+ host: dubbo-samples-xds-provider
+ subset: v1
+ - match:
+ - uri:
+ prefix: /user/v2
+ route:
+ - destination:
+ host: dubbo-samples-xds-provider
+ subset: v2
+```
+
+再次查看`50051` RDS 信息,已经新增两条路由信息,分别路由到 cluster `outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 和 cluster `outbound|50051|v2|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local`
+
+```yaml
+istioctl proxy-config route productpage-v1-65b75f6885-cb7d5 --name=50051 -o json
+```
+
+```json
+[{
+ "name": "50051",
+ ....,
+ {
+ "name": "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local:50051",
+ "domains": [
+ "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local:50051",
+ "dubbo-samples-xds-provider.dubbo-demo",
+ "dubbo-samples-xds-provider.dubbo-demo:50051",
+ "dubbo-samples-xds-provider.dubbo-demo.svc",
+ "dubbo-samples-xds-provider.dubbo-demo.svc:50051",
+ "10.104.227.50",
+ "10.104.227.50:50051"
+ ],
+ "routes": [{
+ "match": {
+ "prefix": "/user/v1",
+ "caseSensitive": true
+ },
+ "route": {
+ "cluster": "outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "timeout": "0s",
+ .......
+ ,
+ {
+ "match": {
+ "prefix": "/user/v2",
+ "caseSensitive": true
+ },
+ "route": {
+ "cluster": "outbound|50051|v2|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "timeout": "0s",
+ ......
+ ],
+ "validateClusters": false
+}]
+```
+
+### DestinationRule 对 CDS的影响
+
+提交DestinationRule 规则
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+ name: dubbo-samples-xds-provider
+ namespace: dubbo-demo
+spec:
+ host: dubbo-samples-xds-provider
+ subsets:
+ - name: v1
+ labels:
+ version: v1
+ - name: v2
+ labels:
+ version: v2
+
+```
+
+查询 cluster `dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` ,相比之前多了 EDS `outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 
+
+和 `outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 。
+
+```yaml
+istioctl proxy-config cluster productpage-v1-65b75f6885-cb7d5 --fqdn=dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+```
+
+```json
+...
+
+ ],
+ "name": "outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "type": "EDS",
+ "edsClusterConfig": {
+ "edsConfig": {
+ "ads": {},
+ "initialFetchTimeout": "0s",
+ "resourceApiVersion": "V3"
+ },
+ "serviceName": "outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local"
+ },
+
+
+...
+ "name": "outbound|50051|v2|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "type": "EDS",
+ "edsClusterConfig": {
+ "edsConfig": {
+ "ads": {},
+ "initialFetchTimeout": "0s",
+ "resourceApiVersion": "V3"
+ },
+ "serviceName": "outbound|50051|v2|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local"
+ },
+...
+
+ "name": "outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local",
+ "type": "EDS",
+ "edsClusterConfig": {
+ "edsConfig": {
+ "ads": {},
+ "initialFetchTimeout": "0s",
+ "resourceApiVersion": "V3"
+ },
+ "serviceName": "outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local"
+ },
+ ....
+
+```
+
+### Pod 打标对EDS的影响
+
+分别部署`dubbo-samples-xds-provider` v1、v2 版本各一个。
+
+```bash
+kubectl get pod -n dubbo-demo --show-labels=true
+
+NAME READY STATUS RESTARTS AGE LABELS
+dubbo-samples-xds-provider-565d5c8844-5m66w 1/1 Running 0 71m app=dubbo-samples-xds-provider,pod-template-hash=565d5c8844
+dubbo-samples-xds-provider-565d5c8844-crq8s 1/1 Running 0 71m app=dubbo-samples-xds-provider,pod-template-hash=565d5c8844
+dubbo-samples-xds-provider-565d5c8844-v6zvr 1/1 Running 0 71m app=dubbo-samples-xds-provider,pod-template-hash=565d5c8844
+dubbo-samples-xds-provider-v1-7f68b67f55-z9d85 1/1 Running 0 5m39s app=dubbo-samples-xds-provider,pod-template-hash=7f68b67f55,version=v1
+dubbo-samples-xds-provider-v2-54b49d86c4-pxs5z 1/1 Running 0 14s app=dubbo-samples-xds-provider,pod-template-hash=54b49d86c4,version=v2
+
+```
+
+再次查看 ESD 出现了 v1、v2 版本的数据名称和 cluster 对应上。而且`outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local` 包含 v1、v2 版本的 endpoint。
+
+```bash
+istioctl proxy-config endpoint productpage-v1-65b75f6885-cb7d5 | grep dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+
+
+10.244.1.58:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.1.61:50051 HEALTHY OK outbound|50051|v1|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.1.61:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.1.62:50051 HEALTHY OK outbound|50051|v2|dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.1.62:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.2.55:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+10.244.2.56:50051 HEALTHY OK outbound|50051||dubbo-samples-xds-provider.dubbo-demo.svc.cluster.local
+```
+
+### XDS 路由总结
+
+1. VirtualService 修改 RDS 数据;
+
+2. DestinationRule 修改 CDS 数据;
+
+3. Pod 标签与EDS 适配 ;
+
+## Dubbo 路由适配
+
+1. 将 XDS 协议与 Dubbo 路由体系结合起来,新创建 XDSRouter 完成此功能;
+
+2. XDSRouter 监听 RDS 获取路由规则,完成 uri、head 匹配功能;
+
+3. XDSRouter 监听 EDS 获取 endpoint 数据,完成对实例 subsets 的适配;
+
+4. Dubbo 内部对 XDS 资源建立一套通知机制;