Proxyless mode refers to Dubbo communicating directly with Istiod, utilizing the xDS protocol to achieve capabilities such as service discovery and service governance. This example will demonstrate how to use Proxyless mode through a simple demonstration.
This section primarily introduces the code architecture of the example used in this article. By mimicking the relevant configurations in this example, existing project code can be quickly adapted to run in Proxyless Mesh mode.
To keep the example simple, a straightforward interface definition is used, returning a concatenated result of parameters.
public interface GreetingService {
String sayHello(String name);
}
@DubboService(version = "1.0.0")
public class AnnotatedGreetingService implements GreetingService {
@Override
public String sayHello(String name) {
System.out.println("greeting service received: " + name);
return "hello, " + name + "! from host: " + NetUtils.getLocalHost();
}
}
Since the native xDS protocol does not support obtaining the mapping from the interface to the application name, the providedBy
parameter needs to be configured to indicate which application this service comes from.
In the future, we will implement automatic service mapping relationship retrieval based on Dubbo Mesh’s control panel, eliminating the need for independent parameter configurations.
@Component("annotatedConsumer")
public class GreetingServiceConsumer {
@DubboReference(version = "1.0.0", providedBy = "dubbo-samples-xds-provider")
private GreetingService greetingService;
public String doSayHello(String name) {
return greetingService.sayHello(name);
}
}
The server configuration registers the Istio address as the registration center, and the protocol is xds.
We recommend setting the protocol
to tri (fully compatible with grpc) for a better experience within the Istio environment.
To allow Kubernetes to be aware of the application’s status, the qosAcceptForeignIp
parameter needs to be configured for Kubernetes to obtain the correct application status, aligning the lifecycle.
dubbo.application.name=dubbo-samples-xds-provider
dubbo.application.metadataServicePort=20885
dubbo.registry.address=xds://istiod.istio-system.svc:15012
dubbo.protocol.name=tri
dubbo.protocol.port=50052
dubbo.application.qosAcceptForeignIp=true
The client configuration registers the Istio address as the registration center, and the protocol is xds.
dubbo.application.name=dubbo-samples-xds-consumer
dubbo.application.metadataServicePort=20885
dubbo.registry.address=xds://istiod.istio-system.svc:15012
dubbo.application.qosAcceptForeignIp=true
Currently, Dubbo only supports Mesh deployment in Kubernetes environments, so you need to set up a Kubernetes environment before running this example.
Reference Documentation:
minikube(https://kubernetes.io/zh-cn/docs/tutorials/hello-minikube/)
kubeadm(https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/)
Reference Documentation for Istio Installation:
Istio Installation Documentation(https://istio.io/latest/docs/setup/getting-started/)
Note: When installing Istio, you must enable first-party-jwt support (add the --set values.global.jwtPolicy=first-party-jwt
parameter when using the istioctl
tool); otherwise, client authentication will fail.
Reference for Installation Commands:
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.xx.x
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo --set values.global.jwtPolicy=first-party-jwt -y
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/dubbo-samples-xds
mvn clean package -DskipTests
Since Kubernetes adopts containerized deployment, the code needs to be packaged in an image before deployment.
cd ./dubbo-samples-xds-provider/
# dubbo-samples-xds/dubbo-samples-xds-provider/Dockerfile
docker build -t apache/dubbo-demo:dubbo-samples-xds-provider_0.0.1 .
cd ../dubbo-samples-xds-consumer/
# dubbo-samples-xds/dubbo-samples-xds-consumer/Dockerfile
docker build -t apache/dubbo-demo:dubbo-samples-xds-consumer_0.0.1 .
cd ../
# Initialize namespace
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-xds/deploy/Namespace.yml
# Switch namespace
kubens dubbo-demo
cd ./dubbo-samples-xds-provider/src/main/resources/k8s
# dubbo-samples-xds/dubbo-samples-xds-provider/src/main/resources/k8s/Deployment.yml
# dubbo-samples-xds/dubbo-samples-xds-provider/src/main/resources/k8s/Service.yml
kubectl apply -f Deployment.yml
kubectl apply -f Service.yml
cd ../../../../../dubbo-samples-xds-consumer/src/main/resources/k8s
# dubbo-samples-xds/dubbo-samples-xds-consumer/src/main/resources/k8s/Deployment.yml
kubectl apply -f Deployment.yml
cd ../../../../../
By checking the logs of the consumer, the following logs can be observed:
result: hello, xDS Consumer! from host: 172.17.0.5
result: hello, xDS Consumer! from host: 172.17.0.5
result: hello, xDS Consumer! from host: 172.17.0.6
result: hello, xDS Consumer! from host: 172.17.0.6
clusterId
Typically, in Kubernetes, Istio’s clusterId
is Kubernetes
. If you are using a self-built Istio production cluster or a cluster provided by a cloud vendor, you may need to configure the clusterId
.
Configuration Method: Specify the ISTIO_META_CLUSTER_ID
environment variable to the desired clusterId
.
Reference Configuration:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dubbo-samples-xds-consumer
spec:
selector:
matchLabels:
demo: consumer
replicas: 2
template:
metadata:
labels:
demo: consumer
spec:
containers:
- env:
- name: ISTIO_META_CLUSTER_ID
value: Kubernetes
- name: dubbo-samples-xds-provider
image: xxx
clusterId
Retrieval Method:
kubectl describe pod -n istio-system istiod-58b4f65df9-fq2ks Read the value of
CLUSTER_ID
from the environment variables.
Since the current Dubbo version does not support Istio’s third-party-jwt
authentication, it is necessary to configure jwtPolicy
as first-party-jwt
.
Due to the current limitations of the Dubbo version with Istio’s communication model, it is not possible to obtain the application name corresponding to the interface. Therefore, the providedBy
parameter needs to be configured to indicate which application this service comes from. In the future, we will implement automatic service mapping retrieval based on Dubbo Mesh’s control panel.
In Proxyless mode, application-level service discovery is performed via Kubernetes Native Service
. However, due to Istio’s limitations, currently, only http
and grpc
traffic interception and forwarding are supported. Therefore, the Kubernetes Service
configuration needs to specify the spec.ports.name
attribute to start with http
or grpc
.
Thus, we recommend using the triple protocol (fully compatible with grpc). Even if the name
is configured to start with grpc
, it can still function properly, but it affects the traffic routing capabilities.
Reference Configuration:
apiVersion: v1
kind: Service
metadata:
name: dubbo-samples-xds-provider
spec:
clusterIP: None
selector:
demo: provider
ports:
- name: grpc-tri
protocol: TCP
port: 50052
targetPort: 50052
Since Dubbo 3’s application-level service discovery metadata cannot be obtained from Istio, it must rely on service introspection. This requires the Dubbo MetadataService
port to be unified across the entire cluster.
Reference Configuration:
dubbo.application.metadataServicePort=20885
In the future, we will implement automatic retrieval of service metadata based on Dubbo Mesh’s control panel.
Due to the working principles of Kubernetes probe health checks, if the initiator of the health check request is not localhost
, the qosAcceptForeignIp
parameter needs to be configured to allow global access.
dubbo.application.qosAcceptForeignIp=true
Note: The qos port contains dangerous commands; please assess network security first. Even if qos is not open, it only affects Kubernetes’s ability to retrieve Dubbo’s lifecycle status.
In Proxyless mode, pods do not require envoy injection. Please ensure there are no labels of istio-injection=enabled
in the namespace.
In Proxyless mode, the default connection to Istiod is via SSL, but plain text connections to Istiod are also supported.
Reference Configuration for Plain Text Connection:
dubbo.registry.secure=plaintext