云计算·大数据 频道

破解Kubernetes应用开发困局

如果您的开发环境是Minikube或自建/云K8s集群,开发的对象是微服务应用,自定义Controller或Operator,并且正在面临编码/调试/测试循环慢的问题。通过本文,您将收获如何借助开源工具实现在Kubernetes环境下更加高效的开发循环反馈,以及解密开源工具Nocalhost的全新用法和核心原理。

▲腾讯云CODING高级架构师 王炜

嘉宾介绍:王炜,腾讯云CODING DevOps高级架构师。CNCF大使,曾任腾讯云大学、腾讯云原生技术开放日、腾讯Live开发者大会、Techo开发者大会、QECon等大会讲师,中国电子技术标准化研究院木兰开源社区导师。主导 Nocalhost——云原生开发工具:https://github.com/nocalhost/nocalhost,并著有《Spinnaker 实战:云原生多云环境的持续部署方案》。

以下是王炜老师在SACC2022大会的演讲实录:

一、K8s环境下的开发困局

对于传统的开发过程来说,大部分开发处于一个单体应用的架构。随着单体应用越来越复杂,很多团队会发现,单体应用已经不能很好地嵌合公司的业务发展需要,也不能很好地在公司现有组织架构的责任划分中承担迭代作用。

此时,越来越来的公司会把单体应用选择拆分为微服务。由微服务组成的应用之后,微服务之间的运行以及它所需要的环境有很大的差异。微服务可能由不同的团队负责研发,团队里面采用的语言是多样性的。

微服务依赖、打包、运行、迁移越来越难,Docker提供镜像打包的解决方案。容器越来越多,服务编排、发现、稳定性监控、自愈等成为新的挑战。Kubernetes提供容器编排的解决方案。

在运维方面,开发难、概念繁多,声明式定义学习成本高;调试难,无法像本地一样调试,开发效率低。完全面向运维提供能力,对开发增加了巨大的负担。云原生环境下的学习成本,招聘成本,用人成本急剧上升。

云原生开发技能广度要求急剧提升,传统应用后端需要具备Java、SpringBoot、Redis、Nginx、Mysql等技能。云原生应用后端需要具备Java、SpringCloud、Docker、Prometheus、Redis、Nginx、Mysql、etcd、gRPC、Fluentd等技能。

这张图是CNCF基金会的云原生全景图,里面有数百个项目。其中的技术栈是非常复杂的,每家公司用的技术栈都不太一样,所以对于开发同学来讲,不仅开发和调试变得很难,而且需要学习的东西也变得非常多。

在基于K8s环境下去做开发的时候,第一,开发同学缺少背景知识。第二,K8s和容器本身给他带来一些开发和调试的问题。这就导致一个普通的开发同学在云原生的环境下,做开发是极其困难的。

除此之外,CNCF官方在云原生开发工具方面,提供一些项目来解决我们的开发问题。对于开发环节,CNCF官方以及社区仍然缺少标准化的实践。总而言之,云原生开发工具依然缺失,目前社区没有非常好的解决方案。

二、主流的云原生开发方式

关于主流的云原生开发方式,可以分为四个过程:全手工流程,业务应用采用了K8s,本地编码之后,手动构建镜像,并且推送到镜像仓库,修改工作负载镜像版本,等待K8s重新调度;自动化CI/CD流程,编码后,推送到代码仓库,自动触发CI/CD流程,等待生效。

Minikube+Telepresence,Minikube拉起本地K8s开发环境,Telepresence实现本地编码。云环境+Telepresence,云上K8s集群提供计算资源解决弹性能的问题,Telepresence本地编码。

本地环境和容器、工作负载声明有很大的差异,导致业务源码很难在本地运行。

一是环境差异,工作负载声明了 env、configmap、secret、volume 等,很难在本地复制出 完全一致的环境。 二是跨平台差异,即便是能够将远端的env、configmap挂载到本地,也难以屏蔽跨平台之间的差异。三是网络限制,全量代理的方式会使得网络拓扑产生变化,导致内网、公网访问无法达到预期。

