使用 kubectl describe pod
查看異常的 pod 的狀態,在容器列表里看 State
字段,其中 ExitCode
即程序退出時的狀態碼,正常退出時為0。如果不為0,表示異常退出,我們可以分析下原因。
退出狀態碼的區間
- 必須在 0-255 之間
- 0 表示正常退出
- 外界中斷將程序退出的時候狀態碼區間在 129-255,(操作系統給程序發送中斷信號,比如
kill -9
是SIGKILL
,ctrl+c
是SIGINT
) - 一般程序自身原因導致的異常退出狀態區間在 1-128 (這只是一般約定,程序如果一定要用129-255的狀態碼也是可以的)
假如寫代碼指定的退出狀態碼時不在 0-255 之間,例如: exit(-1)
,這時會自動做一個轉換,最終呈現的狀態碼還是會在 0-255 之間。我們把狀態碼記為 code
- 當指定的退出時狀態碼為負數,那么轉換公式如下:
256 - (|code| % 256)
- 當指定的退出時狀態碼為正數,那么轉換公式如下:
code % 256
常見異常狀態碼
-
- 137
- 此狀態碼一般是因為 pod 中容器內存達到了它的資源限制(
resources.limits
),一般是內存溢出(OOM),CPU達到限制只需要不分時間片給程序就可以。因為限制資源是通過 linux 的 cgroup 實現的,所以 cgroup 會將此容器強制殺掉,類似於kill -9
- 還可能是宿主機本身資源不夠用了(OOM),內核會選取一些進程殺掉來釋放內存
- 不管是 cgroup 限制殺掉進程還是因為節點機器本身資源不夠導致進程死掉,都可以從系統日志中找到記錄:
ubuntu 的系統日志在
/var/log/syslog
,centos 的系統日志在/var/log/messages
,都可以用journalctl -k
來查看系統日志 - 此狀態碼一般是因為 pod 中容器內存達到了它的資源限制(
- 1 和 255
- 這種可能是一般錯誤,具體錯誤原因只能看容器日志,因為很多程序員寫異常退出時習慣用
exit(1)
或exit(-1)
,-1 會根據轉換規則轉成 255
- 這種可能是一般錯誤,具體錯誤原因只能看容器日志,因為很多程序員寫異常退出時習慣用
- 137
狀態碼參考
這里羅列了一些狀態碼的含義:Appendix E. Exit Codes With Special Meanings
Linux 標准中斷信號
Linux 程序被外界中斷時會發送中斷信號,程序退出時的狀態碼就是中斷信號值加上 128 得到的,比如 SIGKILL
的中斷信號值為 9,那么程序退出狀態碼就為 9+128=137。以下是標准信號值參考:
Signal Value Action Comment ────────────────────────────────────────────────────────────────────── SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process SIGINT 2 Term Interrupt from keyboard SIGQUIT 3 Core Quit from keyboard SIGILL 4 Core Illegal Instruction SIGABRT 6 Core Abort signal from abort(3) SIGFPE 8 Core Floating-point exception SIGKILL 9 Term Kill signal SIGSEGV 11 Core Invalid memory reference SIGPIPE 13 Term Broken pipe: write to pipe with no readers; see pipe(7) SIGALRM 14 Term Timer signal from alarm(2) SIGTERM 15 Term Termination signal SIGUSR1 30,10,16 Term User-defined signal 1 SIGUSR2 31,12,17 Term User-defined signal 2 SIGCHLD 20,17,18 Ign Child stopped or terminated SIGCONT 19,18,25 Cont Continue if stopped SIGSTOP 17,19,23 Stop Stop process SIGTSTP 18,20,24 Stop Stop typed at terminal SIGTTIN 21,21,26 Stop Terminal input for background process SIGTTOU 22,22,27 Stop Terminal output for background process
C/C++ 退出狀態碼
/usr/include/sysexits.h
試圖將退出狀態碼標准化(僅限 C/C++):
#define EX_OK 0 /* successful termination */ #define EX__BASE 64 /* base value for error messages */ #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ #define EX_NOUSER 67 /* addressee unknown */ #define EX_NOHOST 68 /* host name unknown */ #define EX_UNAVAILABLE 69 /* service unavailable */ #define EX_SOFTWARE 70 /* internal software error */ #define EX_OSERR 71 /* system error (e.g., can't fork) */ #define EX_OSFILE 72 /* critical OS file missing */ #define EX_CANTCREAT 73 /* can't create (user) output file */ #define EX_IOERR 74 /* input/output error */ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #define EX_PROTOCOL 76 /* remote error in protocol */ #define EX_NOPERM 77 /* permission denied */ #define EX_CONFIG 78 /* configuration error */ #define EX__MAX 78 /* maximum listed value */