k8s 微服务这种环境,最佳的开发调试方案是什么

2023-12-15 12:53:18 +08:00
 Moonkin
要求:
1.开发完的代码不能在本地部署运行,应当在 k8sj 集群中(这样服务的出流量都不需要做任何改变,本机不需要配置 k8s 的 rbac 等)
2.由于 1 ,最好是远程调试,比如 go dlv 。
3.不能有生成镜像的步骤(每次调试都要生成镜像太浪费时间)
4.不能影响线上用户,支持多人开发。识别测试请求,进入测试服务

我当前的设想是这样:
假设名字是 dev1 的老铁要开发名字是 mysvc 的服务
1.dev1-pod 是 dev1 老铁的开发机,在 k8s 集群中运行,老铁在本地开发完代码,在开发机 git pull ,make ,./run 。
2.dev1 老铁有一个 yaml ,里面是 mysvc-dev1 service 和 dev1-pod pod ,这个 service 指向这个 pod ,selector 用 dev1 就行。部署这个 yaml
3.服务 mysvc 在接收到请求后,第一步是识别特定测试标识 dev1 (比如 http header ),转发到 mysvc+标识=mysvcdev1 服务,所有服务代码都这样写。(转发功能只需要本服务名字拼接标识,当作目标服务,k8s 的 dns 可以直接解析)

但是这个设想有明显的缺点:
1.开发机不能 mount 根目录 / ,只能/home ,/var/http ,这样,也就是说开发机如果重启,通过 apt-get 安装的工具可能会丢。。
2.根据所开发的服务名字不同,mysvc-dev1 这个 service 也需要改名字,这本身不是痛点,但是 rbac 需要让所有服务都接受这类 service ,不能拒绝。
4582 次点击
所在节点    程序员
34 条回复
Chad0000
2023-12-15 13:04:11 +08:00
目前我们的项目不是微服务,是单体应用。但我自创轮子,在搞混合开发,方案如下:

- 所有服务都完全独立
- 服务分两部分:一个用来定义(接口和参数),一个用来实现
- 搞出环境概念,环境中有各种服务的地址无需配置
- 有必要的话,服务也可以在本地启动(直接跟你的项目一起,而不是独立的 Pod 中)
- 这样本地调试的时候只需要加入开发环境,引用相应的服务定义项目即可
- 实际部署的时候一组服务可以部署在一起,或按需要分开部署
- 这样所有服务部署在一起,就还是单体;每个服务都独立部署就是微服务;按调用频率分组部署,就是混合;

最大的好处是可以无缝迁移现有单体应用。我现在本地 Debug 还是按单体的风格来(当然也可以不用)。
zhenjiachen
2023-12-15 13:08:39 +08:00
单元测试加 mock
balancircle
2023-12-15 13:40:24 +08:00
alibaba KtConnect
StoneHuLu
2023-12-15 13:42:31 +08:00
我们不是微服务,就是开发和测试环境内网打通,开发机本机运行能直接调用测试环境数据库和 api
lazyfighter
2023-12-15 14:06:12 +08:00
开发测试环境打通, 中间件依赖 Nodeport 导出 我现在是这么干的
Moonkin
2023-12-15 14:24:34 +08:00
@Chad0000 这是部署在 k8s 中吗?环境概念包括开发依赖工具吗,比如编译工具
Moonkin
2023-12-15 14:26:48 +08:00
看了下似乎 mesh 就有我说的这个测试标识的功能。但是 KtConnect 似乎要在本地调试,,
Moonkin
2023-12-15 14:27:36 +08:00
@StoneHuLu
@lazyfighter
本地和线上环境打通是很爽。。
serialt
2023-12-15 15:00:27 +08:00
OP 说的是 okteto ?
Chad0000
2023-12-15 15:04:51 +08:00
@Moonkin #6

我自己的项目是部署在 K3S 中,公司的并没有。公司的是屎山单体,我在用我的方式改造而已。

环境的意思就是服务的运行环境,比如.net 中那可能就是 asp.net core 。服务最终编译成 dll ,由运行环境动态加载(或直接依赖)。然后这个运行环境可向注册中心注册暴露调用地址。你本地起一个任意项目(可以是 Console )作为本地运行环境,你可以引用所有需要的服务对应的接口,可以直接写代码调用接口背后的实现。你的本地运行环境会负责将请求发给对应的接口运行环境。或你本地如果有这个接口的实现,那么就会直接在本地调用。通过这种设计我实现了服务可以在任何地方运行,可以调用任意服务,也可以被任意服务调用。如下面这个图:

Chad0000
2023-12-15 15:08:37 +08:00
本质就是运行环境负责将服务运行起来,然后拦截本地服务对其他服务的调用请求(伪依赖注入),如果目标服务在本地,则直接调用本地的服务,如果不在本地,则在注册中心会找到目标服务的地址,发起远程调用(一般 HTTP ,也可以是基于消息的 RPC )。
StoneHuLu
2023-12-15 15:43:39 +08:00
@Moonkin #8 我理解是如果测试环境和开发环境不打通,那开发效率也太慢了。。而且就数据库之类的咋整,难道每个开发自己搞一个数据库吗,我们是测试环境和开发环境打通,开发人员和测试人员都在这个环境进行开发和测试,有问题直接本机打断点调试,基本都能迅速百分百复现问题,然后测试完毕上预发布环境再测一遍,这里如果产生问题就得靠日志解决了,最后才是生产环境。
ghos
2023-12-15 16:06:30 +08:00
alibaba KtConnect +1
xuanbg
2023-12-15 16:10:24 +08:00
不太明白题主的各种条件,反正我们有个开发环境,IDEA 直接开调试模式就能打断点调试,方便得很。
Masoud2023
2023-12-15 16:14:53 +08:00
正常项目就应该能在本地跑,只能进环境测试其实是一种非常烂的开发流程。
Moonkin
2023-12-15 16:21:23 +08:00
@serialt 基本一样。。它这个 dev environment 的概述也是用的容器,如果在容器中用 apt-get 装了什么,重启大概也会丢。。
Moonkin
2023-12-15 16:24:05 +08:00
@Masoud2023 换个角度,,如果你有几个 vps ,在上面搞了一些网站,还有数据库,redis ,本地开发要想访问只能通过公网 ip 的形式。但是这些 vps 直接可以内网 ip 访问,代码也应该写内网域名。本地很难接入吧。
litchinn
2023-12-15 16:34:03 +08:00
我看你不是自己提到了 go dlv 这种线上 debug 工具吗,不让用吗
Masoud2023
2023-12-15 16:37:03 +08:00
@Moonkin #17

所以才要做分生产测试 uat+环境隔离+配置管理啊。

本地开发人员就不应该碰到生产环境内容。

代码里更不能写死生产相关的配置,应该用 nacos 或者环境变量或者最次也得用 spring 配合 profile 做配置切分呀。
perfectlife
2023-12-15 16:44:11 +08:00
我们是本地和开发环境通过 vpn 打通,可以远程 debug, 日常都是提交代码自动构建发到 dev/test/uat 环境。痛点是如果单纯的只是本地启动服务想访问 k8s 集群里的服务好弄,麻烦的是你本地启动一个服务 a ,线上同时也启动了一个服务 a ,都注册上去了,别的服务调用这个服务 a 就会比较恶心,另外本地启动的服务默认注册上去的 ip 会是你的本地 ip ,不是 vpn 分配的 ip ,别的服务访问这个 ip 还失败,还需要修改配置文件来指定 ip

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1000654

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX