You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用bpftool分离残留的eBPF cgroup程序?

不用bpftool清理残留cgroup eBPF程序的解决方案

先排查根源:阻止程序自动重现

重启虚拟机后程序再次出现,大概率是Cilium服务开机自启并自动重新挂载了eBPF程序,先停止并禁用Cilium的自动挂载:

  • 停止Cilium服务:systemctl stop cilium.service(如果是容器运行的Cilium,直接停止对应容器)
  • 禁用开机自启:systemctl disable cilium.service

方法1:通过Systemd重启服务清理cgroup绑定

对于system.slice下的系统服务(如systemd-udevd、systemd-journald等),重启服务会让systemd销毁旧cgroup并创建新实例,绑定在旧cgroup上的eBPF程序会因挂载点消失被内核自动卸载:

  • 单个服务重启示例:systemctl restart systemd-udevd.service
  • 批量重启残留程序对应的服务:
    for svc in systemd-udevd.service systemd-journald.service systemd-logind.service; do
        systemctl restart $svc
    done
    

操作后用bpftool cgroup tree验证,对应cgroup下的程序应已消失。


方法2:编写C工具调用内核bpf()系统调用手动Detach

bpftool本质是封装内核bpf系统调用,我们可以自己实现轻量工具完成detach,不依赖bpftool:
示例代码(编译需链接libbpf):

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <bpf/libbpf.h>
#include <linux/bpf.h>

int detach_cgroup_prog(const char *cgroup_path, enum bpf_attach_type attach_type, __u32 prog_id) {
    int cgroup_fd = open(cgroup_path, O_RDONLY);
    if (cgroup_fd < 0) {
        perror("open cgroup");
        return -1;
    }

    struct bpf_prog_detach_attr attr = {
        .target_fd = cgroup_fd,
        .attach_type = attach_type,
        .prog_id = prog_id,
    };

    int ret = bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
    if (ret < 0) {
        perror("bpf prog detach");
        close(cgroup_fd);
        return -1;
    }

    close(cgroup_fd);
    return 0;
}

int main(int argc, char **argv) {
    if (argc != 4) {
        fprintf(stderr, "Usage: %s <cgroup-path> <attach-type> <prog-id>\n", argv[0]);
        fprintf(stderr, "Attach types: 6(ingress), 7(egress), 14(device)\n");
        return 1;
    }

    const char *cgroup_path = argv[1];
    enum bpf_attach_type attach_type = atoi(argv[2]);
    __u32 prog_id = atoi(argv[3]);

    return detach_cgroup_prog(cgroup_path, attach_type, prog_id) ? 1 : 0;
}

编译命令:gcc -o cgroup_detach cgroup_detach.c -lbpf
使用示例:要移除/sys/fs/cgroup/system.slice/systemd-udevd.service下ID为1844的ingress程序,执行:
./cgroup_detach /sys/fs/cgroup/system.slice/systemd-udevd.service 6 1844
(attach_type对应值:ingress=6,egress=7,device=14)


方法3:手动销毁自定义cgroup(谨慎操作)

对于非systemd管理的自定义cgroup,可直接删除cgroup目录(需先迁移目录下所有进程):

  1. 查看并迁移cgroup内的进程到根cgroup:
    # 列出目标cgroup下的进程
    cat /sys/fs/cgroup/your-custom-cgroup/cgroup.procs
    # 迁移每个进程
    for pid in $(cat /sys/fs/cgroup/your-custom-cgroup/cgroup.procs); do
        echo $pid > /sys/fs/cgroup/cgroup.procs
    done
    
  2. 删除cgroup目录:rmdir /sys/fs/cgroup/your-custom-cgroup
    注意:systemd管理的cgroup不建议手动删除,优先用方法1重启服务。

额外验证

清理后执行bpftool prog show,若目标cgroup程序仍存在,说明还有其他引用(如挂载到其他cgroup),需继续排查对应挂载点重复清理。

内容的提问来源于stack exchange,提问作者Angela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:57:22