Docker的進(jìn)程和Cgroup概念詳解
容器里的進(jìn)程組織或關(guān)系
0號進(jìn)程:containerd-shim
角色:
- containerd-shim 是容器的父進(jìn)程,負(fù)責(zé)管理容器的生命周期,接收容器內(nèi)的執(zhí)行的指令。
- 它通過調(diào)用 runc 創(chuàng)建容器,并處理容器內(nèi)的指令。
特點(diǎn):
- 容器依賴:
- containerd-shim 是容器的祖宗進(jìn)程,如果它掛掉,整個容器也會退出。
- 進(jìn)程管理:
- 如果容器的1號進(jìn)程結(jié)束,containerd-shim 會回收容器命名空間中的所有進(jìn)程。
- 如果1號進(jìn)程未結(jié)束,但其子進(jìn)程結(jié)束,子進(jìn)程會成為僵尸進(jìn)程,需要由1號進(jìn)程回收。
- 信號處理:
- docker stop 會向容器的1號進(jìn)程發(fā)送 SIGTERM(-15)信號。
- 如果1號進(jìn)程沒有信號轉(zhuǎn)發(fā)能力,它會向容器內(nèi)的所有進(jìn)程發(fā)送 SIGKILL(-9)信號。
- 如果1號進(jìn)程有信號轉(zhuǎn)發(fā)能力,它會向容器內(nèi)的所有進(jìn)程轉(zhuǎn)發(fā) SIGTERM(-15) 信號。
- docker stop 會向容器的1號進(jìn)程發(fā)送 SIGTERM(-15)信號。
1號進(jìn)程:容器內(nèi)的第一個進(jìn)程
角色:
- 1號進(jìn)程是容器內(nèi)的第一個進(jìn)程,代表容器的生命周期。
- 它通常是用戶指定的應(yīng)用程序進(jìn)程。
特點(diǎn):
- 生命周期:
- 1號進(jìn)程結(jié)束,容器也會結(jié)束。
- 1號進(jìn)程必須在前臺運(yùn)行,否則容器會退出。
- 功能缺陷(與操作系統(tǒng)進(jìn)程的區(qū)別):
- 容器內(nèi)的1號進(jìn)程不一定是所有用戶進(jìn)程的祖先。
- 如果1號進(jìn)程成為孤兒進(jìn)程,它會被init進(jìn)程(0號進(jìn)程)收養(yǎng)。
- 用戶開發(fā)的1號進(jìn)程可能缺乏回收僵尸進(jìn)程和轉(zhuǎn)發(fā)信號的能力。
應(yīng)具備的能力:
- 回收僵尸進(jìn)程::定期調(diào)用 wait 或 waitpid 回收僵尸子進(jìn)程。
- 信號轉(zhuǎn)發(fā):將接收到的信號(如 SIGTERM)轉(zhuǎn)發(fā)給子進(jìn)程。
~# docker container inspect text | grep -i pid pid:41404---------對應(yīng)的就是容器內(nèi)的1號進(jìn)程 ~# ps -elf | grep 41404 pid:41404 ppid:41382---------對應(yīng)的就是容器內(nèi)的0號進(jìn)程
進(jìn)程收到信號后的三種反應(yīng)
信號是操作系統(tǒng)向進(jìn)程發(fā)送的一種通知,用于通知進(jìn)程發(fā)生了某種事件。可以用于進(jìn)程間通信或控制進(jìn)程行為。
- 忽略(Ignore):
- 進(jìn)程對信號不做任何處理。
- 示例:忽略 SIGTERM 信號,進(jìn)程不會被終止。
- 捕獲(Catch):
- 進(jìn)程可以注冊自定義的處理函數(shù)(handler)來處理捕獲的信號。
- 當(dāng)信號到達(dá)時,觸發(fā) handler 執(zhí)行。
- 示例:trap 'echo "signal received"' SIGTERM
- 默認(rèn)行為(Default):
- 每個信號都有默認(rèn)行為,由操作系統(tǒng)定義。
- 示例:
- SIGTERM 的默認(rèn)行為是終止進(jìn)程。
- SIGKILL 的默認(rèn)行為是強(qiáng)制終止進(jìn)程。
兩個特權(quán)信號
SIGKILL (-9)
- 作用: 強(qiáng)制終止進(jìn)程。
- 特點(diǎn):
- 無法被忽略。
- 無法被捕獲。
- 使用場景: 當(dāng)進(jìn)程無響應(yīng)時,強(qiáng)制終止進(jìn)程。
SIGSTOP (-19):
- 作用: 暫停進(jìn)程的運(yùn)行
- 特點(diǎn):
- 無法被忽略。
- 無法被捕獲。
- 恢復(fù)運(yùn)行: 發(fā)送 SIGCONT (-18) 信號。
SIGTERM(-15)信號是可以被進(jìn)程忽略或者捕獲的
在容器內(nèi)執(zhí)行 kill 命令的行為
kill -9 1
- 無法殺死容器內(nèi)的1號進(jìn)程。
- 原因: 容器內(nèi)的1號進(jìn)程被打上了 SIGNAL_UNKILLABLE 標(biāo)簽。
kill -19 1
- 無法暫停容器內(nèi)的1號進(jìn)程。
- 原因: 容器內(nèi)的1號進(jìn)程被打上了 SIGNAL_UNKILLABLE 標(biāo)簽。
kill -15 1
- 有可能殺死容器內(nèi)的1號進(jìn)程。
- 如果1號進(jìn)程沒有注冊 SIGTERM 信號的處理函數(shù),它會忽略該信號。
- 如果1號進(jìn)程注冊了 SIGTERM 信號的處理函數(shù),它會執(zhí)行該函數(shù)。
Cgroup 介紹
Cgroup(Control Group)是 Linux 內(nèi)核提供的一種機(jī)制,用于限制、控制和監(jiān)控進(jìn)程組的資源使用。它允許系統(tǒng)管理員對一組進(jìn)程的資源使用進(jìn)行精細(xì)化管理,包括 CPU、內(nèi)存、磁盤 I/O 等。Cgroup 是容器技術(shù)(如 Docker、Kubernetes)中實(shí)現(xiàn)資源隔離和管理的基礎(chǔ)。
為何要用 Cgroup?Cgroup 的主要作用是限制容器或進(jìn)程組對宿主機(jī)資源的使用,防止某個容器或進(jìn)程過度占用資源,從而影響其他容器或進(jìn)程的正常運(yùn)行。通過 Cgroup,可以確保宿主機(jī)上的多個容器或進(jìn)程能夠公平、穩(wěn)定地共享系統(tǒng)資源。
在 Linux 系統(tǒng)中,可以通過以下命令查看和管理 Cgroup
# 查看當(dāng)前的 Cgroup 控制層級 cat /proc/cgroups # 創(chuàng)建一個新的 Cgroup mkdir /sys/fs/cgroup/cpu/my_cgroup # 將一個進(jìn)程加入到 Cgroup 中 echo "PID" > /sys/fs/cgroup/cpu/my_cgroup/tasks # 設(shè)置 CPU 限制 echo "2" > /sys/fs/cgroup/cpu/my_cgroup/cpu.cfs_quota_us
CPU Cgroup 中與 CFS 相關(guān)的參數(shù)
CFS(Completely Fair Scheduler)是 Linux 內(nèi)核中的一種調(diào)度算法,用于公平地分配 CPU 時間給各個進(jìn)程。Cgroup 中與 CFS 相關(guān)的參數(shù)決定了進(jìn)程組對 CPU 的使用率。
- cpu.cfs_period_us:表示 CPU 的時間周期,單位為微秒 (μs)。例如,設(shè)置為 100ms (100,000 μs),表示一個周期為 100 毫秒。
- cpu.cfs_quota_us:表示在該時間周期內(nèi),控制組內(nèi)的進(jìn)程最多可以使用的 CPU 時間。例如,設(shè)置為 50ms (50,000 μs),表示在 100ms 的周期內(nèi),進(jìn)程最多可以使用 50ms 的 CPU 時間。此時,CPU 使用率為 50ms / 100ms = 0.5,即 50%。
- cpu.shares:用于控制同一層級下的多個控制組之間的 CPU 資源分配。當(dāng)宿主機(jī)上的 CPU 資源不足時,cpu.shares 會生效,決定各個控制組之間的 CPU 資源分配比例。cpu.shares 的值越大,分配的 CPU 資源越多。
總結(jié):
- cpu.cfs_quota_us與cpu.cfs_period_us這兩個值決定了每個控制組所有進(jìn)程可使用cpu資源的最大值
- cpu.shares這個值決定了cpu cgroup子系統(tǒng)下控制組可用cpu的相對比例,不過只有當(dāng)系統(tǒng)上cpu被占滿時,這個比例才會在各個控制組間起作用
Kubernetes 中的資源管理
在 Kubernetes 中,Pod 的資源請求和限制可以通過 requests 和 limits 來設(shè)置。
- requests:表示 Pod 對資源的最低需求。Kubernetes 會根據(jù) requests 來調(diào)度 Pod,確保節(jié)點(diǎn)上有足夠的資源。requests 對應(yīng) Cgroup 中的 cpu.shares,表示初始的 CPU 資源申請量。實(shí)際使用量可以超過 requests,但不會低于它。
- limits:表示 Pod 對資源使用的上限。Kubernetes 會通過 Cgroup 限制 Pod 的資源使用,確保不會超過 limits 設(shè)置的值。limits 對應(yīng) Cgroup 中的 cpu.cfs_quota_us 和 cpu.cfs_period_us,表示 CPU 使用的硬性上限。
但是要注意,limits 設(shè)置的上限是否能達(dá)到,還取決于宿主機(jī)的實(shí)際資源情況。如果宿主機(jī)資源不足,Pod 可能無法達(dá)到 limits 設(shè)置的上限。
memory cgroup
每個容器都有對應(yīng)的 memory cgroup 控制組,位于 /sys/fs/cgroup/memory/system.slice/docker - xxx
,用于管理容器內(nèi)存。
主要參數(shù):
- memory.limit_in_bytes:設(shè)置容器內(nèi)所有進(jìn)程可占用的物理內(nèi)存上限,子 group 最多只能設(shè)置到父級 group 的該值。
- memory.oom_control:默認(rèn)為 0,表示開啟 OOM 機(jī)制;可設(shè)為 1 關(guān)閉,通過 echo 1 > memory.oom_control 實(shí)現(xiàn)。
- memory.usage_in_bytes:只讀參數(shù),顯示容器內(nèi)所有進(jìn)程占用的物理內(nèi)存總量。
示例: 容器啟動時,rss 為 100 M,page cache 為 899 M,內(nèi)存總使用量為 999 M;隨著進(jìn)程運(yùn)行,申請更多內(nèi)存后,rss 增至 200 M,page cache 減至 699 M,內(nèi)存總使用量仍為 899 M,但實(shí)際進(jìn)程占用的物理內(nèi)存增大。
容器的可用磁盤進(jìn)行配額
默認(rèn)情況,容器內(nèi)的可用磁盤空間是沒有限制的。
容器內(nèi)的文件系統(tǒng) = lowerdir + upperdir
寫入操作
- 在容器內(nèi)寫容器文件系統(tǒng)里寫東西(任何目錄都沒有掛載任何外部存儲卷)
- 那此時寫入的數(shù)據(jù),都寫到了upperdir層,也就是寫到的宿主機(jī)上。
- 所以如果不加以限制,很有可能會導(dǎo)致宿主機(jī)磁盤空間寫滿。
如何解決問題?有兩種方式:
- 對容器的可用磁盤進(jìn)行配額
- 對容器寫操作的目錄,應(yīng)該掛載一個專門的外部存儲卷(推薦)
到此這篇關(guān)于Docker的進(jìn)程和Cgroup概念的文章就介紹到這了,更多相關(guān)Docker Cgroup概念內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jenkins+Docker實(shí)現(xiàn)自動化部署
本文介紹了在CentOS7和Git(Gitee)環(huán)境下如何使用Jenkins進(jìn)行自動化部署,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09Deepin使用docker安裝mysql數(shù)據(jù)庫過程詳解
這篇文章主要介紹了Deepin使用docker安裝mysql數(shù)據(jù)庫過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06Docker容器沒有權(quán)限寫入宿主機(jī)目錄的解決方案
這篇文章主要介紹了Docker容器沒有權(quán)限寫入宿主機(jī)目錄的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03在 docker 之間導(dǎo)出導(dǎo)入鏡像的方法
本篇文章主要介紹了在 docker 之間導(dǎo)出導(dǎo)入鏡像的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07docker運(yùn)行nginx綁定配置文件失敗原因以及問題解決
最近工作中在使用docker運(yùn)行nginx的時候遇到了些問題,下面分享給大家,這篇文章主要給大家介紹了關(guān)于docker運(yùn)行nginx綁定配置文件失敗原因以及問題解決的相關(guān)資料,需要的朋友可以參考下2023-02-02docker啟動elasticsearch時內(nèi)存不足問題及解決方法
這篇文章主要介紹了docker啟動elasticsearch時內(nèi)存不足問題,本文給大家分享安裝過程及解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07docker安裝elastic?search的詳細(xì)過程
這篇文章主要介紹了docker安裝elastic?search的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06