nodejs前端项目部署到k8s,导致线上故障的排查与解决方法


前言

因我们的前后端项目都部署在k8s集群中,前端项目采用npm和node管理

事故背景: 某天前端同事在测试环境更新完一个前端服务后,访问正常,然后按照正常流程上线到生产环境,但是,在生产环境更新完成后,测试同事反馈访问报502错误,我就去服务器排查刚才发布的服务,检查pod状态是RUNNING状态,更新时间也是几分钟前,从表面看没有问题,由此,赶紧回滚镜像,停止上线,拉开问题排查与解决之路~


一、从测试环境开始排查

与前端同事沟通,该前端服务启动后会有一个3001端口

使用命令进入到刚才更新的pod中
	kubectl exec -it k8s-xxx-xxx-1960-0 -- /bin/bash
	netstat -lntp |grep 3001
	ps -ef

在这里插入图片描述
由上图所示,测试环境的服务启动后,有对应的端口及进程服务,因此我猜测生产环境该服务并未完全启动导致更新后报502问题

二、生产环境排查

1.复制对应服务的deployment、svc、ingress的 yaml文件,修改服务名、镜像,然后手动进行发布

2. 发布之后访问还是502,然后采用测试环境的排查方法,最终确认该服务pod启动后,对应的端口、进程都没启动,怀疑是假启动,但是pod是RUNNING的,给人造成了迷惑

3.进入到该容器中

	kubectl exec -it k8s-xxx-xxx-2360-0 -- /bin/bash
	netstat -lntp |grep 3001
	ps -ef

发现服务并未启动,也没有相关进程

4.在容器中手动执行启动命令

FROM node:12.19.0
WORKDIR /output
COPY ./output /output
EXPOSE 3001
ENV NODE_ENV=production
CMD nohup npm run start >out.log 2>&1 && tail -f out.log
根据dockerfile找到对应的启动命令,手动启动
	npm run start
	再次检查,发现服务能正常启动,且访问正常

至此,已确认问题: 生产环境502问题是因为服务启动造成的,那么具体未启动的原因是什么?请看下面描述

经过在网上查找相关问题、以及问其他前端同事,最终确认是因为pm2导致环境变量过多引起的。K8S启动时会给容器注入环境变量,K8S集群中的项目数越多,环境变量也就越多。使用PM2进行node进程的管理会在启动时会导入系统中的环境变量,当环境变量数量过多时,就会导致服务启动失败。

在这里插入图片描述

5.检查测试环境与生产环境该服务中的环境变量个数

5.1、进入测试环境该服务的容器中,执行 env |grep wc -l命令,如下图所示,总共396个环境变量,比较少

在这里插入图片描述

5.2、进入生产环境该服务的容器中,执行 env |grep wc -l命令,如下图所示,共有2594个环境变量

在这里插入图片描述

6.解决方法

方法一、

和研发确认不相干的环境变量,然后修改启动脚本,添加要取消掉的相关变量 A_BJ01|B_BJ01|EXPO_|10,如下所示 在pm2启动前清除系统中的环境变量

#!/bin/sh
cd "$(dirname $0)"/.. || exit 1
echo "$(dirname $0)"
PROC_NAME='xxx'

help(){
    echo "${0} <start|stop|restart|status>"
    exit 1
}

status(){
    wcx=`ps -eo "command" | grep PM2 | wc -l`
    if [ $wcx == 1 ]; then
        status="offline"
    else
        status="online"
    fi
    echo $status
    if [ X"$status" == X"online" ]; then
        return 0
    else
        return 1
    fi
}

start(){
#修改A_BJ01|B_BJ01|EXPO_|10此处变量即可
    for i in `env | grep -E -i 'A_BJ01|B_BJ01|EXPO_|10' | sed 's/=.*//'` ; do
       unset $i
    done
    NODE_ENV=production
    pm2 start
    sleep 3
    status
}

请根据自己环境中的变量进行修改,不可直接粘贴使用
让研发同事将该脚本上传到对应的代码仓库,重新进行CICD操作,然后检查对应的服务端口和进程以及环境变量,发现启动成功,完美解决问题。

方法二、

在报错服务的deployment.spec.template.spec模块下添加如下内容,其中enableServiceLinks 表示是否将 Service 的相关信息注入到 Pod 的环境变量中,默认是 true:
enableServiceLinks: false


总结

以上就是今天要分享的内容,也是第一次遇到这个问题,主要是不熟悉前端node和pm2,解决方法也是网上找方案及问同事,不过最终还是有用。在解决完上线问题后,前端同事本地调试pm2,打印打console.log,也发现是环境变量参数的长度异常,最终定位是process.env会获取操作系统的所有变量,造成process.env多达70000以上字节长度。占了99%的process.env长度,并且皆为无用变量。因此,为了避免生产和测试环境再次出现该问题,对每个服务都进行了环境变量的筛选,通过脚本的方式在pm2启动前进行没用的环境变量清理,确保后续服务发版顺利!!!

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,可用于构建高性能的网络应用程序。Node.js前端项目源码主要是指使用Node.js作为后端服务器,配合前端技术(如HTML、CSS、JavaScript)构建的项目源代码。 Node.js前端项目源码通常包括以下几个方面: 1. 后端逻辑:Node.js可以用于编写后端逻辑,处理客户端请求、与数据库交互、进行业务逻辑处理等。在项目源码中会包含后端逻辑的代码,如路由定义、数据处理、用户认证等。 2. 前端资源管理:Node.js也可以用作静态资源服务器,托管前端静态资源(如HTML、CSS、JavaScript文件)。前端项目源码中会包含前端资源的配置和管理,如页面模板的引入、静态资源的打包压缩等。 3. 数据库交互:很多Node.js前端项目会涉及数据库的操作,比如MySQL、MongoDB等。在项目源码中会包含数据库连接、数据查询、数据修改等相关代码。 4. 异步处理:Node.js以事件驱动的方式进行处理,对于异步操作的处理方式会在项目源码中有所体现,如回调函数、Promise、async/await等。 5. 接口定义:Node.js前端项目通常会定义接口供前端调用,项目源码中会包含接口定义和实现部分。 总的来说,Node.js前端项目源码是一种综合利用Node.js后端能力和前端技术进行项目开发的代码,它涵盖了项目的整体架构、后端逻辑、前端资源管理、数据库交互和接口定义等方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值