转载至我的博客 www.infrastack.cn/?p=88 ,公众号:架构成长指南
在我们系统部署到 k8s 以后,开发测试模式也会有一定变化,下面是一些常见的问题,如果处理不好,直接影响我们的效率
- 本地服务如何访问k8s里面的服务进行功能测试?
- 本地如何快速访问集群中资源,比如访问某个微服务的 swagger?
- 如何把集群里面流量转发到本地服务,进行功能测试?
- 如何临时快速部署一个服务到 k8s 里面进行功能验证?
以上问题,我相信大多数开发者都会遇到过,而且常用的方式应该是把服务部署到 k8s中在进行测试,这种方式虽然简单,但是效率很低,因为我们的系统还在单元测试,遇到的bug会比较多,每次改动都要重新发布,时间都花费在系统打包部署上面了
下面推荐一个阿里开源的k8s 工具,它可以帮助我们解决以上问题
KtConnect介绍
KtConnect(Kt为Kubernetes Toolkit集群工具包的简写)由阿里开源,是一款基于Kubernetes环境用于提高本地测试联调效率的小工具,它提供了本地和测试环境集群的双向互联能力
特性
Connect
:建立数据代理通道,实现本地服务直接访问Kubernetes集群内网(包括Pod IP和Service域名)Exchange
:让集群服务流量重定向到本地,实现快速验证本地版本和调试排查问题Mesh
:创建路由规则重定向特定流量,实现多人协作场景下互不影响的本地调试Preview
:暴露本地服务到集群,实现无需发布即可在线预览集成效果
快速体验
在这篇文档里,使用一个简单的示例,来快速演示通过KtConnect完成本地直接访问集群中的服务、以及将集群中指定服务的请求转发到本地的过程。
安装
shell
brew install kt-connect
部署实例应用
为了便于展示结果,首先在集群中部署一个Tomcat服务并创建一个默认首页:
shell
kubectl create deployment tomcat --image=tomcat:9 --port=8080
kubectl expose deployment tomcat --port=8080 --target-port=8080
kubectl exec deployment/tomcat -c tomcat -- /bin/bash -c 'mkdir webapps/ROOT; echo "hello world v1" > webapps/ROOT/index.html'
查询Pod和服务的IP地址:
shell
kubectl get pod -o wide --selector app=tomcat
kubectl get svc tomcat
可知Tomcat实例的Pod IP为172.18.25.22
,服务的Cluster IP为192.168.220.59
,记下待用。
连接集群网络
使用ktctl connect
命令建立从本地到集群的网络通道,注意该命令需要管理员权限。
shell
sudo ktctl connect
本地访问集群资源
输出以上日志以后,就可以在本地直接访问集群资源了,可通过浏览器或curl
命令来验证:
shell
# 在本地直接访问PodIP
curl http://172.18.25.22:8080
#在本地访问ClusterIP
curl http://192.168.220.59:8080
#使用<service>作为域名访问服务
curl http://tomcat:8080
#使用<servicename>.<namespace>域名访问服务
curl http://tomcat.default:8080
# 使用集群内完整域名访问服务
curl http://tomcat.default.svc.cluster.local:8080
将集群流量转发到本地
为了验证集群访问本地服务的场景,我们在本地也启动一个Tomcat的容器,并为其创建一个内容不同的首页。
shell
docker run -d --name tomcat -p 8080:8080 tomcat:9
docker exec tomcat /bin/bash -c 'mkdir webapps/ROOT; echo "hello world local v2" > webapps/ROOT/index.html'
KtConnect提供了两种能够让集群流量重定向到本地服务的命令,使用场景上稍有不同。
- Exchange:将集群指定服务的所有流量转向本地
- Mesh:将集群指定服务的部分流量(按Header或Label规则)转向本地
Exchange命令
将k8s集群里访问指定服务的所有请求拦截并转发到本地的指定端口上。通常用于调试在测试环境里,当前服务未部署到 k8s 集群,又想快速验证的场景
使用ktctl exchange
命令将先前部署到集群中的tomcat
服务流量全部转到本地8080
端口:
shell
ktctl exchange tomcat --expose 8080
在本地或者集群中访问示例开始时部署到集群的tomcat
服务,查看输出结果:
如果未运行
ktctl connect
,只能从k8s集群内访问
arduino
curl http://tomcat:8080
可以看到,访问集群里tomcat
服务的请求转发到了本地的Tomcat实例
如果我们微服务部署在 K8s 中还是使用的eureka或者 nacos,这种方式可能不支持,因为这种方式是服务消费方直接调用的服务提供方的 pod ip 地址
Mesh命令
将集群里访问指定服务的部分请求拦截并转发到本地的指定端口。通常用于团队协作时,需要定向调试调用链中间位置的服务,又不希望影响其他开发者正常使用测试环境的场景。
Mesh命令,能够直接实现HTTP请求的自动按需路由,为了便于验证结果,先停止ktctl exchange
命令。然后通过ktctl mesh
命令创建代理Pod:
shell
ktctl mesh tomcat --expose 8080
查看以上红色标记部分,输出了一个特定的Header值。此时,直接访问集群里的tomcat
服务,流量将正常进入集群的服务实例,若请求包含Mesh命令输出的Header,则会转发流量到本地服务实例
shell
curl http://tomcat:8080
curl -H 'VERSION: feo3x' http://tomcat:8080
实际测试中可以使用ModHeader插件,在浏览器发起http中自动追加自定义 header
将本地服务提供给其他开发者
在开发过程中,也可以利用KtConnect将本地服务快速"部署"到集群,变成一个临时的服务,供其他开发者或集群中的其他服务临时使用。
- Preview:将本地服务注册为集群里的Service
- Forward:将集群服务映射到本地,结合Preview命令可实现开发者之间跨主机使用Localhost地址互访
Preview命令
将本地运行的服务实例注册到集群上。主要用于将本地开发中的服务提供给其他开发者进行联调和预览。
下面使用ktctl preview
命令将运行在本地8080
端口的服务注册到测试集群,命名为tomcat-v2
。
css
ktctl preview tomcat-v2 --expose 8080
注册成功以后,集群里的服务就可以通过tomcat-v2
名称来访问本地注册的服务实例了
其他开发者也可以在执行ktctl connect
后,直接通过tomcat-v2
服务名称来预览该服务的实时情况:
Forward命令
将任意IP或集群中的服务映射到本地的指定端口。用于在测试时,使用localhost
地址便捷的访问集群中的特定IP或服务,典型场景是是访问其他开发者通过Preview命令注册的本地服务。
如上图当开发者A运行了前述的Preview命令后,开发者B可以使用ktctl forward
命令将它映射到自己本地的9090
端口,然后进行调用
shell
ktctl forward tomcat-v2 9090:8080
执行完以上命令后,开发者就可以访问localhsot:9090
执行
是不是感觉forward命令与kubectl port-forward
命令相似,其实这块只是额外增加了断网自动重连的能力。