溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

docker 資源限制以及應(yīng)用的總結(jié)

發(fā)布時(shí)間:2020-07-31 20:58:14 來(lái)源:網(wǎng)絡(luò) 閱讀:33837 作者:tty之星 欄目:建站服務(wù)器

一、Docker(linux container)所依賴的底層技術(shù)(隔離技術(shù))

1 Namespace

用來(lái)做容器的隔離,有了namespace,在docker container里頭看來(lái),就是一個(gè)完整的linux的世界。在host看來(lái),container里的進(jìn)程,就是一個(gè)普通的host進(jìn)程namespace提供這種pid的映射和隔離效果,host承載著container,就好比一個(gè)世外桃源。

namespace包括:pid namespacenet namespace、ipc namespace、mnt namespaceuts namespace、user namespace

例如我們運(yùn)行一個(gè)容器

docker 資源限制以及應(yīng)用的總結(jié) 

查看容器的進(jìn)程號(hào)

docker 資源限制以及應(yīng)用的總結(jié) 

可以看到該容器的pid3894,在宿主的/proc目錄下存在3894進(jìn)程的目錄

通過(guò)kill可以結(jié)束該容器

docker 資源限制以及應(yīng)用的總結(jié) 

 

查看/proc/[pid]/ns文件

3.8版本的內(nèi)核開(kāi)始,用戶就可以在/proc/[pid]/ns文件下看到指向不同namespace號(hào)的文件,效果如下所示,形如[4026531839]者即為namespace號(hào)。

我們運(yùn)行一個(gè)容器并獲取容器的pid

docker 資源限制以及應(yīng)用的總結(jié) 

獲取容器的pid

docker 資源限制以及應(yīng)用的總結(jié) 

#ls -l /proc/pid/ns         <<pid表示應(yīng)用容器PID

docker 資源限制以及應(yīng)用的總結(jié) 

如果兩個(gè)進(jìn)程指向的namespace編號(hào)相同,就說(shuō)明他們?cè)谕粋€(gè)namespace下,否則則在不同namespace里面。

例如我們?cè)賱?chuàng)建一個(gè)容器,網(wǎng)絡(luò)模式為container 使用 --net=container:NAMEorID 指定

docker 資源限制以及應(yīng)用的總結(jié) 

從上面可以看出兩個(gè)容器的net namespace編號(hào)相同說(shuō)明他們?cè)谕粋€(gè)net namespace,共用一個(gè)網(wǎng)絡(luò)。

 

 

Docker使用了pid、network、mnt、ipc、uts等命名空間來(lái)隔離進(jìn)程、網(wǎng)絡(luò)、文件系統(tǒng)等資源。注意,由于Linux并不是namespace了所有東西(如cgroups、/sys、SELinux、/dev/sd*、內(nèi)核模塊等),僅靠這幾個(gè)namespace是無(wú)法實(shí)現(xiàn)像KVM那樣的完全資源隔離的。

pid namespacePID namespace隔離非常實(shí)用,它對(duì)進(jìn)程PID重新標(biāo)號(hào),即兩個(gè)不同namespace下的進(jìn)程可以有同一個(gè)PID,實(shí)現(xiàn)進(jìn)程隔離,容器只能看到自己的進(jìn)程,并且每個(gè)容器都有一個(gè)pid1的父進(jìn)程,kill掉該進(jìn)程容器內(nèi)的所有進(jìn)程都會(huì)停止;

 

net namespace:實(shí)現(xiàn)網(wǎng)絡(luò)隔離,每個(gè)容器都可以設(shè)置自己的interface、routersiptables等;docker默認(rèn)采用veth的方式將container中的虛擬網(wǎng)卡同host上的一個(gè)docker bridge: docker0連接在一起;

 

ipc namespacecontainer中進(jìn)程交互還是采用linux常見(jiàn)的進(jìn)程間交互方法(interprocess communication - IPC)容器中進(jìn)程間通信采用的方法包括常見(jiàn)的信號(hào)量、消息隊(duì)列和共享內(nèi)存。然而與虛擬機(jī)不同的是,容器內(nèi)部進(jìn)程間通信對(duì)宿主機(jī)來(lái)說(shuō),實(shí)際上是具有相同PID namespace中的進(jìn)程間通信,在同一個(gè)IPC namespace下的進(jìn)程彼此可見(jiàn),而與其他的IPC namespace下的進(jìn)程則互相不可見(jiàn)。

 

