# 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
xdsServiceDiscovery
variable in thecom.huaweicloud.sermant.template.TemplateDeclarer
class undertemplate/template-plugin
in 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
XdsServiceDiscovery
to 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-test
must 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-test
After 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.properties
with the following configuration:# xDS service switch agent.service.xds.service.enable=true
After completing the execution, package the Sermant image and the host microservice image. Start the
service-test
service 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 pod
command.
# 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.Set
containing 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
process
function 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() String
Get the Istio cluster name the instance belongs to getServiceName() String
Get the Kubernetes service name the instance belongs to getHost() String
Get the Pod IP of the instance getPort() int
Get the port of the instance getMetaData() Map<String, String>
Get the metadata of the instance isHealthy() boolean
Check 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 String
The name of the service to which the Cluster service instance belongs clusterName String
The 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 String
Region information zone String
Zone information subZone String
Sub-zone information loadBalanceWeight int
Load balancing weight localityPriority int
Locality 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.TemplateDeclarer
class undertemplate/template-plugin
in the project, add the variablexdsRouteService
to 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
xdsRouteService
to 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-test
must 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.properties
to enable the xDS service. The configuration example is as follows:# xDS service switch agent.service.xds.service.enable=true
After 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: 1
Note:
${POD_NAME}
must be the name of the pod where the host microservice is running. You can check it using thekubectl get pod
command.
# 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 String
The name of the route configuration routeMatch XdsRouteMatch
The matching rule for the route routeAction XdsRouteAction
The 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.TemplateDeclarer
class undertemplate/template-plugin
in the project, add the variableloadBalanceService
to 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
loadBalanceService
to get the load balancing strategy of a service:XdsLbPolicy serviceLbPolicy = loadBalanceService.getBaseLbPolicyOfService("spring-test"); System.out.println("Service lb policy: " + serviceLbPolicy);
Note:
service-test
must 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.properties
to enable the xDS service. The configuration example is as follows:# xDS service switch agent.service.xds.service.enable=true
After 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_ROBIN
Note:
${POD_NAME}
must be the name of the pod where the host microservice is running. You can check it using thekubectl get pod
command.
# 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.TemplateDeclarer
class under thetemplate/template-plugin
directory of the project, add a variablexdsFlowControlService
to 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
xdsFlowControlService
to 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-test
must be the name of the Kubernetes Service, andv1
is 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.properties
file, with the following example configuration:# xDS service switch agent.service.xds.service.enable=true
After 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: 300
Note:
${POD_NAME}
must be the name of the Pod running the host microservice, which can be viewed using thekubectl get pod
command.
# 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
XdsRequestCircuitBreakers
has 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
XdsInstanceCircuitBreakers
has 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 long
Maximum number of allowed retry attempts perTryTimeout long
Time 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 XdsDelay
Request delay configuration abort XdsAbort
Request abort configuration Request delay configuration
XdsDelay
, with the following fields:Field Name Field Type Description fixedDelay long
Delay time (in milliseconds) percentage FractionalPercent
Probability of triggering a delay, including numerator (numerator)
and denominator (denominator)Request abort configuration
XdsAbort
, with the following fields:Field Name Field Type Description httpStatus int
HTTP status code returned when aborting the request percentage FractionalPercent
Probability 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 XdsTokenBucket
Token bucket configuration responseHeaderOption List<XdsHeaderOption>
Configuration of response header operations percent FractionalPercent
Probability of triggering rate-limiting, including numerator
and denominatorToken bucket configuration
XdsTokenBucket
, with the following fields:Field Name Field Type Description maxTokens int
Maximum number of tokens in the bucket tokensPerFill int
Number of tokens added per fill operation fillInterval long
Time interval between token refills (in ms) Response header operation configuration
XdsHeaderOption
, with the following fields:Field Name Field Type Description header XdsHeader
Response header information, containing key
: header name,value
: header valueenabledAppend boolean
Whether 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