Add more content and fix format

This commit is contained in:
Baohua Yang
2026-02-25 21:06:21 -08:00
parent dd449bc84f
commit ecab788013
119 changed files with 566 additions and 496 deletions

View File

@@ -1,9 +1,102 @@
## 18.2 控制组
控制组是 Linux 容器机制的另外一个关键组件负责实现资源的审计和限制
控制组 (Cgroups) Linux 容器机制的另外一个关键组件如果说命名空间 (Namespace) 决定了容器能**看到**什么那么控制组就决定了容器能**使用**多少资源
它提供了很多有用的特性以及确保各个容器可以公平地分享主机的内存CPU磁盘 IO 等资源当然更重要的是控制组确保了当容器内的资源使用产生压力时不会连累主机系统
在安全领域中资源的不可用性本身就是一种安全威胁控制组负责实现资源的审计和限制这对于抵御资源耗尽型攻击如拒绝服务攻击 DoS至关重要
尽管控制组不负责隔离容器之间相互访问处理数据和进程它在防止拒绝服务 (DDOS) 攻击方面是必不可少的尤其是在多用户的平台 (比如公有或私有的 PaaS) 控制组十分重要例如当某些应用程序表现异常的时候可以保证一致地正常运行和性能
### 18.2.1 为什么资源限制关乎安全
控制组机制始于 2006 内核从 2.6.24 版本开始被引入
默认情况下Docker 容器对系统资源的使用是没有限制的一个容器理论上可以使用宿主机所有的 CPU 计算能力吃光所有的内存耗尽所有的系统 PID
想象一下以下场景
- 一个恶意用户向你暴露在公网的应用发起海量并发请求
- 应用程序逻辑中存在内存泄漏漏洞
- 黑客在入侵容器后在里面运行了挖矿木马程序
如果没有 Cgroups 的限制某个容器内的异常行为或恶意攻击将会榨干宿主机的资源导致宿主机上其他健康的容器甚至 Docker 守护进程自身因为 OOMOut Of Memory崩溃或 CPU 饥饿而停止响应
### 18.2.2 核心资源限制实战
为了确保多租户平台如公有或私有的 PaaS 平台的稳定性或者在生产环境防止服务级联故障我们要养成在启动容器时**显式声明资源上限**的习惯
#### 1. 内存限制
限制内存可以防止应用程序因内存泄漏或恶意载荷导致宿主机 OOM
**关键参数**
- `-m, --memory=""`硬限制容器可使用的最大内存量
- `--memory-swap=""`限制容器可使用的内存与 Swap 总量
**实战示例**
限制容器最多只能使用 512MB 内存并且禁用 Swap memory memory-swap 设置成一样的值即可
```bash
$ docker run -d \
--name web_app \
--memory="512m" \
--memory-swap="512m" \
nginx:alpine
```
如果该容器内的应用尝试分配超过 512MB 的内存该进程将会被内核的 OOM Killer 杀掉但绝不会波及到宿主机的其他部分
#### 2. CPU 限制
限制 CPU 可以防止个别计算密集型的容器垄断 CPU 时间片保证系统的调度公平性
**关键参数**
- `--cpus=<value>`指定容器可以使用的 CPU 核心数量可以是小数
- `-c, --cpu-shares=0`软限制设置容器使用 CPU 的相对权重默认是 1024
**实战示例**
限制容器最多使用 1.5 CPU 核心的算力
```bash
$ docker run -d \
--name worker_app \
--cpus="1.5" \
busybox \
md5sum /dev/urandom
```
即使上面的命令是一个死循环的哈希计算进程容器也永远无法吃满双核 CPU 系统的全部算力
#### 3. 进程数限制
进程炸弹Fork Bomb是一种典型的拒绝服务攻击方式它通过不断 `fork()` 新进程来耗尽系统的进程表条目导致系统无法创建任何新任务
**关键参数**
- `--pids-limit=<number>`限制容器内允许创建的最大进程数
**实战示例**
一个常规的 Web 服务进程数通常在几十到上百之间我们可以设定一个合理的上限来防范 Fork 炸弹
```bash
$ docker run -d \
--name app_service \
--pids-limit=100 \
python:alpine python app.py
```
当容器内的进程总数达到 100 任何尝试派生新进程的操作都会失败并返回 `Resource temporarily unavailable`从而挫败相关的攻击行为
### 18.2.3 最佳实践建议
在生产环境中不仅要在单机使用 Docker 命令时设置这些参数更应当在集群编排工具中将资源配额制度化
例如 Kubernetes 强烈建议为每个 Pod 设置 `requests` `limits`
```yaml
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
```
通过 Cgroups 的资源边界控制你可以从根本上切断一条导致整个系统雪崩的脆弱链路这也进一步使得 Docker 以及容器技术成为了现代高可用服务的基础设施首选