mnt namespace通過(guò)隔離文件系統(tǒng)掛載點(diǎn)對(duì)隔離文件系統(tǒng)提供支持,不同mnt namespace中的文件結(jié)構(gòu)發(fā)生變化也互不影響。你可以通過(guò)/proc/[pid]/mounts查看到所有掛載在當(dāng)前namespace中的文件系統(tǒng),還可以通過(guò)/proc/[pid]/mountstats看到mount namespace中文件設(shè)備的統(tǒng)計(jì)信息,包括掛載文件的名字、文件系統(tǒng)類型、掛載位置等等

docker 資源限制以及應(yīng)用的總結(jié) 

注:43234是容器的進(jìn)程號(hào)

 

uts namspaceUTS namespace提供了主機(jī)名和域名的隔離,這樣每個(gè)容器就可以擁有了獨(dú)立的主機(jī)名和域名,在網(wǎng)絡(luò)上可以被視作一個(gè)獨(dú)立的節(jié)點(diǎn)而非宿主機(jī)上的一個(gè)進(jìn)程。

user namespace:每個(gè)container可以有不同的 user group id, 也就是說(shuō)可以在container內(nèi)部用container內(nèi)部的用戶執(zhí)行程序而非Host上的用戶。

 

對(duì)于容器所依賴的內(nèi)核文件系統(tǒng)(這些都是non-namespaced),為了保證安全性,docker將其限制為只讀的,例如進(jìn)入一個(gè)容器執(zhí)行mount命令:

#mount

docker 資源限制以及應(yīng)用的總結(jié) 

 

2 Cgroups

在前面了解了Docker背后使用的資源隔離技術(shù)namespace,通過(guò)系統(tǒng)調(diào)用構(gòu)建一個(gè)相對(duì)隔離的shell環(huán)境,也可以稱之為一個(gè)簡(jiǎn)單的容器。下面我們則要開(kāi)始講解另一個(gè)強(qiáng)大的內(nèi)核工具——cgroups。他不僅可以限制被namespace隔離起來(lái)的資源,還可以為資源設(shè)置權(quán)重、計(jì)算使用量、操控進(jìn)程啟停等等。所以cgroupsControl groups實(shí)現(xiàn)了對(duì)資源的配額和度量。

cgroups是什么?

cgroupsControl Groups)最初叫Process Container,由Google工程師(Paul MenageRohit Seth)于2006年提出,后來(lái)因?yàn)?/span>Container有多重含義容易引起誤解,就在2007年更名為Control Groups,并被整合進(jìn)Linux內(nèi)核。顧名思義就是把進(jìn)程放到一個(gè)組里面統(tǒng)一加以控制

 

groups的作用

通俗的來(lái)說(shuō),cgroups可以限制、記錄、隔離進(jìn)程組所使用的物理資源(包括:CPU、memory、IO等),為容器實(shí)現(xiàn)虛擬化提供了基本保證,是構(gòu)建Docker等一系列虛擬化管理工具的基石Cgroups提供了以下四大功能。

1資源限制(Resource Limitation):cgroups可以對(duì)進(jìn)程組使用的資源總額進(jìn)行限制。如設(shè)定應(yīng)用運(yùn)行時(shí)使用內(nèi)存的上限,一旦超過(guò)這個(gè)配額就發(fā)出OOMOut of Memory)。

2優(yōu)先級(jí)分配(Prioritization):通過(guò)分配的CPU時(shí)間片數(shù)量及硬盤IO帶寬大小,實(shí)際上就相當(dāng)于控制了進(jìn)程運(yùn)行的優(yōu)先級(jí)。

3資源統(tǒng)計(jì)(Accounting): cgroups可以統(tǒng)計(jì)系統(tǒng)的資源使用量,如CPU使用時(shí)長(zhǎng)、內(nèi)存用量等等,這個(gè)功能非常適用于計(jì)費(fèi)。

4進(jìn)程控制(Control):cgroups可以對(duì)進(jìn)程組執(zhí)行掛起、恢復(fù)等操作。

 

下面就介紹cgroup如何做到內(nèi)存,cpuio速率的隔離

本文用腳本運(yùn)行示例進(jìn)程,來(lái)驗(yàn)證Cgroups關(guān)于cpu、內(nèi)存、io這三部分的隔離效果。

測(cè)試機(jī)器環(huán)境

docker 資源限制以及應(yīng)用的總結(jié) 

執(zhí)行mount命令查看cgroup的掛載點(diǎn)

docker 資源限制以及應(yīng)用的總結(jié) 

從上圖可以看到cgroup掛載在/sys/fs/cgroup目錄

