K8S环境下研发如何本地调试?kt-connect使用详解

背景

注:背景有点啰嗦,讲讲一路走来研发本地调试的变化,嫌烦的可以直接跳过,不影响阅读。

2019年

我在的公司当时是个什么情况,只有两个Java应用,还都跑在一个Tomcat Servlet容器。



当时是如何本地调试?都是研发自己电脑装个Mysql,装个Tomcat,自己电脑运行调试,好处嘛就是后端研发互不干扰,想怎么改就怎么改,APP端研发就直连后端的笔记本调试。上线部署嘛就是一个研发手动编译个Jar包丢到云服务器上面,大体就是个草台班子,能干活,但是也就那样。

2020年

到了2020年,公司买了一台服务器,Centos的系统,给装上了Mysql、Tomcat,用上了Redis缓存,RabbitMQ消息队列,有了独立的测试环境,用上了Jenkins自动打包并部署应用,也算鸟枪换炮,起码不用自己打包了。



这个时候是如何本地调试呢?起码不用自己电脑装Mysql了,后面框架由SpringMVC和Struts2都改成Spring Boot,外置的Tomcat也可以去掉了。后端研发本地运行Spring Boot时直连服务器的Mysql进行调试,APP端再也不用连后端研发的笔记本了,有了相对稳定的调试环境。代价就是各个后端的数据库更新结构要保持兼容性,避免影响他人。

2021年

随着业务增长,后端框架由Spring Boot进化为Spring Cloud全家桶,应用运行环境由Linux直接运行改为了Docker镜像部署,各类中间件同样也使用了Docker镜像。产品线增加,单一的开发分支已经不能满足需求,为此又开辟了另外一条后端代码分支,同样的开发测试环境也多了一份。



这个时候的本地调试,对于APP端来说变化不大,区别连接后端不同环境使用不同域名而已。对于后端的研发同学就不一样了,每次本地调试自己电脑要常驻一个Eureka和一个Config Server,如果本地调试的微服务依赖比较多,没个大内存真是顶不住。

2022年

业务量继续增加,产品同事数量增加了,那个需求量真是堆积如山,两个分支已经不能满足要求了,又开了第三个分支,还是不够。每次增加新的分支运行环境,后端研发同学也很痛苦,一堆环境和第三方平台回调需要配置。为了能动态扩容缩容,Spring Cloud全家桶继续演进,抛弃了Zuul网关和Eureka,改为使用Spring Cloud Kubernetes,运行环境全面向K8S靠拢。在此期间公司又采购了一台服务器用于开发测试,内存CPU磁盘满上!



进入K8S时代,后端研发本地的电脑没办法随意连接Linux服务器上面的各种中间件,每个新分支环境里面的每个POD都是一个新的ip,也不可能像之前那样开放指定几个中间件的端口给后端连接,那么多环境每个都做设置的话,运维同学整天不用干别的事了。也由此引出了今天要说的kt-connect工具,通过这个工具,后端研发本地的电脑可以代理访问到各个分支环境,也就是K8S里面的命名空间的所有服务,并且只需要启动需要调试的服务,大大节省了电脑CPU内存占用。

选型

在选择代理访问K8S环境以便于本地调试的工具中,网上有几种。

1. 端口转发

使用Ingress、NodePort、LoadBalancer之类的将流量转发到指定端口,如上文所说,会让运维同学工作量比较大,也不便于分支环境的自动创建和回收,只适合需要暴露端口数量不多的场景。

2. VPN

通过在K8S每个命名空间里面设置一个运行有VPN服务的POD,后端研发笔记本通过VPN客户端连接代理进入到指定命名空间,可以正常访问和解析集群内各类服务,基本能满足日常的要求,缺点是每个命名空间都常驻了一个VPN服务的运行资源。

3. Telepresence

