Linux内核中的cgroups详解

张开发
2026/4/11 15:39:45 15 分钟阅读

分享文章

Linux内核中的cgroups详解
Linux内核中的cgroups详解引言cgroupsControl Groups是Linux内核中的一项重要功能它允许限制、记录和隔离进程组的资源使用如CPU、内存、IO等。cgroups为容器技术提供了资源管理的基础是实现容器资源限制的核心机制。本文将深入探讨Linux内核中的cgroups机制包括其原理、使用方法和应用。cgroups的基本概念1. cgroups的定义cgroups是一种内核机制用于限制、记录和隔离进程组的资源使用。2. cgroups的优势资源限制限制进程组的资源使用资源监控监控进程组的资源使用情况资源隔离隔离不同进程组的资源优先级管理为不同进程组分配不同的资源优先级3. cgroups的版本cgroups v1早期版本功能有限cgroups v2新版本提供更统一的接口cgroups的架构1. cgroups的层次结构cgroup根目录 ├── system.slice │ ├── sshd.service │ └── nginx.service ├── user.slice │ └── user-1000.slice └── machine.slice └── docker-12345.scope2. cgroups的控制器控制器功能描述cpuCPU限制限制CPU使用率cpuacctCPU统计统计CPU使用情况memory内存限制限制内存使用blkio块设备IO限制块设备IOcpusetCPU绑定绑定进程到特定CPUfreezer进程冻结冻结/解冻进程devices设备访问控制设备访问权限net_cls网络分类网络流量分类net_prio网络优先级网络流量优先级hugetlb大页内存限制大页内存使用pids进程数限制限制进程数量3. cgroups的挂载# cgroups v1挂载点 /sys/fs/cgroup/cpu/ /sys/fs/cgroup/memory/ /sys/fs/cgroup/blkio/ # cgroups v2挂载点 /sys/fs/cgroup/cgroups v1的使用1. 创建cgroup# 创建cgroup mkdir /sys/fs/cgroup/cpu/mygroup # 设置CPU限制 echo 50000 /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us # 50% CPU echo 100000 /sys/fs/cgroup/cpu/mygroup/cpu.cfs_period_us # 100ms周期 # 设置内存限制 echo 512M /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes echo 256M /sys/fs/cgroup/memory/mygroup/memory.soft_limit_in_bytes # 设置IO限制 echo 8:0 wbps10485760 /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device # 添加进程 echo pid /sys/fs/cgroup/cpu/mygroup/tasks2. 查看cgroup信息# 查看CPU使用情况 cat /sys/fs/cgroup/cpu/mygroup/cpu.stat # 查看内存使用情况 cat /sys/fs/cgroup/memory/mygroup/memory.stat # 查看IO使用情况 cat /sys/fs/cgroup/blkio/mygroup/blkio.throttle.io_serviced3. 删除cgroup# 删除cgroup rmdir /sys/fs/cgroup/cpu/mygroupcgroups v2的使用1. 挂载cgroups v2# 检查cgroups v2 mount | grep cgroup2 # 挂载cgroups v2 mount -t cgroup2 none /sys/fs/cgroup2. 创建cgroup# 创建cgroup mkdir /sys/fs/cgroup/mygroup # 设置CPU限制 echo max 50000 100000 /sys/fs/cgroup/mygroup/cpu.max # 50% CPU # 设置内存限制 echo max 512M /sys/fs/cgroup/mygroup/memory.max echo low 256M /sys/fs/cgroup/mygroup/memory.low # 设置IO限制 echo 8:0 rbpsmax wbps10485760 /sys/fs/cgroup/mygroup/io.max # 添加进程 echo pid /sys/fs/cgroup/mygroup/cgroup.procs3. 查看cgroup信息# 查看cgroup信息 cat /sys/fs/cgroup/mygroup/cpu.stat cat /sys/fs/cgroup/mygroup/memory.stat cat /sys/fs/cgroup/mygroup/io.statcgroups的API1. libcgroup库#include libcgroup.h int main() { struct cgroup *cgroup; struct cgroup_controller *cgc; int ret; // 初始化libcgroup cgroup_init(); // 创建cgroup cgroup cgroup_new_cgroup(mygroup); if (!cgroup) { fprintf(stderr, Failed to create cgroup\n); return 1; } // 添加CPU控制器 cgc cgroup_add_controller(cgroup, cpu); cgroup_controller_set_uint64(cgc, cpu.cfs_quota_us, 50000); cgroup_controller_set_uint64(cgc, cpu.cfs_period_us, 100000); // 添加内存控制器 cgc cgroup_add_controller(cgroup, memory); cgroup_controller_set_uint64(cgc, memory.limit_in_bytes, 512 * 1024 * 1024); // 创建cgroup ret cgroup_create_cgroup(cgroup, 0); if (ret) { fprintf(stderr, Failed to create cgroup\n); cgroup_free(cgroup); return 1; } // 添加进程 ret cgroup_add_task(cgroup, getpid()); if (ret) { fprintf(stderr, Failed to add task\n); cgroup_free(cgroup); return 1; } // 清理 cgroup_free(cgroup); return 0; }2. 系统调用#include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.h int main() { // 创建cgroup目录 mkdir(/sys/fs/cgroup/cpu/mygroup, 0755); // 设置CPU限制 int fd open(/sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us, O_WRONLY); write(fd, 50000, 5); close(fd); fd open(/sys/fs/cgroup/cpu/mygroup/cpu.cfs_period_us, O_WRONLY); write(fd, 100000, 6); close(fd); // 添加进程 fd open(/sys/fs/cgroup/cpu/mygroup/tasks, O_WRONLY); char pid[10]; sprintf(pid, %d, getpid()); write(fd, pid, strlen(pid)); close(fd); return 0; }cgroups的应用场景1. 容器资源限制Docker、Kubernetes等容器平台使用cgroups限制容器资源。# Docker资源限制 docker run --cpus0.5 --memory512m nginx # Kubernetes资源限制 cat pod.yaml EOF apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx resources: limits: cpu: 0.5 memory: 512Mi requests: cpu: 0.2 memory: 256Mi EOF2. 进程资源控制限制单个进程或进程组的资源使用。# 限制进程CPU使用 taskset -c 0-1 nice -n 19 ./myprogram # 使用cgroups限制 mkdir /sys/fs/cgroup/cpu/myprogram echo 50000 /sys/fs/cgroup/cpu/myprogram/cpu.cfs_quota_us echo 100000 /sys/fs/cgroup/cpu/myprogram/cpu.cfs_period_us echo $$ /sys/fs/cgroup/cpu/myprogram/tasks3. 系统服务管理systemd使用cgroups管理系统服务。# 查看服务的cgroup systemctl status nginx # 设置服务的资源限制 cat /etc/systemd/system/nginx.service.d/limits.conf EOF [Service] CPUQuota50% MemoryLimit512M EOF systemctl daemon-reload systemctl restart nginxcgroups的性能影响1. 性能考虑创建开销cgroup的创建开销很小运行时开销几乎没有运行时开销资源监控会有一定的开销2. 优化策略合理设置限制避免过度限制使用cgroups v2新系统推荐使用v2避免嵌套过深减少cgroup层次3. 性能测试# 测试cgroup创建时间 time mkdir /sys/fs/cgroup/cpu/test rmdir /sys/fs/cgroup/cpu/test # 测试资源限制性能 time cgexec -g cpu:test ./benchmark实际案例分析1. 限制应用程序资源#!/bin/bash # 创建cgroup mkdir -p /sys/fs/cgroup/{cpu,memory}/myapp # 设置CPU限制 echo 25000 /sys/fs/cgroup/cpu/myapp/cpu.cfs_quota_us # 25% CPU echo 100000 /sys/fs/cgroup/cpu/myapp/cpu.cfs_period_us # 设置内存限制 echo 256M /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes # 启动应用 ./myapp APP_PID$! # 添加到cgroup echo $APP_PID /sys/fs/cgroup/cpu/myapp/tasks echo $APP_PID /sys/fs/cgroup/memory/myapp/tasks # 监控资源使用 while true; do echo CPU usage: $(cat /sys/fs/cgroup/cpu/myapp/cpuacct.usage_percpu) echo Memory usage: $(cat /sys/fs/cgroup/memory/myapp/memory.usage_in_bytes) sleep 1 done2. Docker资源限制# 运行容器并限制资源 docker run --name limited-container \ --cpus1.5 \ --memory512m \ --blkio-weight500 \ --restart unless-stopped \ nginx # 查看容器的cgroup docker inspect --format {{ .Id }} limited-container ls -l /sys/fs/cgroup/cpu/docker/container-id3. Kubernetes资源管理apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 resources: limits: cpu: 1 memory: 256Mi requests: cpu: 0.5 memory: 128Mi结论cgroups是Linux内核中实现资源管理的重要机制它为容器技术提供了基础支持。通过cgroups我们可以限制、监控和隔离进程组的资源使用提高系统的可靠性和安全性。理解cgroups的原理和使用方法对于系统管理、容器开发和性能优化都有重要意义。随着容器技术的不断发展cgroups的应用也将更加广泛。

更多文章