前言
因我們的前后端項(xiàng)目都部署在k8s集群中,前端項(xiàng)目采用npm和node管理
事故背景: 某天前端同事在測(cè)試環(huán)境更新完一個(gè)前端服務(wù)后,訪問(wèn)正常,然后按照正常流程上線到生產(chǎn)環(huán)境,但是,在生產(chǎn)環(huán)境更新完成后,測(cè)試同事反饋訪問(wèn)報(bào)502錯(cuò)誤,我就去服務(wù)器排查剛才發(fā)布的服務(wù),檢查pod狀態(tài)是RUNNING狀態(tài),更新時(shí)間也是幾分鐘前,從表面看沒(méi)有問(wèn)題,由此,趕緊回滾鏡像,停止上線,拉開(kāi)問(wèn)題排查與解決之路~
一、從測(cè)試環(huán)境開(kāi)始排查
與前端同事溝通,該前端服務(wù)啟動(dòng)后會(huì)有一個(gè)3001端口
使用命令進(jìn)入到剛才更新的pod中
kubectl exec -it k8s-xxx-xxx-1960-0 -- /bin/bash
netstat -lntp |grep 3001
ps -ef
由上圖所示,測(cè)試環(huán)境的服務(wù)啟動(dòng)后,有對(duì)應(yīng)的端口及進(jìn)程服務(wù),因此我猜測(cè)生產(chǎn)環(huán)境該服務(wù)并未完全啟動(dòng)導(dǎo)致更新后報(bào)502問(wèn)題
二、生產(chǎn)環(huán)境排查
1.復(fù)制對(duì)應(yīng)服務(wù)的deployment、svc、ingress的 yaml文件,修改服務(wù)名、鏡像,然后手動(dòng)進(jìn)行發(fā)布
2. 發(fā)布之后訪問(wèn)還是502,然后采用測(cè)試環(huán)境的排查方法,最終確認(rèn)該服務(wù)pod啟動(dòng)后,對(duì)應(yīng)的端口、進(jìn)程都沒(méi)啟動(dòng),懷疑是假啟動(dòng),但是pod是RUNNING的,給人造成了迷惑
3.進(jìn)入到該容器中
kubectl exec -it k8s-xxx-xxx-2360-0 -- /bin/bash
netstat -lntp |grep 3001
ps -ef
發(fā)現(xiàn)服務(wù)并未啟動(dòng),也沒(méi)有相關(guān)進(jìn)程
4.在容器中手動(dòng)執(zhí)行啟動(dòng)命令
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
根據(jù)dockerfile找到對(duì)應(yīng)的啟動(dòng)命令,手動(dòng)啟動(dòng)
npm run start
再次檢查,發(fā)現(xiàn)服務(wù)能正常啟動(dòng),且訪問(wèn)正常
至此,已確認(rèn)問(wèn)題: 生產(chǎn)環(huán)境502問(wèn)題是因?yàn)榉?wù)啟動(dòng)造成的,那么具體未啟動(dòng)的原因是什么?請(qǐng)看下面描述
經(jīng)過(guò)在網(wǎng)上查找相關(guān)問(wèn)題、以及問(wèn)其他前端同事,最終確認(rèn)是因?yàn)閜m2導(dǎo)致環(huán)境變量過(guò)多引起的。K8S啟動(dòng)時(shí)會(huì)給容器注入環(huán)境變量,K8S集群中的項(xiàng)目數(shù)越多,環(huán)境變量也就越多。使用PM2進(jìn)行node進(jìn)程的管理會(huì)在啟動(dòng)時(shí)會(huì)導(dǎo)入系統(tǒng)中的環(huán)境變量,當(dāng)環(huán)境變量數(shù)量過(guò)多時(shí),就會(huì)導(dǎo)致服務(wù)啟動(dòng)失敗。
5.檢查測(cè)試環(huán)境與生產(chǎn)環(huán)境該服務(wù)中的環(huán)境變量個(gè)數(shù)
5.1、進(jìn)入測(cè)試環(huán)境該服務(wù)的容器中,執(zhí)行 env |grep wc -l
命令,如下圖所示,總共396個(gè)環(huán)境變量,比較少
5.2、進(jìn)入生產(chǎn)環(huán)境該服務(wù)的容器中,執(zhí)行 env |grep wc -l
命令,如下圖所示,共有2594個(gè)環(huán)境變量
6.解決方法
方法一、
和研發(fā)確認(rèn)不相干的環(huán)境變量,然后修改啟動(dòng)腳本,添加要取消掉的相關(guān)變量 A_BJ01|B_BJ01|EXPO_|10,如下所示 在pm2啟動(dòng)前清除系統(tǒng)中的環(huán)境變量
#!/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
}
請(qǐng)根據(jù)自己環(huán)境中的變量進(jìn)行修改,不可直接粘貼使用
讓研發(fā)同事將該腳本上傳到對(duì)應(yīng)的代碼倉(cāng)庫(kù),重新進(jìn)行CICD操作,然后檢查對(duì)應(yīng)的服務(wù)端口和進(jìn)程以及環(huán)境變量,發(fā)現(xiàn)啟動(dòng)成功,完美解決問(wèn)題。
方法二、
在報(bào)錯(cuò)服務(wù)的deployment.spec.template.spec模塊下添加如下內(nèi)容,其中enableServiceLinks 表示是否將 Service 的相關(guān)信息注入到 Pod 的環(huán)境變量中,默認(rèn)是 true:enableServiceLinks: false
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-782412.html
總結(jié)
以上就是今天要分享的內(nèi)容,也是第一次遇到這個(gè)問(wèn)題,主要是不熟悉前端node和pm2,解決方法也是網(wǎng)上找方案及問(wèn)同事,不過(guò)最終還是有用。在解決完上線問(wèn)題后,前端同事本地調(diào)試pm2
,打印打console.log
,也發(fā)現(xiàn)是環(huán)境變量參數(shù)的長(zhǎng)度異常,最終定位是process.env
會(huì)獲取操作系統(tǒng)的所有變量,造成process.env多達(dá)70000以上字節(jié)長(zhǎng)度。占了99%的process.env長(zhǎng)度,并且皆為無(wú)用變量。因此,為了避免生產(chǎn)和測(cè)試環(huán)境再次出現(xiàn)該問(wèn)題,對(duì)每個(gè)服務(wù)都進(jìn)行了環(huán)境變量的篩選,通過(guò)腳本的方式在pm2啟動(dòng)前進(jìn)行沒(méi)用的環(huán)境變量清理,確保后續(xù)服務(wù)發(fā)版順利!!!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-782412.html
到了這里,關(guān)于nodejs前端項(xiàng)目部署到k8s,導(dǎo)致線上故障的排查與解決方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!