国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

500行代碼手寫docker-實現(xiàn)硬件資源限制cgroups

這篇具有很好參考價值的文章主要介紹了500行代碼手寫docker-實現(xiàn)硬件資源限制cgroups。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

(5)500行代碼手寫docker-實現(xiàn)硬件資源限制cgroups

本系列教程主要是為了弄清楚容器化的原理,紙上得來終覺淺,絕知此事要躬行,理論始終不及動手實踐來的深刻,所以這個系列會用go語言實現(xiàn)一個類似docker的容器化功能,最終能夠容器化的運行一個進程。

本章的源碼已經(jīng)上傳到github,地址如下:

https://github.com/HobbyBear/tinydocker/tree/chapter5

之前我們對容器的網(wǎng)絡(luò)命名空間,文件系統(tǒng)命名空間都進行了配置,說到底這些都是為了資源更好的隔離,但是他們無法辦到對硬件資源使用的隔離,比如,cpu,內(nèi)存,帶寬,而今天要介紹的cgroups技術(shù)便能夠?qū)τ布Y源的使用產(chǎn)生隔離。

cgroups技術(shù)簡介

cgroups技術(shù)是內(nèi)核提供的功能,可以通過虛擬文件系統(tǒng)接口對其進行訪問和更改。mount 命令可以查看cgroups在虛擬文件系統(tǒng)下的掛載目錄。

root@ecs-295280:~# mount | grep  cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
root@ecs-295280:~#

一般默認的掛載目錄是在/sys/fs/cgroup 目錄下,系統(tǒng)內(nèi)核在開機時,會默認掛載cgroup目錄。這樣便能通過訪問文件的方式對cgroup功能進行使用。

在/sys/fs/cgroup/ 目錄下,我們看到的每個目錄例如cpu,blkio被稱作subsystem子系統(tǒng),每個子系統(tǒng)下可以設(shè)置各自要管理的進程id。

root@ecs-295280:~# ls /sys/fs/cgroup/
blkio    cpu,cpuacct  freezer  net_cls           perf_event  systemd
cpu      cpuset       hugetlb  net_cls,net_prio  pids        unified
cpuacct  devices      memory   net_prio          rdma

拿cpu這個目錄下的文件舉例

root@ecs-295280:/sys/fs/cgroup/cpu# ls
cgroup.clone_children  cpuacct.usage_percpu_sys   cpu.stat
cgroup.procs           cpuacct.usage_percpu_user  ebpf-agent
cgroup.sane_behavior   cpuacct.usage_sys          hostguard
cpuacct.stat           cpuacct.usage_user         notify_on_release
cpuacct.usage          cpu.cfs_period_us          release_agent
cpuacct.usage_all      cpu.cfs_quota_us           tasks
cpuacct.usage_percpu   cpu.shares
root@ecs-295280:/sys/fs/cgroup/cpu# ll -l

在cpu子系統(tǒng)這個目錄下,有兩個文件cgroup.procs,tasks文件,它們都是用來管理cgroup中的進程。但是,它們的使用方式略有不同:

cgroup.procs文件用于向cgroup中添加或刪除進程,只需要將進程的task id寫入該文件即可。

tasks文件則是用于將整個進程組添加到cgroup中。如果將一個進程組的pid寫入tasks文件,則該進程組中的所有進程都會被添加到cgroup中。

進程被加入到這個cgroup組以后,其使用的cpu帶寬將會受到cpu.cfs_quota_us和cpu.cfs_period_us的影響。通過shell命令查看他們的內(nèi)容。

root@ecs-295280:/sys/fs/cgroup/cpu/test# cat cpu.cfs_period_us
100000
root@ecs-295280:/sys/fs/cgroup/cpu/test# cat cpu.cfs_quota_us
-1

默認情況下,cpu.cfs_period_us是100000,單位是微秒,cpu.cfs_period_us代表了cpu運行一個周期的時長,100000代表了100ms,cpu.cfs_quota_us代表進程所占用的周期時長,-1代表不限制進程使用cpu周期時長,如果cpu.cfs_quota_us是50000(50ms)則代表在cpu一個調(diào)度周期內(nèi),該cgroup下的進程最多只能運行半個周期,如果達到了運行周期的限制,那么它必須等待下一個時間片才能繼續(xù)運行了。

命名行實踐下cgroups隔離特性

