事情背景

  • 公司有一个nodejs的项目,原运行在虚拟机中,现打算迁移到k8s中。在虚机中是用pm2进行管理的,迁移到k8s中的话,正常情况下是比较简单的,只是把代码放入到容器中,配置好,最后 CMD启动pm2就可以了。结果做好镜像,启动pod后发现pm2是启动了,但是node程序没有运行起来。
错误内容如下:
[PM2][ERROR] Process failed to launch spawn E2BIG

经查资料:pm2的作者回答是参数过长 下边的临时解决方法 判断可能是环境变量的问题

确认问题和排查

  • 先是进入到容器中执行env, 发现并不多,这些是一个很正常的env信息。
env内容
HOSTNAME=xxxx
SHELL=/bin/bash
TERM=xterm-256color
HISTSIZE=1000
APP_NAME=xxxxxx
LC_ALL=en_US.UTF-8
USER=root
LS_COLORS=rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:
BUSI_IP=xxx.xxx.xxx.xxx
steamer_log_stdout=True
MAIL=/var/spool/mail/root
PATH=/tools/node/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
PWD=/
TZ=Asia/Shanghai
GATEWAY=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
__STEAMER_POD_UID=xxxxxxxxx
__STEAMER_GATEWAY=
LESSOPEN=||/usr/bin/lesspipe.sh %s
__STEAMER_POD_NAME=xxxxxx
__STEAMER_POD_NAMESPACE=1--88160155
__STEAMER_APP_NAME=xxxx
__STEAMER_POD_IP=xxx.xxx.xxx.xxx
container=docker
_=/usr/bin/env
  • 手动执行pm2 start发现能够正常启动,项目一切正常,很奇怪了难道是pod启动时运行的环境变量不一样吗?更改CMD启动命令 CMD env > /var/log/env.log && pm2 start新建pod启动后查看 /var/log/env.log文件,果然问题在这里,文件有5000多行,26万的字符数! 查看其内容里面记录了所有的service的IP和端口,一时还动不了。
  • 能不能在启动时CMD只加载需要的env信息,其他的全部去除掉。经过查找可能使用env -i组装成一个可以使用的命令
#env --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Set each NAME to VALUE in the environment and run COMMAND.

Mandatory arguments to long options are mandatory for short options too.
  -i, --ignore-environment  start with an empty environment
  -0, --null           end each output line with 0 byte rather than newline
  -u, --unset=NAME     remove variable from the environment
      --help     display this help and exit
      --version  output version information and exit

A mere - implies -i.  If no COMMAND, print the resulting environment.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'env invocation'
  • 经过多次尝试总算是解决了这个问题,最终的命令
CMD env -i /bin/bash -c "export PATH=/tools/node/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin && pm2 start

需要注意的是PATH路径中一定要包含node命令,不然pm2无法启动

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