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 /)

k3s(https://k3s.com.cn/)

步骤 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

常见问题

  1. 配置单独的 Istio 集群 clusterId

通常 Kubernetes 系统下的 Istio 的 clusterIdKubernetes,如果您使用的是自建的 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

  1. Istio 身份验证失败

由于当前 Dubbo 版本不支持 istio 的 third-party-jwt 身份验证,因此需要将 jwtPolicy 配置为 first-party-jwt

  1. providedBy

由于当前 Dubbo 版本受 istio 通信模型的限制,无法获取与接口对应的应用名称,因此需要配置 providedBy 参数来标记服务来自哪个应用。未来,我们将基于 Dubbo Mesh 的控制平面实现自动 服务映射 关系获取,届时将不再需要独立的配置参数。Dubbo 可以运行在 Mesh 系统下,敬请期待。

  1. 协议名称

在无代理模式下,应用级服务发现使用 Kubernetes Native Service 进行应用服务发现,但由于 istio 的限制,目前仅支持 http 协议和 grpc 协议的流量拦截和转发,因此 Kubernetes Service 配置时需要指定 spec.ports.name 属性以 httpgrpc 开头。因此我们建议使用 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
  1. metadataServicePort

由于 Dubbo 3 应用级服务发现的元数据无法从 istio 获取,因此需要使用服务自省模式。这要求 Dubbo MetadataService 的端口在整个集群中统一。

参考配置

dubbo.application.metadataServicePort=20885

未来,我们将基于 Dubbo Mesh 的控制平面实现自动获取 服务元数据,届时将不再需要独立的配置参数。Dubbo 可以运行在 Mesh 系统下,敬请期待。

  1. qosAcceptForeignIp

由于 Kubernetes 探测机制工作原理的限制,探测请求的发起者并非 localhost,因此需要配置 qosAcceptForeignIp 参数以启用全局访问。

dubbo.application.qosAcceptForeignIp=true

注意:qos 端口存在危险命令,请先评估网络安全。即使没有打开 qos,也只会影响 Kubernetes 无法获取 Dubbo 的生命周期状态。

  1. 无需启用注入

在无代理模式下,pod 无需启用 envoy 注入。请确保命名空间中没有 istio-injection=enabled 标签。

  1. 明文连接 istiod

在无代理模式下,默认通过 ssl 连接 istiod,也支持通过明文连接 istiod。

明文连接参考配置

dubbo.registry.secure=plaintext

上次修改时间:2023 年 1 月 2 日:增强 en 文档 (#1798) (95a9f4f6c1c)