網(wǎng)站首頁 編程語言 正文
默認(rèn)情況下容器可以使用的主機 CPU 資源是不受限制的。和內(nèi)存資源的使用一樣,如果不對容器可以使用的 CPU 資源進行限制,一旦發(fā)生容器內(nèi)程序異常使用 CPU 的情況,很可能把整個主機的 CPU 資源耗盡,從而導(dǎo)致更大的災(zāi)難。本文將介紹如何限制容器可以使用的 CPU 資源。
本文的 demo 中會繼續(xù)使用《Docker: 限制容器可用的內(nèi)存》一文中創(chuàng)建的 docker 鏡像 u-stress 進行壓力測試,文中就不再過多的解釋了。
1. 限制可用的 CPU 個數(shù)
在 docker 1.13 及更高的版本上,能夠很容易的限制容器可以使用的主機 CPU 個數(shù)。只需要通過 --cpus 選項指定容器可以使用的 CPU 個數(shù)就可以了,并且還可以指定如 1.5 之類的小數(shù)。接下來我們在一臺有四個 CPU 且負(fù)載很低的主機上進行 demo 演示:
通過下面的命令創(chuàng)建容器,–cpus=2 表示容器最多可以使用主機上兩個 CPU:
docker run -it --rm --cpus=2 u-stress:latest /bin/bash
然后由 stress 命令創(chuàng)建四個繁忙的進程消耗 CPU 資源:
stress -c 4
我們先來看看 docker stats 命令的輸出:
容器 CPU 的負(fù)載為 200%,它的含義為單個 CPU 負(fù)載的兩倍。我們也可以把它理解為有兩顆 CPU 在 100% 的為它工作。再讓我們通過 top 命令看看主機 CPU 的真實負(fù)載情況:哈哈,有點大跌眼鏡!實際的情況并不是兩個 CPU 負(fù)載 100%,而另外兩個負(fù)載 0%。四個 CPU 的負(fù)載都是 50%,加起來容器消耗的 CPU 總量就是兩個 CPU 100% 的負(fù)載。
看來對于進程來說是沒有 CPU 個數(shù)這一概念的,內(nèi)核只能通過進程消耗的 CPU 時間片來統(tǒng)計出進程占用 CPU 的百分比。這也是我們看到的各種工具中都使用百分比來說明 CPU 使用率的原因。
嚴(yán)謹(jǐn)起見,我們看看 docker 的官方文檔中是如何解釋 –cpus 選項的:
Specify how much of the available CPU resources a container can use.
果然,人家用的是 “how much”,不可數(shù)的!并且 --cpus 選項支持設(shè)為小數(shù)也從側(cè)面說明了對 CPU 的計量只能是百分比。
看來筆者在本文中寫的 “CPU 個數(shù)” 都是不準(zhǔn)確的。既然不準(zhǔn)確,為什么還要用?當(dāng)然是為了容易理解。況且筆者認(rèn)為在 --cpus
選項的上下文中理解為 “CPU 個數(shù)” 并沒有問題(有興趣的同學(xué)可以讀讀 –cpus 選項的由來,人家的初衷也是要表示 CPU 個數(shù)的)。
雖然 --cpus 選項用起來很爽,但它畢竟是 1.13 才開始支持的。對于更早的版本完成同樣的功能我們需要配合使用兩個選項:–cpu-period 和 --cpu-quota(1.13 及之后的版本仍然支持這兩個選項)。下面的命令實現(xiàn)相同的結(jié)果:
docker run -it --rm --cpu-period=100000 --cpu-quota=200000 u-stress:latest /bin/bash
這樣的配置選項是不是讓人很傻眼呀!100000 是什么?200000 又是什么? 它們的單位是微秒,100000 表示 100 毫秒,200000 表示 200 毫秒。它們在這里的含義是:在每 100 毫秒的時間里,運行進程使用的 CPU 時間最多為 200 毫秒(需要兩個 CPU 各執(zhí)行 100 毫秒)。要想徹底搞明白這兩個選項的同學(xué)可以參考:CFS BandWith Control。我們要知道這兩個選項才是事實的真相,但是真相往往很殘忍!還好 --cpus 選項成功的解救了我們,其實它就是包裝了 --cpu-period
和 --cpu-quota
。
2. 指定固定的 CPU
通過 --cpus
選項我們無法讓容器始終在一個或某幾個 CPU 上運行,但是通過 --cpuset-cpus
選項卻可以做到!這是非常有意義的,因為現(xiàn)在的多核系統(tǒng)中每個核心都有自己的緩存,如果頻繁的調(diào)度進程在不同的核心上執(zhí)行勢必會帶來緩存失效等開銷。下面我們就演示如何設(shè)置容器使用固定的 CPU,下面的命令為容器設(shè)置了 --cpuset-cpus
選項,指定運行容器的 CPU 編號為 1:
docker run -it --rm --cpuset-cpus="1" u-stress:latest /bin/bash
再啟動壓力測試命令:
stress -c 4
然后查看主機 CPU 的負(fù)載情況:這次只有 Cpu1 達(dá)到了 100%,其它的 CPU 并未被容器使用。我們還可以反復(fù)的執(zhí)行
stress -c 4
命令,但是始終都是 Cpu1 在干活。
再看看容器的 CPU 負(fù)載,也是只有 100%:
--cpuset-cpus
選項還可以一次指定多個 CPU:
docker run -it --rm --cpuset-cpus="1,3" u-stress:latest /bin/bash
這次我們指定了 1,3 兩個 CPU,運行 stress -c 4
命令,然后檢查主機的 CPU 負(fù)載:Cpu1 和 Cpu3 的負(fù)載都達(dá)到了 100%。
容器的 CPU 負(fù)載也達(dá)到了 200%:--cpuset-cpus
選項的一個缺點是必須指定 CPU 在操作系統(tǒng)中的編號,這對于動態(tài)調(diào)度的環(huán)境(無法預(yù)測容器會在哪些主機上運行,只能通過程序動態(tài)的檢測系統(tǒng)中的 CPU 編號,并生成 docker run 命令)會帶來一些不便。
3. 設(shè)置使用 CPU 的權(quán)重
當(dāng) CPU 資源充足時,設(shè)置 CPU 的權(quán)重是沒有意義的。只有在容器爭用 CPU 資源的情況下, CPU 的權(quán)重才能讓不同的容器分到不同的 CPU 用量。--cpu-shares
選項用來設(shè)置 CPU 權(quán)重,它的默認(rèn)值為 1024。我們可以把它設(shè)置為 2 表示很低的權(quán)重,但是設(shè)置為 0 表示使用默認(rèn)值 1024。
下面我們分別運行兩個容器,指定它們都使用 Cpu0,并分別設(shè)置 --cpu-shares
為 512 和 1024:
docker run -it --rm --cpuset-cpus="0" --cpu-shares=512 u-stress:latest /bin/bash
docker run -it --rm --cpuset-cpus="0" --cpu-shares=1024 u-stress:latest /bin/bash
在兩個容器中都運行 stress -c 4 命令。
此時主機 Cpu0 的負(fù)載為 100%:
容器中 CPU 的負(fù)載為:
兩個容器分享一個 CPU,所以總量應(yīng)該是 100%。具體每個容器分得的負(fù)載則取決于 --cpu-shares
選項的設(shè)置!我們的設(shè)置分別是 512 和 1024,則它們分得的比例為 1:2。在本例中如果想讓兩個容器各占 50%,只要把 --cpu-shares 選項設(shè)為相同的值就可以了。
總結(jié)
相比限制容器用的內(nèi)存,限制 CPU 的選項要簡潔很多。但是簡潔絕對不是簡單,大多數(shù)把復(fù)雜東西整簡單的過程都會丟失細(xì)節(jié)或是模糊一些概念,比如從 --cpu-period
和 --cpu-quota
選項到 --cpus 選項的進化。對于使用者來說這當(dāng)然是好事,可以減緩我們的學(xué)習(xí)曲線,快速入手。
原文鏈接:https://blog.csdn.net/weixin_39589455/article/details/130677169
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-12-15 YOLOv5改進之添加CBAM注意力機制的方法_python
- 2022-03-26 c#使用listbox的詳細(xì)方法和常見問題解決_C#教程
- 2022-04-25 關(guān)于mongoDB數(shù)據(jù)庫添加賬號的問題_MongoDB
- 2022-09-26 Anaconda環(huán)境克隆、遷移的詳細(xì)步驟_python
- 2024-01-29 深入了解 Spring BeanPostProcessor 的應(yīng)用
- 2022-07-30 Linux常見命令-搜索查詢類,find 查找文件或者目錄,locate 快速定位文件路徑,grep
- 2022-08-15 spring5:創(chuàng)建spring項目并引入jar包
- 2022-12-14 正則表達(dá)式(?=)正向先行斷言實戰(zhàn)案例_正則表達(dá)式
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支