groups可以限制blkio、cpucpuacct、cpusetdevices、freezer、memory、net_clsns等系統(tǒng)的資源,以下是主要子系統(tǒng)的說(shuō)明:

blkio 這個(gè)子系統(tǒng)設(shè)置限制每個(gè)塊設(shè)備的輸入輸出控制。例如:磁盤,光盤以及usb等等。

cpu 這個(gè)子系統(tǒng)使用調(diào)度程序?yàn)?/span>cgroup任務(wù)提供cpu的訪問(wèn)。

cpuacct 產(chǎn)生cgroup任務(wù)的cpu資源報(bào)告。

cpuset 如果是多核心的cpu,這個(gè)子系統(tǒng)會(huì)為cgroup任務(wù)分配單獨(dú)的cpu和內(nèi)存。

devices 允許或拒絕cgroup任務(wù)對(duì)設(shè)備的訪問(wèn)。

freezer 暫停和恢復(fù)cgroup任務(wù)。

memory 設(shè)置每個(gè)cgroup的內(nèi)存限制以及產(chǎn)生內(nèi)存資源報(bào)告。

net_cls 標(biāo)記每個(gè)網(wǎng)絡(luò)包以供cgroup方便使用,它通過(guò)使用等級(jí)識(shí)別符(classid)標(biāo)記網(wǎng)絡(luò)數(shù)據(jù)包,從而允許 Linux 流量控制程序(TCTraffic Controller)識(shí)別從具體cgroup中生成的數(shù)據(jù)包。

ns:命名空間子系統(tǒng)

 

cgroups管理進(jìn)程cpu資源

我們先看一個(gè)限制cpu資源的例子:

跑一個(gè)耗cpu的腳本

運(yùn)行一個(gè)容器,在容器內(nèi)創(chuàng)建腳本并運(yùn)行腳本,腳本內(nèi)容:

docker 資源限制以及應(yīng)用的總結(jié) 

docker 資源限制以及應(yīng)用的總結(jié) 

將容器切換到后臺(tái)運(yùn)行

在宿主機(jī)上top可以看到這個(gè)腳本基本占了90%cpu資源

docker 資源限制以及應(yīng)用的總結(jié) 

下面用cgroups控制這個(gè)進(jìn)程的cpu資源

對(duì)于centos7來(lái)說(shuō),通過(guò)systemd-cgls來(lái)查看系統(tǒng)cgroups tree

#systemd-cgls

docker 資源限制以及應(yīng)用的總結(jié) 

注:4813就是我們所運(yùn)行的容器pid

docker 資源限制以及應(yīng)用的總結(jié) 

docker 資源限制以及應(yīng)用的總結(jié) 

cpu.cfs_quota_us設(shè)為50000,相對(duì)于cpu.cfs_period_us的100000是50%

docker 資源限制以及應(yīng)用的總結(jié) 

進(jìn)入容器,再次執(zhí)行腳本,打開(kāi)宿主機(jī)的另一個(gè)終端執(zhí)行top命令

然后top的實(shí)時(shí)統(tǒng)計(jì)數(shù)據(jù)如下,cpu占用率將近50%,看來(lái)cgroups關(guān)于cpu的控制起了效果

docker 資源限制以及應(yīng)用的總結(jié) 

 

CPU資源控制

CPU資源的控制也有兩種策略,一種是完全公平調(diào)度(CFSCompletely Fair Scheduler)策略,提供了限額和按比例分配兩種方式進(jìn)行資源控制;另一種是實(shí)時(shí)調(diào)度(Real-Time Scheduler)策略,針對(duì)實(shí)時(shí)進(jìn)程按周期分配固定的運(yùn)行時(shí)間。配置時(shí)間都以微秒(μs)為單位,文件名中用us表示。

CFS調(diào)度策略下的配置

按權(quán)重比例設(shè)定CPU的分配

docker提供了–cpu-shares參數(shù),在創(chuàng)建容器時(shí)指定容器所使用的CPU份額值。例如

使用命令docker run -tid –-cpu-shares 100 鏡像,創(chuàng)建容器,則最終生成的cgroupcpu份額配置可以下面的文件中找到:

# cat /sys/fs/cgroup/cpu/system.slice/docker-<容器的完整長(zhǎng)ID>/cpu.shares

docker 資源限制以及應(yīng)用的總結(jié) 

docker 資源限制以及應(yīng)用的總結(jié) 

cpu-shares的值不能保證可以獲得1個(gè)vcpu或者多少GHzCPU資源,僅僅只是一個(gè)加權(quán)值。

