背景
云原生时代,国内外众多云厂商释放了强大的技术红利。如何使用廉价、稳定、高效的云设施是当今的一大命题。在云上,我们可以轻松创建虚拟网络、虚拟机、数据库和消息队列等基础设施和中间件。我们还可以通过容器服务、EDAS、SAE、函数计算等PaaS和Serverless服务来减轻应用管控压力。.
但事情并非一帆风顺。应用上云已经成为历史上不可抗拒的趋势,但随之而来的,开发者很快意识到了云的另一面:云与云之间的网络断线带来的断网开发体验。上云前,开发者可在本地完成代码开发、测试、联调等闭环开发流程;上云后,数据库、缓存、消息队列等微服务应用部署在云上的虚拟网络中。我们无法再在本地完成开发过程。
如果是中东土豪,他可能会考虑用物理专线打通网络。因为他只需要支付数百万美元的光纤铺设费、楼内光缆租用费、端口占用费、交通费等,同时说服安保团队让环境全面开放向上。
如果是专业的运维人员,可以考虑搭建VPN打通网络。当他费尽心思搭建VPN服务器时,发现同事还是用不上,抱怨道:
看到这些问题,运维哥也觉得累了……
而现在,我们提供了一个开箱即用的插件工具,不需要您花费大量金钱或人力。只需在IDE中一键打开开关,IDE启动的应用程序就可以访问云环境中的数据库、MQ、缓存等微服务。一切都由插件为您完成。
介绍
该工具是我们开发的“端云互联”插件。并且没有传统 VPN 的问题。
端云互联功能集成在基于云的工具产品Alibaba Cloud Toolkit(ACT)中,支持Intellij IDEA和Eclipse IDE。只需在插件市场搜索“Alibaba Cloud Toolkit”即可安装,例如在Intellij IDEA中搜索如下:
我们从2018年开始端云互联项目的研发,在这个过程中,我们迭代了大大小小的版本。我们已经经历了三个里程碑,迄今为止已被数十万人使用。下面介绍一下它的特性支持和实现原理。
端云互联1.0
Phase 1.0解决了本地和云端双向互联的问题,让本地服务不仅可以访问云资源,还可以与云服务进行通信。
双向互连
以下是端云互联的核心架构,分为通道服务和代理两个模块。
其中,模块功能如下:
通道服务与代理之间的通信使用加密通道,中间人无法窃取通道中的数据。在微服务应用中,我们结合Java原生的代理参数和我们自研的流量拦截方案,将应用流量转发到通道服务。
当开发者在 IDE 中启动应用时,端云互联插件会自动拉起通道服务并将相关参数注入到应用中。启动后,应用流量自动转发到通道服务,无需人工干预。
从架构上看云集成,端云互联有点类似于VPN,分为服务器和客户端。但实际上,两者还是有很大区别的。下图对比总结:
其中,在“云访问本地”这一点上,虽然都支持,但具体原理不同。如果采用VPN方案,当其他云服务访问本地服务时,需要手动配置网络路由,否则网络不可达。通过改造微服务框架,端云互联可以让云服务调用代理机,然后通过代理机转发给本地应用,无需设置网络路由。在易用性和安全性方面,端云互联优于VPN。
端云互联2.0
在1.0阶段,我们实现了本地和云端的双向通信,满足了最基本的开发需求。在实际业务中,客户提出了更高的要求。
我们的一个客户有一个庞大的研发团队,他们都使用端云互联进行开发,但是在联调过程中发现了一个问题:研发人员A发起的服务调用有时会转移到其他节点,并且预期研发没有实现。人 B 的本地节点。这个问题是由微服务框架的路由机制造成的。当环境中的服务有多个节点时,使用随机(或轮询)算法进行调用。微服务模块越多,链接越长,问题越严重。
在2.0中,我们提供了多人精准联调的能力,可以让服务请求“调用哪里调用”,可以大大提高服务联调的效率。此外,我们还提供基于代理的远程调试能力,方便云环境下微服务节点本地调试,提高调试效率。
同时,通过横向产品支持,端云互联2.0可以服务于EDAS、SAE、MSE等云原生产品的开发者,获得广泛好评。
多人精准联调
下图描绘了多人联调的典型场景:
小王负责服务A,小张负责服务B。在一次需求迭代中,他们完成了代码开发,正在进行联调。由于微服务框架使用随机(或循环)策略进行调用,因此出现了两个问题:
通过多人精准联调的能力,只有小王发起的请求才能传输到他的本地节点和小张的本地节点,而测试小马的请求只能在云稳定环境中调用。
小王和小张需要做的比较简单。他们只需要在控制台开启全链路流控功能,即可创建流控环境进行测试。流控环境可以配置请求识别规则,通过cookies、headers、请求参数等维度判断是否为测试请求。如果判断通过,请求会被调用到环境中的节点。
然后小王和小张就可以在IDE中添加本地节点到测试环境中,如下图:
这样配置完成后,只有满足特征的请求才会调用小王和小张的节点。在下图中,只有 Header 包含“test”的请求才会被发送到它们的节点:
远程调试
远程调试一直是故障排除的重要手段,但在云原生环境下远程调试并不是一件容易的事。这是因为默认情况下,通常无法从公共网络访问云上的微服务节点。如果需要远程调试,我们需要对目标节点开放公网访问,并设置安全策略允许调试端口流量。
如果当前有 A、B、C 三个服务,每个服务有 3 个节点,那么我们需要建立 3 个安全组,将 9 个公网卡绑定到机器节点上。如下:
这种方法存在以下问题:
甚至在某些场景下,出于安全要求,内网机器节点也不允许挂载公网卡。针对这些问题,端云互联支持基于代理的远程调试,具体如下:
调试请求通过通道服务转发给代理,再由代理转发给目标调试节点。隧道服务和代理之间的隧道是加密的。对于安全要求非常严格的场景,可以通过安全组(或白名单)策略来进一步提高代理的安全级别。
在使用中,只需要配置阿里云远程调试即可。配置内容与IDE自带的远程调试配置基本一致,但支持使用代理连接,如下图:
其中有以下配置项:
云原生产品支持
端云互联2.0支持阿里云微服务领域三大产品,EDAS(企业分布式应用服务)、SAE(无服务器应用引擎)、MSE(微服务引擎)。三款产品都支持微服务治理能力,满足不同的企业需求。产品特点如下:
因此,无论您是 EDAS 用户、SAE 用户还是 MSE 用户,都可以利用端云互联能力提升云端的开发效率。在插件上,这三款产品的配置步骤基本相同,只是产品本身有所不同。配置页面如下所示:
未来,我们将支持更多云原生产品在阿里云上的互联互通,也将服务于阿里云以外的云原生开发者,敬请期待。
端云互联3.0
2.0版本解决了Java应用与云端的互联问题,很多细节也做了打磨,但缺乏对容器领域和诊断能力的支持。我们在 3.0 阶段完成了这些能力。
如果您是 Kubernetes 用户,您可以使用 3.0 插件的 Kubernetes 代理能力,无需额外配置云代理。
如果您是非Java语言用户或者对应用运行环境有一定要求,可以利用3.0插件的容器级互联能力,使用Docker在本地运行应用。在 Docker 容器中,应用可以正常访问云服务和资源,流量通过代理自动转发。
如果您对本地运行的应用程序出现调用异常感到束手无策,可以使用3.0插件的本地链路诊断能力。我们会统一收集本地应用的调用链接,调用异常一目了然。
这些特征将在下面详细描述。
Kubernetes 代理
3.0版本的Kubernetes代理能力可以基于Kubernetes集群自动开启代理通道。
在 Kubernetes 的开发中,我们可以通过 kubectl 命令和 kubeconfig 配置文件与 API Server 通信,访问集群中的容器。API Server 将对请求进行身份验证、身份验证和加密。如果开放API Server的公网访问,那么当我们通过kubectl在本地执行交互命令时,API Server会充当中间代理,如下图:
基于此特性云集成,端云互联3.0插件在应用启动时调用kubectl临时创建代理容器。通过结合 API Server 和临时代理容器,本地应用程序可以访问云服务和其他资源。整体链接如下:
代理容器占用节点内存64MB~128MB,在本地应用停止时自动删除。
插件配置也很简单,只需要设置kubeconfig配置文件,在插件中选择Kubernetes命名空间即可:
启动本地应用时,插件使用kubeconfig配置文件调用kubectl创建临时容器,进行通道开通和流量转发。该插件使用 kubeconfig 配置文件在应用程序终止时调用 kubectl 删除临时容器。
容器级互联
容器级互联意味着Docker容器会在本地启动,你的微服务应用会在容器中运行,微服务应用可以与云环境互联。如果您有以下场景,容器级互联是您的最佳选择:
该模式下,微服务应用和通道服务都使用容器运行,整体交互如下:
在实现层面,容器级互联是基于iptables拦截并转发流量到代理容器中的通道服务,通道服务通过云代理将数据转发到目标地址。在架构上,这种模式有点类似于 Service Mesh 的 Sidecar 模式。应用程序容器将流量转发到通道服务容器(sidecar 容器)。但是,端云互联的通道容器只做数据透明转发,而Service Mesh的sidecar可以进行微服务发现和治理能力,这点不一样。
在使用中,插件运行容器的阿里巴巴微服务容器配置,交互如下:
如果您在应用程序容器中运行 Java 语言应用程序,该插件还支持快速应用程序调试,而无需设置额外的特定参数。启动应用程序时,插件通过环境变量注入 JDWP 调试参数以打开调试端口。该插件进一步结合Intellij IDEA的智能检测,可以使用Attach debugger一键调试容器内的Java应用,如下图:
从图中可以看出,插件会在IDE窗口中打印容器中应用程序的日志输出。日志中的“Listening for transport dt_socket at address: 5005”表示容器中的Java应用已经打开了调试端口。点击 Attach debugger,IDE 会连接到容器中 Java 应用的调试端口,然后就可以调试代码了,如下图:
本地链路诊断
在开发过程中,你有没有遇到过这样的场景:下游服务接口返回500,你只知道接口调用失败,具体原因不明?当我让模块开发人员调查时,他过了很久才回复,“我现在有点忙,我稍后再看看”?等他有空去调查后,发现问题出在另一个模块上,让你找别的同学调查?...
这样的场景在开发过程中很常见,往往一个小问题需要花费大量的精力和时间去排查。该场景是链路跟踪技术的典型场景。现在,我们也将链路追踪集成到端云互联能力中,本地调用链路也可以上报云端,出现异常时问题一目了然。
例如,在当前环境下,存在三个服务:交易中心、商品中心、库存中心。您正在与您的测试同学一起验证新版本的功能。测试同学在页面测试下单流程时,发现下单失败,如下图:
由于涉及的模块数量众多,故障排除需要很长时间。端云互联3.0插件集成ARMS(Real-time Application Monitoring Service)的Java Agent,通过非侵入式埋藏机制收集调用链路上的信息,上报给ARMS服务器统一采集和智能分析。发生异常时,只需要在云端根据 TraceId 查询调用链接,问题一目了然:
TraceId是链接跟踪的底层概念,由前端页面生成,透明传输到下游节点。为了使用方便,插件还提供了打印本地链接的开关。开启后会输出本地应用服务调用链接的相关信息,如下图:
链接输出包含以下信息:
点击Console链接链接可以查看该请求的上下游处理链接,如下图:
我们还可以进一步查看每个服务中的处理细节:
看到这里,是不是觉得排查问题的思路又多了一些呢?:)
写在最后
云原生浪潮势不可挡,势不可挡,也是企业将业务上云的必由之路。但上云从来都不是一帆风顺的,一路上我们总会遇到一些困难和挑战。得益于云原生技术的日益成熟,这些问题必然会有相应的解决方案。
在开发领域,我们是国内云厂商中的先行者。从2018年孵化的端云互联1.0版本到现在的2021年端云互联3.0版本,遇到了大大小小的问题和挑战,但最终都被一一解决。该能力为公有云和专有云的开发者带来了极大的便利,使他们能够在本地完成开发、测试、联调的闭环。
未来,我们将继续提供更好、更强大、更易用的云原生工具来服务开发者,敬请期待。