Linux Cgroups 详解

Namespace是用來實現進程之間的隔離,但是并没有限制其空间的大小。如果想要限制一个进程可以使用的空间,保证各个进程之间不会互相争抢就要用到 Cgroups。

Linux Cgroups(Linux Control Groups)提供了对一组进程及将来子进程的资源限制、控制、统计的能力。这些资源包括

cpu、内存、存储、网络 等

。通过Cgroups,可以方便的控制某个进程占用的资源,并可以实施监控和统计信息。

Cgroups中的三个组件

cgroup 是对进程分组管理的一种机制,一个cgroup包含一组进程,并可以在这个cgroup上增加Linux subsystem的各种参数配置,将一组进程和一 组subsystem的系统参数关联起来。

subsystem 是一组资源控制的模块。包含以下几项。

blkio 设置对块设备输入输出的访问控制。例如磁盘

cpu 设置cgroup中进程的cpu被调度策略。

cpuacct 可以统计cgroup中进程的cpu占用。

cpuset 在多核机器上,设置cgroup中进程可以使用的cpu和内存。此处仅限于NUMA架构。

devices 控制cgroup对设备的访问。

freezer 挂起(suspend)和恢复(resue) cgroup中的进程。

memory 用于控制cgroup中进程的内存占用。

net_cls 将cgroup中进程产生的网络包分类,便于linux tc(traffic controller)可以根据分类区分出来自某个cgroup包并做监控。

net_prio 设置cgroup中进程产生的网络流量的优先级。

ns 使cgroup中的进程在新的Namespace中fork新进程时,创建一个新的cgroup,这个cgroup包含新的Namespace中的进程。

每个subsystem会关联到定义的cgroup,并对这个cgroup中的进程做限制和控制。这些subsystem是逐步合并到内核中的,可以安装apt-get install cgroup-bin 然后通过

lssubsys -a

查看

hierarchy 把一组cgroup串成一个柱状结构,这样的树便是一个hierarchy,通过这种结构,Cgroups可以做到继承。

三个组件的关系

系统创建hierarchy 之后,所有的进程都会加入这个hierarchy的cgroup的根节点。在这个cgroup根节点是hierarchy默认创建的。

一个subsystem只能附加到一个hierarchy上面。

一个进程可以作为多个cgroup的成员,但是cgroup必须在不同的hierarchy中。

一个进程fork的子进程和父进程在同一个cgroup中也可以根据需要移到其他cgroup中。

Kernel接口

前面说道Cgroups中的hierarchy是一种树状结构,Kernel为了对Cgroups的配置更直观,也会显示为树状结构。下面进行实例,了解如何操作Cgroups。

首先创建并挂在一个hierarchy(cgroup树),如下.

leon@leon:~$ mkdir cgroup-test

leon@leon:~$ sudo mount -t cgroup -o none,name=cgroup1 cgroup1 ./cgroup-test/

leon@leon:~$ ls ./cgroup-test/

cgroup.clone_children  cgroup.procs  cgroup.sane_behavior  notify_on_release  release_agent  tasks

这些文件就是这个hierarchy中cgroup根节点的配置项,上面这些文件含义如下。

cgroup.clone_children, cpuset的subsystem会读取这个文件的配置,如果值是1(默认值0),子cgroup才会继承父cgroup的cpuset配置。

cgroup.procs 是树中当前结点cgroup的进程组id,现在的位置是在根节点,这个文件中会有现在系统中所有进程组的ID。

notify_on_release和release_agent会在一起使用。notify_on_release标识当这个cgroup最后一个进程退出的时候是否执行了 release_agent;release_agent则是一个路径,通常用作进程退出后自动清理掉不再使用的cgroup。

tasks标识该cgroup下面的进程ID,如果把一个进程ID写到tasks中便会将相应的进程加入到这个cgroup中。

然后创建刚才建立的hierarchy上cgroup根节点中扩展出的两个子cgroup。