該加權(quán)值是一個(gè)整數(shù)(必須大于等于2)表示相對(duì)權(quán)重,最后除以權(quán)重總和算出相對(duì)比例,按比例分配CPU時(shí)間。

默認(rèn)情況下,每個(gè)docker容器的cpu份額都是1024。單獨(dú)一個(gè)容器的份額是沒(méi)有意義的,只有在同時(shí)運(yùn)行多個(gè)容器時(shí),容器的cpu加權(quán)的效果才能體現(xiàn)出來(lái)。例如,兩個(gè)容器A、Bcpu份額分別為1000500,在cpu進(jìn)行時(shí)間片分配的時(shí)候,容器A比容器B多一倍的機(jī)會(huì)獲得CPU的時(shí)間片。容器A的進(jìn)程一直是空閑的,那么容器B是可以獲取比容器A更多的CPU時(shí)間片的。極端情況下,比如說(shuō)主機(jī)上只運(yùn)行了一個(gè)容器,即使它的cpu份額只有50,它也可以獨(dú)占整個(gè)主機(jī)的cpu資源。

cgroups只在容器分配的資源緊缺時(shí),也就是說(shuō)在需要對(duì)容器使用的資源進(jìn)行限制時(shí),才會(huì)生效。因此,無(wú)法單純根據(jù)某個(gè)容器的cpu份額來(lái)確定有多少cpu資源分配給它,資源分配結(jié)果取決于同時(shí)運(yùn)行的其他容器的cpu分配和容器中進(jìn)程運(yùn)行情況。

cpu-shares演示案例:

先刪除docker主機(jī)上運(yùn)行的容器

docker 資源限制以及應(yīng)用的總結(jié) 

Docker通過(guò)--cpu-shares 指定CPU份額

運(yùn)行一個(gè)容器指定cpu份額為1024

docker 資源限制以及應(yīng)用的總結(jié) 

注:

--cpu-shares 指定CPU份額,默認(rèn)就是1024

--cpuset-cpus可以綁定CPU。例如,指定容器在--cpuset-cpus 0,1 或--cpuset-cpus  0-3

--cpu是stress命令的選項(xiàng)表示產(chǎn)生n個(gè)進(jìn)程每個(gè)進(jìn)程都反復(fù)不停的計(jì)算隨機(jī)數(shù)的平方根

stress命令是linux下的一個(gè)壓力測(cè)試工具。

docker宿主機(jī)上打開(kāi)一個(gè)terminal執(zhí)行top

docker 資源限制以及應(yīng)用的總結(jié) 

然后再啟動(dòng)一個(gè)容器,--cpu-shares512

docker 資源限制以及應(yīng)用的總結(jié) 

查看top的現(xiàn)實(shí)結(jié)果

docker 資源限制以及應(yīng)用的總結(jié) 

可以看到container1的CPU占比為1024/(1024+512)=2/3,container2的CPU占比為512/(1024+512)=1/3

container1cpu.shares改為512,

#echo “512” >/sys/fs/cgroup/cpu/system.slice/docker-<容器的完整長(zhǎng)ID>/cpu.shares

docker 資源限制以及應(yīng)用的總結(jié) 

可以看到兩個(gè)容器的CPU占比趨于平均

 

設(shè)定CPU使用周期使用時(shí)間上限

cgroups 里,可以用 cpu.cfs_period_us cpu.cfs_quota_us 來(lái)限制該組中的所有進(jìn)程在單位時(shí)間里可以使用的 cpu 時(shí)間。cpu.cfs_period_us 就是時(shí)間周期,默認(rèn)為 100000,即百毫秒。cpu.cfs_quota_us 就是在這期間內(nèi)可使用的 cpu 時(shí)間,默認(rèn) -1,即無(wú)限制。

 

cpu.cfs_period_us:設(shè)定時(shí)間周期單位為微秒(μs,必須與cfs_quota_us配合使用。

cpu.cfs_quota_us :設(shè)定周期內(nèi)最多可使用的時(shí)間單位為微秒(μs。這里的配置指task對(duì)單個(gè)cpu的使用上限。

 

舉個(gè)例子,如果容器進(jìn)程需要每1秒使用單個(gè)CPU0.2秒時(shí)間,可以將cpu-period設(shè)置為1000000(即1秒),cpu-quota設(shè)置為2000000.2秒)。

當(dāng)然,在多核情況下,cfs_quota_uscfs_period_us的兩倍,就表示在兩個(gè)核上完全使用CPU,例如如果允許容器進(jìn)程需要完全占用兩個(gè)CPU,則可以將cpu-period設(shè)置為100000(即0.1秒),cpu-quota設(shè)置為2000000.2秒)。

