docker网络原理及cgroup
docker網(wǎng)絡(luò)模式的特性?
?docker初始狀態(tài)下有三種默認(rèn)的網(wǎng)絡(luò)模式 ,bridg(橋接),host(主機(jī)),none(無(wú)網(wǎng)絡(luò)設(shè)置)
網(wǎng)絡(luò)模式? ? ? ? ? ? ? ? ? ? ? ? ? ? ?配置? ? ? ? ? ? ? ? ? ? ? ? ?說(shuō)明
host//主機(jī)模式?? ?–network host?? ?容器和宿主機(jī)共享網(wǎng)絡(luò)命名空間
container//容器模式?? ?–network container:容器的id或者名字?? ?容器與指定的容器共享網(wǎng)絡(luò)命名空間
none//無(wú)網(wǎng)絡(luò)模式?? ?–network none?? ?容器擁有獨(dú)自的網(wǎng)絡(luò)命名空間,但是沒(méi)有任何設(shè)置
bridge//橋接模式?? ?–network bridge?? ?容器擁有獨(dú)自的網(wǎng)絡(luò)命名空間,且擁有獨(dú)立的IP,端口,路由等,使用veth pair 連接docker0 網(wǎng)橋,并以docker0網(wǎng)橋?yàn)榫W(wǎng)關(guān)
host主機(jī)模式
相當(dāng)于Vmware中的橋接模式,與宿主機(jī)在同一個(gè)網(wǎng)絡(luò)中,但沒(méi)有獨(dú)立IP地址。Docker使用了Linux的Namespaces技術(shù)來(lái)進(jìn)行資源隔離,如PID Namespace隔離進(jìn)程,Mount Namespace隔離 文件系統(tǒng),Network Namespace隔離網(wǎng)絡(luò)等。一個(gè)Network Namespace提供了一份獨(dú)立的網(wǎng)絡(luò)環(huán)境,包括網(wǎng)卡、路由、iptable規(guī)則等都與其他的Network Namespacel隔離。一個(gè)Docker容器一 般會(huì)分配一個(gè)獨(dú)立的Network. Namespace。
但如果啟動(dòng)容器的時(shí)候使用host模式, 那么這個(gè)容器將不會(huì)獲得一 個(gè)獨(dú)立的Network Namespace,而是和宿主機(jī)共用一個(gè)Network Namespace。 容器將不會(huì)虛擬出自己的網(wǎng)卡、配置自己的IP等,而是使用宿主機(jī)的IP和端口。
容器和宿主機(jī)共享網(wǎng)絡(luò)命名空間,但沒(méi)有獨(dú)立IP地址,使用宿主機(jī)的IP地址,和宿主機(jī)共享端口范圍,例如宿主機(jī)使用了80端口,那么容器不能使用80端口。這種模式比較方便,但不安全。?
?container模式
在理解了host模式后,這個(gè)模式也就好理解了。這個(gè)模式指定新創(chuàng)建的容器和已經(jīng)存在的一個(gè)容器共享一個(gè)Network Namespace,而不是和宿主機(jī)共享。 新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的Ie,而是和一個(gè)指定的容器共享re、端口范圍等。同樣,兩個(gè)容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的。兩個(gè)容器的進(jìn)程可以通過(guò)lo網(wǎng)卡設(shè)備通信。
?none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說(shuō),這個(gè)locker容器沒(méi)有網(wǎng)卡、iP、路由等信息。這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒(méi)有其他網(wǎng)卡、這種類型的網(wǎng)絡(luò)沒(méi)有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
?bridge 橋接模式
?bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不用--net參數(shù),就是bridge模式。
相當(dāng)于Vmware中的 nat模式,容器使用獨(dú)立.network Namespace,并連接到docker)虛擬網(wǎng)卡。通過(guò)dockerO網(wǎng)橋以及iptables
nat表配置與宿主機(jī)通信,此模式會(huì)為每一個(gè)容器分配hetwork Mamespace、設(shè)置等,并將一個(gè)主機(jī)上的 Docker容器連接到一個(gè)虛擬網(wǎng)橋上。
?(1)當(dāng)Docker進(jìn)程啟動(dòng)時(shí),會(huì)在主機(jī)上創(chuàng)建一個(gè)名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動(dòng)的Dokcer容器會(huì)連接到這個(gè)虛擬網(wǎng)橋上。虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過(guò)交換機(jī)連在了一個(gè)二層網(wǎng)絡(luò)中。
(2)從docker0子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置dockerO的I地址為容器的默認(rèn)網(wǎng)關(guān)。在主機(jī)上創(chuàng)建一對(duì)虛擬網(wǎng)卡veth pair設(shè)備。veth設(shè)備總是成對(duì)出現(xiàn)的,它們組成了一個(gè)數(shù)據(jù)的通道,數(shù)據(jù)從一個(gè)設(shè)備進(jìn)入,就會(huì)從另一個(gè)設(shè)備出來(lái)、因此,veth設(shè)備常用來(lái)連接兩個(gè)網(wǎng)絡(luò)設(shè)備。
(3 ) Docker將 veth pair 設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0(容器的網(wǎng)卡),另一端放在主機(jī)中,以veth*這樣類似的名字命名,并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中。可以通過(guò) brctl show命令查看。
(4) 使用docker run -p 時(shí),docker實(shí)際是在iptables做了DNAT規(guī)則,實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能。可以使用iptables -t nat -vnL查看。
Docker容器的資源控制
?Docker通過(guò)Cgroup 來(lái)控制容器使用的資源配額,包括CPU、內(nèi)存、磁盤(pán)三大方面,基本覆蓋了常見(jiàn)的資源配額和使用量控制。Caroup 是ControlGroups的縮寫(xiě),是Linux 內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組所使用的物理資源(如 cpu、內(nèi)存、磁盤(pán),io等等)的機(jī)制,被LXC、docker等很多項(xiàng)目用于實(shí)現(xiàn)進(jìn)程資源控制。Cgroup本身是提供將進(jìn)程進(jìn)行分組化管理的功能和接口的基礎(chǔ)結(jié)構(gòu),I/O或內(nèi)存的分配控制等具體的資源管理是通過(guò)該功能來(lái)實(shí)現(xiàn)的。
cgroups,是一個(gè)非常強(qiáng)大的 linux 內(nèi)核工具,他不僅可以限制被 namespace 隔離起來(lái)的資源,還可以為資源設(shè)置權(quán)重、計(jì)算使用量、操控進(jìn)程啟停等等。所以 cgroups(Control groups)實(shí)現(xiàn)了對(duì)資源的配額和度量。
cgroups 有四大功能
資源限制:可以對(duì)任務(wù)使用的資源總額進(jìn)行限制
優(yōu)先級(jí)分配:通過(guò)分配的 cpu 時(shí)間片數(shù)量以及磁盤(pán) IO 帶寬大小,實(shí)際上相當(dāng)于控制了任務(wù)運(yùn)行優(yōu)先級(jí)
資源統(tǒng)計(jì):可以統(tǒng)計(jì)系統(tǒng)的資源使用量,如 cpu 時(shí)長(zhǎng),內(nèi)存用量等
任務(wù)控制:cgroup 可以對(duì)任務(wù)執(zhí)行掛起、恢復(fù)等操作
cpu的使用率上限?
?Linux通過(guò)CFS (Completely Fair Scheduler,完全公平調(diào)度器)來(lái)調(diào)度各個(gè)進(jìn)程對(duì)ceu的使用。CFS默認(rèn)的調(diào)度周期是100ms 。我們可以設(shè)置每個(gè)容器進(jìn)程的調(diào)度周期,以及在這個(gè)周期內(nèi)各個(gè)容器最多能使用多少CPU時(shí)間。
cgroups實(shí)現(xiàn)方式及工作原理
在對(duì)cgroups規(guī)則和自通有一定了解以后,下面簡(jiǎn)單介紹操作系統(tǒng)內(nèi)核級(jí)別上cgroups的工作原理,希望能有助于讀者理解cgroups如何對(duì)Docker容器中的進(jìn)程產(chǎn)生作用。
cgroups的實(shí)現(xiàn)本質(zhì)上是給任務(wù)掛上鉤子,當(dāng)任務(wù)運(yùn)行的過(guò)程中涉及某種資源時(shí),就會(huì)觸發(fā)鉤子上所附帶的子系統(tǒng)進(jìn)行檢測(cè),根據(jù)資源列別不同,使用對(duì)應(yīng)的技術(shù)進(jìn)行資源限制和優(yōu)先級(jí)分配。
cgroups如何判斷資源超限及超出限額后的措施
對(duì)于不同的系統(tǒng)資源,cgroups提供了統(tǒng)一的接口對(duì)資源進(jìn)行控制和統(tǒng)計(jì),但限制的具體方式則不盡相同。比如memorary子系統(tǒng),會(huì)描述內(nèi)存狀態(tài)的“mm_struct”結(jié)構(gòu)體中記錄它所屬的cgroup,當(dāng)進(jìn)程需要申請(qǐng)更多內(nèi)存時(shí),就會(huì)觸發(fā)cgroup用量檢測(cè),用量超過(guò)cgroup規(guī)定的限額,則拒絕用戶的內(nèi)存申請(qǐng),否則就給予相應(yīng)內(nèi)存并在cgroup的統(tǒng)計(jì)信息中記錄。實(shí)際實(shí)現(xiàn)要比上述描述復(fù)雜的多,不僅需要考慮內(nèi)存的分配和回收,還需要考慮不同類型的內(nèi)存如cache和swap等。
進(jìn)程所需的內(nèi)存超過(guò)它所屬的cgroup最大限額以后,如果設(shè)置了OOM Control(內(nèi)存超限控制),那么進(jìn)程就會(huì)收到OOM信號(hào)并結(jié)束;否則進(jìn)程就會(huì)被掛起,進(jìn)入睡眠狀態(tài),進(jìn)入睡眠狀態(tài),直到cgroup中其他進(jìn)程釋放了足夠的內(nèi)存資源為止。Docker中默認(rèn)是開(kāi)啟OOM Control的。其他子系統(tǒng)的實(shí)現(xiàn)與此類似,cgroups提供了多種資源限制的策略供用戶選擇。
cgroup與任務(wù)之間的關(guān)聯(lián)關(guān)系
實(shí)現(xiàn)上,cgroup與任務(wù)之間是多對(duì)多關(guān)系,所以它們并不直接關(guān)聯(lián),而是通過(guò)一個(gè)中間結(jié)構(gòu)把雙向的關(guān)聯(lián)信息記錄起來(lái)。每個(gè)任務(wù)結(jié)構(gòu)體tsak_struct中都包含了一個(gè)指針,可以查到對(duì)應(yīng)的cgroup的情況,同時(shí)也可以查詢到各個(gè)子系統(tǒng)的狀態(tài),這些子系統(tǒng)狀態(tài)中也包含了找到任務(wù)的指針,不同類型的子系統(tǒng)按需定義本身的控制信息結(jié)構(gòu)體,最終在地定義的結(jié)構(gòu)體中吧子系統(tǒng)狀態(tài)指針包含進(jìn)去,然后內(nèi)核通過(guò)container_of(這個(gè)宏可以通過(guò)一個(gè)結(jié)構(gòu)體的成員找到結(jié)構(gòu)體自身)等宏定義來(lái)獲取對(duì)應(yīng)的結(jié)構(gòu)體,關(guān)聯(lián)到任務(wù),從此達(dá)到資源限制的目的。同時(shí),為了讓cgroups便于用戶理解和使用,也為了用精簡(jiǎn)的內(nèi)核代買(mǎi)為cgroup提供熟悉的權(quán)限和命名空間管理,內(nèi)核開(kāi)發(fā)者們按照Linux虛擬文件轉(zhuǎn)化器(Virtual Filesystem Switch,VFS)接口實(shí)現(xiàn)了一套名為cgroup的文件系統(tǒng),非常巧的用來(lái)表示cgroups的層級(jí)概念,把各個(gè)子系統(tǒng)的實(shí)現(xiàn)都瘋撞到文件系統(tǒng)的各項(xiàng)操作中。
Docker在使用cgroup時(shí)的注意事項(xiàng)
在實(shí)際使用過(guò)程中,Docker需要通過(guò)掛載cgroup文件系統(tǒng)新建一個(gè)層級(jí)結(jié)構(gòu),掛載時(shí)指定要綁定的子系統(tǒng)。把cgroup文件系統(tǒng)掛載上以后,就可以像操作文件一樣對(duì)cgroup的層級(jí)進(jìn)行瀏覽和操作管理(包括權(quán)限管理、子文件管理等)。除了cgroup文件系統(tǒng)以外,內(nèi)核沒(méi)有為cgroups的訪問(wèn)和操作添加任何系統(tǒng)調(diào)用。
/sys/fs/cgroup/cpu/docker/下文件的作用
前面已經(jīng)說(shuō)過(guò),以資源開(kāi)頭的文件都是用來(lái)限制這個(gè)cgroup下任務(wù)的可用配置文件。
一個(gè)cgroup創(chuàng)建完成,不管綁定了何種子系統(tǒng),其目錄下都會(huì)生成以下幾個(gè)文件,用來(lái)描述cgroup的相應(yīng)信息。同樣,把相應(yīng)信息寫(xiě)入這些配置文件中就可以生效。
本文由淺入深的講解了cgroups,從cgroups是什么,到cgroups要怎么用,最后對(duì)大量的cgroup子系統(tǒng)進(jìn)行了講解。可以看到內(nèi)核對(duì)cgroups的支持已經(jīng)較多,但是依舊有許多工作要完善。如網(wǎng)絡(luò)方面目前通過(guò)TC(Traffic Controller)來(lái)控制,未來(lái)需要統(tǒng)一整合;由縣級(jí)調(diào)度方面依舊有很大的改進(jìn)空間。
? ? ? CPU資源的控制也有兩種策略,
一種是完全公平調(diào)度 (CFS:Completely 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)度策略下的配置
設(shè)定CPU使用周期使用時(shí)間上限
cpu.cfs_period_us:設(shè)定周期時(shí)間,必須與cfs_quota_us配合使用。
cpu.cfs_quota_us :設(shè)定周期內(nèi)最多可使用的時(shí)間。這里的配置指task對(duì)單個(gè)cpu的使用上限,若cfs_quota_us是cfs_period_us的兩倍,就表示在兩個(gè)核上完全使用。數(shù)值范圍為1000 - 1000,000(微秒)。
cpu.stat:統(tǒng)計(jì)信息,包含nr_periods(表示經(jīng)歷了幾個(gè)cfs_period_us周期)、nr_throttled(表示task被限制的次數(shù))及throttled_time(表示task被限制的總時(shí)長(zhǎng))。
按權(quán)重比例設(shè)定CPU的分配
cpu.shares:設(shè)定一個(gè)整數(shù)(必須大于等于2)表示相對(duì)權(quán)重,最后除以權(quán)重總和算出相對(duì)比例,按比例分配CPU時(shí)間。(如cgroup A設(shè)置100,cgroup B設(shè)置300,那么cgroup A中的task運(yùn)行25%的CPU時(shí)間。對(duì)于一個(gè)4核CPU的系統(tǒng)來(lái)說(shuō),cgroup A 中的task可以100%占有某一個(gè)CPU,這個(gè)比例是相對(duì)整體的一個(gè)值。)
? ? ? ? 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í)間。
cpuacct資源報(bào)告
? ? 這個(gè)子系統(tǒng)的配置是cpu子系統(tǒng)的補(bǔ)充,提供CPU資源用量的統(tǒng)計(jì),時(shí)間單位都是納秒。
cpuacct.usage:統(tǒng)計(jì)cgroup中所有task的cpu使用時(shí)長(zhǎng)
cpuacct.stat:統(tǒng)計(jì)cgroup中所有task的用戶態(tài)和內(nèi)核態(tài)分別使用cpu的時(shí)長(zhǎng)
cpuacct.usage_percpu:統(tǒng)計(jì)cgroup中所有task使用每個(gè)cpu的時(shí)長(zhǎng)
cpuset
? ? ?為task分配獨(dú)立CPU資源的子系統(tǒng),參數(shù)較多,這里只選講兩個(gè)必須配置的參數(shù),同時(shí)Docker中目前也只用到這兩個(gè)。
cpuset.cpus:可使用的CPU編號(hào),如0-2,16代表 0、1、2和16這4個(gè)CPU
cpuset.mems:與CPU類似,表示cgroup可使用的memory node,格式同上,NUMA系統(tǒng)使用
device ( 限制task對(duì)device的使用)
? ? ?設(shè)備黑/白名單過(guò)濾
devices.allow:允許名單,語(yǔ)法type device_types:node_numbers access type ;type有三種類型:b(塊設(shè)備)、c(字符設(shè)備)、a(全部設(shè)備);access也有三種方式:r(讀)、w(寫(xiě))、m(創(chuàng)建)
devices.deny:禁止名單,語(yǔ)法格式同上
? ? 統(tǒng)計(jì)報(bào)告
? devices.list:報(bào)???告???為???這???個(gè)??? cgroup 中???的?task設(shè)???定???訪???問(wèn)???控???制???的???設(shè)???備
freezer - 暫停/恢復(fù)cgroup中的task
? ? ? 只有一個(gè)屬性,表示進(jìn)程的狀態(tài),把task放到freezer所在的cgroup,再把state改為FROZEN,就可以暫停進(jìn)程。不允許在cgroup處于FROZEN狀態(tài)時(shí)加入進(jìn)程。freezer.state 包括如下三種狀態(tài):
- FROZEN 停止
- FREEZING 正在停止,這個(gè)是只讀狀態(tài),不能寫(xiě)入這個(gè)值。
- THAWED 恢復(fù)
memory (內(nèi)存資源管理)
memory.limit_bytes:強(qiáng)制限制最大內(nèi)存使用量,單位有k、m、g三種,填-1則代表無(wú)限制
memory.soft_limit_bytes:軟限制,只有比強(qiáng)制限制設(shè)置的值小時(shí)才有意義
memory.memsw.limit_bytes:設(shè)定最大內(nèi)存與swap區(qū)內(nèi)存之和的用量限制
memory.oom_control: 0表示開(kāi)啟,當(dāng)cgroup中的進(jìn)程使用資源超過(guò)界限時(shí)立即殺死進(jìn)程。默認(rèn)包含memory子系統(tǒng)的cgroup都啟用。當(dāng)oom_control不啟用時(shí),實(shí)際使用內(nèi)存超過(guò)界限時(shí)進(jìn)程會(huì)被暫停直到有空閑的內(nèi)存資源
? ? ?統(tǒng)計(jì)
memory.usage_bytes:報(bào)???告???該??? cgroup中???進(jìn)???程???使???用???的???當(dāng)???前???總???內(nèi)???存???用???量(以字節(jié)為單位)
memory.max_usage_bytes:報(bào)???告???該??? cgroup 中???進(jìn)???程???使???用???的???最???大???內(nèi)???存???用???量
memory.failcnt:報(bào)???告???內(nèi)???存???達(dá)???到???在??? memory.limit_in_bytes設(shè)???定???的???限???制???值???的???次???數(shù)???
memory.stat:包含大量的內(nèi)存統(tǒng)計(jì)數(shù)據(jù)。
cache:頁(yè)???緩???存???,包???括??? tmpfs(shmem),單位為字節(jié)。
rss:匿???名???和??? swap 緩???存???,不???包???括??? tmpfs(shmem),單位為字節(jié)。
mapped_file:memory-mapped 映???射???的???文???件???大???小???,包???括??? tmpfs(shmem),單???位???為???字???節(jié)???
pgpgin:存???入???內(nèi)???存???中???的???頁(yè)???數(shù)???
pgpgout:從???內(nèi)???存???中???讀???出???的???頁(yè)???數(shù)
swap:swap 用???量???,單???位???為???字???節(jié)???
active_anon:在???活???躍???的???最???近???最???少???使???用???(least-recently-used,LRU)列???表???中???的???匿???名???和??? swap 緩???存???,包???括??? tmpfs(shmem),單???位???為???字???節(jié)???
inactive_anon:不???活???躍???的??? LRU 列???表???中???的???匿???名???和??? swap 緩???存???,包???括??? tmpfs(shmem),單???位???為???字???節(jié)
active_file:活???躍??? LRU 列???表???中???的??? file-backed 內(nèi)???存???,以???字???節(jié)???為???單???位
inactive_file:不???活???躍??? LRU 列???表???中???的??? file-backed 內(nèi)???存???,以???字???節(jié)???為???單???位
unevictable:無(wú)???法???再???生???的???內(nèi)???存???,以???字???節(jié)???為???單???位???
hierarchical_memory_limit:包???含??? memory cgroup 的???層???級(jí)???的???內(nèi)???存???限???制???,單???位???為???字???節(jié)???
hierarchical_memsw_limit:包???含??? memory cgroup 的???層???級(jí)???的???內(nèi)???存???加??? swap 限???制???,單???位???為???字???節(jié)???
Docker: 限制容器可用的 CPU
? ? ? 通過(guò) --cpus 選項(xiàng)指定容器可以使用的 CPU 個(gè)數(shù),這個(gè)還是默認(rèn)設(shè)置了cpu.cfs_period_us(100000)和cpu.cfs_quota_us(200000)
實(shí)驗(yàn):
docker run -itd --name c1 centos:7 /bin/bash
docker ps -a
cd /sys/fs/cgroup/cpu/docker/容器的ID號(hào)/
cat cpu.cfs_quota_us ? #默認(rèn)情況是-1,表示不限額
cat cpu.cfs_period_us ? #默認(rèn)情況是100000
?docker ps -a
docker exec -it c1 bash
vi /cpu.sh
#!/bin/bash
i=0
while true
do
let i++;
done
chmod +x /cpu.sh ./cpu.sh
?
————————————————
版權(quán)聲明:本文為CSDN博主「FYR@」的原創(chuàng)文章
原文鏈接:https://blog.csdn.net/FYR1018/article/details/125603891
本文為CSDN博主「張忠琳」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,
原文鏈接:https://blog.csdn.net/zhonglinzhang/article/details/64905759
本文為CSDN博主「站在這別動(dòng),我去給你買(mǎi)橘子」的原創(chuàng)文章
原文鏈接:https://blog.csdn.net/qq_62462797/article/details/127975686
總結(jié)
以上是生活随笔為你收集整理的docker网络原理及cgroup的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2022-2028全球及中国健康资讯交换
- 下一篇: 火箭双杀尼克斯 哈林组合和砍50分