前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >0 改造迁移 Dubbo 到 Istio

0 改造迁移 Dubbo 到 Istio

原创
作者头像
谢正伟
发布2020-07-15 17:13:28
1.6K0
发布2020-07-15 17:13:28
举报
文章被收录于专栏:泛互云原生

本文试验了一种方法,不修改 dubbo 的代码,只通过部署的方式将 Dubbo 应用部署到 Istio 中,并实现 Istio 集群中的实例与集群外的实例相互调用,和谐共存。

下面是这种方法的架构图:

架构图
架构图

从图中可以看出,所有的 Dubbo 应用注册都注册到了 zk 中,并可以实现集群内外的互访。在集群内部,通过 接口和服务名的映射实现集群内的互访。

其中的关键点是,Istio 集群内 Dubbo 应用启动的时候,指定一个接口和服务名的映射关系文件:

代码语言:txt
复制
java –jar -Ddubbo.resolve.file=services.properties app-fat.jar

并且,这个参数映射的优先级高于其他的配置方法。

下面是这一实验过程:

传统 dubbo 应用部署

先上代码为敬,也可以跳过代码看关键点:

代码语言:txt
复制
# 创建命名空间,无 sidecar 注入
apiVersion: v1
kind: Namespace
metadata:
  name: dubbo
spec:
  finalizers:
    - kubernetes

---
# 在 dubbo 中部署 zk
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: zk
  namespace: dubbo
  labels:
    app: zk
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: zk
    spec:
      containers:
        - name: zk
          image: zookeeper:3.6.1
          ports:
            - containerPort: 2181
              name: client
---
# 通过 service 连接 zk
apiVersion: v1
kind: Service
metadata:
  name: zk
  namespace: dubbo
  labels:
    name: zk
spec:
  ports:
  - name: client
    port: 2181
    targetPort: 2181
  selector:
    app: zk
---
# 在 dubbo 中的 provider
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-provider
  namespace: dubbo
  labels:
    app: hello-dubbo-provider
    version: v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-dubbo-provider
      version: v1
  template:
    metadata:
      labels:
        app: hello-dubbo-provider
        version: v1
    spec:
      containers:
        - name: hello-dubbo-provider
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-provider:2.0.1
          command: ["java","-jar","hello-dubbo-provider-fat.jar"]
          env:
            - name: ns
              value: "dubbo"
          ports:
            - containerPort: 20880
              protocol: TCP

---
# 部署 hello-dubbo-consumer, 没有 sidecar
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-consumer
  namespace: dubbo
  labels:
    app: hello-dubbo-consumer
    version: v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-dubbo-consumer
      version: v1
  template:
    metadata:
      labels:
        app: hello-dubbo-consumer
        version: v1
    spec:
      restartPolicy: Always
      containers:
        - name: hello-dubbo-consumer
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-consumer:1.0.4
          command: ["java","-jar","hello-dubbo-consumer-fat.jar"]
          ports:
            - containerPort: 20880
              protocol: TCP

上面的文件部署了一个普通的 K8S 命名空间,未指定 sidecar 注入。部署了 zk,provider 和 consumer,也可以使用虚拟部署(腾讯云TKE 打通了 pod 网络 和 node 网络)。部署后,直接可以调用。

在 Istio 中部署

继续上代码先,建议跳过代码看关键:

代码语言:txt
复制
# 创建命名空间,有 sidecar 注入
apiVersion: v1
kind: Namespace
metadata:
  name: dubbo-mesh
  labels:
    istio-injection: enabled
spec:
  finalizers:
    - kubernetes


---
# hello-dubbo-provider 服务
apiVersion: v1
kind: Service
metadata:
  name: hello-dubbo-provider
  namespace: dubbo-mesh
  labels:
    name: hello-dubbo-provider
spec:
  ports:
  - name: dubbo-rpc
    protocol: TCP
    port: 20880
    targetPort: 20880
  selector:
    app: hello-dubbo-provider

---
# 部署 hello-dubbo-provider 应用,有sidecar
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-provider
  namespace: dubbo-mesh
  labels:
    app: hello-dubbo-provider
    version: v1-mesh
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-dubbo-provider
      version: v1-mesh
  template:
    metadata:
      labels:
        app: hello-dubbo-provider
        version: v1-mesh
    spec:
      containers:
        - name: hello-dubbo-provider
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-provider:2.0.1
          command: ["java","-jar","hello-dubbo-provider-fat.jar"]
          env:
            - name: ns
              value: "dubbo-mesh"
          ports:
            - containerPort: 20880
              protocol: TCP

