像在K8S集群中一样运行本地程序

对于使用了Kubernetes作为应用运行环境的开发者而言,在同一个集群中我们可以使用命名空间(Namespace)快速创建多套隔离环境,在相同命名空间下,服务间使用Service的内部DNS域名进行相互访问。 基于Kubernetes强大的隔离以及服务编排能力,可以实现一套定义编排(YAML)多处部署的能力。

不过,一般来说Kubernetes使用的容器网络与开发者的所在的办公网络直接并不能直接连通。 因此,如何高效的利用Kubernetes进行服务间的联调测试,成为在日常开发工作中一道绕不开的坎。本文我们就来聊一聊,如何加速基于Kubernetes的研发效率。

使用自动化流水线加速研发效率?

为了能够让开发者能够更快的将修改的代码部署到集群测试环境中,一般来说我们会引入持续交付流水线,将代码的编译,镜像的打包上传以及部署通过自动化的方式来解决。如下所示:


从一定程度上来说,这种方式可以避免开发人员进行大量重复性的工作。但是,虽然整个过程自动化了,但是开发人员也不得不每次进行代码变更之后都需要等待流水线的运行。对于开发人员来说,每次代码变更后等待流水线运行或许已经成为整个开发任务过程中体验最糟糕的部分。

像在集群中一样运行本地程序

最理想的状态是我在本地IDE中启动我的服务,然后这个服务就可以无缝的和远程的kubernetes集群中的各个其它服务实现互相调用。需要解决两个问题:

  • 我依赖了其它的服务:运行在本地的代码可以直接通过podIP,clusterIP甚至是Kubernetes集群内的DNS地址访问到部署在集群中的其它应用,如下图左;
  • 其它的服务依赖了我:运行在Kubernetes集群中的其它应用可以在不做任何改变的情况下访问我到运行的本地的代码,如下图右。

要实现刚才说的两种本地联调方式,主要需要解决以下3个问题:

  1. 本地网络与Kubernetes集群网络直接的连通问题
  2. 在本地实现Kubernetes中内部服务的DNS解析;
  3. 如果将对集群中其它Pod访问的流量转移到本地;

云效开发者工具KT

为了简化在Kubernetes下进行联调测试的复杂度,云效在SSH隧道网络的基础上并结合Kubernetes特性构建了一款面向开发者的辅助工具kt,如下所示:

当本地运行的服务C’希望能够直接访问集群中default命名空间下的Service A和Service B时,运行如下命令:

$ ktctl -namespace=default

KT会自动在集群中部署SSH/DNS代理容器,并构建本地到Kubernetes集群的VPN网络并通过DNS代理实现集群服务DNS域名解析,在运行KT之后,开发者的本地程序可以直接像运行在集群中的服务一样通过service名字调用集群中部署的其它应用:

而如果希望集群中的其它Pod(比如图中的PodD和PodE)能够通过ServiceC访问到本地运行的程序C‘,通过如下命令,指定需要替换的目标Deployment以及指定本地服务端口:

# -swap-deployment指定需要替换的目标Deployment
# -expose 指定本地服务运行的端口
ktctl -swap-deployment c-deployment -expose=8080

KT在构建VPN网络的同时,还会自动通过代理容器接管集群原有的PodC实例,并直接转发的本地的8080端口。实现集群应用联调本地。

经过上述两步的操作,就可以真正的使用云原生的方式来开发调试云原生应用了,非常酷!

工作原理

下面解析KT的工作原理,如果你已经迫不及待的想尝试KT的功能,可以直接跳到文章尾获取KT工具安装方式。

KT主要由两部分组成,

  1. 在本地运行的命令行工具ktctl
  2. 运行在集群中的SSH/DNS代理容器。

在工作原理上KT实际上是结合Kubernetes自身能力实现的一个基于SSH的VPN网络。这这部分,笔者将详细介绍云效Kubernetes开发者工具KT的工作原理:

打通SSH协议通道

在Kubernetes命令行工具kubectl中内置的port-forward命令可以帮助用户建立本地端口到Kubernetes集群中特定Pod实例端口间的网络转发。
当我们在集群中部署一个包含sshd服务的容器后,通过port-forward可以将容器的SSH服务端口映射到本地:

# 将对本地2222端口转发到kt-porxy实例的22端口
$ kubectl port-forward deployments/kt-proxy 2222:22
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

在运行端口转发后,就可以直接通过本地的2222端口通过SSH协议进入到Kubernetes集群的kt-proxy实例中。从而打通本地与集群之间的SSH网络链路。

本地动态端口转发与VPN

在打通SSH网络之后,我们就可以利用SSH通道实现本地到集群的网络请求,其中最基本的方式就是使用SSH动态端口转发的能力。
使用如下命令,通过本地2000运行的代理,可以将网络请求通过集群中运行的kt-proxy容器进行转发,从而实现本地到集群网络请求的转发:

# ssh -D [本地网卡地址:]本地端口 name@ip -p映射到kt-proxy的22端口的本地端口
ssh -D 2000 root@127.0.0.1 -p2222

在启用SSH动态端口转发后,通过设置http_proxy环境变量后,即可直接在命令行中访问集群网络:

# export http_proxy=socks5://127.0.0.1:ssh动态端口转发的代理端口
export http_proxy=socks5://127.0.0.1:2000

不过原生SSH动态端口转发也有一定的限制那就是无法直接使用UDP协议,这里我们选择了一个替代方案sshuttle. 如下命令所示:

# --dns 启动DNS协议转发
# --to-ns 指定DNS服务地址,即kt-proxy的pod ip
# -e ssh运行命令
# -r 目标ssh地址
# 其它 需要代理的网段信息
sshuttle --dns --to-ns 172.16.1.36 -e 'ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null' -r root@127.0.0.1:2222 172.16.1.0/16 172.19.1.0/16 -vv

sshuttle工具在SSH协议之上构建了一个简易的VPN网络,同时支持DNS协议转发。因此,接下来的问题就是实现一个自定义的DNS服务即可,而该服务在KT中是直接内置在KT代理镜像中。

远程端口转发

在本地到集群的链路打通之后。 接下来需要解决的就是从集群到本地的访问链路。这部分,我们会使用到SSH的远程端口转发能力,如下所示,指定所有对kt-proxy的8080端口的网络请求都会通过SSH隧道直接转发到本地的8080端口:

# ssh -R 8080:localhost:8080 root@127.0.0.1 -p2222
ssh -R 8080:localhost:8080 root@127.0.0.1 -p2222

因此,在KT的实现过程之中,结合Kubernetes基于标签的松耦合能力,我们只需要克隆原有应用实例的YAML描述,并将容器替换为kt-proxy即可。从而将对集群中原有应用的请求通过SSH远程端口转发到本地。

综上,通过利用Kubernetes原生能力以及适度的扩展,开发者可以快速在本地利用KT打破本地网络与Kubernetes网络之间的界限,大大提升使用Kubernetes进行联调测试的效率。

小结

工具承载了对特定问题的解决方案,而工程技术实践则是对其价值的放大。阿里巴巴云效平台,致力于为开发者提供一站式的企业研发与协作服务,并将阿里多年的软件工程实践以一种更加开发的形态反馈技术社区,欢迎更多的技术开发者入驻。目前对于Mac用户可以直接从:下载[](https://yuque.antfin-inc.com/aone/vb47kz/hl0lub/edit)地址 下载并体验KT工具

像在K8S集群中一样运行本地程序相关推荐

  1. K8S集群中Node节点资源不足导致Pod无法运行的故障排查思路

    K8S集群中Node节点资源不足导致Pod无法运行的故障排查思路 文章目录 K8S集群中Node节点资源不足导致Pod无法运行的故障排查思路 1.Node节点资源不足可能会产生的故障 2.Node节点 ...

  2. 如何在 Serverless K8s 集群中低成本运行 Spark 数据计算?

    作者 | 柳密 阿里巴巴阿里云智能 本文整理自<Serverless 技术公开课> 导读:本节课主要介绍如何在 Serverless Kubernetes 集群中低成本运行 Spark 数 ...

  3. K8S集群中Pod资源处于Terminating或Unknown状态排查思路

    K8S集群中Pod资源处于Terminating或Unknown状态排查思路 文章目录 K8S集群中Pod资源处于Terminating或Unknown状态排查思路 1.Pod资源处于Terminat ...

  4. K8S集群中Pod资源处于Pending状态排查思路

    K8S集群中Pod资源处于Pending状态排查思路 文章目录 K8S集群中Pod资源处于Pending状态排查思路 1.Pod资源处于Pending状态的原因 2.Pod资源处于Pending状态的 ...

  5. 终于解决 k8s 集群中部署 nodelocaldns 的问题

    终于解决 k8s 集群中部署 nodelocaldns 的问题 参考文章: (1)终于解决 k8s 集群中部署 nodelocaldns 的问题 (2)https://www.cnblogs.com/ ...

  6. K8S集群中Pod挂载Storageclass存储卷异常排查思路

    K8S集群中Pod挂载Storageclass存储卷异常排查思路 故障描述: Jenkins是在K8S集群中部署的,Jenkins使用的各种资源以及全部创建了,但是Jenkins的Pod依旧无法启动, ...

  7. K8S集群中Pod资源处于CrashLoopBackOff状态排查思路

    K8S集群中Pod资源处于CrashLoopBackOff状态排查思路 文章目录 K8S集群中Pod资源处于CrashLoopBackOff状态排查思路 1.Pod资源处于CrashLoopBackO ...

  8. K8S集群中Pod与Pod之间网络故障排查思路

    K8S集群中Pod与Pod之间网络故障排查思路 文章目录 K8S集群中Pod与Pod之间网络故障排查思路 1.Pod与Pod之间通信故障 2.Pod与Pod之间网络通信故障排查思路 1.Pod与Pod ...

  9. K8S集群中Pod资源常见的异常状态以及排查思路

    K8S集群中Pod资源常见的异常状态以及排查思路 1.Pod资源的结构 Pod资源中会有一个基础容器Pause容器,每一个Pod资源下都会有一个Pause容器,Pause容器负责创建一个虚拟网络和存储 ...

  10. K8S集群中Pod资源数据丢包排查思路

    K8S集群中Pod资源数据丢包排查思路 Pod资源可能会由于网络原因产生丢包的现象. 当Pod资源存在丢包的现象时,会出现下面的报错: Connect to 100.111.156.74 port 5 ...

最新文章

  1. 对服务器文件夹写,服务器文件夹写入权限设置
  2. 语言abline画不出线_教材中定性分析的R语言实例
  3. 利用SeekFree的核心板调试MM32F3277的ISP功能
  4. 服务器操作系统2008安装图解,IBM服务器windows2008操作系统安装步骤图文(13页)-原创力文档...
  5. 【项目管理】ITTO-采购管理
  6. 循环嵌套-使用字符串运算直接输出小星星
  7. qt怎么创建pri文件
  8. linux终端下的网页浏览器w3m
  9. HBase MapReduce实例分析
  10. 图书管理系统mysql数据库设计_简单的图书馆管理系统数据库设计
  11. 西门子PLC模块大类
  12. SRTF最短剩余时间优先调度C语言实现
  13. android iCloud 短信,云助手 基于安卓的iCloud
  14. Mac 如何彻底删除/卸载程序
  15. h5制作 php 开源,PHP源码:2019最新仿易企秀V15.1完整版开源版源码,修复采集功能、新增同行站模板采集等...
  16. Prompt learning系列之入门篇
  17. 京沪高铁全程提供WiFi无线网络技术揭密
  18. 第三章:EB配置DIO输出(s32k144)
  19. C4D阿诺德Arnold渲染器:C4DtoA mac版(支持c4d r23)
  20. tas5424_TAS5424 Datasheet(数据表) 10 Page - Texas Instruments

热门文章

  1. Android中SQLite,ContentProvider和ContentResolver的使用(一)
  2. nj04---事件回调函数
  3. Mini-project # 1 - Rock-paper-scissors-lizard-Spock
  4. poj1466二分图
  5. 我的 Python3.x 的开始-2018.8.3
  6. UNIGUI接收普通消息和被动回复用户消息
  7. C#中常见的数据结构简单介绍
  8. 491 Increasing Subsequences 递增子序列
  9. java解决中文乱码的几种写法
  10. 【新版】Android技术博客精华汇总