在搜索的过程中发现了这个代理工具,几乎可以说9成的中英文技术文章都推荐使用这个工具,功能非常强大,不但提供了VPN所具有的代理功能,可以访问到命名空间内所有服务,还能指定各种规则拦截指定服务的流量到本地机器,相当于本地机器也能作为一个普通的POD提供对外服务。大体设计原理如下:



在研发本地电脑执行如下命令

telepresence helm install --kubeconfig .\kubeconfig

telepresence connect ---kubeconfig .\kubeconfig

就会自动在K8S集群创建一个命名空间ambassador,并且部署一个traffic-manager的pod,用于流量管理,而在研发笔记本本地则会启动2个daemon服务,其中一个叫Root Daemon,用于建立一条双向代理通道,并管理本地电脑与K8S集群之间的流量,另外一个User Daemon则是负责与Traffic Manager通信,设置拦截规则,如果登录后还负责与Ambassador Cloud进行通信。

通过配置拦截规则,拦截的POD里面会安装一个traffic-agent,官方文档说明是类似K8S集群的sidecar模式,对注入POD进行流量劫持,所有流量出入通过traffic-manager进行重新路由。

The Traffic Agent is a sidecar container that facilitates intercepts. When an intercept is first started, the Traffic Agent container is injected into the workload's pod(s).

虽然他的功能很强大,但是在目前2.5版本的使用过程中,为了使用他的拦截和Preview Url功能必须在他家的商业云平台Ambassador Cloud进行注册登陆(注:不知道为什么网上技术文章都没提到这点,测试的时候非得要登录他家云平台),并且拦截规则的配置是通过云平台的网页进行操作的,联网的要求,包括可能存在的安全,泄露之类的隐患,我觉得是不可接受,也因此不得不放弃使用这个工具。

还有一个不得不说的缺点就是,老版本使用后可以清理掉自动创建的命名空间(namespace)和pod、拦截agent的功能(telepresence uninstall)也没了,在2.5版本的命令参数里面完全消失了,这就导致每次使用后,如果想保持环境干净,还得麻烦运维同学去清理掉,非常麻烦,简直逼死洁癖患者。

4. kt-connect

所幸开源社区又找到了另外一款类似Telepresence的工具,名为kt-connect,使用版本为v0.3.6(顺便说下我们使用的K8S版本是1.24),并且它无需联网登陆什么账号,结束命令执行默认还会自动清理。阿里出品,不确定是不是又一个KPI开源项目,但是至少这一刻我对这个工具是非常满意的。

原理

同Telepresence类似,但不同的是,kt-connect只会在指定连接的命名空间(namespace)里面新建一个自用的pod,然后部署一个kt-connect-shadow的镜像。相比Telepresence,它在模式进行了细分扩展,分为四大模式:

1. Connect模式

ktctl.exe connect --kubeconfig .\kubeconfig --namespace feature-N --debug

这个模式下,kt-connect起到的是一个类似于VPN的作用,研发本地电脑可以访问到连接的命名空间(namespace)内的所有服务,但是并没有加到集群里面其他服务里面,其他服务的流量并不会转发到本地电脑。

注1:与telepresence类似,kt-connect所有命令都要带上--kubeconfig,确保有足够权限和能正确连接K8S集群的API Server,很多文章都很少提到这点,假如K8S集群限制权限,或者与研发不在同一个网络,必须确保使用运维同学提供的有足够权限的授权文件kubeconfig来进行连接。

注2:

Failed to setup port forward local:28344 -> pod kt-connect-shadow-gseak:53 error="error upgrading connection: error sending request: Post "https://10.0.8.101:8443/api/v1/namespaces/feature-N/pods/kt-connect-shadow-gseak/portforward": dial tcp 10.0.8.101:8443: connectex: A socket operation was attempted to an unreachable host.",

如果出现以上报错的话,有可能是kt-connect路由BUG,可能本地电脑的路由与新加的通往API Server的路由有冲突,增加参数--excludeIps 10.0.8.101/32即可,如果网段冲突比较多,可以扩大网段范围,例如--excludeIps 10.0.8.0/24 参考issue-302