---
# 动态配置,将接口和服务的映射放入 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: services-list
  namespace: dubbo-mesh
data:
  services: |-
    tencent.demo.DemoService=dubbo://hello-dubbo-provider:20880
---
# 部署 hello-dubbo-consumer, 有 sidecar
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-consumer
  namespace: dubbo-mesh
  labels:
    app: hello-dubbo-consumer
    version: v1-mesh
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-dubbo-consumer
      version: v1-mesh
  template:
    metadata:
      labels:
        app: hello-dubbo-consumer
        version: v1-mesh
    spec:
      restartPolicy: Always
      containers:
        - name: hello-dubbo-consumer
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-consumer:1.0.4
          command: ["java","-jar","-Ddubbo.resolve.file=services.properties", "hello-dubbo-consumer-fat.jar"]
          volumeMounts:
            - name: services-conf
              mountPath: /app/services.properties
              subPath: services.properties
      volumes:
          - name: services-conf
            configMap:
              name: services-list
              items:
                - key: services
                  path: services.properties

上面的部署代码:

  • 部署了一个自动注入 sidecar 的命名空间:dubbo-mesh。
  • 部署了 Consumer 和 Provider,使用了同样的镜像。
  • 将 services.properties 的信息写入了 ConfigMap 中,并通过 volumes 映射文件到程序工作目录。
  • 在启动脚本中加入参数 -Ddubbo.resolve.file=services.properties。

现在 Istio 集群中的 consumer 调用 tencent.demo.DemoService 接口的时候,就会使用集群内的服务名:hello-dubbo-provider 了。

调用结果

下面是调用结果:

在dubbo集群中的 Consumer 日志:

代码语言:txt
复制
2020-07-15T08:34:07.033484467Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.0.93
2020-07-15T08:34:12.034650941Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.0.93
2020-07-15T08:34:17.04025799Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.1.14
2020-07-15T08:34:22.041549659Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.1.14
2020-07-15T08:34:27.04354781Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.67
2020-07-15T08:34:32.044685931Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.0.94
2020-07-15T08:34:37.045901507Z 你好:哈哈, V2 来自 dubbo 空间 @ 172.24.1.143

所有的 Provider 实例都被调用到了。

在 dubbo-mesh 中的 Consumer 的日志:

代码语言:txt
复制
2020-07-15T08:42:59.733141083Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.5
2020-07-15T08:43:04.735234844Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.5
2020-07-15T08:43:09.737490538Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.5
2020-07-15T08:43:14.740803604Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.5
2020-07-15T08:43:19.743157701Z 你好:哈哈, V2 来自 dubbo-mesh 空间 @ 172.24.2.5

集群内的应用通过服务名调用,只能调用到集群内的 Provider。

但在去掉 services.properties 映射后,Istio 集群内 和 集群外 的 Consumer 展现了同样的日志信息。

More

在上面的 Isito 集群中,Consumer 访问外部的应用的时候,存在出的流量,并且经过了 envoy 劫持,在 Dubbo 场景下,需要将 global.outboundTrafficPolicy.mode 设置为 ALLOW_ANY,或者创建 ServiceEntry 策略。

但由于流出集群的 outbound 流量被 Envoy 劫持感觉“毫无意义”,可以考虑使用策略将出流量绕过 envoy 以提高效率,如下:

代码语言:txt
复制
#...
  template:
    metadata:
      annotations:
        traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.0.50.0/24,172.24.2.0/24,172.24.1.0/24,172.24.0.0/24"
 #...

程序代码可参考:

https://github.com/cloudbeer/dubbo-mesh-demo

其中的两个部署文件分别位于 deploy/d-dubbo.yaml, deploy/d-mesh.yaml。

总结

使用上述方法,我们可以在不修改代码的情况下,完美地将 Dubbo 应用部署到 Istio 集群,并且可以不影响业务,慢慢迁移,迁移一个应用,就在 services.properties 中加入 接口和服务映射。

但实际环境的 Dubbo 的迁移仍然是一件比较复杂的过程,需要经过大量测试验证才能确保最终成果。

同学们,加油!


参考:

dubbo 直连提供者: http://dubbo.apache.org/zh-cn/docs/user/demos/explicit-target.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 传统 dubbo 应用部署
  • 在 Istio 中部署
  • 调用结果
  • More
  • 总结
相关产品与服务
服务网格
服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档