我們來實驗下:

對cpu使用率進行限制

在cpu的一級目錄下,是包含了當(dāng)前系統(tǒng)所有進程,為了不影響它們,我們在cpu的一級目錄下創(chuàng)建一個test目錄,然后單獨的在test目錄中的tasks文件加入進程id。

???? ??cgroup的每個子系統(tǒng)是分級的,這個級別體現(xiàn)在目錄層級上,默認子目錄會繼承父目錄的屬性,子目錄也可以通過修改子目錄下的文件,來覆蓋掉父目錄的屬性。

root@ecs-295280:/sys/fs/cgroup/cpu/test# pwd
/sys/fs/cgroup/cpu/test

設(shè)置cpu.cfs_quota_us為一個時間片的一半,設(shè)置tasks,把當(dāng)前進程加入到cgroup中

root@ecs-295280:/sys/fs/cgroup/cpu/test# cat cpu.cfs_quota_us
50000
root@ecs-295280:/sys/fs/cgroup/cpu/test# sh -c "echo $$ > tasks"
root@ecs-295280:/sys/fs/cgroup/cpu/test# cat tasks
65961
66314

在當(dāng)前shell 界面,通過stress對cpu進行壓力測試。我的虛擬機是一個核,我這里直接通過stress對這一個cpu核進行壓測。

root@ecs-295280:/sys/fs/cgroup/cpu/test# stress --cpu 1 --timeout 60

啟動另一個終端,查看cpu占用情況

Tasks:  94 total,   2 running,  92 sleeping,   0 stopped,   0 zombie
%Cpu(s): 51.9 us,  0.0 sy,  0.0 ni, 48.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1982.9 total,    451.3 free,    193.4 used,   1338.2 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1597.9 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  66333 root      20   0    3856    100      0 R  50.3   0.0   0:06.00 stress
      1 root      20   0  102780  12420   8236 S   0.0   0.6   0:05.93 systemd

可以看到的是cpu占用率在達到百分之50時就不上去了,這正是由于stress進程是bash進程的子進程,繼承了bash進程的cgroup,所以cpu使用率受到了限制。

對內(nèi)存使用率進行限制

再來看看如何通過cgroup對內(nèi)存進行限制,這次我們就應(yīng)該進入到memory這個子系統(tǒng)的目錄了,同樣我們在其下面創(chuàng)建一個test目錄。

root@ecs-295280:/sys/fs/cgroup/memory# mkdir test
root@ecs-295280:/sys/fs/cgroup/memory# cd test/
root@ecs-295280:/sys/fs/cgroup/memory/test# pwd
/sys/fs/cgroup/memory/test

然后把當(dāng)前進程加進去

root@ecs-295280:/sys/fs/cgroup/memory/test# sh -c "echo $$ > tasks"
root@ecs-295280:/sys/fs/cgroup/memory/test# cat tasks
65961
66476

設(shè)置最大使用內(nèi)存,memory目錄下限制最大使用內(nèi)存需要設(shè)置memory.limit_in_bytes 這個文件,默認情況下,它是一個大的離譜的值,我們將它改為100M

root@ecs-295280:/sys/fs/cgroup/memory/test# cat memory.limit_in_bytes
9223372036854771712
root@ecs-295280:/sys/fs/cgroup/memory/test# vim memory.limit_in_bytes
root@ecs-295280:/sys/fs/cgroup/memory/test# cat memory.limit_in_bytes
104857600

這個時候通過stress 對內(nèi)存進行壓力測試,我們限制了100M,但是如果stress要求分配200M內(nèi)存,看看能正常分配嗎?

root@ecs-295280:/sys/fs/cgroup/memory/test# stress --vm-bytes 200m --vm-keep  -m 1
stress: info: [66533] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [66533] (415) <-- worker 66534 got signal 9
stress: WARN: [66533] (417) now reaping child worker processes
stress: FAIL: [66533] (451) failed run completed in 0s

可以看到的是,程序崩潰了,原因則是由于發(fā)生了oom,因為內(nèi)存已經(jīng)被我們限制到了100M,通過test目錄下的memory.oom_control文件可以看到發(fā)生oom的次數(shù)。

oom_kill_disable 0
under_oom 0
oom_kill 1

oom_kill 為1代表發(fā)生oom后,進程被kill掉的次數(shù)。

