「Bug」Jenkins Slaveカートンとゾンビプロセス

2333 ワード

問題の説明
問題が発生したのは私たちの主Jenkins Slaveで、Ubuntu仮想マシンの中で、Dockerを使って4つの異なる環境のJenkins Slaveを走って、c#/golang/flutter/pythonなどの構築/テスト環境を提供します.
また、このサーバは電源を切らず、24 hでサービスを提供しています.
しばらくすると、このJenkins Slave仮想マシンのメモリは高くなりません.これは、次のコンストラクションの速度を速めるためにデーモンプロセスを維持するコンストラクションタスクがあるため、メモリが解放されません.
約1ヶ月後、問題は発生しました:仮想マシンのヒントはまだ2 Gの空きメモリ(cachedを含まない)があるのに、sshの登録には2、3分近くかかり、登録後のtop/htopも1分近く黒い画面になります.不思議なことに、他のコマンド(ls/cd/df/du/docker)は正常で、明らかなカートン現象はありません.
迅速なソリューション
他の加速構築用Jenkins Slaveと比較すると、毎晩電源を切る(節電)ので、問題はありません.
そこでそれを再起動し、一時的に問題を解決した.
原因分析
まず、カートンの一般的な調査プロセスをリストします.
  • 性能問題:CPU/RAM/IO/Network
  • ゾンビプロセスによりPidリソースが不足している.
  • ICMP-ping、tcp-pingを使用してNIC
  • を検査する.
  • システムの問題、kernelとsyslog
  • をチェック
    CPU/RAMに問題がなく、毎晩シャットダウンするSlaveにも問題がない以上、カートンは長期運転時に発生することを示しています.
    チェック:
  • システムの負荷は正常で、パフォーマンスの問題を排除します.
  • カーネルパラメータ:前の図は便利で、すべてのサーバにvm.max_map_count=262144を設置しました(elasticsearch 6.8+必要)
  • は、このパラメータのため、redisが長期にわたって動作した後、応答が遅いという問題に直面したことがある.それと関係があるかもしれません.

  • Jenkins Slave仮想マシンには66248のプロセスがありますが、そのうち66009はゾンビプロセス
  • です.
    Jenkins Slaveの最も明らかな問題は、ゾンビのプロセスが多すぎることです.
    ゾンビプロセスman psにおけるゾンビプロセス(状態Z)の解釈は以下の通りである.
    Z defunct ("zombie") process, terminated but not reaped by its parent
    サブプロセスが終了したが、親プロセスがwaitシステム呼び出しによってサブプロセスを収穫しなかった場合、このサブプロセスはゾンビプロセスになる.topコマンドの2行目には、ゾンビプロセスの数が表示されます.
    ゾンビプロセスを表示するコマンド:ps -ef| grep defunc、defuncは「死者」を意味します.
    ゾンビプロセスはkillコマンドで殺すことはできません(死んだプロセスhhhを殺すことはできません)、親プロセスを殺すことで間接的に殺すしかありません.
    システムにゾンビプロセスが多すぎると、OSプロセステーブルのリソースが大量に消費され、システムがカートンし、最終的にクラッシュします.
    前述のpsコマンドにより、これらのzombiesの親プロセスは基本的にjenkins-agentプロセスであり、サーバを再起動するとプロセスも再起動されるため、サーバは正常に戻ります.しかし、これは明らかに治標の方法にすぎず、しばらくするとゾンビプロセスが堆積し、サーバーカートンを招く.
    治根の解決策を探ってみると、Jenkins zombieを検索すると次のようなIssues、PRが発見された.
  • Handling of zombie processes would be useful
  • defunct sh and sleep processes when running on slave-jnlp
  • Wrapper process leaves zombie when no init process present
  • Start long running containers with --init

  • 最も簡単な解決策は、dockerによってjenkins-agentを起動するときに--initパラメータを追加することです.対応するdocker-composeパラメータはdocker-compose reference-initです.
    それでdocker-compose.ymlにこのパラメータを追加して、この問題を解決しました.