使用示例:

使用命令docker run創(chuàng)建容器

docker 資源限制以及應(yīng)用的總結(jié) 

在宿主機(jī)上執(zhí)行top

docker 資源限制以及應(yīng)用的總結(jié) 

從上圖可以看到基本占了100%cpu資源

則最終生成的cgroupcpu周期配置可以下面的目錄中找到:

/sys/fs/cgroup/cpu/system.slice/docker-<容器的完整長(zhǎng)ID>/

docker 資源限制以及應(yīng)用的總結(jié) 

修改容器的cpu.cfs_period_us cpu.cfs_quota_us

docker 資源限制以及應(yīng)用的總結(jié) 

執(zhí)行top查看cpu資源

docker 資源限制以及應(yīng)用的總結(jié) 

從上圖可以看到基本占了50%cpu資源

 

RT調(diào)度策略下的配置 實(shí)時(shí)調(diào)度策略與公平調(diào)度策略中的按周期分配時(shí)間的方法類似,也是在周期內(nèi)分配一個(gè)固定的運(yùn)行時(shí)間。

cpu.rt_period_us :設(shè)定周期時(shí)間。

cpu.rt_runtime_us:設(shè)定周期中的運(yùn)行時(shí)間。

docker 資源限制以及應(yīng)用的總結(jié) 

 

cpuset - CPU綁定

對(duì)多核CPU服務(wù)器docker還可以控制容器運(yùn)行限定使用哪些cpu內(nèi)核和內(nèi)存節(jié)點(diǎn),即使用–cpuset-cpus–cpuset-mems參數(shù)。對(duì)具有NUMA拓?fù)洌ň哂卸?/span>CPU、多內(nèi)存節(jié)點(diǎn))的服務(wù)器尤其有用,可以對(duì)需要高性能計(jì)算的容器進(jìn)行性能最優(yōu)的配置。如果服務(wù)器只有一個(gè)內(nèi)存節(jié)點(diǎn),則–cpuset-mems的配置基本上不會(huì)有明顯效果

注:

現(xiàn)在的機(jī)器上都是有多個(gè)CPU和多個(gè)內(nèi)存塊的。以前我們都是將內(nèi)存塊看成是一大塊內(nèi)存,所有CPU到這個(gè)共享內(nèi)存的訪問(wèn)消息是一樣的。但是隨著處理器的增加,共享內(nèi)存可能會(huì)導(dǎo)致內(nèi)存訪問(wèn)沖突越來(lái)越厲害,且如果內(nèi)存訪問(wèn)達(dá)到瓶頸的時(shí)候,性能就不能隨之增加。NUMANon-Uniform Memory Access)就是這樣的環(huán)境下引入的一個(gè)模型。比如一臺(tái)機(jī)器是有2個(gè)處理器,有4個(gè)內(nèi)存塊。我們將1個(gè)處理器和兩個(gè)內(nèi)存塊合起來(lái),稱為一個(gè)NUMA node,這樣這個(gè)機(jī)器就會(huì)有兩個(gè)NUMA node。在物理分布上,NUMA node的處理器和內(nèi)存塊的物理距離更小,因此訪問(wèn)也更快。比如這臺(tái)機(jī)器會(huì)分左右兩個(gè)處理器(cpu1, cpu2),在每個(gè)處理器兩邊放兩個(gè)內(nèi)存塊(memory1.1, memory1.2, memory2.1,memory2.2),這樣NUMA node1cpu1訪問(wèn)memory1.1memory1.2就比訪問(wèn)memory2.1memory2.2更快。所以使用NUMA的模式如果能盡量保證本node內(nèi)的CPU只訪問(wèn)本node內(nèi)的內(nèi)存塊,那這樣的效率就是最高的。

 

使用示例:

docker 資源限制以及應(yīng)用的總結(jié) 

表示創(chuàng)建的容器只能用0、1、2這三個(gè)內(nèi)核。最終生成的cgroupcpu內(nèi)核配置如下:

docker 資源限制以及應(yīng)用的總結(jié) 

cpuset.cpus:在這個(gè)文件中填寫cgroup可使用的CPU編號(hào),如0-2,16代表 01、2164個(gè)CPU。

cpuset.mems:與CPU類似,表示cgroup可使用的memory node,格式同上

