一.問題描述
近期遇到k8s環境中一個pod無法正常啟動,啟動報錯,[PM2][ERROR] Process failed to launch spawn E2BIG
。
二.問題分析
2.1.了解報錯相關知識
查閱資料發現,上面的問題,是因為環境變量過多引起的。K8S啟動時會給容器注入環境變量,K8S集群中的項目數越多,環境變量也就越多。而pm2在啟動時會導入系統中的環境變量,當環境變量數量過多時,就會報錯[PM2][ERROR] Process failed to launch spawn E2BIG。
2.2.確定變量數量閾值
使用env或者printenv命令查看容器中的變量,果然環境變量特別多有。
但為何內部環境未復現,然后對比客戶和內部環境:
客戶環境故障pod中:env |wc輸出有2111個;
內部環境正常pod中:env |wc輸出有1853個;
然后嘗試給內部環境正常pod對應values.yaml注入自定義隨機環境變量用於增加pod環境變量數目,發現當此pod中環境變量為 2050左右 會出現[PM2][ERROR] Process failed to launch spawn E2BIG異常。
2.3.確定具體原因
1.將客戶故障pod的env打印到error.txt后取出;
2.將內部正常pod的env打印后info.txt后取出;
3.對比環境變量;
對比error.txt和info.txt兩個文件內容中環境變量的key,發現error.txt中多了506個GET_JS*服務相關變量相關變量:
4.確定GET_NODEJS* 環境變量來源
既然pod環境變量是在同一namespace中是疊加的,那他應該屬於某個pod,進行pod過濾后過果然發現大量get_yaohong的pod服務,
5.確定get_nodejs服務有效性
和業務咨詢此問題后了解到此服務在客戶正常使用的版本中已經廢棄。
文檔鏈接:https://www.cnblogs.com/yaohong/p/16002922.html
三.解決方案
3.1.方案1-清理無效pod
在第二章中提到了找到了引起環境變量增加500多個的服務,然后刪掉此服務的相關資源:
#kubectl get svc |grep get_yaohong |awk '{print $1}' |xargs kubectl delete svc #kubectl get deployment |grep get_yaohong|awk '{print $1}' |xargs kubectl delete deployment
3.2.方案2-修改pm2源碼
修改pm2源碼,過濾掉環境變量。
編輯/usr/local/lib/node_modules/pm2/lib/Common.js,修改process.env部分。
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); });
3.3.方案3-清除環境變量
第三個方案是在pm2啟動前清除系統中的環境變量。
正常啟動命令前,先執行一段清除系統變量的腳本。
for i in `env | grep -E -i 'SERVICE|HOST|ADDR|PORT' | sed 's/=.*//'` ; do unset $i;done
3.4.方案4-修改k8s資源
在報錯服務的deployment.spec.template.spec模塊下添加如下內容,其中enableServiceLinks 表示是否將 Service 的相關信息注入到 Pod 的環境變量中,默認是 true:
enableServiceLinks: false
文檔鏈接:https://www.cnblogs.com/yaohong/p/16002922.html