# xDS Service
Istio is deployed with a control plane and a data plane. Traditionally, the data plane uses sidecar containers with network proxies (such as Envoy), which increases network latency for microservice calls. In Kubernetes environments, Sermant uses the xDS protocol to communicate directly with Istiod, enabling service discovery. Using a Proxyless Service Mesh based on Istio+Sermant can significantly reduce microservice call latency and simplify system deployment. This article introduces how to use Sermant's xDS service in plugin development.
# Service Discovery Based on xDS Protocol
# Feature Introduction
Service discovery based on xDS protocol allows Sermant to connect to Istio's control plane to obtain Kubernetes service information and the corresponding specific service instance information.
Note: Using Sermant's xDS service discovery capability requires the service to be deployed in a Kubernetes container environment and istio is running.
# Development Example
This development example is based on the project created in the Creating Your First Plugin document and demonstrates how the plugin uses the xDS service discovery capability provided by the Sermant framework to obtain service instances:
Add the
xdsServiceDiscoveryvariable in thecom.huaweicloud.sermant.template.TemplateDeclarerclass undertemplate/template-pluginin the project to get the xDS service discovery service provided by the Sermant framework for obtaining service instances:XdsServiceDiscovery xdsServiceDiscovery = ServiceManager.getService(XdsCoreService.class).getXdsServiceDiscovery();After obtaining the service discovery instance, you can call the APIs provided by
XdsServiceDiscoveryto perform corresponding actions. This example demonstrates how to directly obtain service instance information for a service namedservice-test:@Override public ExecuteContext before(ExecuteContext context) throws Exception { Set<ServiceInstance> serviceInstance = xdsServiceDiscovery.getServiceInstance("service-test"); Iterator<ServiceInstance> iterator = serviceInstance.iterator(); while (iterator.hasNext()) { ServiceInstance instance = iterator.next(); System.out.println("ServiceInstance: [" + instance.getHost() + " : " + instance.getPort() + "]"); } }Note:
service-testmust be the name of the Kubernetes Service. The obtained service instance information corresponds to the Pod instance data of that service, an example Kubernetes Service looks like this:apiVersion: v1 kind: Service metadata: name: service-test spec: type: ClusterIP ports: - name: http port: 8080 targetPort: 8080 protocol: TCP selector: app: service-testAfter completing the development, refer to the Packaging and Building process in the Creating Your First Plugin document. Execute mvn package in the root directory of the project to generate the build artifact.
Enable the xDS service and set it to be enabled in
agent/config/config.propertieswith the following configuration:# xDS service switch agent.service.xds.service.enable=trueAfter completing the execution, package the Sermant image and the host microservice image. Start the
service-testservice in the k8s environment and create the corresponding service instances (implemented by the user). Finally, start the host application in Kubernetes and mount Sermant. Refer to the Sermant Injector User Guide for guidance on packaging Sermant and the host image in the Kubernetes environment, as well as mounting Sermant for startup.After the host microservice pod with Sermant mounted starts successfully, you can execute the following command to obtain the host microservice logs and view the service instances obtained through the xDS service discovery capability:
$ kubectl logs -f ${POD_NAME} ServiceInstance: [xxx.xxx.xxx.xxx : xxxx]Note:
${POD_NAME}must be the name of the pod running the host microservice, which can be viewed using thekubectl get podcommand.
# xDS Service Discovery API
Obtain xDS Service Discovery Service:
XdsServiceDiscovery xdsServiceDiscovery = ServiceManager.getService(XdsCoreService.class).getXdsServiceDiscovery();
The xDS Service Discovery service has three interface methods: used respectively for directly obtaining service instances, obtaining service instances through subscription and obtaining service instances through cluster.
Set<ServiceInstance> getServiceInstance(String serviceName);
void subscribeServiceInstance(String serviceName, XdsServiceDiscoveryListener listener);
Optional<XdsClusterLoadAssigment> getClusterServiceInstance(String clusterName);
# Directly Obtain Service Instance
Obtain the service instance information of the Kubernetes service, returning a
java.util.Setcontaining all instances of the service.xdsServiceDiscovery.getServiceInstance("service-test")
# Subscribe to Obtain Service Instances
Subscribe to the service instance information of the Kubernetes service and register a service discovery listener. The listener's
processfunction can execute custom operations when service instances change.xdsServiceDiscovery.subscribeServiceInstance("service-test", new XdsServiceDiscoveryListener() { @Override public void process(Set<ServiceInstance> instances) { // do something } });XdsServiceDiscoveryListener (opens new window),contains the following interface methods:
Method Description void process(Set instances) Callback interface for processing the latest service instance information ServiceInstance (opens new window), with the following methods:
Method Name Return Type Description getClusterName() StringGet the Istio cluster name the instance belongs to getServiceName() StringGet the Kubernetes service name the instance belongs to getHost() StringGet the Pod IP of the instance getPort() intGet the port of the instance getMetaData() Map<String, String>Get the metadata of the instance isHealthy() booleanCheck if the service is healthy
# Get Service Instances through Cluster
Retrieve the service instance information of a Service Cluster. The return type is
Optional<XdsClusterLoadAssignment>, which contains all service instances of the Cluster:xdsServiceDiscovery.getClusterServiceInstance("outbound|8080||service-test.default.svc.cluster.local");Cluster service instance XdsClusterLoadAssignment (opens new window) has the following fields:
Field Name Field Type Description serviceName StringThe name of the service to which the Cluster service instance belongs clusterName StringThe name of the Cluster localityInstances Map<XdsLocality, Set<ServiceInstance>>The service instances of the Cluster, consisting of service instances from different localities Locality information XdsLocality (opens new window) has the following fields:
Field Name Field Type Description region StringRegion information zone StringZone information subZone StringSub-zone information loadBalanceWeight intLoad balancing weight localityPriority intLocality priority
# Route Configuration Service Based on xDS Protocol
# Feature Introduction
The Route Configuration Service Based on xDS Protocol allows Sermant to connect with Istio's control plane to retrieve the routing configuration information of Kubernetes Services.
Note: To use Sermant's xDS routing configuration service, the service must be deployed in a Kubernetes container environment and running Istio.
# Development Example
This development example is based on the project created in the Create Your First Plugin document, demonstrating how a plugin can retrieve routing configuration information for services using the xDS routing configuration service provided by the Sermant framework:
In the
io.sermant.template.TemplateDeclarerclass undertemplate/template-pluginin the project, add the variablexdsRouteServiceto obtain the xDS route configuration service provided by the Sermant framework, which is used to get the routing configuration information of the services:XdsRouteService xdsRouteService = ServiceManager.getService(XdsCoreService.class).getXdsRouteService();After obtaining the route configuration service instance, you can call the API provided by
xdsRouteServiceto get the routing configuration information of a specified service:List<XdsRoute> serviceRoute = xdsRouteService.getServiceRoute("spring-test"); System.out.println("The size of routing config: " + serviceRoute.size());Note:
service-testmust be the name of a Kubernetes Service. The retrieved routing configuration is delivered through Istio's DestinationRule and VirtualService. For the specific routing configuration fields and templates supported by Sermant, please refer to the section Routing based on xDS Service.After development, you can follow the Packaging and Building steps from the first plugin creation to generate the build artifact by executing mvn package in the project root directory.
Enable the xDS service and configure
agent/config/config.propertiesto enable the xDS service. The configuration example is as follows:# xDS service switch agent.service.xds.service.enable=trueAfter completion, package the Sermant image and the host microservice image. Start the host microservice in Kubernetes and mount Sermant. For guidance on packaging Sermant and host images and mounting Sermant to start host microservices in Kubernetes, please refer to the Sermant Injector User Guide. Use the DestinationRule and VirtualService rules according to the Istio Routing Configuration Template provided by Sermant.
After the host microservice is successfully started with Sermant mounted, you can execute the following command to fetch the logs of the host microservice and check the number of routing configurations retrieved by the xDS route configuration service:
$ kubectl logs -f ${POD_NAME} The size of routing config: 1Note:
${POD_NAME}must be the name of the pod where the host microservice is running. You can check it using thekubectl get podcommand.
# xDS Route Configuration Service API
To obtain the xDS Route Configuration Service:
XdsRouteService xdsRouteService = ServiceManager.getService(XdsCoreService.class).getXdsRouteService();
The xDS Route Configuration Service has two API methods: one for getting the routing information of a Service, and the other for checking whether a Cluster has enabled same AZ routing.
List<XdsRoute> getServiceRoute(String serviceName);
boolean isLocalityRoute(String clusterName);
# Get Service Routing Configuration
Retrieve the routing configuration information of a Kubernetes Service. The return type is
List<XdsRoute>, containing all the routing configuration for that Service:xdsRouteService.getServiceRoute("service-test");The routing configuration entity XdsRoute (opens new window) includes the following fields:
Field Name Field Type Description name StringThe name of the route configuration routeMatch XdsRouteMatchThe matching rule for the route routeAction XdsRouteActionThe routing destination for the match
# Cluster AZ Routing
Check whether the Cluster of a Service has enabled same AZ routing. The return type is
boolean:xdsRouteService.isLocalityRoute("outbound|8080||service-test.default.svc.cluster.local");
# Load Balancing Configuration Service Based on xDS Protocol
# Feature Introduction
The Load Balancing Configuration Service Based on xDS Protocol allows Sermant to connect with Istio's control plane to retrieve the load balancing rules of Kubernetes Services.
Note: To use Sermant's xDS load balancing configuration service, the service must be deployed in a Kubernetes container environment and running Istio.
# Development Example
This development example is based on the project created in the Create Your First Plugin document, demonstrating how a plugin can retrieve the load balancing rules for services using the xDS load balancing configuration service provided by the Sermant framework:
In the
io.sermant.template.TemplateDeclarerclass undertemplate/template-pluginin the project, add the variableloadBalanceServiceto obtain the xDS load balancing configuration service provided by the Sermant framework, which is used to get the load balancing rules of the services:XdsLoadBalanceService loadBalanceService = ServiceManager.getService(XdsCoreService.class).getLoadBalanceService();After obtaining the load balancing configuration service, you can call the API provided by
loadBalanceServiceto get the load balancing strategy of a service:XdsLbPolicy serviceLbPolicy = loadBalanceService.getBaseLbPolicyOfService("spring-test"); System.out.println("Service lb policy: " + serviceLbPolicy);Note:
service-testmust be the name of a Kubernetes Service. The load balancing configuration is delivered through Istio's DestinationRule. For the specific supported fields and load balancing rules in the configuration, and configuration templates, please refer to the section Load balancing based on xDS Service.After development, you can follow the Packaging and Building steps from the first plugin creation to generate the build artifact by executing mvn package in the project root directory.
Enable the xDS service and configure
agent/config/config.propertiesto enable the xDS service. The configuration example is as follows:# xDS service switch agent.service.xds.service.enable=trueAfter completion, package the Sermant image and the host microservice image. Start the host microservice in Kubernetes and mount Sermant. For guidance on packaging Sermant and host images and mounting Sermant to start host microservices in Kubernetes, please refer to the Sermant Injector User Guide. Use the DestinationRule provided by Sermant in the Istio Load Balancing Configuration Template.
After the host microservice is successfully started with Sermant mounted, you can execute the following command to fetch the logs of the host microservice and check the load balancing strategy retrieved by the xDS load balancing configuration service:
$ kubectl logs -f ${POD_NAME} Service lb policy: ROUND_ROBINNote:
${POD_NAME}must be the name of the pod where the host microservice is running. You can check it using thekubectl get podcommand.
# xDS Load Balancing Configuration Service API
To obtain the xDS Load Balancing Configuration Service:
XdsLoadBalanceService loadBalanceService =
ServiceManager.getService(XdsCoreService.class).getLoadBalanceService();
The xDS Load Balancing Configuration Service provides two API methods: one for getting the load balancing rules of a Service, and another for the load balancing rules of a Cluster:
XdsLbPolicy getLbPolicyOfCluster(String clusterName);
XdsLbPolicy getBaseLbPolicyOfService(String serviceName);
# Get Load Balancing Rules of a Service
Retrieve the load balancing rules for a Service. The return type is
XdsLbPolicy:loadBalanceService.getBaseLbPolicyOf("spring-test");The load balancing rule entity class XdsLbPolicy (opens new window) is an enumeration type.
Load Balancing Rule Description XdsLbPolicy.RANDOM Random load balancing rule XdsLbPolicy.ROUND_ROBIN Round-robin load balancing rule XdsLbPolicy.LEAST_REQUEST Least-request load balancing rule XdsLbPolicy.UNRECOGNIZED Unrecognized load balancing rule
# Get Load Balancing Rules of the Cluster
Retrieve the load balancing rules of a Service Cluster. The return type is
XdsLbPolicy.loadBalanceService.getLbPolicyOfCluster("outbound|8080||service-test.default.svc.cluster.local");
# Flow Control Service Based on xDS Protocol
# Function Introduction
The Flow Control Service based on the xDS protocol allows Sermant to connect to the Istio control plane to retrieve flow control configurations for Kubernetes Services.
Note: To use the Sermant xDS flow control service, the service must be deployed in a Kubernetes container environment running Istio.
# Development Example
This development example is based on the project created in the Create Your First Plugin document, demonstrating how a plugin can use the xDS flow control service provided by the Sermant framework to retrieve flow control rules for a service:
In the
io.sermant.template.TemplateDeclarerclass under thetemplate/template-plugindirectory of the project, add a variablexdsFlowControlServiceto obtain the xDS flow control service provided by the Sermant framework, which is used to retrieve the flow control rules for the service:XdsFlowControlService xdsFlowControlService = ServiceManager.getService(XdsCoreService.class).getXdsFlowControlService();After obtaining the xDS flow control service, you can call the API provided by
xdsFlowControlServiceto retrieve the flow control rules for the service:Optional<XdsInstanceCircuitBreakers> circuitBreakersOptional = xdsFlowControlService.getInstanceCircuitBreakers("spring-test", "v1"); System.out.println("circuitBreaker : " + circuitBreakersOptional.get().getInterval());Note:
spring-testmust be the name of the Kubernetes Service, andv1is the cluster name of the Kubernetes Service. The flow control rules retrieved are issued through Istio's DestinationRule (opens new window), VirtualService (opens new window), and EnvoyFilter (opens new window). For the specific flow control rule fields supported by Sermant, the configurable flow control rules, and configuration templates, please refer to the section on Flow Control Capabilities Based on xDS Service.After development is complete, you can follow the Packaging and Build process from the "Create Your First Plugin" guide. After running mvn package in the root directory of the project, the build artifact will be generated.
Enable the xDS service and set it in the
agent/config/config.propertiesfile, with the following example configuration:# xDS service switch agent.service.xds.service.enable=trueAfter execution is completed, package the Sermant image and the host microservice image. Start the host microservice on Kubernetes and mount Sermant. For guidance on packaging the Sermant and host images, as well as starting the host microservice with Sermant mounted in a Kubernetes environment, please refer to the Sermant Injector User Manual. Issue the configuration based on the configuration templates in the Flow Control Configuration Field Support provided by Sermant.
After the host microservice successfully starts with the Sermant-mounted Pod, you can execute the
kubectl logs -f ${POD_NAME}command to view the logs of the host microservice and check the circuit breaker information retrieved via the xDS flow control service:circuitBreaker: 300Note:
${POD_NAME}must be the name of the Pod running the host microservice, which can be viewed using thekubectl get podcommand.
# xDS Flow Control Service API
Accessing xDS Flow Control Service:
XdsFlowControlService xdsFlowControlService = ServiceManager.getService(XdsCoreService.class).getXdsFlowControlService();
The xDS Flow Control Service provides five interface methods, which are used to retrieve rules for request circuit breaking, instance circuit breaking, retry policies, fault injection, and rate limiting:
Optional<XdsRequestCircuitBreakers> getRequestCircuitBreakers(String serviceName, String clusterName);
Optional<XdsInstanceCircuitBreakers> getInstanceCircuitBreakers(String serviceName, String clusterName);
Optional<XdsRetryPolicy> getRetryPolicy(String serviceName, String routeName);
Optional<XdsRateLimit> getRateLimit(String serviceName, String routeName, String port);
Optional<XdsHttpFault> getHttpFault(String serviceName, String routeName);
# Getting Request Circuit Breaker Rules
To retrieve request circuit breaker rules, the return type is
Optional<XdsRequestCircuitBreakers>.xdsFlowControlService.getRequestCircuitBreakers("service-test", "v1");The request circuit breaker configuration
XdsRequestCircuitBreakershas the following fields:
| Field Name | Field Type | Description |
|---|---|---|
| maxRequests | int | The maximum number of active requests allowed. |
# Getting Instance Circuit Breaker Rules
To retrieve instance circuit breaker rules, the return type is
Optional<XdsInstanceCircuitBreakers>.xdsFlowControlService.getInstanceCircuitBreakers("service-test", "v1");The instance circuit breaker configuration
XdsInstanceCircuitBreakershas the following fields:
| Field Name | Field Type | Description |
|---|---|---|
| splitExternalLocalOriginErrors | boolean | Whether to distinguish between local and external errors. If set to true, consecutiveLocalOriginFailures is used to detect whether the instance failure count exceeds the threshold. |
| consecutive5xxFailure | int | The number of 5xx errors that can occur before the instance is circuit-broken. Timeout, connection errors/failures, and request failures are treated as 5xx errors. |
| consecutiveLocalOriginFailure | int | The number of local origin errors that can occur before the instance is circuit-broken. |
| consecutiveGatewayFailure | int | The number of gateway errors (502, 503, 504 response codes) that can occur before the instance is circuit-broken. |
| interval | long | The detection time interval. If the error count exceeds the threshold within this interval, the instance is circuit-broken. |
| baseEjectionTime | long | The minimum ejection time for an instance. The time an instance remains in a circuit-broken state is equal to the failure count multiplied by the minimum ejection time. |
| maxEjectionPercent | int | The maximum percentage of instances that can be ejected from the pool. |
| minHealthPercent | double | The minimum percentage of healthy instances required. At least this percentage of instances must be healthy for ejection to proceed. |
Note: Errors occurring before sending bytes to the server are considered local source errors, while errors occurring after sending bytes to the server are considered external errors.
# Retrieving Retry Rules
To retrieve the retry rules, the return value is of type
Optional<XdsRetryPolicy>.xdsFlowControlService.getRetryPolicy("service-test", "v1-routes");Retry configuration
XdsRetryPolicy, with the following fields:Field Name Field Type Description maxAttempts longMaximum number of allowed retry attempts perTryTimeout longTime interval for each retry attempt retryConditions List<String>Retry conditions, supporting 5xx, gateway-error, connect-failure, retriable-4xx,
retriable-status-codes, retriable-headers
# Retrieving Fault Injection Rules
To retrieve the fault injection rules, the return value is of type
Optional<XdsHttpFault>.xdsFlowControlService.getHttpFault("service-test", "v1-routes");Fault injection configuration
XdsHttpFault, with the following fields:Field Name Field Type Description delay XdsDelayRequest delay configuration abort XdsAbortRequest abort configuration Request delay configuration
XdsDelay, with the following fields:Field Name Field Type Description fixedDelay longDelay time (in milliseconds) percentage FractionalPercentProbability of triggering a delay, including numerator (numerator)
and denominator (denominator)Request abort configuration
XdsAbort, with the following fields:Field Name Field Type Description httpStatus intHTTP status code returned when aborting the request percentage FractionalPercentProbability of triggering a request abort, including numerator
and denominator
# Retrieving Rate Limiting Rules
To retrieve the rate-limiting rules, the return value is of type
Optional<XdsRateLimit>.xdsFlowControlService.getRateLimit("service-test", "v1-routes", "8003");Rate-limiting configuration
XdsRateLimit, with the following fields:Field Name Field Type Description tokenBucket XdsTokenBucketToken bucket configuration responseHeaderOption List<XdsHeaderOption>Configuration of response header operations percent FractionalPercentProbability of triggering rate-limiting, including numerator
and denominatorToken bucket configuration
XdsTokenBucket, with the following fields:Field Name Field Type Description maxTokens intMaximum number of tokens in the bucket tokensPerFill intNumber of tokens added per fill operation fillInterval longTime interval between token refills (in ms) Response header operation configuration
XdsHeaderOption, with the following fields:Field Name Field Type Description header XdsHeaderResponse header information, containing key: header name,value: header valueenabledAppend booleanWhether to append to the response header. If true, and the header already exists, append the new value to the existing value;
iffalse, or the header does not exist, it will be added as a new header.
# xDS Service Configuration
In the agent/config/config.properties file of the Sermant Agent package, you can enable the xDS service using the agent.service.xds.service.enable configuration item. Other xDS service configurations are also set in this file:
# xDS service switch
agent.service.xds.service.enable=false