通過(guò)docker exec <容器ID> taskset -c -p 1(容器內(nèi)部第一個(gè)進(jìn)程編號(hào)一般為1),可以看到容器中進(jìn)程與CPU內(nèi)核的綁定關(guān)系,可以認(rèn)為達(dá)到了綁定CPU內(nèi)核的目的。

總結(jié):

CPU配額控制參數(shù)的混合使用

當(dāng)上面這些參數(shù)中時(shí),cpu-shares控制只發(fā)生在容器競(jìng)爭(zhēng)同一個(gè)內(nèi)核的時(shí)間片時(shí),如果通過(guò)cpuset-cpus指定容器A使用內(nèi)核0,容器B只是用內(nèi)核1,在主機(jī)上只有這兩個(gè)容器使用對(duì)應(yīng)內(nèi)核的情況,它們各自占用全部的內(nèi)核資源,cpu-shares沒(méi)有明顯效果。

cpu-periodcpu-quota這兩個(gè)參數(shù)一般聯(lián)合使用,在單核情況或者通過(guò)cpuset-cpus強(qiáng)制容器使用一個(gè)cpu內(nèi)核的情況下,即使cpu-quota超過(guò)cpu-period,也不會(huì)使容器使用更多的CPU資源。

cpuset-cpus、cpuset-mems只在多核、多內(nèi)存節(jié)點(diǎn)上的服務(wù)器上有效,并且必須與實(shí)際的物理配置匹配,否則也無(wú)法達(dá)到資源控制的目的。

在系統(tǒng)具有多個(gè)CPU內(nèi)核的情況下,需要通過(guò)cpuset-cpus為容器CPU內(nèi)核才能比較方便地進(jìn)行測(cè)試。

 

內(nèi)存配額控制

CPU控制一樣,docker也提供了若干參數(shù)來(lái)控制容器的內(nèi)存使用配額,可以控制容器的swap大小、可用內(nèi)存大小等各種內(nèi)存方面的控制。主要有以下參數(shù):

Docker提供參數(shù)-m, --memory=""限制容器的內(nèi)存使用量,如果不設(shè)置-m,則默認(rèn)容器內(nèi)存是不設(shè)限的,容器可以使用主機(jī)上的所有空閑內(nèi)存

內(nèi)存配額控制使用示例

設(shè)置容器的內(nèi)存上限,參考命令如下所示

#docker  run  -dit  --memory128m  鏡像

默認(rèn)情況下,除了–memory指定的內(nèi)存大小以外,docker還為容器分配了同樣大小的swap分區(qū),也就是說(shuō),上面的命令創(chuàng)建出的容器實(shí)際上最多可以使用256MB內(nèi)存,而不是128MB內(nèi)存。如果需要自定義swap分區(qū)大小,則可以通過(guò)聯(lián)合使用–memory–swap參數(shù)來(lái)實(shí)現(xiàn)控制。

docker 資源限制以及應(yīng)用的總結(jié) 

可以發(fā)現(xiàn),使用256MB進(jìn)行壓力測(cè)試時(shí),由于超過(guò)了內(nèi)存上限(128MB內(nèi)存+128MB swap),進(jìn)程被OOM(out of memory)殺死。

使用250MB進(jìn)行壓力測(cè)試時(shí),進(jìn)程可以正常運(yùn)行

docker 資源限制以及應(yīng)用的總結(jié) 

通過(guò)docker stats可以查看到容器的內(nèi)存已經(jīng)滿負(fù)載了。

#docker  stats  test2

 docker 資源限制以及應(yīng)用的總結(jié)

 

對(duì)上面的命令創(chuàng)建的容器,可以查看到在cgroups的配置文件中,查看到容器的內(nèi)存大小為128MB (128×1024×1024=134217728B),內(nèi)存和swap加起來(lái)大小為256MB (256×1024×1024=268435456B)

#cat /sys/fs/cgroup/memory/system.slice/docker-<容器的完整ID>/memory.limit_in_bytes
134217728

#cat /sys/fs/cgroup/memory/system.slice/docker-<容器的完整ID>/memory.memsw.limit_in_bytes
268435456

docker 資源限制以及應(yīng)用的總結(jié) 

 

磁盤IO配額控制

主要包括以下參數(shù):

--device-read-bps:限制此設(shè)備上的讀速度(bytes per second),單位可以是kb、mb或者gb--device-read-iops:通過(guò)每秒讀IO次數(shù)來(lái)限制指定設(shè)備的讀速度。

--device-write-bps :限制此設(shè)備上的寫速度(bytes per second),單位可以是kb、mb或者gb。

