一、kt-connect 介绍

背景

影响软件开发效率最大的问题依然是集成的问题,DevOps 通过持续交付流水线的方式不断的对软件进行集成,但是 DevOps 仍然存在很多问题,比如:

  • 开发环境崩溃
  • 改代码后部署时间过长
  • 疑难问题要多次加日志来排查

background_1

对于我们来说,问题主要是第二个,目前做开发验证有三种方式:

  1. 拷贝代码到 CD 环境,通过 kubectl patch 挂载路径执行,流程繁琐
  2. 在开发环境装 cloud ide 来调试:类似 code-server 和 theia 改造而来
  3. 提交代码后,DevOps 第二天部署好后验证,需要合并代码验证时间长

介绍

kt-connect 是阿里开源的一个工具,是轻量级的面向 k8s 用户的开发测试环境调试工具,开源地址 https://github.com/alibaba/kt-connect。工具核心功能:

  • 建立本地到集群的通道
  • 建立集群到本地的通道
  • 提升开发环节的效率问题
  • 解决开发测试环境的复用问题

introduce_1

二、kt-connect 使用流程

安装

安装 sshuttle:https://github.com/sshuttle/sshuttle

安装 kt-connect:https://github.com/alibaba/kt-connect/blob/master/docs/en-us/downloads.md

Connect 连接

Connect 建立本地到集群的 VPN 网络,同时将 Kubernetes 集群的 DNS 解析能力整合到本地,让用户可以直接通过 PodIP, ClusterIP 以及 DNS 域名访问到集群内的服务。下面以服务 ecp-dashboard-api 来做使用验证:

  • 拷贝测试环境~/.kube/config 到本地~/.kube/config

    1
    2
    
    ➜  ~ kubectl get ns | grep ems
         ems     Active   8d
    
  • sudo ktctl –debug -n ems connect

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    查看服务 ecp-dashboard-api svc ip 和 pod ip:
    [root@node-4 ~]# kubectl get svc -nems | grep ecp-dashboard-api
    ecp-dashboard-api-int  ClusterIP      10.222.235.183   <none>       80/TCP     8d
    
    [root@node-4 ~]# kubectl get -nems pods -owide| grep ecp-dashboard-api
    ecp-dashboard-api-596d5df985-fb4mj   1/1     Running   0  26h     10.232.0.240   node-5
    ecp-dashboard-api-596d5df985-qxbnp   1/1     Running   0  26h     10.232.1.184   node-6
    ecp-dashboard-api-596d5df985-s7qf4   1/1     Running   0  26h     10.232.5.91    node-4
    
    本地通过 cluster_ip/service_name/pods_id 访问:
    curl -v "http://10.222.235.183:80/ecp-dashboard-api/api/v1/product/obtains/tag-crd"
    curl -v "http://ecp-dashboard-api-int:80/ecp-dashboard-api/api/v1/product/obtains/tag-crd"
    curl -v "http://10.232.0.240:8000/ecp-dashboard-api/api/v1/product/obtains/tag-crd"
    

    能正常访问到 ecp-dashboard-api 服务:

    connect_1

  • 拷贝开发环境中,ecp-dashboard-api 的配置文件 config.toml 到本地

  • 本地 IDE 中指定启动命令和配置文件,启动 IDE 调试

  • 使用接口测试工具,请求本地启动的服务

    1
    2
    3
    
    curl -v "http://127.0.0.1:8000/ecp-dashboard-api/api/v1/product/obtains/tag-crd"
    {"code":1,"message":"cannot get token from header","data":null}
    这里返回校验出错,是业务代码中接受到请求后,校验到没有用户信息返回的
    

这种方式优点:是可以连接依赖的 k8s 集群服务,不会停掉集群的相应服务,不影响其他用户。

缺点:是依赖接口测试工具,测试稍复杂。

Exchange 连接

Exchange 命令将集群内的流量打到开发者的本地进程,通过在集群内部署代理容器,替换集群内的原有应用,并将所有对代理容器的请求直接转发到本地端口。继续以服务 ecp-dashboard-api 来做使用验证:

  • 参考 connect 流程,本地先启动 ecp-dashboard-api 调试
  • 等待以下命令成功,查看服务对应的 deploy,原有的 deploy 副本置为 0,新生成一个 ecp-dashboard-api-kt-xx 的 deploy,副本为 1,这个 deploy 对应的 pod 就是负责转发请求到本地的
    1
    
    sudo ktctl -n ems exchange ecp-dashboard-api --expose 8000,
    
    exchange_1
  • 在开发环境点击页面,请求就转发到本地了 exchage_2

这种方式优点:集群可访问本地服务,调试只需要在网页上操作即可。

缺点:是会替换掉集群的对应服务,多人调试同一个服务会阻塞,并且容易使环境崩溃。

Mesh 连接

Mesh 命令和 exchange 相似,但 exchange 命令会独占服务,导致阻塞和环境不稳定。

Mesh 则是在保持原有应用 Pod 不变的前提下,创建一个新的代理容器并且继承原应用的所有标签,但是会新增加一个随机的 version 标签。

配合 Istio 的流量规则,只转发有特殊标记的的请求到本地:

mesh_1

三、kt-connect 原理

connect 原理

通过 connect 命令日志可以看到步骤分为: theory_1

  • 在集群空间创建 shadow deploy:kt-connect-daemon-xx,暴露 22 端口

  • 建立端口转发:kubectl -n default port-forward kt-connect-daemon-xx 2222:22

  • 获取 k8s 集群的 CIDR 集合(svc ip 和 pod ip 地址范围),使用 sshuttle 捕获集群请求,并转发给 shadow pod

    1
    
    sshuttle --dns --to-ns 10.232.6.13 --verbose --ssh-cmd ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i /Users/yefeng/.ktctl/connect/kt_hmrb_id_rsa --remote root@127.0.0.1:2222 --exclude 127.0.0.1 10.232.2.0/24 10.232.3.0/24 10.232.4.0/24 10.232.5.0/24 10.232.0.0/24 10.232.1.0/24 10.232.8.0/24 10.232.7.0/24 10.232.6.0/24 10.222.0.0/16
    
  • shadow pod 将请求转发给对应的后端

    theory_2

Exchange 原理

通过 exchange 命令日志可以看到步骤分为: theory_3

  • 新增 shadow deploy,使用的 Label 和原 deploy 一样

  • 设置原服务 deploy 副本为 0

    theory_4

    从 pod 变化上也可以看到: theory_5

  • 在 Local 和 K8s 之间建立通道:kubectl -n ems port-forward ecp-dashboard-api-kt-xx 2226:22

  • ssh 远程转发,将对 shadow pod 的请求转发到本地服务的 8000 端口:

    1
    
    ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -R 8000:127.0.0.1:8000 root@127.0.0.1 -p2226 sh loop.sh
    

    theory_6

  • 注:0.2.0 版本开始,使用 shadow pod 代替 shadow deployment,exchange 不生成 deploy 了

四、使用建议

  • 在开发初期,使用 connect 验证整体流程,避免环境崩溃
  • 在开发后期,代码稳定后,使用 exchange 直接在网页测试
  • 为了环境可以多人复用,建议开发测试环境默认安装 istio,使用 mesh 来分流测试
  • 改造 kt-connect 的 exchange 命令,不替换服务而是复制请求

参考