可以看到创建子文件夹的同时,Kernel会标记这个cgroup的子cgroup,他们会继承父cgroup的属性。

在cgroup中添加和移动进程 一个进程在Cgroups的hierarchy中,只能在一个cgroup节点上存在,系统所有进程都会默认在根节点上存在,可以将进程移动到其他节点上,只需要将 进程ID移动到cgroup节点的tasks文件即可。

可以看到当前进程已经被添加到cgroup-1中了。**第一行**

通过subsystem限制cgroup进程的资源 上面的hierarchy没有关系任何的subsystem,所以没有限制cgroup占用的系统资源。本质系统默认为subsystem创建了hierarchy,比如memory的hierarchy。

可以看到/sys/fs/cgroup/memory目录挂载在memory subsystem的hierarchy上。下面进入到memory目录下创建cgroup。限制内存。

这样就创建成功,并添加了内存使用的限制。

可以看到9752 使用内存最大为100M

Docker是如何使用Cgroups的

Docker是通过Cgroups实现容器资源的限制和监控。

可以看到最大限制是134217728 使用的是1970176.这些都是我们在/sys/fs/cgroup/memory中找到的。由此可见docker本质上也是这样做的。

Go语言实现Cgroups限制容器资源

在Namespace的基础之上增加Cgroup的限制,使其具有限制内存的功能。

package main

import (

 "os"

 "os/exec"

 "log"

 "syscall"

 "path"

 "fmt"

 "io/ioutil"

 "strconv"

)

const cgroupMemoryHierarchyMount = "/sys/fs/cgroup/memory" //内存挂载点的路径

