Files
docker_practice/13_implementation/cgroups.md

247 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 控制组
## 什么是控制组
控制组Control Groups简称 cgroups Linux 内核的一个特性用于**限制记录和隔离**进程组的资源使用CPU内存磁盘 I/O网络等
> **核心作用**让多个容器公平共享宿主机资源防止单个容器耗尽系统资源
```
无 cgroups 限制: 有 cgroups 限制:
┌──────────────────────┐ ┌──────────────────────┐
│ 宿主机资源 │ │ 宿主机资源 │
│ ┌─────────────┐ │ │ ┌───┬───┬───┐ │
│ │ 容器 A │ │ │ │ A │ B │ C │ │
│ │ 占用所有 │ │ │ │1GB│1GB│1GB│ ← 限制│
│ │ 内存和 CPU │ │ │ ├───┼───┼───┤ │
│ └─────────────┘ │ │ │2核│1核│1核│ │
│ 容器 B、C 饥饿 │ │ └───┴───┴───┘ │
└──────────────────────┘ └──────────────────────┘
```
---
## cgroups 的历史
| 时间 | 事件 |
|------|------|
| 2006 | Google 工程师提出 cgroups 概念 |
| 2008 | Linux 2.6.24 正式支持 cgroups v1 |
| 2016 | Linux 4.5 引入 cgroups v2 |
| 现在 | Docker 默认使用 cgroups v2如系统支持 |
---
## cgroups 可以限制的资源
| 资源类型 | 子系统 | 说明 |
|---------|--------|------|
| **CPU** | `cpu`, `cpuset` | CPU 使用时间和核心分配 |
| **内存** | `memory` | 内存使用上限和 swap |
| **块设备 I/O** | `blkio` | 磁盘读写速度限制 |
| **网络** | `net_cls`, `net_prio` | 网络带宽优先级 |
| **进程数** | `pids` | 限制进程/线程数量 |
---
## Docker 中的资源限制
### 内存限制
```bash
# 限制容器最多使用 512MB 内存
$ docker run -m 512m myapp
# 限制内存 + swap
$ docker run -m 512m --memory-swap 1g myapp
# 软限制(超过时警告,不会 OOM Kill
$ docker run --memory-reservation 256m myapp
```
| 参数 | 说明 |
|------|------|
| `-m` / `--memory` | 硬限制超过会 OOM Kill |
| `--memory-swap` | 内存 + swap 总限制 |
| `--memory-reservation` | 软限制内存竞争时生效 |
| `--oom-kill-disable` | 禁用 OOM Killer谨慎使用 |
### CPU 限制
```bash
# 限制使用 1.5 个 CPU 核心
$ docker run --cpus=1.5 myapp
# 限制使用 CPU 0 和 1
$ docker run --cpuset-cpus="0,1" myapp
# 设置 CPU 使用权重(相对值,默认 1024
$ docker run --cpu-shares=512 myapp
```
| 参数 | 说明 |
|------|------|
| `--cpus` | 限制 CPU 核心数 1.5 |
| `--cpuset-cpus` | 绑定到特定 CPU 核心 |
| `--cpu-shares` | CPU 时间片权重相对值 |
| `--cpu-period` / `--cpu-quota` | 精细控制 CPU 配额 |
### 磁盘 I/O 限制
```bash
# 限制设备写入速度为 10MB/s
$ docker run --device-write-bps /dev/sda:10mb myapp
# 限制设备读取速度
$ docker run --device-read-bps /dev/sda:10mb myapp
# 限制 IOPS
$ docker run --device-write-iops /dev/sda:100 myapp
```
### 进程数限制
```bash
# 限制最多 100 个进程
$ docker run --pids-limit=100 myapp
```
---
## 查看容器资源使用
```bash
# 实时监控所有容器的资源使用
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
abc123 web 0.50% 45.5MiB / 512MiB 8.89% 1.2kB / 0B 0B / 0B
def456 db 2.30% 256MiB / 1GiB 25.00% 5.6kB / 3.2kB 4.1MB / 2.3MB
# 查看特定容器
$ docker stats mycontainer
# 查看容器的 cgroup 配置
$ docker inspect mycontainer --format '{{json .HostConfig}}' | jq
```
---
## 资源限制的效果
### 内存超限
```bash
# 启动限制 100MB 内存的容器
$ docker run -m 100m stress --vm 1 --vm-bytes 200M
# 容器会被 OOM Killer 杀死
$ docker ps -a
CONTAINER ID STATUS NAMES
abc123 Exited (137) 5 seconds ago hopeful_darwin
# 137 = 128 + 9表示被 SIGKILL (9) 杀死
```
### CPU 限制验证
```bash
# 不限制 CPU
$ docker run --rm stress --cpu 4
# 占满所有 CPU
# 限制为 1 个核心
$ docker run --rm --cpus=1 stress --cpu 4
# 只能使用约 100% CPU1 个核心)
```
---
## cgroups v1 vs v2
| 特性 | cgroups v1 | cgroups v2 |
|------|-----------|-----------|
| 层级结构 | 多层级每个资源单独 | 统一层级 |
| 管理复杂度 | 复杂 | 简化 |
| 资源分配 | 基于层级 | 基于子树 |
| PSI压力监控 | | |
| rootless 容器 | 部分支持 | 完整支持 |
### 检查系统使用的版本
```bash
# 查看 cgroup 版本
$ mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
# 如果显示 cgroup2 表示 v2
# 或者
$ cat /proc/filesystems | grep cgroup
nodev cgroup
nodev cgroup2
```
---
## Compose 中设置限制
```yaml
services:
web:
image: nginx
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
```
---
## 最佳实践
### 1. 始终设置内存限制
```bash
# 防止 OOM 影响宿主机
$ docker run -m 1g myapp
```
### 2. 为关键应用设置 CPU 保证
```bash
$ docker run --cpus=2 --cpu-shares=2048 critical-app
```
### 3. 监控资源使用
```bash
# 配合 Prometheus + cAdvisor 监控
$ docker run -d --name cadvisor \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor
```
---
## 本章小结
| 资源 | 限制参数 | 示例 |
|------|---------|------|
| **内存** | `-m` | `-m 512m` |
| **CPU 核心数** | `--cpus` | `--cpus=1.5` |
| **CPU 绑定** | `--cpuset-cpus` | `--cpuset-cpus="0,1"` |
| **磁盘 I/O** | `--device-write-bps` | `--device-write-bps /dev/sda:10mb` |
| **进程数** | `--pids-limit` | `--pids-limit=100` |
## 延伸阅读
- [命名空间](namespace.md)资源隔离
- [安全](../security/README.md)容器安全概述
- [Docker Stats](../05_container/README.md)监控容器资源