查看原文
其他

破解Kubernetes应用开发困局

李雪薇 ITPUB 2023-03-21

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



 本期分享嘉宾 

王炜

腾讯云CODING DevOps高级架构师

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

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


K8s环境下的开发困局

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

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

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

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

云原生开发技能广度要求急剧提升,传统应用后端需要具备JavaSpringBootRedisNginxMysql等技能。云原生应用后端需要具备JavaSpringCloudDockerPrometheusRedisNginxMysqletcdgRPCFluentd等技能。

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

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

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


主流的云原生开发方式

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

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

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

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


热加载原理


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

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

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


开发和调试演示

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

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

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

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

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

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

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

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

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


开源共建

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


规划

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

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





近期文章精选 

实时数仓是一个产品还是解决方案?

对话MySQL之父Monty:代码要写到100岁

架构师所需的硬实力与软技能


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存