它的作用类似VPN,能够打通k8s集群跟本地的网络。
主要有以下四种模式:
Connect:本地网络直接访问k8s集群网络
Exchange:转发集群流量到本地
Service Mesh支持:对于使用Istio的开发者,KT支持创建一个指向本地的Version版本
Preview:将本地服务注册为集群里的Service
实战开始
为了便于展示结果,首先在集群中部署一个nginx服务并创建一个默认首页:
kubectl create ns test
kubectl create deployment nginx --image=nginx:latest --port=80 -n test
deployment.apps/nginx created
kubectl expose deployment nginx --port=80 --target-port=80 -n test
service/nginx exposed
kubectl exec deployment/nginx -c nginx -n test -- /bin/bash -c 'echo kt-connect demo v1 >/usr/share/nginx/html/index.html'
查询pod和服务的ip地址
kubectl get po -n test -o wide --selector app=nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-585449566-v8p5b 1/1 Running 0 17m 10.244.169.158 k8s-node2
kubectl get svc -n test nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.109.20.133 80/TCP 60m
可知nginx实例的Pod IP为10.244.169.158 ,服务的Cluster IP为10.109.20.133,记下待用。
模式一(Connect):连接集群网络
原理
kt-connect会在指定连接的命名空间(namespace)里面新建一个自用的pod,然后部署一个kt-connect-shadow的镜像。
这个模式下,kt-connect起到的是一个类似于VPN的作用,开发本地电脑可以访问到连接的命名空间(namespace)内的所有服务,但是并没有加到集群里面其他服务里面,其他服务的流量并不会转发到本地电脑。
kt-connect所有命令都要带上--kubeconfig(k8s集群授权文件),确保有足够权限和能正确连接K8S集群的API Server。
安装kt-connect(安装到自己本地mac上)
其它系统及版本可以从这下载:
https://alibaba.github.io/kt-connect/?spm=a2c6h.12873639.article-detail.7.4eb6135dRtdL56#/zh-cn/guide/downloads
下载并安装KT(以x86 64位版本为例)
$ curl -OL https://github.com/alibaba/kt-connect/releases/download/v0.3.6/ktctl_0.3.6_MacOS_x86_64.tar.gz
$ tar zxf ktctl_0.3.6_MacOS_x86_64.tar.gz
$ mv ktctl /usr/local/bin/ktctl
$ ktctl --version
在本地mac启动服务并测试
$ sudo ktctl connect --kubeconfig ./config --namespace test
5:31PM INF Using cluster context kubernetes-admin@kubernetes (kubernetes)
5:31PM INF KtConnect 0.3.6 start at 91483 (darwin amd64)
5:31PM INF Fetching cluster time ...
5:31PM INF Using tun2socks mode
5:31PM INF Successful create config map kt-connect-shadow-jhqrg
5:31PM INF Deploying shadow pod kt-connect-shadow-jhqrg in namespace test
......
5:31PM INF Setup local DNS with upstream [tcp:127.0.0.1:20626 udp:192.168.9.200:53]
5:31PM INF Creating udp dns on port 10053
5:31PM INF ---------------------------------------------------------------
5:31PM INF All looks good, now you can access to resources in the kubernetes cluster
5:31PM INF ---------------------------------------------------------------
#这里名称空间我选择的test,因为我测试服务起在这个名称空间下
这时候去看k8s集群,会启动一个如下的pod,并且在本地也可以直接访问集群资源了
kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
kt-connect-shadow-jhqrg 1/1 Running 0 2m57s
nginx-585449566-v8p5b 1/1 Running 0 24m
#在本地mac测试访问,可以访问到集群资源
sudo curl http://10.244.169.158:80 # 在本地直接访问PodIP
kt-connect demo v1
sudo curl http://10.109.20.133:80 # 在本地访问ClusterIP
kt-connect demo v1
sudo curl http://nginx:80 # 使用作为域名访问服务
kt-connect demo v1
sudo curl http://nginx.test:80 # 使用.域名访问服务
kt-connect demo v1
sudo curl http://nginx.test.svc.cluster.local:80 # 使用集群内完整域名访问服务
kt-connect demo v1
模式二(Exchange):将集群指定服务的所有流量转向本地
原理
将指定服务的所有流量拦截下来转发到研发本地电脑的端口,使用这个模式能对环境里的访问请求直接进行调试。
在本地mac启动服务并测试
为了验证集群访问本地服务的场景,我们在本地也启动一个nginx的容器,并为其创建一个内容不同的首页。
docker run -d --name nginx -p 80:80 nginx:latest
docker exec nginx /bin/bash -c 'echo kt-connect local v2 >/usr/share/nginx/html/index.html'
使用ktctl exchange命令将先前部署到集群中的nginx服务流量全部转到本地80端口:
$ ktctl exchange nginx --kubeconfig ./config --namespace test --expose 80
5:48PM INF Using cluster context kubernetes-admin@kubernetes (kubernetes)
5:48PM INF KtConnect 0.3.6 start at 93381 (darwin amd64)
......
5:48PM INF Reverse tunnel 0.0.0.0:80 -> 127.0.0.1:80 established
5:48PM INF Service nginx unlocked
5:48PM INF ---------------------------------------------------------------
5:48PM INF Now all request to service 'nginx' will be redirected to local
5:48PM INF ---------------------------------------------------------------
然后可以发现k8s集群中新起了一个nginx-kt-exchange的pod
kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx-585449566-v8p5b 1/1 Running 0 39m
nginx-kt-exchange-hltni 1/1 Running 0 73s
测试
在集群中访问示例开始时部署到集群的nginx服务,查看输出结果:
curl http://nginx:80
kt-connect local v2
在本地访问得同时运行ktctl connect才能访问,如下:
sudo ktctl connect --kubeconfig ./config --namespace test
curl http://nginx:80
kt-connect local v2
可以看到,访问集群里nginx服务的请求被路由到了本地的nginx实例,现在就可以直接在本地调试这个服务了。
模式三(Mesh)将集群指定服务的部分流量(按Header或Label规则)转向本地
Mesh命令有两种运行模式,默认的auto模式不需要额外的服务网格组件,能够直接实现HTTP请求的自动按需路由。
$ ktctl mesh nginx --kubeconfig ./config --namespace test --expose 80
......
5:58PM INF Reverse tunnel 0.0.0.0:80 -> 127.0.0.1:80 established
5:58PM INF ---------------------------------------------------------------
5:58PM INF Now you can access your service by header 'VERSION: ztqmo'
5:58PM INF ---------------------------------------------------------------
5:58PM INF Service nginx unlocked
在命令日志的末尾,输出了一个特定的Header值。此时,直接访问集群里的tomcat服务,流量将正常进入集群的服务实例:
$ curl http://nginx:80
kt-connect demo v1
若请求包含Mesh命令输出的Header,则流量将自动被本地的服务实例接收,注意:这里在本地访问也得运行ktctl connect。
$ sudo ktctl connect --kubeconfig ./config --namespace test
$ curl -H 'VERSION: ztqmo' http://nginx:80
kt-connect local v2
这个模式本地电脑的服务和K8S集群里面相同的服务同时对外响应请求,但是只有通过指定的http请求头VERSION: xxxx的请求才会转发到本地电脑,相比Exchange模式,保证了其他人服务正常使用,同时研发又能进行本地调试。每次生成的请求头VERSION的值都是动态生成的,如果要固定这个值,可以通过参数--versionMark写死,例如固定值为test,命令如下:
ktctl mesh nginx --kubeconfig ./config --namespace test--expose 80 --versionMark test
模式四(Preview):将本地服务提供给其他开发者
kctl preview serviceB --kubeconfig .\config --namespace test --expose 80
不同于Exchange和Mesh模式要求K8S集群有一个在运行的服务,Preview模式可以将本地电脑运行的程序部署到K8S集群中作为一个全新的Service对外提供服务,非常便于新建服务的开发调试、预览等作用。