Skip to content

Commit

Permalink
doc(xds): add xds feature document (#1126)
Browse files Browse the repository at this point in the history
  • Loading branch information
whalecold authored Sep 6, 2024
1 parent 2d7fa38 commit 6235b19
Show file tree
Hide file tree
Showing 2 changed files with 394 additions and 55 deletions.
205 changes: 176 additions & 29 deletions content/en/docs/kitex/Tutorials/advanced-feature/xds.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ Kitex supports xDS API via the extension of [kitex-contrib/xds](https://github.c
- [ThriftProxy](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/thrift_proxy/v3/thrift_proxy.proto): configure via patching [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/).
- Timeout:
- Configuration inside `HTTP route configuration`: configure via VirtualService.
- Retry:
- Configuration inside [RetryPolicy](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-retrypolicy), configure via [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/).
- Rate Limit:
- Configuration inside [LocalRateLimitFilter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter), configure via [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/) .
- Circuit Breaker:
- Configuration inside [OutlierDetection](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/outlier_detection.proto), configure via [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/).

## Usage

Expand All @@ -35,10 +41,11 @@ The `xdsClient` is responsible for the interaction with the xDS Server (i.e. Ist
- `POD_NAMESPACE`: the namespace of the current service.
- `POD_NAME`: the name of this pod.
- `INSTANCE_IP`: the ip of this pod.
- `KITEX_XDS_METAS`: the metadata of this connection to Istiod, which is used to identify the pod.

Add the following part to the definition of your container that uses xDS-enabled Kitex client.

```
```yaml
- name: POD_NAMESPACE
valueFrom:
fieldRef:
Expand All @@ -51,22 +58,17 @@ valueFrom:
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: KITEX_XDS_METAS
value: '{"CLUSTER_ID":"Kubernetes","DNS_AUTO_ALLOCATE":"true","DNS_CAPTURE":"true","INSTANCE_IPS":"$(INSTANCE_IP)","ISTIO_VERSION":"1.13.5","NAMESPACE":"$(POD_NAMESPACE)"}'
```
### Client-side
For now, we only provide the support on the client-side.
To use a xds-enabled Kitex client, you should specify `destService` using the URL of your target service and add one option `WithXDSSuite`.

- Construct a `xds.ClientSuite` that includes `RouteMiddleware` and `Resolver`, and then pass it into the `WithXDSSuite` option.
To use a xds-enabled Kitex client, you should specify `destService` using the URL of your target service and add one option `xdssuite.NewClientOption()`.

```
// import "github.com/cloudwego/kitex/pkg/xds"
client.WithXDSSuite(xds.ClientSuite{
RouterMiddleware: xdssuite.NewXDSRouterMiddleware(),
Resolver: xdssuite.NewXDSResolver(),
}),
```go
// "github.com/kitex-contrib/xds/xdssuite"
xdssuite.NewClientOption()
```

- The URL of the target service should be in the format, which follows the format in [Kubernetes](https://kubernetes.io/):
Expand All @@ -78,6 +80,10 @@ client.WithXDSSuite(xds.ClientSuite{
<service-name>:<service-port> // access the <service-name> in same namespace.
```

### Server-side

The server-side add the option with `xdssuite.NewLimiter()` to enable limit traffic policy.

#### Traffic route based on Tag Match

We can define traffic route configuration via [VirtualService](https://istio.io/latest/docs/reference/config/networking/virtual-service/) in Istio.
Expand All @@ -88,7 +94,7 @@ The following example indicates that when the tag meets one of the conditions in
- `userid` prefix match `2100`
- `env` regex match `[dev|sit]`

```
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
Expand Down Expand Up @@ -120,7 +126,7 @@ To match the rule defined in VirtualService, we can use `client.WithTag(key, val

- Set key and value to be "stage" and "canary" to match the above rule defined in VirtualService.

```
```go
client.WithTag("stage", "canary")
callopt.WithTag("stage", "canary")
```
Expand All @@ -133,7 +139,7 @@ The example below shows that requests with method equal to SayHello are routed t

- uri: `/${PackageName}.${ServiceName}/${MethodName}`

```
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
Expand All @@ -155,14 +161,129 @@ spec:
timeout: 0.5s
```

## Example
#### Circuit Breaker
Kitex supports the circuit breaker on service and instance dimension, default is for instance, you can use `xdssuite.WithServiceCircuitBreak(true)` to switch the circuit breaker.

The usage is as follows:
The following example shows how to configure the circuit breaker on the client side. The configuration is as follows:
- `spec.configPatches[0].match.cluster.service`: the service name of the target service, should obey the specification of the FQDN.
- `failure_percentage_threshold`: the threshold of the failure rate, when the failure rate exceeds this value, the circuit breaker will be triggered.
- `failure_percentage_request_volume`: the number of requests that need to be collected to calculate the failure rate.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: circuitbreak-client
namespace: default
spec:
configPatches:
- applyTo: CLUSTER
match:
context: SIDECAR_OUTBOUND
cluster:
service: hello.default.svc.cluster.local
patch:
operation: MERGE
value:
outlier_detection:
failure_percentage_threshold: 10
failure_percentage_request_volume: 100
workloadSelector:
labels:
# the label of the client pod.
app.kubernetes.io/name: kitex-client
```

#### Retry
We can define retry policy configuration via [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/).

The following example shows how to configure the retry policy on the client side. The configuration is as follows:
- `spec.configPatches[0].match.routeConfiguration.name`: the service name of the target service, should obey the specification of the FQDN.
- `retryPolicy.numRetries`: the number of retries.
- `retryPolicy.perTryTimeout`: the timeout of each retry.
- `retryPolicy.retryBackOff.baseInterval`: the base interval of the retry.
- `retryPolicy.retryBackOff.maxInterval`: the maximum interval of the retry.
- `retryPolicy.retriableHeaders`: as the differences between xDS and Kitex configuration, use the `kitexRetryErrorRate` and `kitexRetryMethods` to specify the `errorRate` and `retryMethods` to match the specific methods that required to implement the retry strategy, use commas to separate multiple methods. It is recommended that the retry strategy is only configured for idempotent methods.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: retry-policy
namespace: default
spec:
configPatches:
- applyTo: HTTP_ROUTE
match:
context: SIDECAR_OUTBOUND
routeConfiguration:
name: hello.default.svc.cluster.local:21001
vhost:
name: hello.default.svc.cluster.local:21001
patch:
operation: MERGE
value:
route:
retryPolicy:
numRetries: 3
perTryTimeout: 100ms
retryBackOff:
baseInterval: 100ms
maxInterval: 100ms
retriableHeaders:
- name: "kitexRetryErrorRate"
stringMatch:
exact: "0.29"
- name: "kitexRetryMethods"
stringMatch:
exact: "Echo,Greet"
workloadSelector:
labels:
# the label of the service pod.
app.kubernetes.io/name: kitex-client
```

#### Limit
We can define rate limit configuration via [EnvoyFilter](https://istio.io/latest/docs/reference/config/networking/envoy-filter/).

The following example shows how to configure the limit policy on the server side. The configuration is as follows:
- `tokens_per_fill`: the qps limit, as the kitex will fill tokens into the bucket every 100ms, so the uint tokens is tokens_per_fill / 10, should set the number which is multiples of 10.
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ratelimit-client
namespace: default
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: http_local_rate_limiter
token_bucket:
# the qps limit
tokens_per_fill: 100
workloadSelector:
labels:
# the label of the server pod.
app.kubernetes.io/name: kitex-server
```

## Example

The usage of client is as follows:

```go
import (
"github.com/cloudwego/kitex/client"
xds2 "github.com/cloudwego/kitex/pkg/xds"
"github.com/kitex-contrib/xds"
"github.com/kitex-contrib/xds/xdssuite"
"github.com/cloudwego/kitex-proxyless-test/service/codec/thrift/kitex_gen/proxyless/greetservice"
Expand All @@ -178,10 +299,7 @@ func main() {
// initialize the client
cli, err := greetservice.NewClient(
destService,
client.WithXDSSuite(xds2.ClientSuite{
RouterMiddleware: xdssuite.NewXDSRouterMiddleware(),
Resolver: xdssuite.NewXDSResolver(),
}),
xdssuite.NewClientOption(),
)
req := &proxyless.HelloRequest{Message: "Hello!"}
Expand All @@ -191,6 +309,37 @@ func main() {
)
}
```
The usage of server is as follows:
```go
package main
import (
"log"
"net"
"github.com/cloudwego/kitex/pkg/klog"
"github.com/cloudwego/kitex/server"
xdsmanager "github.com/kitex-contrib/xds"
"github.com/kitex-contrib/xds/xdssuite"
echo "github.com/whalecold/kitex-demo/helloworld/kitex_gen/hello/echoservice"
)
func main() {
if err := xdsmanager.Init(); err != nil {
klog.Fatal(err)
}
addr, _ := net.ResolveTCPAddr("tcp", ":6789")
svr := echo.NewServer(new(GreetServiceImplProto),
server.WithServiceAddr(addr),
xdssuite.NewLimiter(),
)
err := svr.Run()
if err != nil {
log.Println(err.Error())
}
}
```

Detailed examples can be found here [kitex-proxyless-example](https://github.com/cloudwego/kitex-examples/tree/main/proxyless).

Expand All @@ -200,7 +349,7 @@ Detailed examples can be found here [kitex-proxyless-example](https://github.com

mTLS is not supported for now. Please disable mTLS via configuring PeerAuthentication.

```
```yaml
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
Expand All @@ -211,12 +360,10 @@ spec:
mode: DISABLE
```

### Limited support for Service Governance

Current version only support Service Discovery, Traffic route and Timeout Configuration via xDS on the client-side.

Other features supported via xDS, including Load Balancing, Rate Limit and Retry etc., will be added in the future.
### The limited traffic policy
The Loadbalancer dynamic configuration is not supported for now.

## Dependencies

Kitex >= v0.4.0
- server discovery, route, timeout supported in Kitex >= v0.4.0 [xDS](https://github.com/kitex-contrib/xds) >= 0.2.0
- limit, retry, circuitbreak supported in Kitex >= v0.4.0 [xDS](https://github.com/kitex-contrib/xds) >= 0.4.1
Loading

0 comments on commit 6235b19

Please sign in to comment.