自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊容器中的一號進程

系統(tǒng) Linux
Linux 進程在樹中排序。每個進程都可以產(chǎn)生子進程,并且除了最頂層的進程之外,每個進程都有一個父進程。

如何理解 init 進程?

linux 進程在樹中排序。每個進程都可以產(chǎn)生子進程,并且除了最頂層的進程之外,每個進程都有一個父進程。

一旦我們啟動了多個進程,那么容器里就會出現(xiàn)一個 pid 1,也就是我們常說的 1 號進程或者 init 進程,然后由這個進程創(chuàng)建出其他的子進程。接下來,我?guī)闶崂硪幌?init 進程是怎么來的。

一個 Linux 操作系統(tǒng),在系統(tǒng)打開電源,執(zhí)行 BIOS/boot-loader 之后,就會由 boot-loader 負責加載 Linux 內(nèi)核。Linux 內(nèi)核執(zhí)行文件一般會放在 /boot 目錄下,文件名類似 vmlinuz*。在內(nèi)核完成了操作系統(tǒng)的各種初始化之后,這個程序需要執(zhí)行的第一個用戶態(tài)程就是 init 進程。

內(nèi)核代碼啟動 1 號進程的時候,在沒有外面參數(shù)指定程序路徑的情況下,一般會從幾個缺省路徑嘗試執(zhí)行 1 號進程的代碼。這幾個路徑都是 Unix 常用的可執(zhí)行代碼路徑。

系統(tǒng)啟動的時候先是執(zhí)行內(nèi)核態(tài)的代碼,然后在內(nèi)核中調(diào)用 1 號進程的代碼,從內(nèi)核態(tài)切換到用戶態(tài)。

目前主流的 Linux 發(fā)行版,無論是 RedHat 系的還是 Debian 系的,都會把 /sbin/init 作為符號鏈接指向 Systemd。Systemd 是目前最流行的 Linux init 進程,在它之前還有 SysVinit、UpStart 等 Linux init 進程。

docker中的init

在 Linux 上有了容器的概念之后,一旦容器建立了自己的 Pid Namespace(進程命名空間),這個 Namespace 里的進程號也是從 1 開始標記的。所以,容器的 init 進程也被稱為 1 號進程。你只需要記?。? 號進程是第一個用戶態(tài)的進程,由它直接或者間接創(chuàng)建了 Namespace 中的其他進程。

每個Docker容器都是一個PID命名空間,這意味著容器中的進程與主機上的其他進程是隔離的。PID命名空間是一棵樹,從PID 1開始,通常稱為init。

注意:當你運行一個Docker容器時,鏡像的ENTRYPOINT就是你的根進程,即PID 1(如果你沒有ENTRYPOINT,那么CMD就會作為根進程,你可能配置了一個shell腳本,或其他的可執(zhí)行程序,容器的根進程具體是什么,完全取決于你的配置)。

PID 1在處理kill信號的特別之處

與其他進程不同的是:

PID 1它會忽略具有默認操作的任何信號。因此除非經(jīng)過編碼,否則應(yīng)用沒有監(jiān)聽 SIGTERM 信號,或者應(yīng)用中沒有實現(xiàn)處理 SIGTERM 信號的邏輯,應(yīng)用就不會停止。比如默認的Bash與C語言的程序,是沒有注冊SIGTERM 信號的handler;

PID 1永遠不會響應(yīng) SIGKILL 和 SIGSTOP 這兩個特權(quán)信號;

對于其他的信號,如果用戶自己注冊了 handler,1 號進程可以響應(yīng)。

把Bash當作PID 1呢?

每個基礎(chǔ)鏡像都有這個是Bash 。Bash 正確地收割了采用的子進程。Bash 可以運行任何東西。所以在你的Dockerfile中,你肯定會用這個:

CMD ["/bin/bash", "-c", "/path-to-your-app"]

Bash默認不會處理SIGTERM信號,因此這將會導(dǎo)致如下的問題:第一個問題是:如果將Bash作為PID 1運行,那么發(fā)送到Docker容器docker stop的信號,最終都是將 SIGTERM信號發(fā)送到Bash,但是Bash默認不會處理SIGTERM信號,也不會將它們轉(zhuǎn)發(fā)到任何地方(除非您自己編寫代碼實現(xiàn))。docker stop命令執(zhí)行后,容器會有一個關(guān)閉的時限,默認為10秒,超過十秒則用kill強制關(guān)閉。換句話說,給 Bash發(fā)送SIGTERM信號終止時,會等待十秒鐘,然后被內(nèi)核強制終止包含所有進程的整個容器。這些進程通過 SIGKILL 信號不正常地終止。SIGKILL是特權(quán)信號,無法被捕獲,因此進程無法干凈地終止。假設(shè)服務(wù)正在運行的應(yīng)用程序正忙于寫入文件;如果應(yīng)用程序在寫入過程中不干凈地終止,文件可能會損壞。不干凈的終止是不好的。這幾乎就像從服務(wù)器上拔下電源插頭一樣。

