上传文件至 'Docker-MD'

main
diandian 1 month ago
parent b41b137a15
commit 67ca374ef2

@ -0,0 +1,171 @@
<h1><center>深入理解容器Docker中的Cgroups</center></h1>
**作者:行癫(盗版必究)**
------
#### 1、Cgroups 是什么
**官方定义**Cgroups 是 Linux 内核提供的一种机制用来限制、记录、隔离进程组所使用的资源CPU、内存、磁盘 I/O、网络等
**通俗理解**:它就像一个“配额管理器”或“资源闸门”,用来规定容器能用多少资源,防止“一个人吃光一桌菜”的情况
#### 2、生活中的类比
想象一个自助餐厅
**没有 Cgroups**
每个人(进程)都可以随便拿菜(系统资源),结果有些人很能吃(比如内存泄漏的进程),把菜全拿走了,其他人饿肚子(服务器卡死)
**有了 Cgroups**
A 同学最多拿 2个汉堡CPU 限制)
B 同学最多只准吃 500g 米饭(内存限制)
C 同学一次只能舀 1碗汤I/O 限制)
这样,每个人都能吃到,不会有人霸占资源
总结:在 Docker 容器里Cgroups 就是餐厅的“取餐规则”
#### 3、Cgroups控制的资源类型
**CPU**:限制容器使用 CPU 的比例或核心数
👉 类比:一个人不能霸占整个烤肉炉,只能用 30% 的火力
**内存**:限制容器能用多少内存,超过就会被 OOM-Killer 杀掉
👉 类比:吃饭的盘子大小有限,超过盘子边缘就不能再装
**I/O**:限制容器的磁盘读写速度
👉 类比:打饭窗口一次只能舀多少汤,不能狂灌
**网络**(通过 TC 等):限制带宽
👉 类比:每个人过安检的通道是限流的,不可能冲在前面挤爆
#### 4、Docker 与 Cgroups 的关系
Docker 自己并不实现资源隔离,而是调用 Linux 内核的功能
**Namespace** → 给容器提供“独立环境”,比如独立的进程树、网络、文件系统
**Cgroups** → 控制和分配容器能用多少资源
👉 可以把 Namespace 看作“墙壁”Cgroups 看作“饭票”
Docker 本身只是“餐厅管理软件”,真正发力的是内核的 Namespace 和 Cgroups
#### 5、应用案例
##### 限制CPU share
CPU 资源:
主机上的进程会通过时间分片机制使用 CPUCPU 的量化单位是频率,也就是每秒钟能执行的运算次数。为容器限制 CPU 资源并不能改变 CPU 的运行频率,而是改变每个容器能使用的 CPU 时间片。理想状态下CPU 应该一直处于运算状态(并且进程需要的计算量不会超过 CPU 的处理能力)
Docker 限制 CPU Share
docker 允许用户为每个容器设置一个数字,代表容器的 CPU share默认情况下每个容器的 share 是 1024。这个 share 是相对的,本身并不能代表任何确定的意义。当主机上有多个容器运行时,每个容器占用的 CPU 时间比例为它的 share 在总额中的比例。docker 会根据主机上运行的容器和进程动态调整每个容器使用 CPU 的时间比例
例子:
如果主机上有两个一直使用 CPU 的容器(为了简化理解,不考虑主机上其他进程),其 CPU share 都是 1024那么两个容器 CPU 使用率都是 50%;如果把其中一个容器的 share 设置为 512那么两者 CPU 的使用率分别为 67% 和 33%;如果删除 share 为 1024 的容器,剩下来容器的 CPU 使用率将会是 100%
好处:
能保证 CPU 尽可能处于运行状态,充分利用 CPU 资源,而且保证所有容器的相对公平
缺点:
无法指定容器使用 CPU 的确定值
设置 CPU share 的参数:
-c --cpu-shares它的值是一个整数
我的机器是 4 核 CPU因此运行一个stress容器,使用 stress 启动 4 个进程来产生计算压力:
```shell
# docker pull progrium/stress
# yum install htop -y
# docker run --rm -it progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] --> hogcpu worker 4 [7] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] --> hogcpu worker 3 [8] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [9] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [10] forked
```
在另外一个 terminal 使用 htop 查看资源的使用情况:
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/7n18fo_pTFNkVJh7YB_Y0g.png)
上图中看到CPU 四个核资源都达到了 100%。四个 stress 进程 CPU 使用率没有达到 100% 是因为系统中还有其他机器在运行
为了比较,另外启动一个 share 为 512 的容器
```shell
# docker run --rm -it -c 512 progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] --> hogcpu worker 4 [6] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] --> hogcpu worker 3 [7] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [9] forked
```
因为默认情况下,容器的 CPU share 为 1024所以这两个容器的 CPU 使用率应该大致为 21下面是启动第二个容器之后的监控截图
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/Ja6pTPxoymBhtTRmjhbrRQ.png)
两个容器分别启动了四个 stress 进程,第一个容器 stress 进程 CPU 使用率都在 54% 左右,第二个容器 stress 进程 CPU 使用率在 25% 左右,比例关系大致为 21符合之前的预期
##### 限制容器的 CPU 核数:
-c --cpu-shares 参数只能限制容器使用 CPU 的比例,或者说优先级,无法确定地限制容器使用 CPU 的具体核数;从 1.13 版本之后docker 提供了 --cpus 参数可以限定容器能使用的 CPU 核数。这个功能可以让我们更精确地设置容器 CPU 使用量,是一种更容易理解也因此更常用的手段;-cpus 后面跟着一个浮点数,代表容器最多使用的核数,可以精确到小数点二位,也就是说容器最小可以使用 0.01 核 CPU
限制容器只能使用 1.5 核数 CPU
```shell
# docker run --rm -it --cpus 1.5 progrium/stress --cpu 3
stress: info: [1] dispatching hogs: 3 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] --> hogcpu worker 3 [7] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [9] forked
```
在容器里启动三个 stress 来跑 CPU 压力,如果不加限制,这个容器会导致 CPU 的使用率为 300% 左右(也就是说会占用三个核的计算能力)。实际的监控如下图:
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/9UmN9NvD1JFTwHY4DGL1mA.png)
可以看到,每个 stress 进程 CPU 使用率大约在 50%,总共的使用率为 150%,符合 1.5 核的设置
如果设置的 --cpus 值大于主机的 CPU 核数docker 会直接报错:
```shell
# docker run --rm -it --cpus 8 progrium/stress --cpu 3
docker: Error response from daemon: Range of CPUs is from 0.01 to 4.00, as there are only 4 CPUs available.
See 'docker run --help'.
```
如果多个容器都设置了 --cpus ,并且它们之和超过主机的 CPU 核数,并不会导致容器失败或者退出,这些容器之间会竞争使用 CPU具体分配的 CPU 数量取决于主机运行情况和容器的 CPU share 值。也就是说 --cpus 只能保证在 CPU 资源充足的情况下容器最多能使用的 CPU 数docker 并不能保证在任何情况下容器都能使用这么多的 CPU因为这根本是不可能的
#### 6、Cgroups 工作原理的图
![](https://xingdian-image.oss-cn-beijing.aliyuncs.com/35ea710e-41ed-410b-8744-d7134a5125e1.png)

@ -0,0 +1,58 @@
<center><h1>深入理解容器Docker中的Namespaces</h1></center>
**作者:行癫(盗版必究)**
------
#### 1、Namespaces 是什么
**官方定义**Namespace 是 Linux 内核的一种功能,用来隔离系统资源,使不同的进程组只能“看到”属于自己命名空间的资源
**通俗理解**Namespace 就像给容器戴上了“眼罩”,它只能看到自己房间里的东西,看不到外面的世界
#### 2、生活中的类比
想象一个大型宿舍楼(物理机)
没有 Namespace
所有人住在一个大通铺全局系统谁都能看见别人的行李进程、地址网络、钥匙PID非常混乱
有了 Namespace
学校在宿舍楼里加了 **隔断**
每个房间有自己的门牌号PID Namespace
每个房间有自己的 Wi-FiNetwork Namespace
每个房间只能看到自己放的衣柜Mount Namespace
每个房间里的人起床后只知道自己是“1号”容器内的 PID 1
👉 这样,每个宿舍(容器)的人都觉得“我是独立的”,虽然实际上大家还是住在同一栋楼(宿主机)
#### 3、常见的 Namespace 类型
**PID Namespace**:进程隔离。容器里的进程从 1 开始编号,看不到宿主机的进程
**NET Namespace**网络隔离。容器有自己的网卡、IP、路由表
**MNT Namespace**:文件系统挂载隔离。每个容器有自己的根目录
**UTS Namespace**:主机名隔离。容器里 `hostname` 可以和宿主机不一样
**IPC Namespace**:进程间通信隔离(信号量、共享内存等)
**USER Namespace**:用户隔离。容器里的 root 用户不一定是真正宿主机的 root
#### 4、Docker 与 Namespaces 的关系
Docker 本身只是调用内核的 Namespace 功能
容器看上去像是一个独立的小操作系统,其实只是被内核隔离在自己的“命名空间”里
![](https://xingdian-image.oss-cn-beijing.aliyuncs.com/ChatGPT%20Image%202025%E5%B9%B49%E6%9C%8819%E6%97%A5%2012_59_55.png)
Loading…
Cancel
Save