三、热加载原理

如何实现容器热加载?从Dockerfile说起,Dockerfile CMD或ENTRYPOINT定义容器启动命令,只需要运行自己编译的二进制文件,对应容器PID=1的进程。如果将二进制文件替换为源码运行的方式,那么就实现了容器的热加载。

事实上,实现容器热加载还缺少三个基本的条件:1、源码从哪来?2、Golang Runtime从哪来?3、PID=1的进程替换成源码运行,如果进程停止,容器将Crash,怎么阻止?

对此,从本地同步到容器;将业务容器的镜像替换为Runtime镜像;替换PID=1 进程为阻塞进程:/bin/sh -c tail -f /dev/null。

四、开发和调试演示

根据Nocalhost使用角色来分类的话,对于基础设施团队来讲,可以采用Server端,高度集中管理开发环境、开发者、应用、开发集群等开发资源,实现开发者间环境隔离。使用前提是已定义“应用”,具备重部能力,例如Manifest、Helm、 Kustomize。

对于开发者来讲,直接提供的能力是IDE插件,在开发过程无需重新构建镜像,本地编码实时生效,缩短开发-调试-测试的循环反馈,提高开发和调试效率。使用前提是集群内已有工作负载即可进行开发。

管理人员的诉求是统一管理微服务应用包,降低应用的维护成本;统一管理开发环境和集群,提高集群资源的利用率,同时具备隔离特性;为新员工快速分配开发环境,分配环境后立刻能进行应用开发;弹性的开发环境资源,用完销毁、降低开发成本。

Nocalhost Server隔离开发环境,并且统一管理开发资源。为开发创建基于NS隔离的开发环境,开发者可使用管理员预定义的应用随时拉起开发环境。统一管理开发者、集群、开发环境、应用,配合IDE插件使用。

IDE插件支持VSCode和Jetbrains全系列插件,支持两种开发方式,具备容器热加载和一键Debug功能。本地编码实时生效,无需重新构建镜像。便捷的一键调试功能和一键Run,屏蔽新人使用复杂度。

替换容器镜像为开发镜像,提供语言编译和运行环境。继承configmap、env、volume挂载等配置,这是源码在容器里运行的核心基础。此外,替换容器PID=1的进程为阻塞进程,防止容器Crash。增加文件同步的Sidecar,实现本地和容器源码同步。在IDE内自动获取远端容器Terminal,方便启停进程。

在开发环境的使用过程中,有一个常见的差异是很多团队会共用开发环境的概念,来管理自己的开发环境。在这种模式下,不适合直接替换掉某一个Service,将它进入开发模式里,因为这会破坏开发环境,影响到其他人的开发。

那么,对于共用开发环境的用法,Nocalhost提供Duplicate开发模式,又称为复制开发模式。它不会直接替换掉Service,而是会先复制一个出来。

在隔离开发环境,也就是说开发环境是个人独享的。这种情况下就可以用Replace开发模式,直接替换某个工作负载,这是最简单的一个方式,可以实现所见即所得的开发体验。

五、开源共建

目前,Nocalhost已经在Github上面全部开源,包括插件端和Server端,且免费使用,有大概1100个Star左右。最近,我们把Nocalhost捐赠给CNCF,成为CNCF的SANDBOX项目。所以,Nocalhost是一个公共的项目,不会有厂商绑定的问题,以及长时间不维护的问题。

六、规划

Nocalhost整个产品里面会做一些长远的规划。比如说,VCluster虚拟集群、开发空间休眠、虚拟隔离开发空间。社区有一种技术叫做VCluster,可以基于父亲K8s集群虚拟出n个子K8s集群。

对于非工作时间,Nocalhost可以实现开发空间自动进行休眠,直接把工作负载的副本数缩为零,从而让它不占用你的计算资源。虚拟隔离开发环境,可以将其理解为Service Mesh开发环境的增强。

0
相关文章