Istio + Proxyless
Proxyless mode means that Dubbo communicates directly with Istiod, and implements service discovery and service governance capabilities through the xDS protocol. In this example, a simple example will be used to demonstrate how to use the Proxyless mode.
code structure
This section mainly introduces the code structure of the example used in this article. By imitating the relevant configuration in this example and modifying the existing project code, the existing project can quickly run in Proxyless Mesh mode.
1. Interface definition
In order to make the example simple enough, a simple interface definition is used here, and only the parameters are spliced to be returned.
public interface GreetingService {
String sayHello(String name);
}
2. Interface implementation
@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();
}
}
3. Client subscription method
**Because the native xDS protocol cannot support the mapping from interface to application name, it is necessary to configure the providedBy
parameter to mark which application this service comes from. **
In the future, we will realize automatic service mapping relationship acquisition based on the control plane of Dubbo Mesh, and there will be no need for independent configuration parameters at that time. Dubbo can be run under the Mesh system, so stay tuned.
@Component("annotated Consumer")
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);
}
}
4. Server configuration
The server configuration registration center is the address of istio, and the protocol is xds.
We recommend configuring protocol
to be the tri protocol (fully compatible with the grpc protocol) for a better experience in the istio system.
In order to make Kubernetes aware of the state of the application, it is necessary to configure qosAcceptForeignIp
parameter so that Kubernetes can obtain the correct application state, [alignment lifecycle](/en/docs3-v2/java-sdk/advanced-features-and-usage/ others/dubbo-kubernetes-probe/).
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
5. Client Configuration
The client configuration registration center is the address of istio, 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
Quick start
Step 1: Build the Kubernetes environment
Currently Dubbo only supports Mesh deployment in the Kubernetes environment, so you need to build the Kubernetes environment before running and starting this example.
Build reference documents:
minikube(https://kubernetes.io/zh-cn/docs/tutorials/hello-minikube/)
[kubeadm(https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/)](https://kubernetes.io/zh-cn/docs/setup/production-environment/tools /)
Step 2: Build the Istio environment
Build the Istio environment reference document:
Istio Installation Documentation (https://istio.io/latest/docs/setup/getting-started/)
Note: When installing Istio, you need to enable [first-party-jwt support](https://istio.io/latest/docs/ops/best-practices/security/#configure-third-party-service-account- tokens) (add the parameter --set values.global.jwtPolicy=first-party-jwt
when using the istioctl
tool to install)**, otherwise it will cause the problem of client authentication failure.
Attached installation command reference:
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
Step 3: Pull the code and build
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/dubbo-samples-xds
mvn clean package -DskipTests
Step 4: Build the image
Since Kubernetes adopts containerized deployment, the code needs to be packaged in a mirror 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 ../
Step 5: Create namespace
# Initialize the namespace
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-xds/deploy/Namespace.yml
# switch namespace
kubens dubbo-demo
Step 6: Deploy the container
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 ../../../../../
Looking at the log of the consumer, you can observe the following log:
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
common problem
- Configure a separate Istio cluster
clusterId
Usually the clusterId
of Istio under the Kubernetes system 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 clusterId
.
Configuration method: Specify the ISTIO_META_CLUSTER_ID
environment variable as 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
How to get clusterId
:
kubectl describe pod -n istio-system istiod-58b4f65df9-fq2ks Read the value of
CLUSTER_ID
in the environment variable
- Istio authentication failed
Since the current Dubbo version does not support istio’s third-party-jwt
authentication, it is necessary to configure jwtPolicy
to first-party-jwt
.
- providedBy
Since the current Dubbo version is limited by the communication model of istio and cannot obtain the application name corresponding to the interface, it is necessary to configure the providedBy
parameter to mark which application the service comes from.
In the future, we will realize automatic service mapping relationship acquisition based on the control plane of Dubbo Mesh, and there will be no need for independent configuration parameters at that time. Dubbo can be run under the Mesh system, so stay tuned.
- protocol name
In Proxyless mode, application-level service discovery uses Kubernetes Native Service
for application service discovery, but due to the limitation of istio, it currently only supports traffic interception and forwarding of http
protocol and grpc
protocol, so Kubernetes Service
is configured in When you need to specify the spec.ports.name
property to start with http
or grpc
.
Therefore we recommend using the triple protocol (fully compatible with the grpc protocol). Here, even if name
is configured to start with grpc
, it is actually a dubbo
protocol that can also perform normal service discovery, but it affects the function of traffic routing.
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
- metadataServicePort
Since the metadata discovered by Dubbo 3 application-level services cannot be obtained from istio, it is necessary to use the service introspection mode. This requires that the port of Dubbo MetadataService
is unified in the whole cluster.
Reference configuration:
dubbo.application.metadataServicePort=20885
In the future, we will realize automatic acquisition of service metadata based on the control plane of Dubbo Mesh, and no independent configuration parameters will be required at that time. Dubbo can be run under the Mesh system, so stay tuned.
- qosAcceptForeignIp
Due to the limitations of the working principle of the Kubernetes probe detection mechanism, the originator of the detection request is not localhost
, so you need to configure the qosAcceptForeignIp
parameter to enable global access.
dubbo.application.qosAcceptForeignIp=true
Note: There are dangerous commands on the qos port, please evaluate the security of the network first. Even if the qos is not open, it only affects the inability of Kubernetes to obtain the life cycle status of Dubbo.
- Do not need to enable injection
In Proxyless mode, the pod does not need to enable envoy injection. Please make sure that there is no istio-injection=enabled
label in the namespace.
- Plain text connection istiod
In Proxyless mode, connect to istiod through ssl by default, and also support connecting to istiod through clear text.
Plain text connection reference configuration:
dubbo.registry.secure=plaintext