--device-write-iops:通過(guò)每秒寫IO次數(shù)來(lái)限制指定設(shè)備的寫速度。

--blkio-weight:容器默認(rèn)磁盤IO的加權(quán)值,有效值范圍為10-1000。

--blkio-weight-device:針對(duì)特定設(shè)備的IO加權(quán)控制。其格式為DEVICE_NAME:WEIGHT

 

磁盤IO配額控制示例

blkio-weight

使用下面的命令創(chuàng)建兩個(gè)–blkio-weight值不同的容器:

在容器中同時(shí)執(zhí)行下面的dd命令,進(jìn)行測(cè)試

docker 資源限制以及應(yīng)用的總結(jié) 

docker 資源限制以及應(yīng)用的總結(jié) 

注:oflag=direct規(guī)避掉文件系統(tǒng)的cache,把寫請(qǐng)求直接封裝成io指令發(fā)到硬盤

 

3 Chroot

如何在container里頭,看到的文件系統(tǒng),就是一個(gè)完整的linux系統(tǒng),有/etc/lib 等,通過(guò)chroot實(shí)現(xiàn)

 

4 Veth

container里,執(zhí)行ifconfig可以看到eth0的網(wǎng)卡,如何通信呢?其實(shí)是在host上虛擬了一張網(wǎng)卡出來(lái)(veth73f7),跟container里的網(wǎng)卡做了橋接,所有從container出來(lái)的流量都要過(guò)host的虛擬網(wǎng)卡,進(jìn)container的流量也是如此。

 

5 Union FS

對(duì)于這種疊加的文件系統(tǒng),有一個(gè)很好的實(shí)現(xiàn)是AUFS,這個(gè)可以做到以文件為粒度的copy-on-write,為海量的container的瞬間啟動(dòng)。

 

6 Iptables, netfilter

主要用來(lái)做ip數(shù)據(jù)包的過(guò)濾,比如可以做container之間無(wú)法通信,container可以無(wú)法訪問(wèn)host的網(wǎng)絡(luò),但是可以通過(guò)host的網(wǎng)卡訪問(wèn)外網(wǎng)等這樣的網(wǎng)絡(luò)策略

 

 

二、學(xué)習(xí)Docker也有一段時(shí)間了,了解了Docker的基本實(shí)現(xiàn)原理,也知道了Docker的使用方法,這里對(duì)Docker的一些典型應(yīng)用場(chǎng)景做一個(gè)總結(jié)

 

1配置簡(jiǎn)化
  這是Docker的主要使用場(chǎng)景。將應(yīng)用的所有配置工作寫入Dockerfile中,創(chuàng)建好鏡像,以后就可以無(wú)限次使用這個(gè)鏡像進(jìn)行應(yīng)用部署了。這大大簡(jiǎn)化了應(yīng)用的部署,不需要為每次部署都進(jìn)行繁瑣的配置工作,實(shí)現(xiàn)了一次打包,多次部署。這大大加快了應(yīng)用的開(kāi)發(fā)效率,使得程序員可以快速搭建起開(kāi)發(fā)測(cè)試環(huán)境,不用關(guān)注繁瑣的配置工作,而是將所有精力都盡可能用到開(kāi)發(fā)工作中去。

 

2、代碼流水線管理
  代碼從開(kāi)發(fā)環(huán)境到測(cè)試環(huán)境再到生產(chǎn)環(huán)境,需要經(jīng)過(guò)很多次中間環(huán)節(jié),Docker給應(yīng)用提供了一個(gè)從開(kāi)發(fā)到上線均一致的環(huán)境,開(kāi)發(fā)測(cè)試人員均只需關(guān)注應(yīng)用的代碼,使得代碼的流水線變得非常簡(jiǎn)單,這樣應(yīng)用才能持續(xù)集成和發(fā)布。

 

3、快速部署
  在虛擬機(jī)之前,引入新的硬件資源需要消耗幾天的時(shí)間。Docker的虛擬化技術(shù)將這個(gè)時(shí)間降到了幾分鐘,Docker只是創(chuàng)建一個(gè)容器進(jìn)程而無(wú)需啟動(dòng)操作系統(tǒng),這個(gè)過(guò)程只需要秒級(jí)的時(shí)間。

 

4、應(yīng)用隔離
  資源隔離對(duì)于提供共享hosting服務(wù)的公司是個(gè)強(qiáng)需求。如果使用VM,雖然隔離性非常徹底,但部署密度相對(duì)較低,會(huì)造成成本增加。

