Introduction to Linux cgroups
Above is the namespace technology for building Linux containers, which helps isolate the process from its own space, but how Docker limits the size of each space to ensure they don't scramble with each other. Then you need to use the Cgroups technology of Linux. Concept
The Linux cgroups (Control Groups) provides the resources for a set of processes and future child processes, including CPU, memory, storage, network, etc. By Cgroups, it is easy to limit the resource footprint of a process and monitor process monitoring and statistics in real time. three components in cgroups: cgroup
Cgroup is a mechanism for group management of Processes, a cgroup contains a set of processes, and can be configured on this cgroup to increase the configuration of various parameters of the Linux subsystem, associating a set of processes with a set of subsystem system parameters.
Subsystem
subsystem is a set of resource-controlled modules that typically contain: Blkio set up access control for block devices (such as hard disks) the CPU of a process in the CPU Setup Cgroup is a scheduled policy Cpuacct can count the CPU usage of processes in Cgroup Cpuset the CPU and memory that processes in the Cgroup can be used on multi-core machines (where memory is used only with NUMA schemas) devices control access to devices in cgroup process freezer for suspend (suspends) and recovery (resumes) The process in Cgroup memory is used to control the memory footprint of processes in Cgroup net_cls is used to classify (Cgroup) the network packets generated by the processes in classify so that the TC (traffic controller) of Linux can be sorted by category ( ClassID) area to separate the packets from a cgroup and do the current limit or monitor. Net_prio sets the priority NS for network traffic generated by the process in Cgroup this subsystem is special, and its role is to create a new namespace when the process in Cgroup is new fork newns new Processes (Cgroup). This cgroup contains the new namespace process.
Each subsystem is associated with the Cgroup that defines the limit, and the processes in this cgroup are limited and controlled, and these subsystem are gradually merged into the kernel to see what subsystem the current kernel supports. You can install the Cgroup command-line tool (Apt-get install cgroup-bin), and then see Lssubsys supported kernel through subsystem.
"' Shell /lssubsys-a
Cpuset
Cpu,cpuacct
Blkio
Memory
Devices
Freezer
Net_cls,net_prio
Perf_event
Hugetlb
PIDs
* The function of hierarchy hierarchy is to string a set of Cgroup into a tree-like structure, one such tree is a hierarchy, through this tree-like structure, cgroups can be inherited. My system, for example, restricts CPU usage by cgroup1 a set of scheduled task processes, and then one of the scheduled dump log processes also needs to limit disk IO, in order to avoid limiting the impact to other processes, you can create cgroup2 to inherit from Cgroup1 and limit the disk's Io,
This cgroup2 inherits the CPU limitations in the CGROUP1 and increases disk IO restrictions without affecting other processes in cgroup1.
### three components are related to each other: we can see from the description of the above components that the cgroups is based on the collaboration of the three components, so what is the relationship between the three components? * Once the system has created a new hierarchy, all processes in the system are added to the root cgroup node of this hierarchy, which is hierarchy created by default, and the Cgroup root node
The subsequent creation of the Cgroup in this hierarchy is the child node of this root Cgroup node. * A subsystem can only be attached to a hierarchy * a hierarchy can attach multiple subsystem * A process can be a member of multiple cgroup, but these cgroup must be in a different hierarchy *
When a process fork a subprocess, the child process is in the same cgroup as the parent process, or it can be moved to other cgroup as needed. _ These words now do not understand the temporary matter, after we actually use the process will gradually understand the relationship between them. _ ### Kernel Interface: The above introduced so many cgroups structure, that how to call kernel to configure cgroups it. The above learned that the hierarchy in cgroups is a tree-like structure, kernel in order to make the configuration of cgroups more intuitive, cgroups through a virtual tree file system to do the configuration, through the level of directory virtual Cgroup tree,
Now let's take a configuration example to see how to operate cgroups. * First, we want to create and mount a hierarchy (Cgroup tree): ' ➜~ mkdir cgroup-test # Create a hierarchy mount point ➜~ sudo mount-t cgrOup-o none,name=cgroup-test cgroup-test./cgroup-test # mount a hierarchy➜~ ls./cgroup-test # mount and we can see that the system generates a few defaults in this directory
Document Cgroup.clone_children Cgroup.procs cgroup.sane_behavior notify_on_release release_agent Tasks "" These files are the root node Cgroup configuration item in this hierarchy, which means that the subsystem of the ' Cgroup.clone_children ' cpuset will read this profile if the value is 1 (the default is 0),
The child Cgroup inherits the Cpuset configuration of the parent cgroup.
-' Cgroup.procs ' is the process group ID in the cgroup of the current node in the tree, and now we are in the root node, in this file there will be all the process group IDs in the system now. -' notify_on_release ' and ' release_agent ' will be used together, ' notify_on_release ' means ' release_agent ' when this cgroup last process exits.
Release_agent ' is a path that is typically used as a process exit to automatically clean out cgroup that is no longer in use.
-' tasks ' also represent the process ID below the Cgroup, and if a process ID is written to the ' tasks ' file, the process is added to the cgroup. * Then, we created two cgroup in the root cgroup of the hierarchy we just created: ' ➜cgroup-test sudo mkdir cgroup-1 # Create a child cgroup ' cgroup-1 ' ➜
Cgroup-test sudo mkdir cgroup-2 # creates the son cgroup "cgroup-1" ➜cgroup-test tree. |--Cgroup-1 | |--Cgroup.clone_children | |--Cgroup.procs | |--NotifY_on_release | '--Tasks | | cgroup-2 | |--Cgroup.clone_children | |--Cgroup.procs | |--Notify_on_release | '--tasks | cgroup.clone_children | | cgroup.procs | cgroup.sane_behavior | notify_on_release |
-Release_agent '-tasks ' can be seen in a cgroup directory to create a folder, kernel will mark the folder will be the cgroup of the child Cgroup, they will inherit the attributes of the parent cgroup. * Add and move processes in Cgroup: a process can exist only on a Cgroup node in a cgroups hierarchy, and all processes in the system default to the root node, moving processes between cgroup nodes.
Only the process ID needs to be written to the tasks file of the Cgroup node that is moved to. "' ➜cgroup-1 echo $$ 7475➜cgroup-1 sudo sh-c" echo $$ >> Tasks "to move the process of my terminal to Cgroup-1 ➜cgroup-1 C
At/proc/7475/cgroup 13:name=cgroup-test:/cgroup-1 11:perf_event:/
10:cpu,cpuacct:/user.slice 9:freezer:/
8:blkio:/user.slice 7:devices:/user.slice 6:cpuset:/
5:hugetlb:/
4:pids:/user.slice/user-1000.slice 3:memory:/user.slice 2:net_cls,net_prio:/
1:name=systemd:/user.slice/user-1000.slice/session-19.scope "We can see that our current ' 7475 ' process has been added to the ' cgroup-test:/cgroup-1 '. * by subsystem restricting the resources of processes in Cgroup we created the hierarchy, but this hierarchy is not associated with any subsystem, so there is no way to restrict the resource footprint of the process through the hierarchy Cgroup , in fact, the system by default has created a default hierarchy for each subsystem, such as memory hierarchy: "➜~ Mount | grep memory Cgroup on/sys/fs/cgroup/memory type Cgroup (rw,nosuid,nodev,noexec,relatime,memory,nsroot=/) ' can see , in the '/sys/fs/cgroup/memory ' directory is hung in the hierarchy of the memory subsystem. Let's do this by creating a cgroup in this hierarchy that restricts the memory occupied by the process: "' ➜memory stress--vm-bytes 200m--vm-keep-m 1 # First, we do not limit the start of a footprint Saved stress process ➜memory sudo mkdir test-limit-memory && cd test-limit-memory # Create a cgroup➜test-limit-memory sudo sh-c "echo" 100m "> memory.limit_in_bytes" sudo sh-c "echo" 100m "> memory.limit_in_bytes" # Set maximum Cgroup maximum memory footprint Move the current process into this cgroup for 100m➜test-limit-memory sudo sh-c "echo $$ > Tasks" ➜test-limit-memory stress--vm-byte s 200m--vm-keep-m 1 # Run the stress process that takes up memory 200m again the results are as follows (passOver top monitoring): ' PID PPID time+%cpu%mem PR NI S virt RES UID COMMAND 8336 8335 0:08.23 99.0 1 0.0 0 R 212284 205060 1000 stress 8335 7475 0:00.00 0.0 0.0 0 S 7480 876 1000 Stress P ID PPID time+%cpu%mem PR NI S virt RES UID COMMAND 8310 8309 0:01.17 7.6 0 R 212284 1 02056 1000 Stress 8309 7475 0:00.00 0.0 0.0 0 S 7480 796 the 1000 Stress "" can be seen through Cgroup, we succeeded
Limit the maximum memory footprint of the stress process to 100m. # # Docker How to use cgroups: We know that Docker is the resource limitations and monitoring of containers through cgroups, and we'll look at how Docker configures cgroups with a real container instance below: ' ➜~ # do Cker run-m Set memory limit ➜~ sudo docker run-itd-m 128m ubuntu 957459145e9092618837cf94a1cb356e206f2f0da560b40cb31035 E442d3df11➜~ # Docker creates cgroup➜~ for each container in the system's hierarchy CD/SYS/FS/CGROUP/MEMORY/DOCKER/957459145E9092618837CF94A1 CB356E206F2F0DA560B40CB31035E442D3DF11➜957459145E9092618837CF94A1CB356E206F2F0DA560B40CB31035E442D3DF11 # View CgroUp memory limit ➜957459145e9092618837cf94a1cb356e206f2f0da560b40cb31035e442d3df11 cat memory.limit_in_bytes 134217728➜9 57459145E9092618837CF94A1CB356E206F2F0DA560B40CB31035E442D3DF11 # View the amount of memory used by processes in Cgroup ➜ 957459145e9092618837cf94a1cb356e206f2f0da560b40cb31035e442d3df11 cat memory.usage_in_bytes 430080 ' can see Docker through
Create cgroup for each container and configure resource constraints and resource monitoring through Cgroup.
# # using the Go language to limit the resources of the container by Cgroup below we add cgroup restrictions on the container in the previous section, which implements the ability to limit the memory of the container:
Package Main
Import (
"Os/exec"
"Path"
"OS"
"FMT"
"Io/ioutil"
"Syscall"
"StrConv"
)
Const CGROUPMEMORYHIERARCHYMOUNT = "/sys/fs/cgroup/memory"
Func Main () {
If OS. Args[0] = = "/proc/self/exe" {
Container process
Fmt. Printf ("Current PID%d", Syscall.) Getpid ())
Fmt. Println ()
CMD: = Exec.command ("sh", "-C", stress--vm-bytes 200m--vm-keep-m 1)
Cmd. Sysprocattr = &syscall. sysprocattr{
}
Cmd. Stdin = OS. Stdin
Cmd. Stdout = OS. Stdout
Cmd. Stderr = OS. Stderr
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. Stderr
If err: = cmd. Start (); Err!= Nil {
FMT. Println ("ERROR", err)
OS. Exit (1)
} else {
//Get fork out of the process map in the external namespace of the PID
FMT. Printf ("%v", cmd. Process.pid
////Create Cgroup OS on the hierarchy of the system by default to create a Mount memory subsystem
. Mkdir (path. Join (Cgroupmemoryhierarchymount, "Testmemorylimit"), 0755)
//Add the container process to this cgroup
ioutil. WriteFile (path. Join (Cgroupmemoryhierarchymount, "Testmemorylimit", "Tasks"), []byte (StrConv. Itoa (cmd. process.pid))/0644)
//Limit Cgroup process using
ioutil. WriteFile (path. Join (Cgroupmemoryhierarchymount, "Testmemorylimit", "memory.limit_in_bytes"), []byte ("100m"), 0644)
}
Cmd. Process.wait ()
}
By configuring the Cgroups virtual file system, we have limited the memory footprint of the stress process in the container to ' 100m '.
PID USER PR NI virt RES SHR S%cpu%mem time+ COMMAND
10861 Root 0 212284 102464 212 R 6.2 5.0 0:01.13 Stress
"' summary
In this section, we mainly introduce the Linux cgroups, through the Linux cgroups three kinds of structure, can arbitrarily customize the resource constraints and do the monitoring of resources, and finally use the go language to do a cgroups limited resources of the demo, Describes how to use the go language to manipulate the container's cgroups and limit the container's resources.
Related book recommendation << write docker>> yourself