在簡單看完cgroup如何對cpu和內(nèi)存進行限制以后,看看golang代碼如何實現(xiàn)。

golang代碼實現(xiàn)cgroups配置

在用代碼對cgroup的操作本質(zhì)上就是對cgroup的文件進行操作。

cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		err = cmd.Start()
		if err != nil {
			fmt.Println(err)
		}

		containerName := os.Args[2]
		if err := cgroups.ConfigDefaultCgroups(cmd.Process.Pid, containerName); err != nil {
			log.Error("config cgroups fail %s", err)
		}

		if err := network.ConfigDefaultNetworkInNewNet(cmd.Process.Pid); err != nil {
			log.Error("config network fail %s", err)
		}
		cmd.Wait()
		cgroups.CleanCgroupsPath(containerName)

在前面代碼的基礎(chǔ)上,啟動子進程后,父進程把子進程pid添加到一個新的cgroup中,cgroups.ConfigDefaultCgroups方法用于實現(xiàn)對cgroup的控制,以容器名作為cgroup子系統(tǒng)的目錄,然后當(dāng)子進程容器執(zhí)行完畢后,通過cgroups.CleanCgroupsPath去對cgroup相關(guān)目錄進行清理。

func CleanCgroupsPath(containerName string) error {
	output, err := exec.Command("cgdelete", "-r", fmt.Sprintf("memory:%s/%s", dockerName, containerName)).Output()
	if err != nil {
		log.Error("cgdelete fail err=%s output=%s", err, string(output))
	}
	output, err = exec.Command("cgdelete", "-r", fmt.Sprintf("cpu:%s/%s", dockerName, containerName)).Output()
	if err != nil {
		log.Error("cgdelete fail err=%s output=%s", err, string(output))
	}
	return nil
}

清理cgroup的方式我用了cgdelete 命令 刪除掉容器cgroup的配置,直接remove刪除會出現(xiàn)刪除失敗情況。

總結(jié)

這也是我對于手寫容器系列的終章,算是對容器原理的一個入門級講解,其實后續(xù)還可以針對它做很多優(yōu)化,比如實現(xiàn)不同主機上的容器互聯(lián),實現(xiàn)容器日志的功能,實現(xiàn)端口映射,實現(xiàn)卷映射功能,這些功能其實都是建立在我們講的容器原理之上的,懂了原理便能一通百通,希望能給你帶來啟發(fā)。文章來源地址http://www.zghlxwxcb.cn/news/detail-463089.html

