Docker如何安全地停止和刪除容器
前言
上一篇文章講了容器的運(yùn)行啟動:【Docker 那些事兒】如何安全地進(jìn)入到容器內(nèi)部
本篇文章將繼續(xù)承接上一篇,講講如何 停止、刪除容器 和 對容器進(jìn)行資源限制
1. 停止和刪除容器
?? 停止容器
在工作中,有時會需要將容器暫停,例如,要為容器文件系統(tǒng)做一個快照時。使用 docker pause 與 docker unpause 命令可以對容器進(jìn)行暫停與激活操作,并且暫停狀態(tài)的容器不會占用宿主機(jī) CPU 資源。
當(dāng)不再需要業(yè)務(wù)運(yùn)行時,就要將容器關(guān)閉,這時可以使用 docker stop 命令。當(dāng)遇到特殊情況而無法關(guān)閉容器時,還可以使用 docker kill 命令強(qiáng)制終止容器,
示例代碼如下:
以上示例使用 docker kill 命令強(qiáng)制終止了容器。
企業(yè)中通常有大量的容器需要操作,一個一個操作會浪費(fèi)大量的人力及時間成本。在這種情況下,可以將 Docker 命令與正則表達(dá)式結(jié)合起來,實(shí)現(xiàn)對容器的批量操作。
首先查看運(yùn)行狀態(tài)容器的 ID 號,示例代碼如下:
接著使用 正則表達(dá)式 根據(jù)運(yùn)行狀態(tài)容器的 ID 號關(guān)閉正在運(yùn)行的容器,示例代碼如下:
以上示例運(yùn)用 docker stop 命令與正則表達(dá)式批量終止了運(yùn)行中的容器,該命令還有另一種編寫方式,示例代碼如下:
另外,使用類似方法還可以對容器進(jìn)行批量刪除、啟動等操作。
docker stop 與 docker kill 的區(qū)別如下??
- docker stop 執(zhí)行時,首先給容器發(fā)送一個TERM信號,讓容器做一些退出前必須做的保護(hù)性、安全性操作,然后讓容器自動停止運(yùn)行,如果在一段時間內(nèi)容器沒有停止運(yùn)行,再執(zhí)行 kill -9 指令,強(qiáng)制終止容器。
- docker kill 執(zhí)行時,不論容器是什么狀態(tài),在運(yùn)行什么程序,直接執(zhí)行 kill -9 指令,強(qiáng)制終止容器。
?? 刪除容器
容器以其輕量級的特點(diǎn)受人歡迎,通常一些容器使用不久就會閑置,長期積累會導(dǎo)致不必要的資源浪費(fèi),所以要及時清理無用的容器。
與 docker rmi 命令不同,docker rm 命令用于刪除容器,下面將介紹刪除容器的幾種方法。
?? 刪除容器方法一
首先,查看所有容器及其狀態(tài),示例代碼如下:
從以上示例中可以看到,目前宿主機(jī)中有三個處于終止?fàn)顟B(tài)的容器,以及一個處于運(yùn)行狀態(tài)的容器。
然后,結(jié)合正則與 docker rm 命令列出處于終止?fàn)顟B(tài)的容器并進(jìn)行刪除,示例代碼如下:
以上示例使用 docker rm 命令結(jié)合正則表達(dá)式實(shí)現(xiàn)了批量刪除容器,并回顯刪除的容器 ID。
最后,查看并確認(rèn)容器已刪除,示例代碼如下:
從示例中可以看到,處于終止?fàn)顟B(tài)的容器已經(jīng)被刪除,運(yùn)行狀態(tài)的容器并沒有被刪除。
?? 刪除容器方法二
首先,查看所有容器及其狀態(tài),示例代碼如下:
從以上示例中可以看到,宿主機(jī)中有三個處于終止?fàn)顟B(tài)的容器,以及一個處于運(yùn)行狀態(tài)的容器。
接著,使用 docker rm 命令結(jié)合正則表達(dá)式列出所有容器 ID 號并刪除容器,示例代碼如下:
從以上示例中可以看到,命令的執(zhí)行時發(fā)生了報錯,提示無法刪除一個正在運(yùn)行的容器,可以使用 -f 參數(shù)強(qiáng)制執(zhí)行。
然后,查看當(dāng)前容器狀態(tài),示例代碼如下:
上述示例中可以看到,docker rm 命令結(jié)合正則表達(dá)式刪除了三個終止?fàn)顟B(tài)的容器,運(yùn)行中的容器沒有被刪除。
最后,根據(jù)報錯提示在命令中添加一個 -f 參數(shù),表示強(qiáng)制刪除,示例代碼如下:
從以上示例中可以看到,處于運(yùn)行狀態(tài)中的容器已經(jīng)被刪除。
?? 刪除容器方法三
首先,查看當(dāng)前容器及其狀態(tài),示例代碼如下:
接著,使用 docker rm 命令結(jié)合 docker ps -q -f status=exited 命名篩選出處于終止?fàn)顟B(tài)的容器 ID 號,并刪除容器,
示例代碼如下:
上述示例中,命令已經(jīng)執(zhí)行成功。
最后,查看容器是否被刪除,示例代碼如下:
上述示例中可以看到,處于終止?fàn)顟B(tài)的容器都已經(jīng)被刪除。
?? 刪除容器方法四
從 Docker1.13 版本開始,用戶可以使用 docker container prune 命令刪除處于終止?fàn)顟B(tài)的容器。
首先,查看當(dāng)前容器及其狀態(tài),示例代碼如下:
接著,使用命令開始刪除所有處于終止?fàn)顟B(tài)的容器,示例代碼如下:
從以上示例中可以看到,當(dāng) docker container prune 命令執(zhí)行之后,系統(tǒng)會向用戶發(fā)出警告信息,并詢問是否要繼續(xù)。
docker container prune 會直接刪除所有處于終止?fàn)顟B(tài)的容器,為了防止用戶的誤操作,將有用的容器刪除,命令執(zhí)行時會有警告信息與詢問信息。
這時,如果確認(rèn)要刪除,可輸入 “y” ,否則,輸入 “n” 即可阻止命令執(zhí)行。示例刪除了所有處于終止?fàn)顟B(tài)的容器,命令執(zhí)行成功之后返回一個釋放內(nèi)存的值。
最后,查看當(dāng)前容器及其狀態(tài),示例代碼如下:
從以上示例中可以看到,處于終止?fàn)顟B(tài)的容器已經(jīng)被刪除,而處于運(yùn)行狀態(tài)的容器并沒有受到影響。
2. 容器資源限制
在默認(rèn)情況下,Docker 沒有對容器進(jìn)行硬件資源的限制。使用 Dcoker 運(yùn)行容器時,一臺主機(jī)上可能會運(yùn)行成百上千個容器,這些容器雖然相互隔離,但是在底層使用著相同的 CPU、內(nèi)存和 磁盤 等資源。
如果不對容器使用的資源進(jìn)行限制,那么容器對宿主機(jī)資源的消耗可能導(dǎo)致其他容器或進(jìn)程不能夠正常運(yùn)行,嚴(yán)重時可能導(dǎo)致服務(wù)完全不可用。
本節(jié)將介紹如何對容器配置 CPU、內(nèi)存、Block IO 等資源的限制。
?? 限制容器內(nèi)存資源
在 Linux 服務(wù)器上,如果內(nèi)核檢測到?jīng)]有足夠的內(nèi)存(Memory)來執(zhí)行重要的系統(tǒng)功能,內(nèi)核會提示OOME(Out of Memory Error,內(nèi)存溢出)并開始終止進(jìn)程以釋放內(nèi)存,這稱為 OOM 操作。
任何進(jìn)程都有可能被終止,包括 Docker 和其他重要的應(yīng)用程序。如果終止了系統(tǒng)關(guān)鍵進(jìn)程,可能導(dǎo)致整個系統(tǒng)癱瘓。
設(shè)置限制內(nèi)存上限雖然能保護(hù)主機(jī),但是也可能會導(dǎo)致容器里的服務(wù)運(yùn)行不暢。如果為服務(wù)設(shè)置的內(nèi)存上限太小,服務(wù)在正常工作時可能出現(xiàn)資源不足;
如果設(shè)置過大,則會因為調(diào)度器算法浪費(fèi)內(nèi)存。因此,合理的做法是遵循以下原則。
- 為應(yīng)用做內(nèi)存壓力測試,了解正常業(yè)務(wù)需求下內(nèi)存的使用情況,然后再進(jìn)入生產(chǎn)環(huán)境。
- 限制容器的內(nèi)存使用上限。
- 盡量保持主機(jī)的資源充足,一旦通過監(jiān)控發(fā)現(xiàn)資源不足,就進(jìn)行擴(kuò)容或者對容器進(jìn)行遷移。
- 內(nèi)存資源充足的情況下,盡量不要使用 Swap(交換分區(qū)),Swap 的使用會導(dǎo)致內(nèi)存計算變得復(fù)雜,對調(diào)度器造成壓力。
下面介紹Docker啟動參數(shù)中的內(nèi)存限制參數(shù)。
-m
,--memory
設(shè)置容器可使用的最大內(nèi)存,最小值是4MB。
--memory-swap
設(shè)置容器可使用內(nèi)存+Swap的最大值。
--memory-swapiness
默認(rèn)情況下,用戶可以設(shè)置一個0~100的值,代表允許內(nèi)存與交換分區(qū)置換的比例。
--memory-reservation
設(shè)置一個內(nèi)存使用的 soft limit(非強(qiáng)制性限制),如果 Docker 發(fā)現(xiàn)主機(jī)內(nèi)存不足,會執(zhí)行 OOM 操作。這個值必須小于 –memory 設(shè)置的值。
--kernel-memory
容器能夠使用的內(nèi)核內(nèi)存的大小,最小值為 4MB。
--oom-kill-disable
設(shè)置是否在運(yùn)行 OOM 時候終止容器進(jìn)程。
宿主機(jī)會在內(nèi)存不足時,隨機(jī)關(guān)閉一些進(jìn)程,而該參數(shù)會保護(hù)容器進(jìn)程不被關(guān)閉。只有通過設(shè)置 -memory 限制容器內(nèi)存,才可以使用該參數(shù),否則容器會耗盡主機(jī)內(nèi)存,而且導(dǎo)致主機(jī)應(yīng)用被終止。
注:
--memory-swap
只有在設(shè)置了 -memory 時才有意義。
使用 Swap 允許容器在耗盡所有可用的內(nèi)存時,將多余的內(nèi)存需求寫入磁盤。兩者的關(guān)系如表所示。
以上兩個參數(shù)默認(rèn)值都為 -1,即對容器使用 內(nèi)存 和 Swap 沒有限制。
下面使用 progrium/stress 鏡像來介紹如何為容器分配內(nèi)存,該容器可以模擬進(jìn)行壓力測試。
示例代碼如下:
以上示例運(yùn)行了一個容器,分配可用最大內(nèi)存為 300MB,可用 Swap 為 100MB。
其中,–vm 1 參數(shù)表示啟動一個內(nèi)存工作線程
–vm-bytes 280M 參數(shù)表示每個線程分配 280MB 內(nèi)存。
可以看到系統(tǒng)不斷地給容器分配內(nèi)存、釋放內(nèi)存,一直循環(huán)。由于使用的內(nèi)存 380MB,在最大使用量(400MB)之內(nèi),容器正常運(yùn)行。
下面測試內(nèi)存使用超出限額的情況,實(shí)例代碼如下:
從以上示例中可以看到,容器使用的內(nèi)存超過了限額,容器里的進(jìn)程被終止掉了,其中,signal 9 就是終止進(jìn)程信號,最后容器退出。
如果在創(chuàng)建容器時僅指定 -m 參數(shù),不設(shè)置 -memory-swap 參數(shù),那么 -memory-swap 默認(rèn)是 -m 的兩倍,
示例代碼如下:
在以上示例中,容器最多使用 100MB 內(nèi)存和 100MB Swap。
?? 限制容器CPU資源
主機(jī)上的進(jìn)程會通過時間分片機(jī)制使用 CPU。CPU 用頻率來量化,也就是每秒執(zhí)行的運(yùn)算次數(shù)。為容器限制 CPU 資源并不是改變 CPU 的頻率,而是改變每個容器能使用的 CPU 時間片。
理想狀態(tài)下,CPU 應(yīng)該一直處于運(yùn)算狀態(tài),并且進(jìn)程的計算量不會超過 CPU 的處理能力。
Docker 允許用戶為每個容器設(shè)置一個數(shù)字,代表容器的 CPU share(共享),默認(rèn)情況下每個容器的 share 值是 1000。這個 share 值是相對的,本身并不能代表任何確定的意義。當(dāng)主機(jī)上有多個容器運(yùn)行時,每個容器占用的 CPU 時間比例為它的 share 值在總額中的比例。
例如,主機(jī)上有兩個一直使用 CPU 的容器(為了方便理解,不考慮主機(jī)上運(yùn)行的其他進(jìn)程),其 CPU share 都為 1000,那么兩個容器 CPU 使用率都是 50%;
如果把其中一個容器的 share 值設(shè)置為 500,那么兩者 CPU 的使用比為 2:1;如果刪除 share 值為 1000 的容器,剩下來容器的 CPU 使用率將會是 100%。
Docker 為容器設(shè)置 CPU 資源限制的參數(shù)是 -c 或 –cpu-shares,其值是一個整數(shù)。運(yùn)行兩個容器 test01 與 test02,并設(shè)置 CPU 權(quán)重,
示例代碼如下:
以上示例中分別為 test01 與 test02 設(shè)置 CPU share 為 1000 與 2000。
接著,使用 docker stats 查看容器占用 CPU 情況,示例代碼如下:
從以上示例中可以看到,兩個容器 CPU 的使用占比約為 2:1,與先前設(shè)置的 share 值相吻合。
此時將 share 值為 2000 的 test02 容器暫停,再來查看 CPU 使用情況,示例代碼如下:
設(shè)置 CPU 資源限制還可以使用 –cpuset-cpus 參數(shù),它能夠指定容器使用某一顆 CPU。這里使用 CPU 測試鏡像 agileek/cpuset-test 進(jìn)行測試,其功能是將 CPU 用滿,
示例代碼如下:
使用宿主機(jī) top 命令查看 CPU 使用情況,可以看到 CPU1 已經(jīng)被占滿,而 CPU0 沒有受到影響,如圖所示:
?? 限制容器 Block IO
Block IO 表示磁盤的讀寫,Docker 可以用配置 bps(每秒讀寫的數(shù)據(jù)量)和 iops(每秒讀寫的次數(shù))的方式限制容器對磁盤讀寫的帶寬。
下面介紹限制 bps 與 iops 的參數(shù)。
--device-read-bps
限制讀某個設(shè)備的bps。
--device-write-bps
限制寫某個設(shè)備的bps。
--device-read-iops
限制讀某個設(shè)備的iops。
--device-write-iops
限制寫某個設(shè)備的iops。
默認(rèn)情況下,所有容器對磁盤讀寫的帶寬是相同的,通過配置 -blkio-weight 參數(shù)的值(10-1000)可以指定容器 Block IO 的優(yōu)先級。–blkio-weight 與 -cpu-shares 類似,默認(rèn)值都是 500。
下面運(yùn)行的兩個容器 test01 與 test02,其中,test01 讀寫磁盤的帶寬是 test02 的兩倍。
從以上示例中可以看到,容器 test01 的相對權(quán)重值是 800,而 test02 的相對權(quán)重值是 400,故 test01 讀寫磁盤的帶寬是 test02 的兩倍。
下面運(yùn)行一個容器,限制其對 /dev/sda 寫入的速率不高于 20MB/s。因為容器文件系統(tǒng)在宿主機(jī)的 /dev/sda 上,在容器中寫文件相當(dāng)于對宿主機(jī)的 /dev/sda 進(jìn)行寫入操作。
示例代碼如下:
以上示例運(yùn)行了一個 CentOS 容器,并限制其寫 /dev/sda 的速率為 20MB/s。
下面通過命令查看該容器的寫入速率,示例代碼如下:
從以上示例中可以看到,設(shè)置了寫入限制的容器,寫入速率為 19.4MB/s,沒有超過寫入限制的 20MB/s。
作為對比,下面運(yùn)行一個不限制寫入速率的容器,示例代碼如下:
以上示例中,一個不限制讀寫速率的容器,寫入速率是 61.3MB/s。
3. 總結(jié)
這兩篇文章,首先介紹了如何獲取 Docker 幫助手冊;然后通過大量的實(shí)驗講解了操作 Docker 容器的方法,包括進(jìn)入、停止、刪除容器等,以及容器各種狀態(tài)之間如何轉(zhuǎn)換;
最后介紹了 Docker 容器的資源限制,包括 限制內(nèi)存、CPU、BLOCK IO 三種方法。
到此這篇關(guān)于Docker如何安全地停止和刪除容器的文章就介紹到這了,更多相關(guān)Docker 停止刪除容器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Docker安裝配置MySQL的實(shí)現(xiàn)步驟
MySQL 是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在 WEB 應(yīng)用方面 MySQL 是最好的 RDBMS(Relational Database Management System:關(guān)系數(shù)據(jù)庫管理系統(tǒng))應(yīng)用軟件之一。在本教程中,會帶大家正確安裝配置MySQL在Docker2021-11-11docker 啟動elasticsearch鏡像,掛載目錄后報錯的解決
這篇文章主要介紹了docker 啟動 elasticsearch鏡像,掛載目錄后報錯的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11Docker搭建持續(xù)集成平臺Jenkins的最簡教程分享
Jenkins 是一個廣泛使用的開源持續(xù)集成工具,它能夠自動化構(gòu)建、測試和部署軟件項目,本文我們將使用 Docker 搭建一個基于 Jenkins 的持續(xù)集成平臺,感興趣的可以了解下2024-03-03局域網(wǎng)內(nèi)部署 Docker Registry(推薦)
本文將從創(chuàng)建單機(jī)的 Docker Registry 開始,逐步完成局域網(wǎng)內(nèi)可用的 Docker Registry 的創(chuàng)建,并重點(diǎn)解釋如何使用 IP 地址訪問 Registry 的方法2017-05-05Docker數(shù)據(jù)卷常用操作代碼實(shí)例
這篇文章主要介紹了Docker數(shù)據(jù)卷常用操作代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10