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

我需要启动多个 nodejs 容器,怎么共享这些容器的 npm 包缓存

  •  
  •   vevlins · 2023-06-12 10:26:33 +08:00 · 3989 次点击
    这是一个创建于 565 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 k8s 集群上启动多个 nodejs 容器(隔离不同用户的代码),数量高至上万个,不同容器的依赖不完全相同。npm install 阶段不在 dockerfile 中,需要在容器启动后安装。核心诉求是:1. 降低安装时间。2.降低空间占用。

    本来尝试 pnpm store ,想把 pnpm 全局缓存目录当作存储卷,启动时只需要 link 过去,但发现 k8s 不支持 link 。 有什么好办法吗?

    29 条回复    2023-06-13 13:41:50 +08:00
    star7th
        1
    star7th  
       2023-06-12 10:39:25 +08:00   ❤️ 2
    不建议共享,就建议独立搞。
    原因:
    1 ,不同容器的依赖既然不同的话,那何必花力气去共享那一部分相同依赖?
    2 ,磁盘空间不值钱,节省那边磁盘空间并不会有多少差距。至于内存消耗,你共享不共享,都一样的消耗。
    3 ,若强制共享,打破了隔离性,反而会被后面增加很多维护成本。
    yyttrr
        2
    yyttrr  
       2023-06-12 10:58:45 +08:00   ❤️ 1
    肯定要隔离,最好就扔到 dockerfile 里面自己搭建一个 npm 的包仓库,构建镜像的时候优先从自建 npm 仓库拉取
    vevlins
        3
    vevlins  
    OP
       2023-06-12 11:01:53 +08:00
    磁盘空间占用确实还不是大问题,主要是构建速度的考虑,把依赖放在 dockerfile 目前做不到,我做的是一个脚本平台,用户可以随时安装新的依赖。

    目前考虑在 init 容器中搭建一个缓存服务器,从缓存服务器安装依赖。
    pkoukk
        4
    pkoukk  
       2023-06-12 11:02:19 +08:00   ❤️ 1
    不建议共享,各种问题搞死人。而且最好用 lock 锁定依赖版本,我们这有些老项目没有 lock ,重新部署要解决一大堆兼容性问题
    dolphintwo
        5
    dolphintwo  
       2023-06-12 11:04:59 +08:00   ❤️ 1
    用 nexus3 做 npm 私有 registry
    L1shen
        6
    L1shen  
       2023-06-12 11:19:07 +08:00   ❤️ 1
    或者还有种方式,参考 web-contianer 那种,用户在前端就把代码打包完成,到你的容器的时候就可以直接运行
    zy445566
        7
    zy445566  
       2023-06-12 11:30:16 +08:00   ❤️ 1
    其实不能叫共享,但节约空间不是没有办法,你的目的其实也是节约空间是吧。
    就是打成基础镜像,把必用 npm 打进去,上层继承下层镜像复用达到节约空间目的
    Pastsong
        8
    Pastsong  
       2023-06-12 11:32:35 +08:00   ❤️ 1
    把 node_module 打在 image 里
    seki
        9
    seki  
       2023-06-12 11:40:05 +08:00   ❤️ 1
    空间占用没办法解决

    安装时间可以用一个共享的缓存或者本地 registry 来加快速度


    感觉最好的就是在创建镜像之前能打包的就打包,不能打包的二进制依赖在创建镜像时候安装
    otakustay
        10
    otakustay  
       2023-06-12 11:50:45 +08:00   ❤️ 2
    这是个 XY 问题吧,首先为什么要在启动后才安装依赖?
    qq296015668
        11
    qq296015668  
       2023-06-12 12:50:26 +08:00
    @dolphintwo
    Nexus3 确实省事
    shadeofgod
        12
    shadeofgod  
       2023-06-12 13:30:46 +08:00
    可以考虑拿 esbuild/tsup 之类的 bundle 一下,然后再去构建镜像,还可以获得一些性能增强
    dcdlove
        13
    dcdlove  
       2023-06-12 14:03:50 +08:00
    为什么不在容器里用 pnpm 替换 npm ,建立好缓存后直接打包成一个通用得 base 镜像用于其他项目使用
    codehz
        14
    codehz  
       2023-06-12 14:15:42 +08:00
    monorepo ,然后打包成 standalone 的脚本,最后放容器里(
    paledream
        15
    paledream  
       2023-06-12 14:23:20 +08:00
    可以在打包阶段处理这部分共享依赖
    xyjincan
        16
    xyjincan  
       2023-06-12 14:31:56 +08:00
    源码先打包,打包后在启动运行环境就简单了呀
    sunxiaping521
        17
    sunxiaping521  
       2023-06-12 16:39:59 +08:00
    totoro52
        18
    totoro52  
       2023-06-12 16:54:28 +08:00
    node_modules 真的能搞死人, 简直是磁盘杀手
    wangmn
        19
    wangmn  
       2023-06-12 17:10:20 +08:00
    laf.dev serverless 你试试这个开源架构
    vevlins
        20
    vevlins  
    OP
       2023-06-12 17:17:58 +08:00
    @wangmn laf 我用过,跟我的诉求不一样。
    ETiV
        21
    ETiV  
       2023-06-12 17:19:54 +08:00 via iPhone   ❤️ 1
    “npm install 不在 dockerfile” 还不听劝 😂

    有个梗图:容器化是为了解决“在我这儿好使、在对方那里打不开”的问题的…它就是把所有运行所需的依赖打包成一个镜像来达成这一目的的

    两件事:
    1⃣️
    所以你的问题是 node_modules 大,这个可以用 https://pnpm.io/motivation 瘦身一下
    2⃣️
    然后你说的构建期间 npm install 慢,这个可以缓存一下 node_modules 目录,gitlab 可以配置一个变量 避免被 clean 掉
    ETiV
        22
    ETiV  
       2023-06-12 17:32:34 +08:00 via iPhone
    哦对 docker image 还有个“层”的概念

    你可以先把最基础、都通用的 node_modules COPY 进去,这样再 build 、和 pull 都可以避免重新同步这部分文件内容
    vevlins
        23
    vevlins  
    OP
       2023-06-12 18:59:07 +08:00 via iPhone
    @ETiV 不是不听劝,我的业务要求我必须动态加依赖。
    n18255447846
        24
    n18255447846  
       2023-06-13 02:09:55 +08:00
    npm install --registry local
    建个本地源
    n18255447846
        25
    n18255447846  
       2023-06-13 02:12:16 +08:00
    或者 docker volume 挂载 node_modules 目录。没测试过多个容器能否用同一个盘,只是个想法
    whileFalse
        26
    whileFalse  
       2023-06-13 06:05:17 +08:00 via Android
    @vevlins 你还是把业务需要完整的说一下比较好
    zzl22100048
        27
    zzl22100048  
       2023-06-13 10:07:06 +08:00
    是不是要类似这种效果?
    让租户动态的导入依赖库

    https://odh-highlander.github.io/
    https://github.com/guimou/odh-highlander
    cwliang
        28
    cwliang  
       2023-06-13 11:21:34 +08:00
    可以搜一下 node.js 应用构建 image 馊身方案,比如只安装 dependencies 依赖
    cdswyda
        29
    cdswyda  
       2023-06-13 13:41:50 +08:00
    提供一个思路, 用一个 docker 做私有仓库,其他的 nodejs 镜像的 npm 安装源都指向这个,也就是所有的安装都会指向你自己的那个 docker ,所谓安装也就是一次文件拷贝。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2580 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:58 · PVG 12:58 · LAX 20:58 · JFK 23:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.