当K8S遇到PM2

问题描述

某个前端项目使用PM2进行node进程的管理,把该项目打包放到了docker镜像中,使用docker run命令可以正常启动。但是,把docker镜像放入K8S集群后,启动报错,[PM2][ERROR] Process failed to launch spawn E2BIG

解决方案

查阅资料发现,上面的问题,是因为环境变量过多引起的。K8S启动时会给容器注入环境变量,K8S集群中的项目数越多,环境变量也就越多。而pm2在启动时会导入系统中的环境变量,当环境变量数量过多时,就会报错[PM2][ERROR] Process failed to launch spawn E2BIG

使用env或者printenv命令查看容器中的变量,果然环境变量特别多。解决方案也就明确了:减少环境变量。

修改pm2源码

第一个解决方案是修改pm2源码,过滤掉环境变量。
编辑/usr/local/lib/node_modules/pm2/lib/Common.js,修改process.env部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function filterDockerEnv(envObj){
let keys = Object.keys(envObj);
let new_env = {};
let allowKeys = keys.filter(item => !item.startsWith("ENV_HOST_"));
allowKeys.forEach(key => {
new_env[key] = envObj[key];
});
return new_env;
}

var newEnv = filterDockerEnv(env);

// Change to double check (dropped , {pm_cwd: cwd})
app.env = [{}, newEnv, app.env || {}].reduce(function(e1, e2){
return util._extend(e1, e2);
});

清除环境变量

第二个方案是在pm2启动前清除系统中的环境变量。
正常启动命令前,先执行一段清除系统变量的脚本。

1
for i in `env | grep -E -i 'SERVICE|HOST|ADDR|PORT' | sed 's/=.*//'` ; do unset $i;done

第二种方案更加灵活,推荐使用这种方式。

书签

一次NodeJS测试集群全线瘫痪的解决思路
一次环境变量引发的血案
[PM2][ERROR] Process failed to launch spawn E2BIG

0%