首页 > 其他分享 >500行代码手写docker-实现硬件资源限制cgroups

500行代码手写docker-实现硬件资源限制cgroups

时间:2023-05-29 11:26:08浏览次数:37  
标签:硬件资源 fs cgroups sys cgroup test docker root cpu

(5)500行代码手写docker-实现硬件资源限制cgroups

本系列教程主要是为了弄清楚容器化的原理,纸上得来终觉浅,绝知此事要躬行,理论始终不及动手实践来的深刻,所以这个系列会用go语言实现一个类似docker的容器化功能,最终能够容器化的运行一个进程。

本章的源码已经上传到github,地址如下:

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

之前我们对容器的网络命名空间,文件系统命名空间都进行了配置,说到底这些都是为了资源更好的隔离,但是他们无法办到对硬件资源使用的隔离,比如,cpu,内存,带宽,而今天要介绍的cgroups技术便能够对硬件资源的使用产生隔离。

cgroups技术简介

cgroups技术是内核提供的功能,可以通过虚拟文件系统接口对其进行访问和更改。mount 命令可以查看cgroups在虚拟文件系统下的挂载目录。

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 目录下,系统内核在开机时,会默认挂载cgroup目录。这样便能通过访问文件的方式对cgroup功能进行使用。

在/sys/fs/cgroup/ 目录下,我们看到的每个目录例如cpu,blkio被称作subsystem子系统,每个子系统下可以设置各自要管理的进程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子系统这个目录下,有两个文件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命令查看他们的内容。

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一个调度周期内,该cgroup下的进程最多只能运行半个周期,如果达到了运行周期的限制,那么它必须等待下一个时间片才能继续运行了。

命名行实践下cgroups隔离特性

我们来实验下:

对cpu使用率进行限制

在cpu的一级目录下,是包含了当前系统所有进程,为了不影响它们,我们在cpu的一级目录下创建一个test目录,然后单独的在test目录中的tasks文件加入进程id。

标签:硬件资源,fs,cgroups,sys,cgroup,test,docker,root,cpu
From: https://www.cnblogs.com/hobbybear/p/17439897.html

相关文章

  • ubuntu22安装docker、redis、mysql及部署net6应用
    一、更新系统软件包索引sudoaptupdate二、安装dockersudoaptinstalldocker.io三、在docker中安装Mysql拉取mysql镜像dockerpullmysql:latest查看镜像dockerimages运行容器dockerrun-itd-p3306:3306-eMYSQL_ROOT_PASSWORD=123456--namemysql......
  • docker
    镜像与容器镜像:镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成(当docker进入莫名其妙的"编辑模式时",ctrl+c可退出)各种相关命令:镜像相关:(dockercommit容器名称(实)镜像名称(形参);把容器生成为镜像,再由镜像转成tar包。tar包可直接copy到任......
  • Docker Desktop 错误:必须在BIOS中启用 硬件辅助虚拟化和数据执行保护
    一、检查Hyper-V是否开启控制面板—》程序----》启用或关闭Windows功能二、重装DockerDesktopDocker的安装就不在赘述了,按照官网安装即可,需要注意的是win10家庭版的需要安装WSL2–即linux的虚拟机内核,官网也有详细安装步骤三、重新配置Hyper-V(生效)经过无数次重启,安......
  • docker 搭建zabbix-server
    一、zabbix的构架信息1.1zabbix-serverzabbix的server端,负责接受zabbix-agent的监控数据,并且提供各种zabbix的监控功能1.2database用户存储zabbix-agent,或者代理层的数据,本文只使用mysql1.3zabbix-webzabbix的web端,用户监控的展示和一些监控的配置1.4zabbix-java-g......
  • docker部署nacos集群
    1.环境准备准备4台服务器,一台安装nginx和mysql另三台做集群使用IP服务操作系统192.168.3.215Nginx/MysqlCentOS7.9192.168.3.216Nacos-1CentOS7.9192.168.3.217Nacos-2CentOS7.9192.168.3.218Nacos-3CentOS7.9     mysql选用5.7......
  • docker存储
    1、概念1.1、容器本地存储与Docke存储驱动容器本地存储:每个容器都被自动分配了内部存储,即容器本地存储。采用的是联合文件系统。通过存储驱动进行管理。容器本地存储空间:分层结构构成,由一个可写容器层和若干只读的镜像层组成。联合文件系统:Docker的一种底层技术,由存储驱动(StorageD......
  • Docker笔记五之Docker系统变量
    本文首发于公众号:Hunter后端原文链接:Docker笔记五之Docker系统变量当我们运行一个容器的时候是可以向容器内部指定某些变量值的,比如上一篇MySQL笔记中的参数是通过容器运行的时候-e来指定的。往容器里指定变量,有如下几种方法:Dockerfile中定义运行容器的时候指定变量参......
  • docker安装mysql
    转载请注明出处:1.从DockerHub下载MySQL镜像:dockerpullmysql2.运行MySQL容器,并将主机的3306端口映射到容器的3306端口:dockerrun-p3306:3306--namemysql-eMYSQL_ROOT_PASSWORD=your_password-dmysql其中,--namemysql指定容器的名称为mysql,-p3306......
  • docker的CMD和ENTRYPOINT
    在Dockerfile中,`CMD`和`ENTRYPOINT`都用于定义容器启动时要执行的命令或程序,但它们有一些关键的区别。1.`CMD`的作用:-`CMD`指令用于设置容器启动时的默认命令或程序。-`CMD`可以在Dockerfile中只出现一次,如果有多个`CMD`指令,只有最后一个指令会生效。-`......
  • dockerfile里的EXPOSE
    在Dockerfile中,`EXPOSE`指令用于声明容器运行时将要监听的网络端口。`EXPOSE`并不会实际打开容器的端口,它只是向用户和开发人员提供了容器内部服务的网络接口信息。通过在Dockerfile中使用`EXPOSE`,你可以向其他人传达容器暴露的网络服务和端口,以便更好地理解容器的使用和......