对于使用Kubernetes作为应用运行环境的开发者,我们可以使用命名空间(Namespace)在同一个集群中快速创建多个隔离环境,同一个下namespace,服务之间使用Service内部的DNS域名进行访问。基于Kubernetes强大的隔离和服务编排能力,可以在多处部署一套定义编排(YAML)。但是,一般来说,Kubernetes使用的容器网络是不能直连开发者办公网络的。因此,如何高效地利用Kubernetes进行服务间的联调测试,成为了日常开发工作中绕不开的一道坎。这篇文章,我们来谈谈如何基于Kubernetes来加速研发效率。使用自动流水线为了让开发者更快的将修改后的代码部署到集群测试环境中,一般来说,我们会引入持续交付流水线,以自动化的方式解决代码编译、镜像打包上传、部署。如下图:这种方式在一定程度上可以避免开发人员做大量的重复性工作。然而,虽然整个过程是自动化的,但开发人员也必须在每次代码更改后等待管道运行。对于开发人员来说,每次代码更改后等待管道运行可能成为整个开发任务中最糟糕的部分。突破网络限制,本地联调的理想状态是开发者可以直接在本地启动服务,并且这个服务可以和远程kubernetes集群中的其他服务无缝调用。需要解决两个问题:我依赖其他服务:本地运行的代码可以通过podIP、clusterIP甚至Kubernetes集群中的DNS地址直接访问集群中部署的其他应用,如下图左侧;otherservicesdependenon对我而言:Kubernetes集群中运行的其他应用无需任何改动即可访问我本地的代码,如下图右侧所示。要实现刚才提到的两种本地联调方式,需要解决以下三个问题:本地网络与Kubernetes集群网络直连在本地实现Kubernetes内部服务的DNS解析;流量转移到本地;云效开发者工具KT为了简化Kubernetes下联调测试的复杂度,云效构建了一个免费的面向开发者的辅助工具KT(点击下载),如下图:当本地运行的服务C'希望直接访问集群中default命名空间下的ServiceA和ServiceB,运行如下命令:$ktctl-namespace=defaultKT会在集群中自动部署SSH/DNS代理容器,搭建本地到Kubernetes的虚拟专用网络集群,通过DNS代理实现集群服务DNS域名解析。运行KT后,开发者的本地程序可以像运行在集群中的服务一样,直接通过服务名调用集群中部署的其他应用:如果想让集群中的其他Pod(如图中的PodD和PodE)能够通过ServiceC访问本地运行的程序C',使用如下命令指定要替换的目标Deployment并指定本地Service端口:#-swap-deployment指定需要替换的目标Deployment#-expose指定端口其中本地服务运行ktctl-swap-deploymentc-deployment-expose=8080KT在搭建虚拟专用网的同时会通过代理容器自动接管集群原PodC实例直接转发本地8080端口实现集群应用联调本地。通过以上两条命令,开发者可以真正使用云原生的方式在Kubernetes中开发和调试应用。工作原理下面解释一下KT的工作原理。如果你迫不及待想尝试KT的功能,可以直接去下载KT工具。KT主要由两部分组成:运行在本地的命令行工具ktctl和运行在集群中的SSH/DNS代理容器。从工作原理上来说,KT其实是一个基于SSH的网络结合Kubernetes自身的能力实现的。在这一部分,笔者将详细介绍云效Kubernetes开发者工具KT的工作原理:开启SSH协议通道。Kubernetes命令行工具kubectl中内置的port-forward命令可以帮助用户建立本地端口到Kubernetes集群中的特定Pod实例端口。之间的网络转发。当我们在集群中部署一个包含sshd服务的容器时,可以通过port-forward将容器的SSH服务端口映射到本地:#Forwardthelocal2222porttothe22portofthekt-porxyinstance$kubectlport-forwarddeployments/kt-proxy2222:22Forwardingfrom127.0.0.1:8080->8080Forwardingfrom[::1]:8080->8080运行端口转发后,可以通过本地2222端口直接进入Kubernetes集群的kt-proxy实例SSH协议。为了打通本地和集群之间的SSH网络链接。本地动态端口转发SSH网络开通后,我们就可以使用SSH通道实现本地到集群的网络请求。最基本的方法是使用SSH动态端口转发的能力。使用如下命令,通过运行在集群中的kt-proxy容器通过运行在本地2000上的代理转发网络请求,从而实现网络请求从本地到集群的转发:#ssh-D[本地网卡地址:]本地端口名@ip-p映射到kt-proxy的22端口的本地端口ssh-D2000root@127.0.0.1-p2222。开启SSH动态端口转发后,可以通过设置http_proxy环境变量在命令行中直接访问集群网络:#exporthttp_proxy=socks5://127.0.0.1:ssh动态端口转发的代理端口exporthttp_proxy=socks5://127.0.0.1:2000但是原生的SSH动态端口转发也有一定的局限性,就是不能直接使用UDP协议,这里我们选择替代方案sshuttle。显示以下命令:#exporthttp_proxy=socks5://127.0.0.1:ssh动态端口转发的代理端口exporthttp_proxy=socks5://127.0.0.1:2000sshuttle--dns--to-ns172.16.1.36-e'ssh-oStrictHostKeyChecking=no-oUserKnownHostsFile=/dev/null'-rroot@127.0.0.1:2222172.16.1.0/16172.19.1.0/16-vvsshuttle工具在SSH协议之上构建一个简单的虚拟专用网络,同时支持DNS协议转发.因此,接下来的问题就是实现一个自定义的DNS服务,在KT中直接内置到KT代理镜像中。本地到集群的链路建立后,进行远程端口转发。接下来需要解决的是集群到本地的访问链路。在这一部分,我们将使用SSH的远程端口转发能力,如下图,指定所有对kt-proxy8080端口的网络请求都将通过SSH隧道直接转发到本地8080端口:#ssh-R8080:localhost:8080root@127.0.0.1-p2222ssh-R8080:localhost:8080root@127.0.0.1-p2222因此,在KT的实现中,结合Kubernetes的label-based松耦合能力,我们只需要克隆YAML描述即可原始应用程序实例,只需将容器替换为kt-proxy。这样集群中原有应用的请求通过SSH远程端口转发到本地。综上所述,利用Kubernetes的原生能力和适度扩展,开发者可以在本地快速使用KT,打破本地网络和Kubernetes网络的界限,大大提高使用Kubernetes进行联调和测试的效率。总结工具承载着针对具体问题的解决方案,工程技术实践是其价值的放大。阿里巴巴云效平台致力于为开发者提供一站式的企业研发与协同服务,将阿里巴巴多年的软件工程实践以更加发达的形式回馈给技术社区。欢迎更多技术开发者入驻。