第二個問題是:一旦進程退出,Bash也會繼續(xù)退出。如果程序出了bug退出了,Bash會退出,退出代碼為0,而進程實際上崩潰了(但0表示“一切正常”;這將導(dǎo)致Docker或者k8s上重啟策略不符合預(yù)期)。因為真正想要的可能是Bash返回與的進程相同的退出代碼。

請注意,我們對bash進行修改,編寫一個 EXIT 處理程序,它只是向子進程發(fā)送信號:

#!/bin/bash
function cleanup()
{
local pids=`jobs -p`
if [[ "$pids" != "" ]]; then
kill $pids >/dev/null 2>/dev/null
fi
}

trap cleanup EXIT
/path-to-your-app

不幸的是,這并不能解決問題。向子進程發(fā)送信號是不夠的:init 進程還必須等待子進程終止,然后才能終止自己。如果 init 進程過早終止,那么所有子進程都會被內(nèi)核不干凈地終止。

很明顯,需要一個更復(fù)雜的解決方案,但是像 Upstart、Systemd 和 SysV init 這樣的完整 init 系統(tǒng)對于輕量級 Docker 容器來說太過分了。幸運的是,我們有很多在容器中使用的init程序。我們這里推薦使用簡單的tini。

tini當作PID 1

我們在容器中啟動一個init 系統(tǒng)有很多種,這里推薦使用 tini,它是專用于容器的輕量級 init 系統(tǒng),使用方法也很簡單:

FROM openjdk8:8u201-jdk-alpine3.9
RUN apk add --no-cache tini wget \
&& mkdir -p /opt/arthas \
&& cd /opt/arthas \
&& wget https://arthas.aliyun.com/arthas-boot.jar
ENTRYPOINT ["/sbin/tini", "--"]

請注意,Tini中還有一些額外的功能,在Bash或Java中很難實現(xiàn)(例如,Tini可以注冊為“子收割者”,因此它實際上不需要作為PID 1運行來完成“僵尸進程”收割工作),但是這些功能對于一些高級應(yīng)用場景來說非常有用。

為什么docker中會有僵尸進程?

使用容器的理想境界是一個容器只啟動一個進程,但這在現(xiàn)實應(yīng)用中有時是做不到的。

比如說,在一個容器中除了主進程之外,我們可能還會啟動輔助進程,做監(jiān)控或者 rotate logs;再比如說,我們需要把原來運行在虛擬機(VM)的程序移到容器里,這些原來跑在虛擬機上的程序本身就是多進程的。

一旦我們啟動了多個進程,那么容器里就會出現(xiàn)一個 pid 1,也就是我們常說的 1 號進程或者 init 進程,然后由這個進程創(chuàng)建出其他的子進程。比如我們在部署java服務(wù)的時候,我們需要部署一個Arthas(阿爾薩斯),來做為java程序的診斷工具。

總結(jié)

第一個概念是 Linux 1 號進程。它是第一個用戶態(tài)的進程。它直接或者間接創(chuàng)建了 Namespace 中的其他進程。第二個概念是容器里 1 號進程對信號處理的三個要點:

  • PID 1沒有默認的信號處理程序。如果應(yīng)用沒有監(jiān)聽 SIGTERM 信號,或者應(yīng)用中沒有實現(xiàn)處理 SIGTERM 信號的邏輯,應(yīng)用就不會停止,容器也不會終止。
  • 在容器中,1 號進程永遠不會響應(yīng) SIGKILL 和 SIGSTOP 這兩個特權(quán)信號;
  • 對于其他的信號,如果用戶自己注冊了 handler,1 號進程可以響應(yīng)。

第三個概念是tini作為1號進程可以給子進程傳遞SIGTERM信號和收割僵尸進程。

責任編輯:姜華 來源: 運維開發(fā)故事
相關(guān)推薦

2021-09-14 13:25:23

容器pod僵尸進程

2010-11-16 15:29:18

天河一號美國

2011-06-21 09:02:06

天河一號

2009-10-30 11:24:31

2023-08-09 10:23:14

2009-09-17 14:25:49

通用CPU芯片龍芯一號

2009-11-10 13:25:33

天河一號HPC

2012-05-04 13:39:45

天河一號超級計算機

2021-09-14 09:19:49

一號多卡手機卡號碼

2009-11-06 09:37:00

天河一號

2023-11-03 08:22:09

Android系統(tǒng)算法

2011-06-10 13:53:24

天河一號A

2010-10-18 14:47:04

千萬億次天河一號

2014-06-30 09:35:18

中國超級計算機天河一號

2015-12-25 14:25:35

網(wǎng)絡(luò)建設(shè)敏捷網(wǎng)絡(luò)華為

2024-05-09 09:55:08

2020-07-14 07:27:48

容器IoCSpring

2020-06-28 09:12:31

CPU網(wǎng)卡中斷

2022-05-08 13:17:14

CPU內(nèi)存中斷
點贊
收藏

51CTO技術(shù)棧公眾號