您的位置 首页 > 腾讯云社区

Dubbo 与 Istio 共生---啤酒云

当下,越来越多的应用迁入了容器集群。“享受着”云原生带来的便利。mesh 也越来越被广大程序员所接受。

目前,将原有应用迁入容器集群应该不是难事儿,通过 ip 直连访问,几乎毫无影响。但传统微服务应用如何和 mesh 应用共生呢?

本文探讨了一中方法,让 dubbo 和 Istio 可以共生。设想如下:

设想的架构图前提条件传统的 dubbo 应用:包含一个 provider 和一个 consumer。一个 k8s+istio 集群。部署过程部署命名空间

创建一个命名空间 dubbo,这个命名空间没有 sidecar 注入,用于放置 dubbo 传统应用。

apiVersion: v1 kind: Namespace metadata: name: dubbo spec: finalizers: - kubernetes部署 registry

使用 consul 作为注册发现服务器。本示例使用了单节点,开发模式/生产环境请自行查看官网。

需要注意的是:consul agent 默认监听的是 127.0.0.1,实际使用 Service 访问的时候,使用的是 pod 的 IP,所以需要将监听 IP 修改为 0.0.0.0。

apiVersion: apps/v1beta1 kind: Deployment metadata: name: consul namespace: dubbo labels: app: consul spec: replicas: 1 template: metadata: labels: app: consul spec: containers: - name: consul image: consul:1.7.3 args: - "agent" - "-dev" - "-client=0.0.0.0" ports: - containerPort: 8500 name: ui-port - containerPort: 8400 name: alt-port - containerPort: 53 name: udp-port - containerPort: 8443 name: https-port - containerPort: 8080 name: http-port - containerPort: 8301 name: serflan - containerPort: 8302 name: serfwan - containerPort: 8600 name: consuldns - containerPort: 8300 name: server --- apiVersion: v1 kind: Service metadata: name: consul namespace: dubbo labels: name: consul spec: ports: - name: http port: 8500 targetPort: 8500 - name: https port: 8443 targetPort: 8443 - name: rpc port: 8400 targetPort: 8400 - name: serflan-tcp protocol: "TCP" port: 8301 targetPort: 8301 - name: serflan-udp protocol: "UDP" port: 8301 targetPort: 8301 - name: serfwan-tcp protocol: "TCP" port: 8302 targetPort: 8302 - name: serfwan-udp protocol: "UDP" port: 8302 targetPort: 8302 - name: server port: 8300 targetPort: 8300 - name: consuldns port: 8600 targetPort: 8600 selector: app: consul

consul 使用了 Service 暴露服务,在 dubbo 应用中,注册中心的地址应该是:

<dubbo:registry address="consul://consul.dubbo:8500"/>部署 provider

这一步比较简单,没有sidecar。

apiVersion: apps/v1 kind: Deployment metadata: name: hello-dubbo-provider namespace: dubbo labels: app: hello-dubbo-provider version: v1 spec: replicas: 1 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:1.0.1 command: ["java","-jar","hello-dubbo-provider-fat.jar"] ports: - containerPort: 20880 protocol: TCP

查看 log,发现直接连通。

部署 consumer

首先将 consumer 部署在 dubbo 命名空间测试。

apiVersion: apps/v1 kind: Deployment metadata: name: hello-dubbo-consumer namespace: dubbo labels: app: hello-dubbo-consumer version: v1 spec: replicas: 1 selector: matchLabels: app: hello-dubbo-consumer version: v1 template: metadata: labels: app: hello-dubbo-consumer version: v1 spec: containers: - name: hello-dubbo-consumer image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-consumer:1.0.0 command: ["java","-jar","hello-dubbo-consumer-fat.jar"]

测试:直接成功。

为了让dubbo可以访问 isito 的应用,我们需要给 consumer 增加一个 sidecar。

命名空间 xyz 已经开启了 sidecar 自动注入,直接换一个命名空间部署:

... namespace: xyz ...

启动后,有错误,日志如下:

Caused by: org.apache.dubbo.remoting.RemotingException: message can not send, because channel is closed . url:dubbo://10.4.0.211:20880/tencent.demo.DemoService?anyhost=true&application=demo-consumer&check=false&codec=dubbo&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&heartbeat=60000&init=false&interface=tencent.demo.DemoService&methods=sayHello&pid=1&register.ip=10.4.0.213&release=2.7.6&remote.application=hello-dubbo-provider&revision=1.0-SNAPSHOT&side=consumer&sticky=false&timestamp=1591279149752

目标地址通道被关闭,看来是被 envoy 劫持了。

Dubbo provider 在特定的端口提供服务,寻找到不被劫持的方法:excludeOutboundPorts,excludeInboundPorts。妥了。完整的yaml文件如下:

apiVersion: apps/v1 kind: Deployment metadata: name: hello-dubbo-consumer namespace: xyz labels: app: hello-dubbo-consumer version: v1 spec: replicas: 1 selector: matchLabels: app: hello-dubbo-consumer version: v1 template: metadata: annotations: traffic.sidecar.istio.io/excludeOutboundPorts: "20880" traffic.sidecar.istio.io/excludeInboundPorts: "20880" labels: app: hello-dubbo-consumer version: v1 spec: containers: - name: hello-dubbo-consumer image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-consumer:1.0.0 command: ["java","-jar","hello-dubbo-consumer-fat.jar"]

好了,现在全通了。

最终的架构图总结

在 Istio 中,可以将 Dubbo 应用随着 sidecar 一起部署,当需要访问 dubbo 服务的时候,需要将 Envoy 劫持服务端口排除掉;当访问 mesh 的 http 服务时,只需要启动 http client 访问服务名+端口就可以了。

如此,你的 Dubbo 应用便与 istio 应用可以互通访问了。美中不足的是:服务治理并未统一。

好在咱们还有时间。骚年,抓紧把 dubbo 服务改造到 istio 中吧。

改造方法:如何将一个 Dubbo 项目改造成一个 Service Mesh 项目?

附:dubbo 应用的 fatjar 打包

在 pom.xml 中增加如下配置:

<build> <plugins> <plugin> <groupId>com.jolira</groupId> <artifactId>onejar-maven-plugin</artifactId> <version>1.4.4</version> <configuration> <mainClass>tencent.demo.provider.Provider</mainClass> <filename>${project.name}-fat.jar</filename> </configuration> <executions> <execution> <goals> <goal>one-jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ---来自腾讯云社区的---啤酒云

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: