文章目录
-
- 一、资源控制
-
- [1.1 cgroups](#1.1 cgroups)
- [1.2 pidstat](#1.2 pidstat)
- [1.3 stress](#1.3 stress)
- [1.4 实操](#1.4 实操)
-
- [1.4.1 对内存进行控制](#1.4.1 对内存进行控制)
- [1.4.2 对 CPU 进行控制](#1.4.2 对 CPU 进行控制)
- [二、LXC 容器](#二、LXC 容器)
-
- [2.1 LXC 认识](#2.1 LXC 认识)
- [2.2 LXC 命令](#2.2 LXC 命令)
- [2.3 安装 LXC](#2.3 安装 LXC)
- [2.4 LXC 容器实操](#2.4 LXC 容器实操)

一、资源控制
1.1 cgroups
cgroups(Control Groups)是 Linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。简单说,cgroups 可以限制、记录任务组所使用的物理资源。本质上来说,cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。
cgroups 的用途
- Resource limitation:限制资源使用,例:内存使用上限/CPU 的使用限制
- Prioritization:优先级控制,例:CPU 利用/磁盘 IO 吞吐
- Accounting:一些审计或一些统计
- Control:挂起进程/恢复执行进程
cgroups 可以控制的子系统
| 子系统 | 功能说明 |
|---|---|
| blkio | 对块设备的 IO 进行限制 |
| cpu | 限制 CPU 时间片的分配 |
| cpuacct | 生成 cgroup 中的任务占用 CPU 资源的报告,与 cpu 挂载在同一目录 |
| cpuset | 给 cgroup 中的任务分配独立的 CPU(多处理器系统)和内存节点 |
| devices | 限制设备文件的创建,和对设备文件的读写 |
| freezer | 暂停/恢复 cgroup 中的任务 |
| memory | 对 cgroup 中的任务的可用内存进行限制,并自动生成资源占用报告 |
| perf_event | 允许 perf 观测 cgroup 中的 task |
| net_cls | cgroup 中的任务创建的数据报文的类别标识符,这让 Linux 流量控制器(tc 指令)可以识别来自特定 cgroup 任务的数据包,并进行网络限制 |
| hugetlb | 限制使用的内存页数量 |
| pids | 限制任务的数量 |
| rdma | 限制 RDMA 资源(Remote Direct Memory Access,远程直接数据存取) |
1.2 pidstat
pidstat 是 sysstat 的一个命令,用于监控全部或指定进程的 CPU、内存、线程、设备 IO 等系统资源的占用情况。pidstat 第一次采样显示自系统启动开始的各项统计信息,后续采样将显示自上次运行命令后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。
语法
bash
pidstat [选项] [ <时间间隔> ] [ <次数> ]
参数
| 参数 | 说明 |
|---|---|
| -u | 默认参数,显示各进程的 CPU 使用统计 |
| -r | 显示各进程的内存使用统计 |
| -d | 显示各进程的 IO 使用情况 |
| -p | 指定进程号,ALL 表示所有进程 |
| -C | 指定命令 |
| -l | 显示命令名和所有参数 |
安装
- Ubuntu 安装
bash
# 卸载
apt remove sysstat -y
# 安装
apt install sysstat -y
- CentOS 安装
bash
# 卸载
yum remove sysstat -y
# 安装
yum install sysstat -y
1.3 stress
stress 是 Linux 的一个压力测试工具,可以对 CPU、Memory、IO、磁盘进行压力测试。
语法
bash
stress [OPTION [ARG]]
参数
| 参数 | 说明 |
|---|---|
| -c, --cpu N | 产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力 |
| -i, --io N | 产生 N 个进程,每个进程循环调用 sync 将内存缓冲区内容写到磁盘上,产生 IO 压力。通过系统调用 sync 刷新内存缓冲区数据到磁盘中,以确保同步。如果缓冲区内数据较少,写到磁盘中的数据也较少,不会产生 IO 压力。在 SSD 磁盘环境中尤为明显,很可能 iowait 总是 0,却因为大量调用系统调用 sync,导致系统 CPU 使用率 sys 升高 |
| -m, --vm N | 产生 N 个进程,每个进程循环调用 malloc/free 函数分配和释放内存 |
| --vm-bytes B | 指定分配内存的大小 |
| --vm-keep | 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存) |
| -d, --hdd N | 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件) |
| --hdd-bytes B | 指定文件大小 |
| -t, --timeout N | 在 N 秒后结束程序 |
| -q, --quiet | 程序在运行的过程中不输出信息 |
安装
- Ubuntu 安装
bash
# 卸载
apt remove stress -y
# 安装
apt install stress -y
- CentOS 安装
bash
# 卸载
yum remove stress -y
# 安装
yum install stress -y
1.4 实操
1.4.1 对内存进行控制
cgroupv1 操作
- 创建内存控制组:进入
/sys/fs/cgroup/memory目录,创建test_memory目录(系统会自动生成内存限制相关配置文件)
bash
cd /sys/fs/cgroup/memory
mkdir test_memory
- 配置内存上限(限制为 20M):
bash
# 计算20M对应的字节数
expr 20 \* 1024 \* 1024 # 输出20971520
# 设置内存上限
echo "20971520" > test_memory/memory.limit_in_bytes
- 启动内存压力进程(占用50M内存):
bash
stress -m 1 --vm-bytes 50M
- 查看进程PID并绑定到控制组:
bash
# 查看stress进程PID(假设为62518)
pidstat -r -C stress -p ALL 1
# 将进程加入控制组
echo 62518 >> test_memory/tasks
效果:进程因内存超限被终止。
1.4.2 对 CPU 进行控制
cgroupv1 操作
- 创建CPU控制组:
bash
cd /sys/fs/cgroup/cpu
mkdir test_cpu
- 限制CPU使用率为30%(公式:cfs_quota_us/cfs_period_us=30000/100000):
bash
echo 30000 > test_cpu/cpu.cfs_quota_us
- 启动CPU压力进程并绑定(假设PID为62577):
bash
# 启动100%CPU占用进程
stress -c 1
# 绑定进程到控制组
echo 62577 > test_cpu/tasks
效果:CPU使用率被限制在30%。
至此成功的模拟了对内存和 CPU 的使用控制,而 Docker 本质也是调用这些的 API 来完成对资源的管理,只不过 Docker 的易用性和镜像的设计更加人性化,所以 Docker 才能风靡全球,而Docker 对资源控制,对比这种控制可以说简单不止一倍。
二、LXC 容器
2.1 LXC 认识
LXC(LinuX Containers)Linux 容器,一种操作系统层虚拟化技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。
LXC 是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了容器技术使用的一个方案。
LXC 虽然极大的简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会 LXC 的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。
后来就出现了 docker,所以从一定程度上来说,docker 就是 LXC 的增强版。
2.2 LXC 命令
常用命令
| 命令 | 功能 | 格式 |
|---|---|---|
| lxc-checkconfig | 检查系统是否满足容器使用要求 | lxc-checkconfig |
| lxc-create | 创建 LXC 容器 | lxc-create -n NAME -t TEMPLATE_NAME [-- template-options] |
| lxc-start | 启动容器 | lxc-start -n NAME -d |
| lxc-ls | 列出所有容器(-f 显示常用信息) | lxc-ls -f |
| lxc-info | 查看容器详细信息 | lxc-info -n NAME |
| lxc-attach | 进入容器执行命令 | lxc-attach --name=NAME [-- COMMAND] |
| lxc-stop | 停止容器 | lxc-stop -n NAME |
| lxc-destroy | 删除停机状态的容器 | lxc-destroy -n NAME |
2.3 安装 LXC
- Ubuntu 安装
bash
# 安装主程序、模板及网桥工具
apt install lxc lxc-templates bridge-utils -y
# 检查服务运行状态
systemctl status lxc
- CentOS 安装
bash
# 配置 EPEL 源
yum -y install epel-release
# 安装依赖及主程序
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt lxc-extra debootstrap
# 启动服务
systemctl start lxc
systemctl start libvirtd
# 检查服务状态
systemctl status lxc
systemctl status libvirtd
2.4 LXC 容器实操
- 检查 LXC 服务状态
bash
systemctl status lxc
正常状态 :输出显示 active (exited),表示服务已就绪。
- 检查系统功能支持
bash
lxc-checkconfig
核心检查项 :Namespaces(UTS、IPC、PID 等)、Control groups 均需显示 enabled,确保容器隔离与资源控制功能可用。
- 查看容器模板
LXC 提供多种系统模板,存储路径为 /usr/share/lxc/templates/:
bash
ls /usr/share/lxc/templates/
常见模板:lxc-ubuntu、lxc-centos、lxc-debian、lxc-alpine 等。
- 创建 LXC 容器
- Ubuntu 系统创建 Ubuntu 容器
bash
# -t 指定模板,-n 指定容器名,-r 指定系统版本,-a 指定架构
lxc-create -t ubuntu -n lxchost1 -- -r xenial -a amd64
- CentOS 系统创建 CentOS 容器
bash
lxc-create -t centos --name centos1
- Ubuntu 系统创建 CentOS 容器(需用 download 模板)
bash
lxc-create --name centos7 --template=download -- --dist=centos --release=7 --arch=x86_64
创建成功提示 :默认用户 ubuntu,密码 ubuntu,容器存储路径为 /var/lib/lxc/<容器名>,根文件系统路径为 /var/lib/lxc/<容器名>/rootfs。
- 查看容器列表
bash
lxc-ls -f
输出说明:显示容器名称、状态(STOPPED/RUNNING)、IP 地址等信息。
- 启动容器
bash
# -d 表示后台运行
lxc-start -n lxchost1 -d
# 验证启动状态
lxc-ls -f
启动成功 :容器状态变为 RUNNING,并分配内网 IP(如 10.0.3.248)。
- 查看容器详细信息
bash
lxc-info -n lxchost1
输出内容:包含容器 PID、IP 地址、CPU/内存/磁盘使用量等。
- 进入容器(SSH 方式)
bash
# 用户名 ubuntu,密码 ubuntu,IP 为容器分配的内网 IP
ssh ubuntu@10.0.3.248
容器内验证 :执行 ip addr、df -h、ps -ef 等命令,可见容器拥有独立的网络、文件系统和进程空间。
- 容器外执行命令
无需进入容器,直接在宿主机执行容器内命令:
bash
# --clear-env 清除环境变量,执行 echo 命令
lxc-attach -n lxchost1 --clear-env -- echo "Hello bit"
- 停止容器
bash
lxc-stop -n lxchost1
# 验证停止状态
lxc-ls -f
- 删除容器(需先停止)
bash
lxc-destroy -n lxchost1
# 验证删除结果
lxc-ls -f