k8s环境下,开发如何在本地联调?kt-connect详解

它的作用类似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

image.png

模式二(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对外提供服务,非常便于新建服务的开发调试、预览等作用。

你可能感兴趣的:(k8s环境下,开发如何在本地联调?kt-connect详解)