V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Moonkin
V2EX  ›  程序员

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

  •  1
     
  •   Moonkin · 340 天前 · 4520 次点击
    这是一个创建于 340 天前的主题,其中的信息可能已经有所发展或是发生改变。
    要求:
    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 ,不能拒绝。
    34 条回复    2023-12-18 00:22:28 +08:00
    Chad0000
        1
    Chad0000  
       340 天前
    目前我们的项目不是微服务,是单体应用。但我自创轮子,在搞混合开发,方案如下:

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

    最大的好处是可以无缝迁移现有单体应用。我现在本地 Debug 还是按单体的风格来(当然也可以不用)。
    zhenjiachen
        2
    zhenjiachen  
       340 天前
    单元测试加 mock
    balancircle
        3
    balancircle  
       340 天前
    alibaba KtConnect
    StoneHuLu
        4
    StoneHuLu  
       340 天前
    我们不是微服务,就是开发和测试环境内网打通,开发机本机运行能直接调用测试环境数据库和 api
    lazyfighter
        5
    lazyfighter  
       340 天前
    开发测试环境打通, 中间件依赖 Nodeport 导出 我现在是这么干的
    Moonkin
        6
    Moonkin  
    OP
       340 天前
    @Chad0000 这是部署在 k8s 中吗?环境概念包括开发依赖工具吗,比如编译工具
    Moonkin
        7
    Moonkin  
    OP
       340 天前
    看了下似乎 mesh 就有我说的这个测试标识的功能。但是 KtConnect 似乎要在本地调试,,
    Moonkin
        8
    Moonkin  
    OP
       340 天前
    @StoneHuLu
    @lazyfighter
    本地和线上环境打通是很爽。。
    serialt
        9
    serialt  
       340 天前
    OP 说的是 okteto ?
    Chad0000
        10
    Chad0000  
       340 天前   ❤️ 1
    @Moonkin #6

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

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

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

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

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

    代码里更不能写死生产相关的配置,应该用 nacos 或者环境变量或者最次也得用 spring 配合 profile 做配置切分呀。
    perfectlife
        20
    perfectlife  
       340 天前
    我们是本地和开发环境通过 vpn 打通,可以远程 debug, 日常都是提交代码自动构建发到 dev/test/uat 环境。痛点是如果单纯的只是本地启动服务想访问 k8s 集群里的服务好弄,麻烦的是你本地启动一个服务 a ,线上同时也启动了一个服务 a ,都注册上去了,别的服务调用这个服务 a 就会比较恶心,另外本地启动的服务默认注册上去的 ip 会是你的本地 ip ,不是 vpn 分配的 ip ,别的服务访问这个 ip 还失败,还需要修改配置文件来指定 ip
    zicheqingluo
        21
    zicheqingluo  
       340 天前
    劫持下 svc 的解析到测试环境即可
    julyclyde
        22
    julyclyde  
       340 天前
    其实是两件事:
    1 服务注册和发现是否正常
    2 各微服务之间通信是否正常
    victorc
        23
    victorc  
       340 天前
    1.你要学会看日志,每年都要纠正校招生单步调试的坏毛病

    2.都用上了微服务,设计上应该做到低耦合高聚合,其实不太需要调试,基本上就是一些 typo 错误
    datoujiejie221
        24
    datoujiejie221  
       340 天前
    你这相当于本地调试加了个灰度,我们是 springcloud+nacos 的方案,网关根据 nacos 注册的标识来分流。
    buffzty
        25
    buffzty  
       340 天前
    部署个 wireguard 本地可以直接用 pod ip ,serviceid ,集群 dns .cluster.local 在本地和在容器内没有任何区别
    还有 node port 这种东西最好别开
    youngPacce
        26
    youngPacce  
       340 天前 via Android
    你想在生产 debug ?阻塞用户的请求怎么办?
    lozzow
        27
    lozzow  
       340 天前
    直接再集群中开发,vscode remote 然后修改 service 就行,无痛无依赖
    tudou1514
        28
    tudou1514  
       340 天前
    看完,是不是理解为你们想给开发张三固定一个 pod 作为“服务器”?如果这样不建议你们 k8s ,直接虚拟化吧
    wzcloud
        29
    wzcloud  
       340 天前 via iPhone
    telepresent 或者 nocalhost 可以打通本地和集群网络
    sampeng
        30
    sampeng  
       340 天前 via iPhone
    有个东西叫 vpn……

    再说了,我 64G 内存。本地起全套轻轻松松。啊哈哈哈哈
    ihacku
        31
    ihacku  
       340 天前 via Android
    CCIEliu
        33
    CCIEliu  
       338 天前
    nocalhost
    uianz
        34
    uianz  
       338 天前
    我是连 vpn 之前查到可以加一个配置 然后用完整的 servicename(<servicename>.<namespace>.svc.<clusterdomain>)调用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5642 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 03:26 · PVG 11:26 · LAX 19:26 · JFK 22:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.