到了這里,關(guān)于500行代碼手寫docker-實現(xiàn)硬件資源限制cgroups的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 500行代碼代碼手寫docker-將rootfs設(shè)置為只讀鏡像

    500行代碼代碼手寫docker-將rootfs設(shè)置為只讀鏡像

    本系列教程主要是為了弄清楚容器化的原理,紙上得來終覺淺,絕知此事要躬行,理論始終不及動手實踐來的深刻,所以這個系列會用go語言實現(xiàn)一個類似docker的容器化功能,最終能夠容器化的運行一個進程。 本章的源碼已經(jīng)上傳到github,地址如下: 前文提到,如果僅僅將u

    2024年02月06日
    瀏覽(19)
  • 500行代碼手寫docker-以新命名空間運行程序

    500行代碼手寫docker-以新命名空間運行程序

    本系列教程主要是為了弄清楚容器化的原理,紙上得來終覺淺,絕知此事要躬行,理論始終不及動手實踐來的深刻,所以這個系列會用go語言實現(xiàn)一個類似docker的容器化功能,最終能夠容器化的運行一個進程。 本章的源碼已經(jīng)上傳到github,地址如下: 本章要完成的任務(wù)則是g

    2024年02月05日
    瀏覽(23)
  • 500行代碼手寫docker開篇-goland遠程編譯環(huán)境配置

    500行代碼手寫docker開篇-goland遠程編譯環(huán)境配置

    本系列教程主要是為了弄清楚容器化的原理,紙上得來終覺淺,絕知此事要躬行,理論始終不及動手實踐來的深刻,所以這個系列會用go語言實現(xiàn)一個類似docker的容器化功能,最終能夠容器化的運行一個進程。 代碼最終運行效果 本系列源碼已經(jīng)上傳到github,地址如下: 在開始

    2024年02月05日
    瀏覽(23)
  • 使用cgroup工具對服務(wù)器某些/全部用戶進行計算資源限制

    使用cgroup工具對服務(wù)器某些/全部用戶進行計算資源限制

    主要介紹,如何對指定/所有用戶進行資源限定(這里主要介紹cpu和內(nèi)存占用限制),防止某些用戶大量占用服務(wù)器計算資源,影響和擠占他人正常使用服務(wù)器。 安裝 cgroup 管理工具 使用 mount -t cgroup 命令檢查驗證 可以通過編寫 /etc/cgconfig.conf 和 /etc/cgrules.conf 文件進行計算資

    2024年02月10日
    瀏覽(28)
  • Docker資源控制cgroups

    Docker資源控制cgroups

    Docker 通過 Cgroup 來控制容器使用的資源配額,包括 CPU、內(nèi)存、磁盤三大方面, 基本覆蓋了常見的資源配額和使用量控制。 Cgroup 是 ControlGroups 的縮寫,是 Linux 內(nèi)核提供的一種可以限制、記錄、隔離進程組所使用的物理資源(如 CPU、內(nèi)存、磁盤 IO 等等) 的機制,被 LXC、docker 等

    2024年02月10日
    瀏覽(18)
  • 【云原生】Docker Cgroups資源控制管理

    【云原生】Docker Cgroups資源控制管理

    目錄 一、cgroups簡介 cgroups有四大功能: 二、cpu時間片的概念 三、對CPU使用的限制 3.1 設(shè)置CPU使用率上限 (1)查看容器的默認CPU使用限制 (2)進行壓力測試 (3)創(chuàng)建容器時設(shè)置CPU使用時間限制 (4)對已存在的容器進行CPU限制 3.2 設(shè)置CPU資源占用比(設(shè)置多個容器時才有效

    2024年02月12日
    瀏覽(23)
  • 十七、Docker之Cgroup資源配置

    其實在日常的工作中,我們一般都沒有對docker容器進行資源限制,也就是默認情況下,可以使用宿主機的所有資源。但是如果你運行的服務(wù)有問題,就有可能對宿主機和宿主機上的其他業(yè)務(wù)造成影響,這還是有一定的風(fēng)險。那么本文會給大家介紹一下如何對容器進行資源配置

    2024年02月16日
    瀏覽(20)
  • docker cgroup資源占用及docker的鏡像創(chuàng)建

    docker cgroup資源占用及docker的鏡像創(chuàng)建

    基本復(fù)寫了常見的資源配額和使用量控制 cgroup是controlgroup的縮寫 設(shè)置cpu使用率的上限 linux通過cfs(完全公平調(diào)度器)來調(diào)度各個進程對cpu的使用,cfs默認的調(diào)度周期是100ms 我們可以設(shè)置每個容器進程的調(diào)度周期,以及再這個周期內(nèi)各個容器最多能使用cpu時間。 cpu分多少時間

    2024年02月08日
    瀏覽(25)
  • 【云原生】Docker網(wǎng)絡(luò)及Cgroup資源控制

    【云原生】Docker網(wǎng)絡(luò)及Cgroup資源控制

    Docker使用Linux橋接,在宿主機虛擬一個Docker容器網(wǎng)橋(docker0),Docker啟動一個容器時會根據(jù)Docker網(wǎng)橋的網(wǎng)段分配給容器一個IP地址,稱為Container-IP,同時Docker網(wǎng)橋是每個容器的默認網(wǎng)關(guān)。因為在同一宿主機內(nèi)的容器都接入同一個網(wǎng)橋,這樣容器之間就能夠通過容器的 Container-IP 直

    2024年02月16日
    瀏覽(29)
  • linux 內(nèi)核資源配置--cgroups詳解以及在docker中的應(yīng)用

    linux 內(nèi)核資源配置--cgroups詳解以及在docker中的應(yīng)用

    1.1、cgroups 是什么 Linux cgroup (Control Groups)是 Linux 內(nèi)核提供的一種機制, 用于限制進程組使用的資源(如 CPU、內(nèi)存、磁盤 I/O 等) 。通過將進程組劃分為層次結(jié)構(gòu),并將資源限制應(yīng)用于不同層次的組,可以實現(xiàn)對系統(tǒng)資源的統(tǒng)一管理和限制。 cgroup 提供了一套 API,用于創(chuàng)建

    2024年02月16日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包