Docker容器充分利用linux內(nèi)核的namespace提供資源隔離功能。結(jié)合cgroups,可以方便的設(shè)置每個(gè)容器的資源配額。既能滿足資源隔離的需求,又能方便的為不同級(jí)別的用戶設(shè)置不同級(jí)別的配額限制。

 

5、服務(wù)器資源整合
  正如通過(guò)VM來(lái)整合多個(gè)應(yīng)用,Docker隔離應(yīng)用的能力使得Docker同樣可以整合服務(wù)器資源。由于沒(méi)有額外的操作系統(tǒng)的內(nèi)存占用,以及能在多個(gè)實(shí)例之間共享沒(méi)有使用的內(nèi)存,Docker可以比VM提供更好的服務(wù)器整合解決方案。

通常數(shù)據(jù)中心的資源利用率只有30%,通過(guò)使用Docker并進(jìn)行有效的資源分配可以提高資源的利用率。

 

6多版本混合部署
  隨著產(chǎn)品的不斷更新?lián)Q代,一臺(tái)服務(wù)器上部署多個(gè)應(yīng)用或者同一個(gè)應(yīng)用的多個(gè)版本在企業(yè)內(nèi)部非常常見(jiàn)。但一臺(tái)服務(wù)器上部署同一個(gè)軟件的多個(gè)版本,文件路徑、端口等資源往往會(huì)發(fā)生沖突,造成多個(gè)版本無(wú)法共存的問(wèn)題。

如果用docker,這個(gè)問(wèn)題將非常簡(jiǎn)單。由于每個(gè)容器都有自己獨(dú)立的文件系統(tǒng),所以根本不存在文件路徑?jīng)_突的問(wèn)題; 對(duì)于端口沖突問(wèn)題,只需要在啟動(dòng)容器時(shí)指定不同的端口映射即可解決問(wèn)題。

 

7版本升級(jí)回滾
  一次升級(jí),往往不僅僅是應(yīng)用軟件本身的升級(jí),通過(guò)還會(huì)包含依賴項(xiàng)的升級(jí)。但新舊軟件的依賴項(xiàng)很可能是不同的,甚至是有沖突的,所以在傳統(tǒng)的環(huán)境下做回滾一般比較困難。

如果使用docker,我們只需要每次應(yīng)用軟件升級(jí)時(shí)制作一個(gè)新的docker鏡像,升級(jí)時(shí)先停掉舊的容器,然后把新的容器啟動(dòng)。需要回滾時(shí),把新的容器停掉,舊的啟動(dòng)即可完成回滾,整個(gè)過(guò)程各在秒級(jí)完成,非常方便。

 

8、內(nèi)部開(kāi)發(fā)環(huán)境
  在容器技術(shù)出現(xiàn)之前,公司往往是通過(guò)為每個(gè)開(kāi)發(fā)人員提供一臺(tái)或者多臺(tái)虛擬機(jī)來(lái)充當(dāng)開(kāi)發(fā)測(cè)試環(huán)境。開(kāi)發(fā)測(cè)試環(huán)境一般負(fù)載較低,大量的系統(tǒng)資源都被浪費(fèi)在虛擬機(jī)本身的進(jìn)程上了。

Docker容器沒(méi)有任何CPU和內(nèi)存上的額外開(kāi)銷,很適合用來(lái)提供公司內(nèi)部的開(kāi)發(fā)測(cè)試環(huán)境。而且由于Docker鏡像可以很方便的在公司內(nèi)部共享,這對(duì)開(kāi)發(fā)環(huán)境的規(guī)范性也有極大的幫助。

 

9、PaaS
  使用Docker搭建大規(guī)模集群,提供PaaS。這一應(yīng)用是最有前景的一個(gè)了,目前已有很多創(chuàng)業(yè)公司在使用DockerPaaS了,例如云雀云平臺(tái)。用戶只需提交代碼,所有運(yùn)維工作均由服務(wù)公司來(lái)做。而且對(duì)用戶來(lái)說(shuō),整個(gè)應(yīng)用部署上線是一鍵式的,非常方便。

 

10、云桌面
  在每一個(gè)容器內(nèi)部運(yùn)行一個(gè)圖形化桌面,用戶通過(guò)RDP或者VNC協(xié)議連接到容器。該方案所提供的虛擬桌面相比于傳統(tǒng)的基于硬件虛擬化的桌面方案更輕量級(jí),運(yùn)行速率大大提升。不過(guò)該方案仍處于實(shí)驗(yàn)階段,不知是否可行??梢詤⒖家幌?/span>Docker-desktop方案。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI