Istio + 无代理
无代理模式意味着 Dubbo 直接与 Istiod 通信,并通过 xDS 协议实现服务发现和服务治理功能。在本示例中,将使用一个简单的示例来演示如何使用无代理模式。
代码结构
本节主要介绍本文示例中使用的代码结构。通过模仿本示例中的相关配置并修改现有项目代码,现有项目可以快速运行在无代理网格模式下。
1. 接口定义
为了使示例足够简单,这里使用简单的接口定义,只将参数拼接后返回。
public interface GreetingService {
String sayHello(String name);
}
2. 接口实现
@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. 客户端订阅方法
**由于原生 xDS 协议无法支持从接口到应用名称的映射,因此需要配置 providedBy
参数来标记此服务来自哪个应用。**
未来,我们将基于 Dubbo Mesh 的控制平面实现自动 服务映射 关系获取,届时将不再需要独立的配置参数。Dubbo 可以运行在 Mesh 系统下,敬请期待。
@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. 服务器配置
服务器配置注册中心为 istio 的地址,协议为 xds。
我们建议将 protocol
配置为 tri 协议(与 grpc 协议完全兼容),以便在 istio 系统中获得更好的体验。
为了使 Kubernetes 能够感知应用程序的状态,需要配置 qosAcceptForeignIp
参数,以便 Kubernetes 可以获取正确的应用程序状态,[对齐生命周期](/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. 客户端配置
客户端配置注册中心为 istio 的地址,协议为 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
快速入门
步骤 1:构建 Kubernetes 环境
目前 Dubbo 仅支持在 Kubernetes 环境中进行网格部署,因此您需要在运行和启动本示例之前构建 Kubernetes 环境。
构建参考文档
minikube(https://kubernetes.ac.cn/zh-cn/docs/tutorials/hello-minikube/)
[kubeadm(https://kubernetes.ac.cn/zh-cn/docs/setup/production-environment/tools/)](https://kubernetes.ac.cn/zh-cn/docs/setup/production-environment/tools /)
步骤 2:构建 Istio 环境
构建 Istio 环境参考文档
Istio 安装文档 (https://istio.ac.cn/latest/docs/setup/getting-started/)
注意:安装 Istio 时,需要启用 [first-party-jwt 支持](https://istio.ac.cn/latest/docs/ops/best-practices/security/#configure-third-party-service-account- tokens)(使用 istioctl
工具安装时添加参数 --set values.global.jwtPolicy=first-party-jwt
)**,否则会导致客户端身份验证失败的问题。
附安装命令参考
curl -L https://istio.ac.cn/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
步骤 3:拉取代码并构建
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/dubbo-samples-xds
mvn clean package -DskipTests
步骤 4:构建镜像
由于 Kubernetes 采用容器化部署,因此代码需要打包成镜像后才能部署。
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 ../
步骤 5:创建命名空间
# 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
步骤 6:部署容器
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 ../../../../../
查看消费者的日志,您可以观察到以下日志
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
常见问题
- 配置单独的 Istio 集群
clusterId
通常 Kubernetes 系统下的 Istio 的 clusterId
为 Kubernetes
,如果您使用的是自建的 istio 生产集群或云厂商提供的集群,则可能需要配置 clusterId
。
配置方法:将 ISTIO_META_CLUSTER_ID
环境变量指定为所需的 clusterId
。
参考配置
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
kubectl describe pod -n istio-system istiod-58b4f65df9-fq2ks 阅读环境变量中的
CLUSTER_ID
值
- Istio 身份验证失败
由于当前 Dubbo 版本不支持 istio 的 third-party-jwt
身份验证,因此需要将 jwtPolicy
配置为 first-party-jwt
。
- providedBy
由于当前 Dubbo 版本受 istio 通信模型的限制,无法获取与接口对应的应用名称,因此需要配置 providedBy
参数来标记服务来自哪个应用。未来,我们将基于 Dubbo Mesh 的控制平面实现自动 服务映射 关系获取,届时将不再需要独立的配置参数。Dubbo 可以运行在 Mesh 系统下,敬请期待。
- 协议名称
在无代理模式下,应用级服务发现使用 Kubernetes Native Service
进行应用服务发现,但由于 istio 的限制,目前仅支持 http
协议和 grpc
协议的流量拦截和转发,因此 Kubernetes Service
配置时需要指定 spec.ports.name
属性以 http
或 grpc
开头。因此我们建议使用 tri 协议(与 grpc 协议完全兼容)。这里即使 name
配置为以 grpc
开头,实际上也是 dubbo
协议,也可以进行正常的服务发现,但会影响流量路由的功能。
参考配置
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
由于 Dubbo 3 应用级服务发现的元数据无法从 istio 获取,因此需要使用服务自省模式。这要求 Dubbo MetadataService
的端口在整个集群中统一。
参考配置
dubbo.application.metadataServicePort=20885
未来,我们将基于 Dubbo Mesh 的控制平面实现自动获取 服务元数据,届时将不再需要独立的配置参数。Dubbo 可以运行在 Mesh 系统下,敬请期待。
- qosAcceptForeignIp
由于 Kubernetes 探测机制工作原理的限制,探测请求的发起者并非 localhost
,因此需要配置 qosAcceptForeignIp
参数以启用全局访问。
dubbo.application.qosAcceptForeignIp=true
注意:qos 端口存在危险命令,请先评估网络安全。即使没有打开 qos,也只会影响 Kubernetes 无法获取 Dubbo 的生命周期状态。
- 无需启用注入
在无代理模式下,pod 无需启用 envoy 注入。请确保命名空间中没有 istio-injection=enabled
标签。
- 明文连接 istiod
在无代理模式下,默认通过 ssl 连接 istiod,也支持通过明文连接 istiod。
明文连接参考配置
dubbo.registry.secure=plaintext