要将系统从 cgroup v1 切换到 cgroup v2(统一层次结构),主要需要调整内核启动参数并重启系统。以下是具体步骤:

1. 理解核心差异

  • cgroup v1 使用分离的子系统(如 /sys/fs/cgroup/cpu/sys/fs/cgroup/memory 等)。

  • cgroup v2 使用统一的单一层次结构(所有资源控制通过 /sys/fs/cgroup 统一管理)。

2. 修改 GRUB 配置(关键步骤)

cgroup 版本由内核启动参数 systemd.unified_cgroup_hierarchy 控制:


  • systemd.unified_cgroup_hierarchy=0:强制使用 cgroup v1(你的当前配置)。

  • systemd.unified_cgroup_hierarchy=1 或不设置该参数:启用 cgroup v2(默认行为,取决于系统版本)。

操作步骤:

  1. 编辑 GRUB 配置文件:

    bash

    sudo nano /etc/default/grub
    

  2. 找到 GRUB_CMDLINE_LINUX 行,删除 systemd.unified_cgroup_hierarchy=0,修改后应为:

    bash

    GRUB_CMDLINE_LINUX=""
    


    (如果有其他参数,保留其他参数,仅删除 systemd.unified_cgroup_hierarchy=0

  3. 保存文件并退出编辑器(nano 中按 Ctrl+O 保存,Ctrl+X 退出)。

  4. 更新 GRUB 配置(使修改生效):

    bash

    sudo update-grub
    

3. 重启系统

bash

sudo reboot

4. 验证是否切换到 cgroup v2

重启后,通过以下命令验证:


bash

mount | grep cgroup


  • cgroup v2 成功启用的标志:会显示类似以下的挂载信息(注意 cgroup2 类型):

    plaintext

    cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
    

  • 同时,原 v1 的子目录(如 /sys/fs/cgroup/cpu/sys/fs/cgroup/memory)会消失,统一由 /sys/fs/cgroup 管理。

注意事项

  1. 软件兼容性:部分老软件(如旧版本 Docker、Kubernetes)可能依赖 cgroup v1,切换到 v2 前需确认软件支持情况。

    • Docker 自 20.10 版本起支持 cgroup v2,但可能需要额外配置。

    • Kubernetes 自 1.25 版本起默认支持 cgroup v2。

  2. 回滚方法:若需切回 v1,只需重新在 GRUB_CMDLINE_LINUX 中添加 systemd.unified_cgroup_hierarchy=0,然后执行 sudo update-grub 并重启。


通过以上步骤,系统会从 cgroup v1 切换到 v2 统一层次结构。

/etc/fstab'追加,none  /sys/fs/cgroup/cpu  cgroup  defaults,cpu,cpuacct  0  0
sudo sh -c 'echo "none  /sys/fs/cgroup/cpu  cgroup  defaults,cpu,cpuacct  0  0" >> /etc/fstab'

GRUB_CMDLINE_LINUX=\"systemd.unified_cgroup_hierarchy=0 在/etc/default/grub追加上述的这个

s






sudo update-grub

reboot 重启之后就会变成v1 了,

下面是解析,

===================================================================

  • 你的系统中 mount | grep cgroup2 显示已经挂载了 cgroup2cgroup2 on /sys/fs/cgroup type cgroup2 ...),说明系统默认使用 cgroup v2

  • cgroup v2 不再使用 v1 那种单独的子目录(如 /sys/fs/cgroup/cpu),而是采用统一的层级结构,所有控制器(包括 cpu)都通过 /sys/fs/cgroup/cgroup.controllers 管理。

  • 因此你配置的 /sys/fs/cgroup/cpu 目录在 cgroup v2 下不存在,导致 mount -a 报错。

解决方案:

如果你确实需要使用 cgroup v1(比如某些老软件依赖),需要先禁用 cgroup v2 并启用 v1,步骤如下:


  1. 修改 GRUB 配置,强制启用 cgroup v1
    再次编辑 /etc/default/grub,确保 GRUB_CMDLINE_LINUX 中添加了禁用 cgroup v2 的参数:

    bash

    sudo nano /etc/default/grub
    


    找到 GRUB_CMDLINE_LINUX 一行,添加 systemd.unified_cgroup_hierarchy=0,例如:

    bash

    GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"
    

  2. 更新 GRUB 并重启

    bash

    sudo update-grub
    sudo reboot
    

  3. 重启后验证 cgroup 版本
    重启后,检查是否已切换到 cgroup v1:

    bash

    mount | grep cgroup | grep -v cgroup2
    


    此时应该能看到类似 cgroup on /sys/fs/cgroup/cpu ... 的输出(如果没有,说明需要手动创建目录)。

  4. 手动创建挂载点(如果仍不存在)

    bash

    sudo mkdir -p /sys/fs/cgroup/cpu
    

  5. 重新挂载 fstab 配置

    bash

    sudo mount -a
    

  6. 验证挂载是否成功

    bash

    mount | grep cgroup | grep cpu
    


如果你的应用支持 cgroup v2,更推荐直接使用系统默认的 v2 版本,无需额外配置 /etc/fstab,因为 v2 已经包含了 cpu 控制器(可通过 cat /sys/fs/cgroup/cgroup.controllers 查看是否包含 cpu)。

nano /etc/default/grubGRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"

已完成思考

你可能是想编辑 /etc/default/grub 文件并设置 GRUB_CMDLINE_LINUX 参数,命令格式需要调整。正确的操作步骤如下:

1. 用 nano 编辑 /etc/default/grub(需要 root 权限):

bash

sudo nano /etc/default/grub

2. 在文件中找到 GRUB_CMDLINE_LINUX 行:

  • 如果该行已存在(可能为空或有其他参数),修改为:

    bash

    GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"
    

  • 如果该行不存在,直接添加上述内容。

3. 保存并退出:

  • 在 nano 中,按 Ctrl + O 保存,按 Enter 确认文件名,再按 Ctrl + X 退出。

4. 更新 GRUB 配置:

bash

sudo update-grub

5. 重启系统使配置生效:

bash

sudo reboot


重启后,系统会使用 cgroup v1 而非 v2,此时你之前配置的 /etc/fstab 中关于 cgroup/cpu 的挂载应该能正常工作了。

在这个文件夹里 /etc/default/grub 添加"systemd.unified_cgroup_hierarchy=0"用一行命令表示出来

已完成思考

可以使用 sed 命令结合条件判断实现一行命令操作,确保无论原文件中是否存在 GRUB_CMDLINE_LINUX 行都能正确添加参数:


bash

sudo sh -c 'grep -q "^GRUB_CMDLINE_LINUX=" /etc/default/grub && sed -i "s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"systemd.unified_cgroup_hierarchy=0\"/" /etc/default/grub || echo "GRUB_CMDLINE_LINUX=\"systemd.unified_cgroup_hierarchy=0\"" >> /etc/default/grub'

命令解析:

  1. grep -q "^GRUB_CMDLINE_LINUX=" /etc/default/grub:检查文件中是否已存在 GRUB_CMDLINE_LINUX 行

  2. 如果存在(&&):用 sed 替换该行内容为目标值

  3. 如果不存在(||):直接在文件末尾追加该行


shitou@aishitou:~$ sudo docker exec -it 40f0f7e268a7 /bin/bash
[sudo] password for shitou:
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
shitou@aishitou:~$ docker exec -it 40f0f7e268a7 sh
/ # ls
bin                    home                   proc                   srv
dev                    lib                    root                   sys
etc                    lib64                  rootfs                 tmp
glibc-2.28-r0.apk      media                  run                    usr
glibc-bin-2.28-r0.apk  mnt                    sbin                   var
/ # /usr/bin/cadvisor --version
cAdvisor version v0.32.0 (8949c822)
/ # q