func main() {//

    if os.Args[0] == "/proc/self/exe"{

     fmt.Printf("current pid %d", syscall.Getpid())

     fmt.Println()

     cmd := exec.Command("sh", "-c" ,"strees --vm-bytes 200m --vm-keep -m 1")  // 之前我们通过命令行,这里命令还是一样的。

     cmd.SysProcAttr = &syscall.SysProcAttr{

     }

     cmd.Stdin = os.Stdin

     cmd.Stdout = os.Stdout

     cmd.Stderr = os.Stder

     if err := cmd.Run();err!=nil{

      fmt.Println(err)

        os.Exit(1)

     }

    }

    cmd :=exec.Command("/proc/self/exe")

    cmd.SysProcAttr = &syscall.SysProcAttr{

     Cloneflags:syscall.CLONE_NEWUTS|syscall.CLONE_NEWPID|syscall.CLONE_NEWNS,

    }

    cmd.Stdin = os.Stdin

    cmd.Stdout = os.Stdout

    cmd.Stderr = os.Stder

    if err := cmd.Start(); err !=nil{

     fmt.Println("error", err)

     os.Exit(1)

    }else {

     //获取fork的进程pid

     fmt.Printf("%v" ,cmd.Process.Pid)

     // 在系统中默认创建挂在了memory subsystem的hierarchy上创建Cgroup

     os.Mkdir(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit"),0755)

     

     // 将容器加入到这个Cgroup中

     ioutil.WriteFile(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit","tasks"),[]byte(strconv.Itoa(cmd.Process.Pid)),0644)

     

     //限制cgroup的使用

     ioutil.WriteFile(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit","memory.limit_in_bytes"),[]byte("100m"),0644)

     }

     cmd.Process.Wait()

   

    }

通过top就可以查看。

原文链接:https://www.linuxidc.com/Linux/2018-11/155320.htm

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Docker 基础技术之 Linux cgroups 详解

    猿大白
  • 张义飞: Container技术之cgroup入门

    Cgroups 是 control groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资...

    Linux阅码场
  • 直播报名中|K8s cgroups v2 主要应用 及 KEP Memory QoS 方案原理及实现

    ? cgroups 作为 Kubernetes 运行时实现资源隔离和管理的核心技术,而上个星期也有发文讲到:腾讯云 TKE 团队向 Kubernetes 社区...

    腾讯云原生
  • linux cgroups 简介

    cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级...

    菲宇
  • 【美团技术团队博客】Linux资源管理之cgroups简介

    引子 cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,目前越来越火的轻量级...

    美团技术团队
  • 腾讯云 TKE 团队提交 KEP:使用 cgroups v2 实现 Memory QoS

    徐蓓,腾讯云专家工程师,深耕云计算、Kubernetes、离在线混部领域,Kubernetes 社区积极贡献者。 背景 随着云原生进入深水区,很多用户希望通...

    腾讯云原生
  • Docker容器实战(六) - 容器的隔离与限制

    Linux容器中用来实现“隔离”的技术手段:Namespace。 Namespace实际上修改了应用进程看待整个计算机“视图”,即它的“视线”被操作系统做了限制...

    JavaEdge
  • Docker容器实战(六) - 容器的隔离与限制

    Linux容器中用来实现“隔离”的技术手段:Namespace。 Namespace实际上修改了应用进程看待整个计算机“视图”,即它的“视线”被操作系统做了限制...

    心莱科技雪雁
  • 如何通过 Cgroups 机制实现资源限制

    cgroups(全称:control groups)是 Linux 内核的一个功能,它可以实现限制进程或者进程组的资源(如 CPU、内存、磁盘 IO 等)。

    Se7en258
  • linux cgroup原理及使用

    控制群组(control group)(在此指南中简写为 cgroup)是 Linux kernel 的一项功能:在一个系统中运行的层级制进程组,您可对其进行资...

    用户8704439
  • 容器基础之cgroups学习(一)

    Linux cgroups 的全称是 Linux Control Groups,它是 Linux 内核的特性,主要作用是限制、记录和隔离进程组(process ...

    dogfei
  • Linux Cgroup浅析

    cgroups是Linux下控制一个(或一组)进程的资源限制机制,全称是control groups,可以对cpu、内存等资源做精细化控制,比如目前很多的Doc...

    luoxn28
  • cgroup v2介绍及测试

    cgroup是Linux内核允许将流程组织为分层的功能,然后可以限制其使用各种类型资源的组并进行监控。内核的cgroup接口通过伪文件系统,称为cgroupfs...

    有点技术
  • CDH报错:Resource management is disabled for host cdh03 but at least one of its roles has cgroup parame

    (4)进入配置选项,找到 "启用基于 Cgroup 的资源管理" 选项,勾选 - 保存 - (每一台主机)

    静谧星空TEL
  • Kubernetes 普及系列:容器基础入门

    随着云原生时代的来临,云以及分布式计算已经是时下最受欢迎的技术之一了。其中 Docker 作为最知名的容器平台,到底有着怎样的魅力来让其无人不知无人不晓?废话不...

    CODING
  • hadoop入门:第六章YARN文档概述

    1.YARN 结构 文档简介: Yarn的基本思想是拆分资源管理的功能,作业调度/监控到单独的守护进程 ? 英文网址: http://hadoop...

    用户1410343
  • systemd 和 如何修改和创建一个 systemd service (Understanding and administering systemd)

    系统中经常会使用到 systemctl 去管理systemd程序,刚刚看了一篇关于 systemd 和 SysV 相关的文章,这里简要记录一下:

    xuyaowen
  • Docker操作实践(1):容器的本质是什么?容器从何而来?

    容器本质上是一种进程隔离的技术。容器为进程提供了一个隔离的环境,容器内的进程无法访问容器外的进程。

    嘉为蓝鲸
  • Docker容器实战(六) - Docker是如何实现隔离的?

    Linux 命名空间对全局操作系统资源进行了抽象,对于命名空间内的进程来说,他们拥有独立的资源实例,在命名空间内部的进程可以实现资源可见。 对于命名空间外部的...

    JavaEdge

扫码关注云+社区

领取腾讯云代金券