实验环境
安装好Docker
一、传统虚拟机与Docker
传统虚拟机:
每个虚拟机都有独立的操作系统,资源的分配由各自的操作系统分别管理
Docker:
容器没有独立的操作系统,系统资源的分配由docker引擎统一管理
主要通过两个技术实现:namespace、cgroup
namespace主要实现资源的隔离
Cgroup主要实现资源的限制
传统虚拟机与Docker的区别:
传统虚拟机 Docker
磁盘几个或几十G 几十到几百M
CPU内存虚拟系统占用过多 docker引擎几乎不占资源
启动速度几分钟 启动速度几秒
安装管理专门的管理运维 安装管理方便
应用部署每次部署耗时 第二次开始极其方便
耦合性多个服务互相干扰 一个服务一个容器,隔离
系统依赖无相同相似内核,推荐类Unix
二、Namespace(名称/命名空间)
名称空间是Linux内核一个强大的特性。
每个容器都有自己单独的六个名称空间,运行在其中的应用就像是在独立的操作系统中运行一样。
Namespace的六项隔离,实现了容器与宿主机、容器与容器之间的隔离。
它们分别是:
PID Namespace(进程隔离)
作用:隔离进程 ID(PID),使得每个 Namespace 中的进程都有独立的 PID 空间。
效果:在容器中,进程的 PID 从 1 开始,与宿主机或其他容器的 PID 互不影响。
Mount Namespace(文件系统隔离)
作用:隔离文件系统挂载点,使得每个 Namespace 有独立的文件系统视图。
效果:容器可以拥有自己的根文件系统,并且挂载点不会影响宿主机或其他容器。
UTS Namespace(主机名与域名隔离)
作用:隔离主机名(hostname)和域名(domain name)。
效果:每个 Namespace 可以设置独立的主机名和域名,不会影响宿主机或其他容器。
IPC Namespace(进程间通信隔离)
同一个IPC名称空间中的进程之间是可以交互的,不同空间进程无法交互
作用:隔离进程间通信(IPC)资源,如消息队列、共享内存和信号量。
效果:不同 Namespace 中的进程无法通过 IPC 机制通信。
Network Namespace(网络隔离)
作用:隔离网络设备、IP 地址、端口、路由表等网络资源。
效果:每个 Namespace 有独立的网络栈,容器可以拥有独立的 IP 地址和网络配置。
User Namespace(用户与用户组隔离)
作用:隔离用户和用户组 ID,使得每个 Namespace 有独立的用户权限空间。
效果:容器内的用户和用户组 ID 可以独立于宿主机,提升安全性。
三、Cgroup(control group控制组)
控制组(cgroup)是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时对系统资源的竞争。
控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。
Cgroup的四大功能
①资源限制:
可以对任务使用的资源总额进行限制
②优先级分配:
通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制任务运行优先级。
③资源统计:
可以统计系统的资源使用量,如cpu时长,内存用量等
④任务控制:
cgroup可以对任务进行执行挂起,恢复等操作。
挂载cgroup文件系统
mount -t cgroup
-t cgroup:指定要挂载的文件系统类型为 cgroup
cd /sys/fs/cgroup/
1、内存限额
容器内存包括两个部分:物理内存和交换内存(swap)
可以通过参数控制容器内存的使用量:
-m 或者--memory: 设置内存的使用限额
--memory-swap: 设置容器的内存和交换空间总量使用限额
例:
运行一个容器,并且限制该容器最多使用200M内存和100M的swap。
docker run -itd --name container1 -m 200MB --memory-swap 300MB centos:7
查看内存限额文件
cd /sys/fs/cgroup/memory/docker/3700fda05b6e3c1ea55a1bf38496ad76de4a8cc7da1dedf62e021606e7b477f9/
cat memory.limit_in_bytes
cat memory.memsw.limit_in_bytes
2、CPU限制
CPU 份额(-c 或 --cpu-shares)设置容器使用cpu的权重。
CPU 份额是一个相对权重值,用于在多个容器竞争 CPU 资源时分配 CPU 时间。默认值为 1024,表示容器的 CPU 优先级为基准值。设置为 512 表示容器的 CPU 优先级为默认值的一半。如果两个容器的 CPU 份额分别为 512 和 1024,则它们的 CPU 时间分配比例为 1:2。
例:
docker run -itd --name container2 -c 512 centos:7
查看CPU限额文件
cd /sys/fs/cgroup/cpu/docker/c9a167f1f28adcd179e017217f52a69759e429f19f7fe7f9fa3a2c78478119d6/
cat cpu.shares
对比一个没有做CPU权重限制的容器
docker run -itd --name container3 centos:7
cd /sys/fs/cgroup/cpu/docker/f86e3912548928dff1aa6f3a6c4fdfba74173e88dd72d9961da265b2666044a9/
cat cpu.shares
3、磁盘的读写(虚拟机模拟现象有较大偏差)
docker中可以通过设置权重,限制bps和iops的方式控制容器读写磁盘的IO。
bps: 每秒读写的数据量 byte per second
iops: 每秒IO的次数 io per second。
默认情况下,所有容器都能够平等的读写磁盘,也可以通过--blkio-weight参数改变容器的blockIO 的优先级。
--device-read-bps: 显示读取某个设备的bps。
--device-write-bps: 显示写入某个设备的bps。
--device-read-iops: 显示读取某个设备的iops。
--device-write-iops: 显示写入某个设备的iops。
例:
限制testA这个容器,写入/dev/sda这块磁盘的bps为30MB
docker run -it --name testA --device-write-bps /dev/sda:30MB centos:7
从/dev/zero输入,然后输出到test.out文件中,每次大小为1M,总共800次,oflag=direct 用来指定directIO方式写文件,这样才会使--device-write-bps生效。
time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
再运行一个不做限制testB容器,对比速率。
docker run -it --name testB centos:7
time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
4、CPU占比限制
运行一个无限制容器
docker run -it --name test1 centos:7 /bin/bash
编写测试脚本
vi /cpu.sh
添加:
#!/bin/bash
i=0
while true
do
let i++
done
赋予测试脚本执行权限并执行脚本
chmod +x /cpu.sh
./cpu.sh
复制终端使用top命令查看CPU占用率
运行一个限制CPU使用率在50%左右的容器
CPU 配额(--cpu-quota)用于限制容器在单个 CPU 核心上的使用时间。默认值为 100000,表示容器可以使用一个 CPU 核心的 100% 时间。设置为 50000 表示容器最多只能使用一个 CPU 核心的 50% 时间。如果系统有多个 CPU 核心,容器仍然可以在其他核心上使用 CPU 时间。
CPU 配额是一个绝对值,直接限制容器的 CPU 使用量。与 CPU 份额(--cpu-shares)不同,CPU 份额是相对值,仅在多个容器竞争 CPU 资源时生效。
docker run -it --name test2 --cpu-quota 50000 centos:7 /bin/bash
或修改上面无限制创建容器的限额文件
cd /sys/fs/cgroup/cpu/docker/55bcb6ce23310f2912aabaff3d1a62cd3261a97f7bbce3ac34ee067a29dd8830/
echo 50000 > cpu.cfs_quota_us
docker exec -it 55bcb6ce2331 /bin/bash
./cpu.sh
编写测试脚本
vi /cpu.sh
添加:
#!/bin/bash
i=0
while true
do
let i++
done
赋予测试脚本执行权限并执行脚本
chmod +x /cpu.sh
./cpu.sh
复制终端使用top命令查看CPU占用率
通过 --cpu-shares 指定 CPU 份额,默认值为1024
创建两个容器为 c1 和 c2,若只有这两个容器,设置容器的权重,使得c1和c2的CPU资源占比为1/3和2/3。
开启三个终端
终端1:
docker run -it --name c1 --cpu-shares 512 centos:7
安装压力工具
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum -y install wget
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum -y install stress
使用测试工具进行测试
stress -c 4
-c 4: 这是 stress 命令的选项,表示创建 4 个 CPU 密集型进程。每个进程会尽可能地占用一个 CPU 核心的计算资源。
终端2:
docker run -it --name c2 --cpu-shares 1024 centos:7
安装压力工具
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum -y install wget
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum -y install stress
使用测试工具进行测试
stress -c 4
终端3:
top
查看容器实时资源使用情况
docker stats