ktctl.exe connect --kubeconfig .\kubeconfig --namespace feature-N --excludeIps 10.0.8.101/32 --debug

2. Exchange模式

ktctl.exe exchange serviceA --kubeconfig .\kubeconfig --namespace feature-N --expose 12001 --debug

这个模式类似于Telepresence拦截模式,将指定服务的所有流量拦截下来转发到研发本地电脑的端口,使用这个模式能对环境里的访问请求直接进行调试。

具体原理就是将service里面的pod替换成一个serviceA-kt-exchange的pod。

注1:Exchange模式的流量方向是单向的,并不会将本地电脑主动发起的请求代理过去,如果K8S集群跟研发本地电脑不在一个网段内,需要另外开一个命令行运行Connect模式,确保本地服务可以正常连接K8S集群的其他服务,参考issue-216

注2:Exchange模式是通过拦截service进行流量转发,假如集群的请求没有经过service,例如直接解析到pod之类,可能就会出现拦截失败的情况(同理Mesh模式也是如此),所以出现问题记得跟运维同学确认K8S集群内的路由情况。

3. Mesh模式

kctl.exe mesh serviceA --kubeconfig .\kubeconfig --namespace feature-N --expose 12001 --debug

执行命令后可以看到输出日志里面包含类似文字:

2:30PM INF Now you can access your service by header 'VERSION: xxxxx'

这个模式本地电脑的服务和K8S集群里面相同的服务同时对外响应请求,但是只有通过指定的http请求头VERSION: xxxx的请求才会转发到本地电脑,相比Exchange模式,保证了其他人服务正常使用,同时研发又能进行本地调试。每次生成的请求头VERSION的值都是动态生成的,如果要固定这个值,可以通过参数--versionMark写死,例如固定值为test-version,命令如下:

kctl.exe mesh serviceA --kubeconfig .\kubeconfig --namespace feature-N --expose 12001 --debug --versionMark test-version

具体原理就是将serviceA里面的Pod替换成一个serviceA-kt-router的路由镜像,负责根据请求头进行流量代理转发,另外生成一个serviceA-kt-stuntman服务,这个就是线上正常运行的serviceA,还有一个serviceA-kt-mesh-xxxxx服务,这个就负责将代理流量到本地电脑。

4. Preview模式

kctl.exe preview serviceB --kubeconfig .\kubeconfig --namespace feature-N --expose 12001

不同于Exchange和Mesh模式要求K8S集群有一个在运行的服务,Preview模式可以将本地电脑运行的程序部署到K8S集群中作为一个全新的Service对外提供服务,非常便于新建服务的开发调试、预览等作用。

【原创】K8S环境下研发如何本地调试?kt-connect使用详解的更多相关文章

  1. spring-cloud-kubernetes服务发现之在k8s环境下开发spring cloud应用

    通常情况下,我们的线上的服务在迁移到k8s环境下的时候,都是采用平滑迁移的方案.服务治理与注册中心等都是采用原先的组件.比如spring cloud应用,在k8s环境下还是用原来的一套注册中心(如eu ...

  2. 在非k8s 环境下 的应用 使用 Dapr Sidekick for .NET

    在k8s 环境下,通过Operator 可以管理Dapr sidecar, 在虚拟机环境下,我们也是非常需要这样的一个管理组件,类似下图:在这张图片中,在上图左面,我们看到了"dapr.ex ...

  3. VS 2013驱动开发 + Windbg + VM双机调试(亲测+详解)

    ------------VS 2013驱动开发 + Windbg + VM双机调试(亲测+详解)------------- WIN10已上线,随之而来的是VS2015:微软在 "WDK760 ...

  4. 【转】段错误调试神器 - Core Dump详解

    from:http://www.embeddedlinux.org.cn/html/jishuzixun/201307/08-2594.html 段错误调试神器 - Core Dump详解 来源:互联 ...

  5. ios开发——实用技术OC-Swift篇&本地通知与远程通知详解

    本地通知与远程通知详解 一:本地通知   Local Notification的作用 Local Notification(本地通知) :是根据本机状态做出的通知行为,因此,凡是仅需依赖本机状态即可判 ...

  6. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  7. Cloudera CDH 、Impala本地通过Parcel安装配置详解及什么是Parcel

    本文引用自:Cloudera CDH .Impala本地通过Parcel安装配置详解及什么是Parcelhttp://www.aboutyun.com/forum.php?mod=viewthread ...

  8. Javascript 调试利器 Firebug使用详解

    Javascript 调试利器 Firebug使用详解 有时候,为了更清楚方便的查看输出信息,我们可能需要将一些调试信息进行分组输出,那么可以使用console.group来对信息进行分组,在组信息输 ...

  9. Myeclipse程序调试快捷键及步骤详解

    Myeclipse程序调试快捷键及步骤详解: 调试快捷键    Eclipse中有如下一些和运行调试相关的快捷键.    1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点.    ...

随机推荐

  1. 用Python爬取文章,并转PDF格式电子书

    wkhtmltopdf [软件],这个是必学准备好的,不然这个案例是实现不出来的 获取文章内容代码 (https://jq.qq.com/?_wv=1027&k=QgGWqAVF) 发送请求, ...

  2. 字节跳动数据平台技术揭秘:基于 ClickHouse 的复杂查询实现与优化

    更多技术交流.求职机会.试用福利,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 ClickHouse 作为目前业内主流的列式存储数据库(DBMS)之一,拥有着同类型 DBMS 难以企及 ...

  3. 详解HashMap源码解析(上)

    jdk版本:1.8 数据结构: HashMap的底层主要基于数组+链表/红黑树实现,数组优点就是查询块,HashMap通过计算hash码获取到数组的下标来查询数据.同样也可以通过hash码得到数组下标 ...

  4. java中的变量及命名

    变量 变量顾名思义就是可以变化的量 因为java是强类型语言,所以每个变量都必须声明其类型 java变量是最基本的存储单元,要素包括变量名称,变量类型和作用域. 目录 变量 1.常用的变量创建 2.变 ...

  5. 初识Java GUI

    1. 使用Java  Swing 显示的窗口如下 在原有代码基础上添加代码实现对窗口大小 标题等信息

  6. 图论学习笔记·$Floyd$ $Warshall$

    对于图论--虽然本蒟蒻也才入门--于是有了这篇学习笔记\(qwq\) 一般我们对于最短路的处理,本蒟蒻之前都是通过构建二维数组的方式然后对每两个点进行1次深度或者广度优先搜索,即一共进行\(n\)^2 ...

  7. Hippo4J v1.3.1 发布,增加 Netty 监控上报、SpringCloud Hystrix 线程池监控等特性

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info Hippo4J v1.3.1 正式发布,本次发布增加了 Netty 上传动态线程池监控数据.适配 Hystr ...

  8. 基于gitlab 15.1 pages 搭建内部博客一定行版本

    背景 基于 gitlab 15.1版 pages 搭建内部博客,参考官方文档,遇到一个又一个坑.之前看到别人吐槽说 gitlab 官方文档很差,我算是理解了.下面一个个说. 开始 按照官方文档的说法, ...

  9. Golang 盲注脚本

    Golang 盲注脚本 payload部分 其中脚本最重要的环节就是payload部分了,需要如何去闭合,如何构造SQL语句来达到判断的效果.(还有如何绕过waf等等...) bool盲注 下面是最基 ...

  10. 乘风破浪,遇见未来新能源汽车(Electric Vehicle)之特斯拉提车必须知道的十个流程

    订车 线下门店或者官网可以咨询和下单,一般来说,订金就是1000,还算可以接受. 订单账号 特斯拉账号是以邮箱为区分的,而不是手机号,我们下单的时候需要提供一个邮箱用来注册特斯拉账号. 注意了,敲黑板 ...