Linux 内核的 Namespace
和 Cgroups
可以让程序在一个资源可控的独立(隔离)环境中运行,这就是容器运行运用到的核心技术。
通过 CRI 启动一个容器的时候,可以在宿主机上通过 ls -l /proc/<pid/ns/
查看该容器的 Namespace 信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 root@docker-rancher:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fb59b89245b8 harbor.warnerchen.com/rancher/rancher:v2.11.1 "entrypoint.sh" 12 days ago Up 7 days 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp rancher root@docker-rancher:~# docker inspect fb59b89245b8 | grep Pid "Pid" : 1322, "PidMode" : "" , "PidsLimit" : null, root@docker-rancher:~# ls -l /proc/1322/ns/ total 0 lrwxrwxrwx 1 root root 0 Jun 4 22:21 cgroup -> 'cgroup:[4026532399]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 ipc -> 'ipc:[4026532342]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 mnt -> 'mnt:[4026532340]' lrwxrwxrwx 1 root root 0 May 28 14:43 net -> 'net:[4026532344]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 pid -> 'pid:[4026532343]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 pid_for_children -> 'pid:[4026532343]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 time -> 'time:[4026531834]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 time_for_children -> 'time:[4026531834]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 user -> 'user:[4026531837]' lrwxrwxrwx 1 root root 0 Jun 4 22:21 uts -> 'uts:[4026532341]'
可以发现 pid、user 等都指向了独立的 Namespace。
Namespace Linux 内核的 Namespace
类型有很多种,如 cgroup、ipc、network、mount、pid、time、user、uts。
PID Namespace 在容器内查看所有进程,可以看到只运行了一个进程:
1 2 3 4 root@docker-rancher:~# docker exec -it clash-paofucloud ps -ef PID USER TIME COMMAND 1 root 1:40 /clash 28 root 0:00 ps -ef
然后在宿主机上查看容器对应的进程,也是只有一个进程:
1 2 3 root@docker-rancher:~# ps -ef | grep clash root 1316 1278 0 May28 ? 00:01:40 /clash root 370255 369468 0 22:30 pts/0 00:00:00 grep --color=auto clash
这两个其实是同一个进程,但从容器和宿主机上看,PID 却不相同,这是因为创建容器的时候会创建出一个 PID Namespace
,在 PID Namespace
下的进程编号从 1
开始。这其实和 Linux 一样,Linux 开机时就会启动一个 1
号进程,该进程是所有进程的父进程。
而在 PID Namesapce
中只能看到该 PID Namesapce
下的进程,看不到其他 PID Namesapce
下的进程,也就是为什么在容器中执行 ps -ef
的时候只会显示容器内本身的进程。
前面通过 docker inspect
获取到的 PID 就是容器内所有进程的父进程。
Network Namespace 具体实现可以参考:容器网络实现
Mount Namespace 具体实现可以参考:容器文件系统实现
IPC Namespace IPC Namespace
用于隔离不同进程间的进程间通信(IPC)资源,在同一个 IPC Namespace
内的进程,可以共享 IPC 资源;不同 IPC Namespace
的进程之间,互不可见、无法通信。
User Namespace User Namespace
主要是用来隔离用户和用户组的。
UTS Namespace UTS Namespace
用于隔离容器的主机名和域名,意思是每个容器内的主机名都可以独立。
Time Namespace Time Namespace
用于隔离容器的时间,但是容器并没有隔离时间,也就是说所有容器的时间是和宿主机一致的。
Cgroups Cgroups(Control Groups)
是 Linux 内核提供的一种资源管理机制,用于限制、记录和隔离进程组使用的资源(如 CPU、内存、磁盘、网络等)。
Cgroups(Control Groups)
分为 cgroup v1 和 v2,是因为 cgroup v1 在设计和实际使用过程中暴露了不少架构和易用性问题,社区和内核开发者为了解决这些问题,引入了更统一、简洁、可扩展的 cgroup v2。
通过下面的命令可以确认目前使用的是 v1 还是 v2:
1 2 3 stat -fc %T /sys/fs/cgroup/
Cgroup V1 v1 目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 root@docker-test-0:~# ls -l /sys/fs/cgroup/ total 0 dr-xr-xr-x 11 root root 0 Jun 5 2025 blkio lrwxrwxrwx 1 root root 11 Jun 5 2025 cpu -> cpu,cpuacct lrwxrwxrwx 1 root root 11 Jun 5 2025 cpuacct -> cpu,cpuacct dr-xr-xr-x 11 root root 0 Jun 5 2025 cpu,cpuacct dr-xr-xr-x 2 root root 0 Jun 5 2025 cpuset dr-xr-xr-x 11 root root 0 Jun 5 2025 devices dr-xr-xr-x 3 root root 0 Jun 5 2025 freezer dr-xr-xr-x 2 root root 0 Jun 5 2025 hugetlb dr-xr-xr-x 11 root root 0 Jun 5 2025 memory dr-xr-xr-x 2 root root 0 Jun 5 2025 misc lrwxrwxrwx 1 root root 16 Jun 5 2025 net_cls -> net_cls,net_prio dr-xr-xr-x 2 root root 0 Jun 5 2025 net_cls,net_prio lrwxrwxrwx 1 root root 16 Jun 5 2025 net_prio -> net_cls,net_prio dr-xr-xr-x 2 root root 0 Jun 5 2025 perf_event dr-xr-xr-x 11 root root 0 Jun 5 2025 pids dr-xr-xr-x 2 root root 0 Jun 5 2025 rdma dr-xr-xr-x 12 root root 0 Jun 5 2025 systemd dr-xr-xr-x 12 root root 0 Jun 5 2025 unified
其实这些就是 Cgroup 支持的子系统,其中就包含最常见的 CPU、内存子系统。
创建一个容器,并为其设置资源限制:
1 docker run -d --name nginx --memory=256m --cpus="1.5" harbor.warnerchen.com/library/nginx:mainline
此时在 /sys/fs/cgroup/<cpu/memory>/docker/<container_id>/
下就可以看到相关的配置信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 root@docker-test-0:~# ls -l /sys/fs/cgroup/cpu/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23/ total 0 -rw-r--r-- 1 root root 0 Jun 5 10:27 cgroup.clone_children -rw-r--r-- 1 root root 0 Jun 5 10:24 cgroup.procs -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.stat -rw-r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_all -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_percpu -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_percpu_sys -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_percpu_user -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_sys -r--r--r-- 1 root root 0 Jun 5 10:27 cpuacct.usage_user -rw-r--r-- 1 root root 0 Jun 5 10:27 cpu.cfs_burst_us -rw-r--r-- 1 root root 0 Jun 5 10:24 cpu.cfs_period_us -rw-r--r-- 1 root root 0 Jun 5 10:24 cpu.cfs_quota_us -rw-r--r-- 1 root root 0 Jun 5 10:27 cpu.idle -rw-r--r-- 1 root root 0 Jun 5 10:27 cpu.shares -r--r--r-- 1 root root 0 Jun 5 10:27 cpu.stat -rw-r--r-- 1 root root 0 Jun 5 10:27 cpu.uclamp.max -rw-r--r-- 1 root root 0 Jun 5 10:27 cpu.uclamp.min -rw-r--r-- 1 root root 0 Jun 5 10:27 notify_on_release -rw-r--r-- 1 root root 0 Jun 5 10:27 tasks root@docker-test-0:~# ls -l /sys/fs/cgroup/memory/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23/ total 0 -rw-r--r-- 1 root root 0 Jun 5 10:25 cgroup.clone_children --w--w--w- 1 root root 0 Jun 5 10:24 cgroup.event_control -rw-r--r-- 1 root root 0 Jun 5 10:24 cgroup.procs -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.failcnt --w------- 1 root root 0 Jun 5 10:25 memory.force_empty -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.failcnt -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.limit_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.max_usage_in_bytes -r--r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.slabinfo -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.tcp.failcnt -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.tcp.limit_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.tcp.max_usage_in_bytes -r--r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.tcp.usage_in_bytes -r--r--r-- 1 root root 0 Jun 5 10:25 memory.kmem.usage_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:24 memory.limit_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.max_usage_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.memsw.failcnt -rw-r--r-- 1 root root 0 Jun 5 10:24 memory.memsw.limit_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.memsw.max_usage_in_bytes -r--r--r-- 1 root root 0 Jun 5 10:25 memory.memsw.usage_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.move_charge_at_immigrate -r--r--r-- 1 root root 0 Jun 5 10:25 memory.numa_stat -rw-r--r-- 1 root root 0 Jun 5 10:24 memory.oom_control ---------- 1 root root 0 Jun 5 10:25 memory.pressure_level -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.soft_limit_in_bytes -r--r--r-- 1 root root 0 Jun 5 10:25 memory.stat -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.swappiness -r--r--r-- 1 root root 0 Jun 5 10:25 memory.usage_in_bytes -rw-r--r-- 1 root root 0 Jun 5 10:25 memory.use_hierarchy -rw-r--r-- 1 root root 0 Jun 5 10:25 notify_on_release -rw-r--r-- 1 root root 0 Jun 5 10:25 tasks
也可以通过容器 PID 的方式获取 Cgroup 路径:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 root@docker-test-0:~# docker inspect nginx | grep Pid "Pid" : 1561, "PidMode" : "" , "PidsLimit" : null, root@docker-test-0:~# cat /proc/1561/cgroup 13:rdma:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 12:hugetlb:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 11:net_cls,net_prio:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 10:pids:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 9:blkio:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 8:cpuset:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 7:cpu,cpuacct:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 6:devices:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 5:perf_event:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 4:misc:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 3:freezer:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 2:memory:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 1:name=systemd:/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23 0::/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23
以内存为例,在其目录下就能看到限制的信息被写入了 memory.limit_in_bytes
中:
1 2 3 4 root@docker-test-0:~# cat /sys/fs/cgroup/memory/docker/ba9c3dfa1dfb45cbcb9448fbea2ab7fe91fcce7591ed1b73274d371b42ed4d23/memory.limit_in_bytes 268435456 root@docker-test-0:~# expr 268435456 / 1024 / 1024 256
Cgroup v2 可以通过修改内核参数,将 v1 切换为 v2:
在 GRUB_CMDLINE_LINUX_DEFAULT
,添加 systemd.unified_cgroup_hierarchy=1
,反之,如果要从 v2 切到 v1,添加 systemd.unified_cgroup_hierarchy=0
即可:
1 GRUB_CMDLINE_LINUX_DEFAULT="systemd.unified_cgroup_hierarchy=0"
更新 GRUB 并进行重启:
v2 目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 root@docker-test-0:~# ls -l /sys/fs/cgroup/ total 0 -r--r--r-- 1 root root 0 Jun 5 2025 cgroup.controllers -rw-r--r-- 1 root root 0 Jun 5 10:51 cgroup.max.depth -rw-r--r-- 1 root root 0 Jun 5 10:51 cgroup.max.descendants -rw-r--r-- 1 root root 0 Jun 5 2025 cgroup.procs -r--r--r-- 1 root root 0 Jun 5 10:51 cgroup.stat -rw-r--r-- 1 root root 0 Jun 5 2025 cgroup.subtree_control -rw-r--r-- 1 root root 0 Jun 5 10:51 cgroup.threads -rw-r--r-- 1 root root 0 Jun 5 10:51 cpu.pressure -r--r--r-- 1 root root 0 Jun 5 10:51 cpuset.cpus.effective -r--r--r-- 1 root root 0 Jun 5 10:51 cpuset.mems.effective -r--r--r-- 1 root root 0 Jun 5 10:51 cpu.stat drwxr-xr-x 2 root root 0 Jun 5 2025 dev-hugepages.mount drwxr-xr-x 2 root root 0 Jun 5 2025 dev-mqueue.mount drwxr-xr-x 2 root root 0 Jun 5 2025 init.scope -rw-r--r-- 1 root root 0 Jun 5 10:51 io.cost.model -rw-r--r-- 1 root root 0 Jun 5 10:51 io.cost.qos -rw-r--r-- 1 root root 0 Jun 5 10:51 io.pressure -rw-r--r-- 1 root root 0 Jun 5 10:51 io.prio.class -r--r--r-- 1 root root 0 Jun 5 10:51 io.stat -r--r--r-- 1 root root 0 Jun 5 10:51 memory.numa_stat -rw-r--r-- 1 root root 0 Jun 5 10:51 memory.pressure -r--r--r-- 1 root root 0 Jun 5 10:51 memory.stat -r--r--r-- 1 root root 0 Jun 5 10:51 misc.capacity drwxr-xr-x 2 root root 0 Jun 5 2025 proc-sys-fs-binfmt_misc.mount drwxr-xr-x 2 root root 0 Jun 5 2025 sys-fs-fuse-connections.mount drwxr-xr-x 2 root root 0 Jun 5 2025 sys-kernel-config.mount drwxr-xr-x 2 root root 0 Jun 5 2025 sys-kernel-debug.mount drwxr-xr-x 2 root root 0 Jun 5 2025 sys-kernel-tracing.mount drwxr-xr-x 38 root root 0 Jun 5 10:52 system.slice drwxr-xr-x 3 root root 0 Jun 5 10:52 user.slice
运行容器后,在 /sys/fs/cgroup/system.slice/docker-<container_id>.scope/
下就可以看到相关的配置信息,与 v1 不同的是所有配置都放在了一个目录中:
如果是 Kubernetes 通过 CRI 创建的容器,那么是在 /sys/fs/cgroup/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod<pod_id>.slice
路径下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 root@docker-test-0:~# ls -l /sys/fs/cgroup/system.slice/docker-aac538958e1c50f03d7e2725a1d38a3cd259d86580405093731fde3af7e267cb.scope total 0 -r--r--r-- 1 root root 0 Jun 5 10:54 cgroup.controllers -r--r--r-- 1 root root 0 Jun 5 10:54 cgroup.events -rw-r--r-- 1 root root 0 Jun 5 10:54 cgroup.freeze --w------- 1 root root 0 Jun 5 10:56 cgroup.kill -rw-r--r-- 1 root root 0 Jun 5 10:56 cgroup.max.depth -rw-r--r-- 1 root root 0 Jun 5 10:56 cgroup.max.descendants -rw-r--r-- 1 root root 0 Jun 5 10:54 cgroup.procs -r--r--r-- 1 root root 0 Jun 5 10:56 cgroup.stat -rw-r--r-- 1 root root 0 Jun 5 10:54 cgroup.subtree_control -rw-r--r-- 1 root root 0 Jun 5 10:56 cgroup.threads -rw-r--r-- 1 root root 0 Jun 5 10:54 cgroup.type -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.idle -rw-r--r-- 1 root root 0 Jun 5 10:54 cpu.max -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.max.burst -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.pressure -rw-r--r-- 1 root root 0 Jun 5 10:54 cpuset.cpus -r--r--r-- 1 root root 0 Jun 5 10:56 cpuset.cpus.effective -rw-r--r-- 1 root root 0 Jun 5 10:56 cpuset.cpus.partition -rw-r--r-- 1 root root 0 Jun 5 10:54 cpuset.mems -r--r--r-- 1 root root 0 Jun 5 10:56 cpuset.mems.effective -r--r--r-- 1 root root 0 Jun 5 10:54 cpu.stat -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.uclamp.max -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.uclamp.min -rw-r--r-- 1 root root 0 Jun 5 10:54 cpu.weight -rw-r--r-- 1 root root 0 Jun 5 10:56 cpu.weight.nice -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.current -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.events -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.events.local -rw-r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.max -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.rsvd.current -rw-r--r-- 1 root root 0 Jun 5 10:56 hugetlb.1GB.rsvd.max -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.current -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.events -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.events.local -rw-r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.max -r--r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.rsvd.current -rw-r--r-- 1 root root 0 Jun 5 10:56 hugetlb.2MB.rsvd.max -rw-r--r-- 1 root root 0 Jun 5 10:56 io.max -rw-r--r-- 1 root root 0 Jun 5 10:56 io.pressure -rw-r--r-- 1 root root 0 Jun 5 10:56 io.prio.class -r--r--r-- 1 root root 0 Jun 5 10:54 io.stat -rw-r--r-- 1 root root 0 Jun 5 10:54 io.weight -r--r--r-- 1 root root 0 Jun 5 10:56 memory.current -r--r--r-- 1 root root 0 Jun 5 10:54 memory.events -r--r--r-- 1 root root 0 Jun 5 10:56 memory.events.local -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.high -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.low -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.max -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.min -r--r--r-- 1 root root 0 Jun 5 10:56 memory.numa_stat -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.oom.group -rw-r--r-- 1 root root 0 Jun 5 10:56 memory.pressure -r--r--r-- 1 root root 0 Jun 5 10:56 memory.stat -r--r--r-- 1 root root 0 Jun 5 10:56 memory.swap.current -r--r--r-- 1 root root 0 Jun 5 10:56 memory.swap.events -rw-r--r-- 1 root root 0 Jun 5 10:56 memory.swap.high -rw-r--r-- 1 root root 0 Jun 5 10:54 memory.swap.max -r--r--r-- 1 root root 0 Jun 5 10:56 misc.current -rw-r--r-- 1 root root 0 Jun 5 10:56 misc.max -r--r--r-- 1 root root 0 Jun 5 10:56 pids.current -r--r--r-- 1 root root 0 Jun 5 10:56 pids.events -rw-r--r-- 1 root root 0 Jun 5 10:54 pids.max -r--r--r-- 1 root root 0 Jun 5 10:56 rdma.current -rw-r--r-- 1 root root 0 Jun 5 10:56 rdma.max
通过容器 PID 获取 Cgroup 路径:
1 2 3 4 5 6 root@docker-test-0:~# docker inspect nginx | grep Pid "Pid" : 1620, "PidMode" : "" , "PidsLimit" : null, root@docker-test-0:~# cat /proc/1620/cgroup 0::/system.slice/docker-aac538958e1c50f03d7e2725a1d38a3cd259d86580405093731fde3af7e267cb.scope
再次目录下查看 CPU 和内存限制信息:
1 2 3 4 5 6 7 8 root@docker-test-0:~# cat /sys/fs/cgroup/system.slice/docker-aac538958e1c50f03d7e2725a1d38a3cd259d86580405093731fde3af7e267cb.scope/cpu.max 150000 100000 root@docker-test-0:~# cat /sys/fs/cgroup/system.slice/docker-aac538958e1c50f03d7e2725a1d38a3cd259d86580405093731fde3af7e267cb.scope/memory.max 268435456 root@docker-test-0:~# expr 268435456 / 1024 / 1024 256
由此看来,cgroup v1 和 v2 的主要区别在于 v1 每个资源控制器是分开挂载的,层级结构各自独立,配置接口不统一;而 v2 所有控制器统一在一个挂载点下,共享层级结构,接口更简洁一致。v2 是对 v1 的重构,推荐在新系统和容器环境中使用。