当下,越来越多的应用迁入了容器集群。“享受着”云原生带来的便利。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: consulconsul 使用了 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®ister.ip=10.4.0.213&release=2.7.6&remote.application=hello-dubbo-provider&revision=1.0-SNAPSHOT&side=consumer&sticky=false×tamp=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> ---来自腾讯云社区的---啤酒云
微信扫一扫打赏
支付宝扫一扫打赏