Docker 入门前置:容器虚拟化基础之 cgroups 资源控制与 LXC 容器

文章目录

    • 一、资源控制
      • [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 操作

  1. 创建内存控制组:进入 /sys/fs/cgroup/memory 目录,创建 test_memory 目录(系统会自动生成内存限制相关配置文件)
bash 复制代码
cd /sys/fs/cgroup/memory
mkdir test_memory
  1. 配置内存上限(限制为 20M):
bash 复制代码
# 计算20M对应的字节数
expr 20 \* 1024 \* 1024  # 输出20971520
# 设置内存上限
echo "20971520" > test_memory/memory.limit_in_bytes
  1. 启动内存压力进程(占用50M内存):
bash 复制代码
stress -m 1 --vm-bytes 50M
  1. 查看进程PID并绑定到控制组:
bash 复制代码
# 查看stress进程PID(假设为62518)
pidstat -r -C stress -p ALL 1
# 将进程加入控制组
echo 62518 >> test_memory/tasks

效果:进程因内存超限被终止。

1.4.2 对 CPU 进行控制

cgroupv1 操作

  1. 创建CPU控制组:
bash 复制代码
cd /sys/fs/cgroup/cpu
mkdir test_cpu
  1. 限制CPU使用率为30%(公式:cfs_quota_us/cfs_period_us=30000/100000):
bash 复制代码
echo 30000 > test_cpu/cpu.cfs_quota_us
  1. 启动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 容器实操

  1. 检查 LXC 服务状态
bash 复制代码
systemctl status lxc

正常状态 :输出显示 active (exited),表示服务已就绪。

  1. 检查系统功能支持
bash 复制代码
lxc-checkconfig

核心检查项 :Namespaces(UTS、IPC、PID 等)、Control groups 均需显示 enabled,确保容器隔离与资源控制功能可用。

  1. 查看容器模板

LXC 提供多种系统模板,存储路径为 /usr/share/lxc/templates/

bash 复制代码
ls /usr/share/lxc/templates/

常见模板:lxc-ubuntu、lxc-centos、lxc-debian、lxc-alpine 等。

  1. 创建 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

  1. 查看容器列表
bash 复制代码
lxc-ls -f

输出说明:显示容器名称、状态(STOPPED/RUNNING)、IP 地址等信息。

  1. 启动容器
bash 复制代码
# -d 表示后台运行
lxc-start -n lxchost1 -d
# 验证启动状态
lxc-ls -f

启动成功 :容器状态变为 RUNNING,并分配内网 IP(如 10.0.3.248)。

  1. 查看容器详细信息
bash 复制代码
lxc-info -n lxchost1

输出内容:包含容器 PID、IP 地址、CPU/内存/磁盘使用量等。

  1. 进入容器(SSH 方式)
bash 复制代码
# 用户名 ubuntu,密码 ubuntu,IP 为容器分配的内网 IP
ssh ubuntu@10.0.3.248

容器内验证 :执行 ip addrdf -hps -ef 等命令,可见容器拥有独立的网络、文件系统和进程空间。

  1. 容器外执行命令

无需进入容器,直接在宿主机执行容器内命令:

bash 复制代码
# --clear-env 清除环境变量,执行 echo 命令
lxc-attach -n lxchost1 --clear-env -- echo "Hello bit"
  1. 停止容器
bash 复制代码
lxc-stop -n lxchost1
# 验证停止状态
lxc-ls -f
  1. 删除容器(需先停止)
bash 复制代码
lxc-destroy -n lxchost1
# 验证删除结果
lxc-ls -f
相关推荐
Trouvaille ~2 小时前
【Linux】进程间通信(三):共享内存深度剖析与System V IPC机制
linux·c++·操作系统·管道·进程间通信·信号量·system v
Smile_微笑2 小时前
恢复 MySQL 服务(Docker 环境专用)
mysql·adb·docker
卜锦元2 小时前
Docker Compose 部署 MySQL 5.7(生产级实践方案)
数据库·mysql·adb·docker
不怕犯错,就怕不做2 小时前
Linux内核默认允许多个进程打开同一字符设备
linux·驱动开发·嵌入式硬件
ACMer_CTGU2 小时前
解决报错curl: (35) OpenSSL SSL_connect: 连接被对方重设 in connection to download.docker.com:443
网络协议·docker·ssl
\xin2 小时前
SQL 注入、文件上传绕过、MySQL UDF 提权、SUID 提权、Docker 逃逸,以及 APT 持久化技术渗透测试全流程第二次思路
sql·mysql·docker·容器·渗透测试·json·漏洞
羑悻的小杀马特2 小时前
零成本神器组合:用Docker+Uptime Kuma+cpolar打造永不掉线的远程监控系统!
运维·人工智能·docker·容器
禁默2 小时前
Portainer:让 Docker 管理变简单,用cpolar突破局域网后协作更轻松
java·docker·容器·cpolar
StevenZeng学堂2 小时前
一文读懂K8S的PV和PVC以及实践攻略
运维·docker·云原生·容器·kubernetes·云计算·go