2026/5/21 18:30:08
网站建设
项目流程
如何做问卷调查网站,建设部网站从哪登陆,动漫推荐,济南高新区 网站建设公司#x1f3d7;️ cgroup 和 namespace 深度详解
#x1f4da; 核心概念对比
特性cgroup (Control Groups)namespace (命名空间)目的资源限制和分配隔离和虚拟化系统资源视图主要功能CPU、内存、I/O 等资源限制PID、网络、挂载点等隔离工作层级树状层级结构平级或嵌套结构配置…️cgroup 和 namespace 深度详解核心概念对比特性cgroup (Control Groups)namespace (命名空间)目的资源限制和分配隔离和虚拟化系统资源视图主要功能CPU、内存、I/O 等资源限制PID、网络、挂载点等隔离工作层级树状层级结构平级或嵌套结构配置方式通过文件系统接口通过系统调用和文件系统内核版本2.6.242.4.19逐步完善cgroup 详解1.cgroup 架构cgroup v1 (传统架构) ├── 多个独立的子系统 (subsystems) │ ├── blkio - 块设备I/O限制 │ ├── cpu - CPU时间分配 │ ├── cpuacct - CPU使用统计 │ ├── cpuset - CPU和内存节点绑定 │ ├── devices - 设备访问控制 │ ├── freezer - 挂起/恢复进程 │ ├── memory - 内存限制 │ ├── net_cls - 网络流量分类 │ └── net_prio - 网络优先级 └── 每个子系统独立挂载 cgroup v2 (统一层级架构) └── 所有控制器统一管理 ├── io - I/O控制 ├── memory - 内存控制 ├── pids - 进程数限制 └── cpu - CPU控制2.cgroup v1 详细配置安装和挂载# 查看已安装的cgroup支持yuminstalllibcgroup libcgroup-tools# 查看可用的cgroup子系统cat/proc/cgroups# 挂载cgroup v1mount-t cgroup -o cpu,cpuacct cgroup /sys/fs/cgroup/cpu,cpuacctmount-t cgroup -o memory cgroup /sys/fs/cgroup/memory内存子系统配置详解# 创建cgroupcgcreate -g memory:/myapp# 查看内存控制文件ls-la /sys/fs/cgroup/memory/myapp/# 重要文件说明# memory.limit_in_bytes - 内存硬限制超过会触发OOM# memory.soft_limit_in_bytes - 内存软限制超过会被回收# memory.usage_in_bytes - 当前内存使用# memory.max_usage_in_bytes - 历史最大使用# memory.oom_control - OOM控制参数# memory.stat - 详细内存统计# memory.swappiness - swap使用倾向# memory.use_hierarchy - 是否启用层级继承# 设置内存限制1GBecho1073741824/sys/fs/cgroup/memory/myapp/memory.limit_in_bytes# 设置内存swap限制echo2147483648/sys/fs/cgroup/memory/myapp/memory.memsw.limit_in_bytes# 禁用swap使用echo0/sys/fs/cgroup/memory/myapp/memory.swappiness# 查看内存统计重要指标cat/sys/fs/cgroup/memory/myapp/memory.stat# cache - 页面缓存# rss - 匿名页# mapped_file - 文件映射页# pgpgin - 换入页面数# pgpgout - 换出页面数# oom_kill - OOM杀死次数CPU 子系统配置# 创建CPU cgroupcgcreate -g cpu:/cpulimited# CPU配额配置CFS调度器# cpu.cfs_period_us - 周期长度默认100ms# cpu.cfs_quota_us - 配额限制使用的CPU时间# cpu.shares - CPU份额相对权重# 限制使用0.5个CPU核心echo100000/sys/fs/cgroup/cpu/cpulimited/cpu.cfs_period_usecho50000/sys/fs/cgroup/cpu/cpulimited/cpu.cfs_quota_us# 设置CPU份额默认1024echo512/sys/fs/cgroup/cpu/cpulimited/cpu.shares# CPU绑定cpuset子系统cgcreate -g cpuset:/cpu_boundecho0-1/sys/fs/cgroup/cpuset/cpu_bound/cpuset.cpus# 只能使用CPU 0和1echo0/sys/fs/cgroup/cpuset/cpu_bound/cpuset.mems# 只能使用NUMA节点0I/O 子系统配置# 创建blkio cgroupcgcreate -g blkio:/iolimited# 设置读取限制8:0是设备号可以通过lsblk查看echo8:0 1048576/sys/fs/cgroup/blkio/iolimited/blkio.throttle.read_bps_deviceecho8:0 1048576/sys/fs/cgroup/blkio/iolimited/blkio.throttle.write_bps_device# 设置权重默认500echo100/sys/fs/cgroup/blkio/iolimited/blkio.weight进程管理# 将进程加入cgroupcgclassify -g cpu,memory:/myappPID# 在cgroup中启动新进程cgexec -g cpu,memory:/myapp /usr/bin/myapp# 查看cgroup中的进程cat/sys/fs/cgroup/memory/myapp/cgroup.procs# 冻结cgroup中的所有进程echoFROZEN/sys/fs/cgroup/freezer/myapp/freezer.state# 解冻echoTHAWED/sys/fs/cgroup/freezer/myapp/freezer.state3.cgroup v2 配置启用cgroup v2# 在内核启动参数中添加grubby --update-kernelALL --argssystemd.unified_cgroup_hierarchy1# 重启后验证mount|grepcgroup2# 查看cgroup v2结构ls-la /sys/fs/cgroup/统一层级配置# 创建子cgroupmkdir/sys/fs/cgroup/myapp# 启用控制器echomemory cpu io pids/sys/fs/cgroup/cgroup.subtree_control# 设置内存限制echo1G/sys/fs/cgroup/myapp/memory.maxecho500M/sys/fs/cgroup/myapp/memory.high# 软限制# 设置CPU限制echo50000 100000/sys/fs/cgroup/myapp/cpu.max# quota period# 设置进程数限制echo100/sys/fs/cgroup/myapp/pids.maxnamespace 详解1.namespace 类型和功能namespace 类型系统调用隔离内容引入内核版本Mount (mnt)clone(), unshare()文件系统挂载点2.4.19UTSclone(), unshare()主机名和域名2.6.19IPCclone(), unshare()System V IPC, POSIX消息队列2.6.19PIDclone(), unshare()进程ID空间2.6.24Network (net)clone(), unshare()网络设备、协议栈、端口等2.6.29Userclone(), unshare()用户和组ID3.8Cgroupclone(), unshare()cgroup根目录4.6Timeclone(), unshare()系统时钟5.62.namespace API 操作查看 namespace# 查看进程的所有namespacels-la /proc/$$/ns/# 查看namespace的inode号唯一标识ls-la /proc/$$/ns/|awk{print $1, $9, $11}# 查看当前进程的namespace信息cat/proc/self/status|grep-i ns# 查看系统所有namespacesudolsnssudolsns -t pid# 按类型过滤创建 namespace// C语言创建namespace示例#define_GNU_SOURCE#includesched.h#includestdio.h#includeunistd.hintmain(){// 创建新的UTS namespaceif(unshare(CLONE_NEWUTS)-1){perror(unshare);return1;}// 在新namespace中设置主机名sethostname(newnamespace,12);// 验证charhostname[256];gethostname(hostname,sizeof(hostname));printf(New hostname: %s\n,hostname);return0;}命令行操作 namespace# 使用unshare创建新namespace# 创建UTS namespace并修改主机名sudounshare --utsbashhostnamenewhost# 创建PID namespace第一个进程PID为1sudounshare --pid --fork --mount-procbashpsaux# 只能看到namespace内的进程# 创建network namespacesudounshare --netbashiplinkshow# 只有lo接口# 创建完整的容器环境sudounshare --uts --ipc --pid --net --mount --forkbash3.网络 namespace 深度解析# 创建网络namespaceipnetnsaddnetns1ipnetnsaddnetns2# 查看所有网络namespaceipnetns list# 在namespace中执行命令ipnetnsexecnetns1iplinkshowipnetnsexecnetns1ipaddradd192.168.1.1/24 dev loipnetnsexecnetns1iplinksetlo up# 创建veth对连接两个namespaceiplinkaddveth1typeveth peer name veth2# 将veth接口分配到namespaceiplinksetveth1 netns netns1iplinksetveth2 netns netns2# 配置IP地址ipnetnsexecnetns1ipaddradd10.0.0.1/24 dev veth1ipnetnsexecnetns2ipaddradd10.0.0.2/24 dev veth2# 启用接口ipnetnsexecnetns1iplinksetveth1 upipnetnsexecnetns2iplinksetveth2 up# 测试连通性ipnetnsexecnetns1ping10.0.0.24.PID namespace 隔离机制# 创建PID namespacesudounshare --pid --forkbash# 查看当前进程在各级namespace中的PIDecho在PID namespace中的PID:$$echo在父namespace中的PID:$(cat/proc/self/status|grepNSpid|awk{print $3})# 查看/proc文件系统需要重新挂载mount-t proc proc /procpsaux# 现在只能看到namespace内的进程# 查看进程在不同namespace中的映射cat/proc/PID/status|grepNSpid# NSpid: 在各级namespace中的PID列表5.User namespace 权限隔离# 创建user namespaceunshare --user --map-root-userbash# 查看用户映射cat/proc/self/uid_mapcat/proc/self/gid_map# 从外部设置用户映射# 准备映射文件echo0 1000 1/tmp/uid_mapecho0 1000 1/tmp/gid_map# 创建带用户映射的namespaceunshare --user --map-root-user --map-auto --map-users1000,1000,1bash6.Mount namespace 文件系统隔离# 创建mount namespaceunshare --mountbash# 查看当前挂载点mount|wc-l# 创建私有挂载不影响其他namespacemount--make-private /tmp# 绑定挂载mount--bind /source /destination# 创建共享挂载在多个namespace间共享mount--make-shared /tmp# 查看挂载传播类型findmnt -o PROPAGATION /mountpointcgroup namespace 实战创建简单容器1.手动创建容器环境#!/bin/bash# create-mini-container.sh# 创建唯一标识CONTAINER_IDcontainer_$(date%s)CGROUP_PATH/sys/fs/cgroup/memory/$CONTAINER_IDMOUNT_PATH/tmp/$CONTAINER_ID# 1. 创建cgroupmkdir-p$CGROUP_PATHecho100000000$CGROUP_PATH/memory.limit_in_bytesecho0$CGROUP_PATH/memory.swappiness# 2. 创建目录结构mkdir-p$MOUNT_PATH/{bin,lib,lib64,proc,dev,etc}# 3. 复制必要的二进制文件和库cp/bin/bash$MOUNT_PATH/bin/cp/bin/ls$MOUNT_PATH/bin/ ldd /bin/bash|awk{print $3}|xargs-I{}cp{}$MOUNT_PATH/lib/2/dev/null# 4. 使用unshare创建容器unshare --uts --ipc --pid --net --mount --fork\cgexec -g memory:$CONTAINER_ID\bash-c # 设置主机名 hostname$CONTAINER_ID# 挂载proc mount -t proc proc /proc # 切换到容器根目录 cd$MOUNT_PATHpivot_root . . # 启动shell exec /bin/bash 2.使用nsenter进入容器namespace# 查找容器的PIDCONTAINER_PID$(psaux|grephostname$CONTAINER_ID|grep-vgrep|awk{print $2})# 进入容器的所有namespacensenter -t$CONTAINER_PID-m -u -i -n -pbash# 或只进入特定namespacensenter -t$CONTAINER_PID-nbash# 只进入网络namespace高级调试和监控1.namespace 调试工具# 使用strace跟踪namespace操作strace-etraceclone,unshare,setns unshare --utsbash# 查看namespace的变化sudoipnetns monitorsudonsmonitor# 需要自己编译的工具2.cgroup 事件监控# 监控cgroup内存事件inotifywait -m /sys/fs/cgroup/memory/myapp/memory.oom_control# 使用cgroup事件通知API# 在cgroup.event_control中设置监控echomemory.usage_in_bytes memory.oom_control\/sys/fs/cgroup/memory/myapp/cgroup.event_control3.性能分析工具# 使用systemd-cgtop监控cgroup资源使用systemd-cgtop# 使用bpftrace分析cgroup操作bpftrace -etracepoint:cgroup:cgroup_attach_task { printf(%s - %s\n, comm, args-dst_path); }# 使用perf分析namespace开销perf record -e namespaces:* -asleep10⚙️最佳实践和优化1.cgroup 最佳实践# 1. 合理的内存限制# 设置软限制memory.high早于硬限制memory.max# 预留10-20%的缓冲空间# 2. CPU分配策略# 对有波动的服务使用cpu.weight# 对需要保证的服务使用cpu.max# 3. I/O优先级# 数据库服务设置更高的I/O权重# 批处理任务可以设置较低的权重# 4. 层级设计# 按业务划分顶层cgroup# 按服务类型划分子cgroup2.namespace 最佳实践# 1. 最小权限原则# 只创建必要的namespace# 避免给予不必要的权限# 2. 用户映射安全# 使用非root用户映射# 限制映射范围# 3. 网络隔离# 为每个容器使用独立的网络namespace# 使用桥接或macvlan进行网络连接# 4. 挂载传播# 对敏感目录使用私有挂载# 对共享数据使用共享挂载3.生产环境配置示例# /etc/cgconfig.conf group database { memory { memory.limit_in_bytes 4G; memory.memsw.limit_in_bytes 8G; memory.swappiness 10; } cpu { cpu.shares 1024; } blkio { blkio.weight 800; } } group webserver { memory { memory.limit_in_bytes 2G; memory.swappiness 30; } cpu { cpu.shares 512; } }学习资源和扩展1.内核文档# 查看内核cgroup文档cat/usr/share/doc/kernel-doc-*/Documentation/cgroup-v1/*.txtcat/usr/share/doc/kernel-doc-*/Documentation/cgroup-v2.txt# 查看namespace文档find/usr/share/doc/kernel-doc-*/Documentation -name*namespace*2.相关工具# 容器运行时dockerruntiem - 实现OCI标准 crun - 用C写的轻量级运行时 youki - Rust写的运行时# 监控工具cgmon - cgroup监控 nsenter - namespace进入工具 cntr - 容器调试工具