Docker如何安全地停止和刪除容器
前言
上一篇文章講了容器的運行啟動:【Docker 那些事兒】如何安全地進(jìn)入到容器內(nèi)部
本篇文章將繼續(xù)承接上一篇,講講如何 停止、刪除容器 和 對容器進(jìn)行資源限制
1. 停止和刪除容器
?? 停止容器
在工作中,有時會需要將容器暫停,例如,要為容器文件系統(tǒng)做一個快照時。使用 docker pause 與 docker unpause 命令可以對容器進(jìn)行暫停與激活操作,并且暫停狀態(tài)的容器不會占用宿主機 CPU 資源。
當(dāng)不再需要業(yè)務(wù)運行時,就要將容器關(guān)閉,這時可以使用 docker stop 命令。當(dāng)遇到特殊情況而無法關(guān)閉容器時,還可以使用 docker kill 命令強制終止容器,
示例代碼如下:
以上示例使用 docker kill 命令強制終止了容器。
企業(yè)中通常有大量的容器需要操作,一個一個操作會浪費大量的人力及時間成本。在這種情況下,可以將 Docker 命令與正則表達(dá)式結(jié)合起來,實現(xiàn)對容器的批量操作。
首先查看運行狀態(tài)容器的 ID 號,示例代碼如下:
接著使用 正則表達(dá)式 根據(jù)運行狀態(tài)容器的 ID 號關(guān)閉正在運行的容器,示例代碼如下:
以上示例運用 docker stop 命令與正則表達(dá)式批量終止了運行中的容器,該命令還有另一種編寫方式,示例代碼如下:
另外,使用類似方法還可以對容器進(jìn)行批量刪除、啟動等操作。
docker stop 與 docker kill 的區(qū)別如下??
- docker stop 執(zhí)行時,首先給容器發(fā)送一個TERM信號,讓容器做一些退出前必須做的保護性、安全性操作,然后讓容器自動停止運行,如果在一段時間內(nèi)容器沒有停止運行,再執(zhí)行 kill -9 指令,強制終止容器。
- docker kill 執(zhí)行時,不論容器是什么狀態(tài),在運行什么程序,直接執(zhí)行 kill -9 指令,強制終止容器。
?? 刪除容器
容器以其輕量級的特點受人歡迎,通常一些容器使用不久就會閑置,長期積累會導(dǎo)致不必要的資源浪費,所以要及時清理無用的容器。
與 docker rmi 命令不同,docker rm 命令用于刪除容器,下面將介紹刪除容器的幾種方法。
?? 刪除容器方法一
首先,查看所有容器及其狀態(tài),示例代碼如下:
從以上示例中可以看到,目前宿主機中有三個處于終止?fàn)顟B(tài)的容器,以及一個處于運行狀態(tài)的容器。
然后,結(jié)合正則與 docker rm 命令列出處于終止?fàn)顟B(tài)的容器并進(jìn)行刪除,示例代碼如下:
以上示例使用 docker rm 命令結(jié)合正則表達(dá)式實現(xiàn)了批量刪除容器,并回顯刪除的容器 ID。
最后,查看并確認(rèn)容器已刪除,示例代碼如下:
從示例中可以看到,處于終止?fàn)顟B(tài)的容器已經(jīng)被刪除,運行狀態(tài)的容器并沒有被刪除。
?? 刪除容器方法二
首先,查看所有容器及其狀態(tài),示例代碼如下:
從以上示例中可以看到,宿主機中有三個處于終止?fàn)顟B(tài)的容器,以及一個處于運行狀態(tài)的容器。
接著,使用 docker rm 命令結(jié)合正則表達(dá)式列出所有容器 ID 號并刪除容器,示例代碼如下:
從以上示例中可以看到,命令的執(zhí)行時發(fā)生了報錯,提示無法刪除一個正在運行的容器,可以使用 -f 參數(shù)強制執(zhí)行。
然后,查看當(dāng)前容器狀態(tài),示例代碼如下:
上述示例中可以看到,docker rm 命令結(jié)合正則表達(dá)式刪除了三個終止?fàn)顟B(tài)的容器,運行中的容器沒有被刪除。
最后,根據(jù)報錯提示在命令中添加一個 -f 參數(shù),表示強制刪除,示例代碼如下:
從以上示例中可以看到,處于運行狀態(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)被刪除,而處于運行狀態(tài)的容器并沒有受到影響。
2. 容器資源限制
在默認(rèn)情況下,Docker 沒有對容器進(jìn)行硬件資源的限制。使用 Dcoker 運行容器時,一臺主機上可能會運行成百上千個容器,這些容器雖然相互隔離,但是在底層使用著相同的 CPU、內(nèi)存和 磁盤 等資源。
如果不對容器使用的資源進(jìn)行限制,那么容器對宿主機資源的消耗可能導(dǎo)致其他容器或進(jì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)存上限雖然能保護主機,但是也可能會導(dǎo)致容器里的服務(wù)運行不暢。如果為服務(wù)設(shè)置的內(nèi)存上限太小,服務(wù)在正常工作時可能出現(xiàn)資源不足;
如果設(shè)置過大,則會因為調(diào)度器算法浪費內(nèi)存。因此,合理的做法是遵循以下原則。
- 為應(yīng)用做內(nèi)存壓力測試,了解正常業(yè)務(wù)需求下內(nèi)存的使用情況,然后再進(jìn)入生產(chǎn)環(huán)境。
- 限制容器的內(nèi)存使用上限。
- 盡量保持主機的資源充足,一旦通過監(jiān)控發(fā)現(xiàn)資源不足,就進(jìn)行擴容或者對容器進(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(非強制性限制),如果 Docker 發(fā)現(xiàn)主機內(nèi)存不足,會執(zhí)行 OOM 操作。這個值必須小于 –memory 設(shè)置的值。
--kernel-memory
容器能夠使用的內(nèi)核內(nèi)存的大小,最小值為 4MB。
--oom-kill-disable
設(shè)置是否在運行 OOM 時候終止容器進(jìn)程。
宿主機會在內(nèi)存不足時,隨機關(guān)閉一些進(jìn)程,而該參數(shù)會保護容器進(jìn)程不被關(guān)閉。只有通過設(shè)置 -memory 限制容器內(nèi)存,才可以使用該參數(shù),否則容器會耗盡主機內(nèi)存,而且導(dǎo)致主機應(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)行壓力測試。
示例代碼如下:
以上示例運行了一個容器,分配可用最大內(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),容器正常運行。
下面測試內(nèi)存使用超出限額的情況,實例代碼如下:
從以上示例中可以看到,容器使用的內(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ìn)程會通過時間分片機制使用 CPU。CPU 用頻率來量化,也就是每秒執(zhí)行的運算次數(shù)。為容器限制 CPU 資源并不是改變 CPU 的頻率,而是改變每個容器能使用的 CPU 時間片。
理想狀態(tài)下,CPU 應(yīng)該一直處于運算狀態(tài),并且進(jìn)程的計算量不會超過 CPU 的處理能力。
Docker 允許用戶為每個容器設(shè)置一個數(shù)字,代表容器的 CPU share(共享),默認(rèn)情況下每個容器的 share 值是 1000。這個 share 值是相對的,本身并不能代表任何確定的意義。當(dāng)主機上有多個容器運行時,每個容器占用的 CPU 時間比例為它的 share 值在總額中的比例。
例如,主機上有兩個一直使用 CPU 的容器(為了方便理解,不考慮主機上運行的其他進(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ù)。運行兩個容器 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 用滿,
示例代碼如下:
使用宿主機 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。
下面運行的兩個容器 test01 與 test02,其中,test01 讀寫磁盤的帶寬是 test02 的兩倍。
從以上示例中可以看到,容器 test01 的相對權(quán)重值是 800,而 test02 的相對權(quán)重值是 400,故 test01 讀寫磁盤的帶寬是 test02 的兩倍。
下面運行一個容器,限制其對 /dev/sda 寫入的速率不高于 20MB/s。因為容器文件系統(tǒng)在宿主機的 /dev/sda 上,在容器中寫文件相當(dāng)于對宿主機的 /dev/sda 進(jìn)行寫入操作。
示例代碼如下:
以上示例運行了一個 CentOS 容器,并限制其寫 /dev/sda 的速率為 20MB/s。
下面通過命令查看該容器的寫入速率,示例代碼如下:
從以上示例中可以看到,設(shè)置了寫入限制的容器,寫入速率為 19.4MB/s,沒有超過寫入限制的 20MB/s。
作為對比,下面運行一個不限制寫入速率的容器,示例代碼如下:
以上示例中,一個不限制讀寫速率的容器,寫入速率是 61.3MB/s。
3. 總結(jié)
這兩篇文章,首先介紹了如何獲取 Docker 幫助手冊;然后通過大量的實驗講解了操作 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 啟動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)建單機的 Docker Registry 開始,逐步完成局域網(wǎng)內(nèi)可用的 Docker Registry 的創(chuàng)建,并重點解釋如何使用 IP 地址訪問 Registry 的方法2017-05-05