Dubbo3实践:Proxyless + Istio

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Proxyless 模式是指 Dubbo 直接与 Istiod 通信,通过 xDS 协议实现服务发现和服务治理等能力。本示例中将通过一个简单的示例来演示如何使用 Proxyless 模式。[示例地址](https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-xds)## 代码架构本小节中主要介绍本文所使用的示

Proxyless 模式是指 Dubbo 直接与 Istiod 通信,通过 xDS 协议实现服务发现和服务治理等能力。
本示例中将通过一个简单的示例来演示如何使用 Proxyless 模式。

示例地址

代码架构

本小节中主要介绍本文所使用的示例的代码架构,通过模仿本示例中的相关配置改造已有的项目代码可以使已有的项目快速跑在 Proxyless Mesh 模式下。

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("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);
    }
}

4. 服务端配置

服务端配置注册中心为 istio 的地址,协议为 xds。

我们建议将 protocol 配置为 tri 协议(全面兼容 grpc 协议),以获得在 istio 体系下更好的体验。

为了使 Kubernetes 感知到应用的状态,需要配置 qosAcceptForeignIp 参数,以便 Kubernetes 可以获得正确的应用状态,对齐生命周期。

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

快速开始

Step 1: 搭建 Kubernetes 环境

目前 Dubbo 仅支持在 Kubernetes 环境下的 Mesh 部署,所以在运行启动本示例前需要先搭建 Kubernetes 环境。

搭建参考文档:

minikube(https://kubernetes.io/zh-cn/docs/tutorials/hello-minikube/)

kubeadm(https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/)

k3s(https://k3s.io/)

Step 2: 搭建 Istio 环境

搭建 Istio 环境参考文档:

Istio 安装文档(https://istio.io/latest/docs/setup/getting-started/)

注:安装 Istio 的时候需要开启 first-party-jwt 支持(使用 istioctl 工具安装的时候加上 --set values.global.jwtPolicy=first-party-jwt 参数),否则将导致客户端认证失败的问题。

附安装命令参考:

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: 拉取代码并构建

git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/dubbo-samples-xds
mvn clean package -DskipTests

Step 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 ../

Step 5: 创建namespace

# 初始化命名空间
kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-samples/master/dubbo-samples-xds/deploy/Namespace.yml

# 切换命名空间
kubens dubbo-demo

Step 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 ../../../../../

查看 consumer 的日志可以观察到如下的日志:

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 认证,所以需要配置 jwtPolicyfirst-party-jwt

  1. providedBy

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

  1. protocol name

Proxyless 模式下应用级服务发现通过 Kubernetes Native Service 来进行应用服务发现,而由于 istio 的限制,目前只支持 http 协议和 grpc 协议的流量拦截转发,所以 Kubernetes Service 在配置的时候需要指定 spec.ports.name 属性为 http 或者 grpc 开头。
因此我们建议使用 triple 协议(完全兼容 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 probe 探活机制的工作原理限制,探活请求的发起方不是 localhost,所以需要配置 qosAcceptForeignIp 参数开启允许全局访问。

dubbo.application.qosAcceptForeignIp=true

注:qos 端口存在危险命令,请先评估网络的安全性。即使 qos 不开放也仅影响 Kubernetes 无法获取 Dubbo 的生命周期状态。

  1. 不需要开启注入

Proxyless 模式下 pod 不需要再开启 envoy 注入,请确认 namespace 中没有 istio-injection=enabled 的标签。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
XML Dubbo Java
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
155 0
|
Kubernetes Dubbo 应用服务中间件
Dubbo3实践:基于 API-SERVER 的原生 K8S Service
> 该示例演示了直接以 API-SERVER 为注册中心,将 Dubbo 应用部署到 Kubernetes 并复用 Kubernetes Native Service 的使用示例。 > > 此示例的局限在于需要授予每个 Dubbo 应用访问 API-SERVER 特定资源的权限,同时直接访问和监听 API-SERVER 对中小集群来说并没有什么问题,但对于较大规模集群而言可能给 API-SERV
528 0
|
6月前
|
负载均衡 监控 Dubbo
从理论到实践:Dubbo 的 `<dubbo:service>` 与 `<dubbo:reference>` 全面指南
从理论到实践:Dubbo 的 `<dubbo:service>` 与 `<dubbo:reference>` 全面指南
139 0
|
6月前
|
监控 负载均衡 Dubbo
分布式架构与Dubbo基础入门与实践
分布式架构与Dubbo基础入门与实践
63 1
|
监控 Dubbo Cloud Native
Apache Dubbo 云原生可观测性的探索与实践
Apache Dubbo 云原生可观测性的探索与实践
116883 11
|
运维 Dubbo 安全
政采云基于 Dubbo 的混合云数据跨网实践
政采云基于 Dubbo 的混合云数据跨网实践
1192 7
|
Dubbo Java 应用服务中间件
开源微服务如何选型?Spring Cloud、Dubbo、gRPC、Istio 详细对比
开源微服务如何选型?Spring Cloud、Dubbo、gRPC、Istio 详细对比
1092 7
|
存储 运维 监控
Apache Dubbo 云原生可观测性的探索与实践
Apache Dubbo 已接入指标、链路、日志等多维度观测能力,助力云原生实践,本文将介绍 Dubbo 可观测性的探索与实践。
Apache Dubbo 云原生可观测性的探索与实践
|
Kubernetes Dubbo 应用服务中间件
GitHub标星35k+微服务深度原理实践进阶PDF,竟让阿里换下了Dubbo
最近一个粉丝分享了他悲惨的阿里面试故事,好不容易冲进三面,最后凉了! 关键在于微服务部分没回答好。 本人自己说在看到这些面试真题之后人都是懵的,之前这方面也没有很重视,结局就很可惜了。 今天先结合我这个粉丝的经历和面的题,分析一下微服务,以及我在这方面的学习经验也给大家分享一下。
|
Dubbo Java 应用服务中间件
Dubbo 与 gRPC、Spring Cloud、Istio 的关系
Dubbo 与 gRPC、Spring Cloud、Istio 的关系
143 1