目录

Docker-05 资源管理与 docker update:在线调整 CPU、内存与进程限制

本篇较长,按需跳转: docker update 概述 · 不是更新镜像 · CPU · 内存 · PIDs · 在线更新原理 · Compose 漂移 · cgroup v2 · 容器内视图 · docker stats · 排障清单

1. docker update:动态修改已有容器的运行配置

docker update 用于修改一个或多个已经创建的容器的部分运行配置。最常见的用途有两类:

  1. 在线调整 CPU、内存、进程数和块 I/O 等资源约束。
  2. 修改容器的 restart policy。

基本语法:

docker update [OPTIONS] CONTAINER [CONTAINER...]
docker container update [OPTIONS] CONTAINER [CONTAINER...]

docker updatedocker container update 是同一组命令。它既能更新运行中的容器,也能更新已停止的容器:运行中的资源约束通常立即生效;已停止容器会在下次启动时采用新配置。

先用当前客户端确认本机版本支持的参数:

docker update --help
docker version
docker info

不同 Engine、操作系统、cgroup 版本和内核启用的 controller 不同,可用选项和实际效果也可能不同。下面重点讨论 Linux 上最常见的能力。

2. 它不是"更新镜像"

docker update 名称很容易让人误以为它会拉取新镜像或更新容器内应用。实际上它不会修改:

  • 镜像和镜像 tag/digest。
  • ENTRYPOINTCMD、工作目录和运行用户。
  • 环境变量、secret 和配置文件来源。
  • 端口发布、network mode 和容器 hostname。
  • bind mount、volume 和 tmpfs 挂载定义。
  • logging driver、healthcheck 和大多数安全配置。

下面这类变更需要根据新配置重建容器

docker pull example/api:1.1.0
docker rm -f api
docker run -d --name api ... example/api:1.1.0

实际项目应使用 Compose 或编排平台声明完整配置,让平台替换容器,而不是手工拼接旧参数:

docker compose pull api
docker compose up -d --no-deps api

因此要区分三个动作:

命令 修改对象 是否替换容器 是否更新应用镜像
docker update 已有容器的部分 HostConfig
docker restart 已有容器的运行状态
docker compose up 按声明配置协调服务 配置/镜像变化时通常会 可以

3. 查看更新前的基线

不要在没有基线的情况下直接修改生产容器。先保存容器配置和运行状态:

docker inspect api > api.inspect.before.json

docker inspect api | jq '.[0] | {
  status: .State.Status,
  pid: .State.Pid,
  memory: .HostConfig.Memory,
  memory_reservation: .HostConfig.MemoryReservation,
  memory_swap: .HostConfig.MemorySwap,
  nano_cpus: .HostConfig.NanoCpus,
  cpu_shares: .HostConfig.CpuShares,
  cpuset_cpus: .HostConfig.CpusetCpus,
  pids_limit: .HostConfig.PidsLimit,
  restart: .HostConfig.RestartPolicy
}'

还要记录应用指标。资源配置更新成功,只说明 daemon 接受了新配置,不代表业务延迟、吞吐量和错误率符合预期。

4. 动态调整 CPU

4.1 --cpus:设置 CPU 带宽上限

docker update --cpus 1.5 api

--cpus 1.5 表示容器在一个调度周期内最多获得约 1.5 个 CPU 的运行时间。它通常映射为 cgroup 的 quota/period,不代表绑定到某一个半物理核心,也不保证容器一定能获得这些 CPU。

在常见配置中,--cpus 1.5 大致相当于:

docker update --cpu-period 100000 --cpu-quota 150000 api

一般优先用更容易理解的 --cpus;只有需要直接控制调度周期和配额时才使用 --cpu-period--cpu-quota

验证 HostConfig 和 cgroup v2:

docker inspect api --format \
  'NanoCpus={{.HostConfig.NanoCpus}} Period={{.HostConfig.CpuPeriod}} Quota={{.HostConfig.CpuQuota}}'
docker exec api cat /sys/fs/cgroup/cpu.max
docker exec api cat /sys/fs/cgroup/cpu.stat

cpu.stat 中持续增长的 throttling 指标说明进程经常用完配额。提高限额前要同时检查应用 CPU profile,避免用加资源掩盖忙循环、锁竞争或无效重试。

4.2 --cpu-shares:设置竞争时的相对权重

docker update --cpu-shares 512 api

--cpu-shares 是相对权重,不是硬上限:宿主 CPU 空闲时,容器仍可使用更多 CPU;多个 cgroup 竞争时,调度器才按权重分配。它不能代替 --cpus

4.3 --cpuset-cpus:限制可运行的 CPU 集合

docker update --cpuset-cpus '0-3' api
docker inspect api --format '{{.HostConfig.CpusetCpus}}'

这会限制容器进程在哪些逻辑 CPU 上运行,适合 NUMA、缓存局部性或噪声隔离场景。更新前要确认目标 CPU 在线且属于父 cgroup 允许的集合;不要把所有关键服务都绑到相同核心。

在 NUMA 主机上还可能使用 --cpuset-mems 限制内存节点,但错误的 CPU/内存节点组合会导致远端内存访问或更新失败,需要结合 lscpunumactl --hardware 和父 cgroup 配置验证。

5. 动态调整内存

5.1 --memory:硬上限

docker update --memory 768m api

--memory 设置容器内存硬上限。减小上限时要特别谨慎:如果当前使用量高于新上限,内核会回收内存,仍无法满足时可能触发 cgroup OOM,杀死容器进程。

更新前后观察:

docker stats --no-stream api
docker exec api sh -c '
  cat /sys/fs/cgroup/memory.current
  cat /sys/fs/cgroup/memory.max
  cat /sys/fs/cgroup/memory.events
'
docker inspect api --format \
  'Memory={{.HostConfig.Memory}} Swap={{.HostConfig.MemorySwap}} Reservation={{.HostConfig.MemoryReservation}}'

运行时语言的 heap 只是容器内存的一部分。Go/C/Java 服务还会使用线程栈、mmap、共享库、socket buffer、page cache 和其他堆外内存;limit 必须保留余量。

5.2 --memory-reservation:软约束

docker update --memory-reservation 512m --memory 768m api

reservation 用于表达内存压力下的软目标,必须低于硬上限才有意义。它不是预留 512 MB 物理内存,也不能保证进程永远获得这部分容量。

5.3 --memory-swap:内存加 swap 总量

docker update --memory 768m --memory-swap 1g api

--memory--memory-swap 同时设置时,后者通常表示内存 + swap 的总上限,所以上例最多可使用约 768 MB 内存和额外 256 MB swap。--memory-swap--memory 的关系、-1 语义以及宿主是否启用 swap 会影响结果。

已有容器设置过 MemorySwap 时,调整 memory 可能需要在同一命令中提供兼容的 swap 总量,否则 daemon 会拒绝不合法组合。生产变更前先 inspect 当前两个值,并在相同 Engine/cgroup 版本的测试机验证。

swap 能缓解瞬时压力,但可能把内存故障变成长尾延迟。数据库和延迟敏感服务不能只靠扩大 swap 解决泄漏或错误容量规划。

6. 限制进程和线程数量

docker update --pids-limit 512 api
docker inspect api --format '{{.HostConfig.PidsLimit}}'
docker exec api sh -c '
  cat /sys/fs/cgroup/pids.current
  cat /sys/fs/cgroup/pids.max
'

PIDs controller 统计的是内核 task,通常包括进程和线程。限制过低时,应用可能出现:

  • fork: Resource temporarily unavailable
  • 无法创建新线程。
  • Go runtime、JVM、Nginx worker 或调试命令启动失败。
  • 健康检查命令因不能 fork 而失败。

设置上限前要观察峰值线程/进程数并留余量。不同版本对 0-1 或未设置的表示可能不同,以 docker update --help、inspect 和 pids.max 实际值为准。

7. 块 I/O 权重

docker update --blkio-weight 500 api
docker inspect api --format '{{.HostConfig.BlkioWeight}}'

块 I/O 权重通常在多个容器竞争同一块设备时才体现相对优先级。它的效果受存储驱动、I/O scheduler、cgroup 版本、direct/buffered I/O、设备映射和云盘后端影响,不能看到参数成功就断言磁盘吞吐会按比例变化。

数据库 I/O 治理需要结合 iostat、cgroup io.stat、应用 fsync 延迟和真实压测。对具体设备的吞吐/IOPS 限制也受 Engine 与平台支持,应先查看本机 docker update --help

8. 修改 restart policy

docker update --restart unless-stopped api
docker update --restart on-failure:5 worker
docker update --restart no migration

这只修改后续退出时的处理策略,不会立即重启容器,也不会改变当前 PID。四种策略、手动停止、daemon 重启、OOM 和 healthcheck 的完整行为见第 04 篇。

注意 shell 中的 no 直接写通常没有问题;在 Compose YAML 中建议写成字符串 restart: "no",避免被某些 YAML 解析器当作布尔值。

9. 一次更新多个容器

docker update --cpus 1 --memory 512m api-1 api-2 api-3

多个容器可以放在一个命令中,但不要把它理解成数据库事务:如果某个容器不存在、某个约束不合法或内核不支持,可能出现部分目标已经更新、部分目标失败。批量更新后逐个核验:

for name in api-1 api-2 api-3; do
  docker inspect "$name" --format \
    '{{.Name}} memory={{.HostConfig.Memory}} nano_cpus={{.HostConfig.NanoCpus}} restart={{.HostConfig.RestartPolicy.Name}}'
done

关键服务应逐批修改、观察错误率/延迟/OOM/throttling,再继续下一批;这不是跨节点滚动发布机制。

10. 在线更新为什么通常不重启进程

对运行中的 Linux 容器,资源更新大致沿下面的路径发生:

docker CLI
   ↓ Engine API
dockerd / containerd
   ↓ 更新容器运行配置
cgroup controller 文件
   ├── cpu.max / cpu.weight
   ├── memory.max / memory.low 等映射
   └── pids.max / io.*

内核调度器和内存控制器随即使用新值,容器的 namespace、rootfs 和 PID 1 通常不变。验证 PID:

before=$(docker inspect -f '{{.State.Pid}}' api)
docker update --cpus 1.25 api
after=$(docker inspect -f '{{.State.Pid}}' api)
printf 'before=%s after=%s\n' "$before" "$after"

“不重启"不等于"无影响”:收紧 CPU 会立即产生 throttling,收紧内存可能触发回收/OOM,收紧 PIDs 可能让新线程失败。在线变更也需要变更窗口、指标、回滚值和审计记录。

11. 已停止容器也能更新

docker stop api
docker update --memory 1g --cpus 2 --restart unless-stopped api
docker inspect api --format \
  'status={{.State.Status}} memory={{.HostConfig.Memory}} nano_cpus={{.HostConfig.NanoCpus}}'
docker start api

更新已停止容器不会自动启动它。这样可以在启动前修正过低资源限制或 restart policy;但不能借此修改环境变量、端口和挂载,这些仍需要重建。

12. 回滚 docker update

docker update 没有通用的 undo 子命令。回滚依赖更新前保存的具体值:

# 示例:按变更前记录恢复,不要照抄示例值
docker update \
  --cpus 2 \
  --memory 1g \
  --memory-reservation 768m \
  --memory-swap 1536m \
  --pids-limit 1024 \
  --restart unless-stopped \
  api

某些"取消限制"的值因选项、cgroup 和 Engine 版本而异,不能假设全部写 0 就表示无限。先查 docker update --help,并用一个临时容器验证再改生产。

回滚后同时验证 HostConfig、cgroup 和应用指标;仅比较 docker inspect JSON 仍不能证明性能已恢复。

13. Compose 管理下的配置漂移

如果容器由 Compose 创建,手工执行:

docker update --memory 1g demo-api-1

只改变当前容器,compose.yaml 并没有变化。这会造成两份事实:

声明状态:compose.yaml 中的资源配置
实际状态:当前容器 HostConfig / cgroup

手工值可能持续到容器被重建;一旦 Compose 因镜像或配置变化重建容器,手工修改会丢失。正确流程是:

  1. 紧急止损时可先 docker update,记录原值、命令、操作者和时间。
  2. 立即把最终值回写到 Compose/部署配置并走代码审查。
  3. docker compose config 查看最终声明。
  4. 在维护窗口 docker compose up -d;必要时 --force-recreate 消除漂移。
  5. inspect 新容器并验证业务指标。

Compose 示例:

services:
  api:
    image: example/api:1.0.0
    cpus: 1.5
    mem_limit: 768m
    mem_reservation: 512m
    pids_limit: 512
    restart: unless-stopped

Compose 字段的支持和映射受版本/部署目标影响,以 docker compose config 和生成容器的 HostConfig 为准。

14. cgroup v2 对资源限制的影响

Docker 的资源限制最终映射到 Linux cgroup。现代发行版(Ubuntu 22.04+、RHEL 9+、Debian 12+)默认使用 cgroup v2,而早期系统使用 v1。两者的核心区别影响你对资源限制的理解和排障方式。

14.1 v1 和 v2 的区别

维度 cgroup v1 cgroup v2
层级结构 每个 controller(cpu、memory、pids)独立层级 所有 controller 统一层级
文件命名 memory.limit_in_bytescpu.cfs_quota_us memory.maxcpu.max
内存压力信号 memory.soft_limit_in_bytes(效果有限) memory.high(内核主动回收)
PSI 压力指标 不支持 /proc/pressure/{cpu,memory,io}
线程级控制 部分支持 threaded 类型 cgroup

判断当前系统版本:

stat -fc %T /sys/fs/cgroup
# tmpfs     → cgroup v1(或 hybrid)
# cgroup2fs → cgroup v2

# Docker 也会显示
docker info --format '{{.CgroupVersion}}'

14.2 v2 的关键控制文件

容器内可以直接查看 cgroup v2 控制文件:

docker exec api sh -c '
  echo "=== 内存 ==="
  echo "memory.max=$(cat /sys/fs/cgroup/memory.max)"
  echo "memory.current=$(cat /sys/fs/cgroup/memory.current)"
  echo "memory.high=$(cat /sys/fs/cgroup/memory.high)"
  echo ""
  echo "=== CPU ==="
  cat /sys/fs/cgroup/cpu.max
  echo ""
  echo "=== PIDs ==="
  echo "pids.max=$(cat /sys/fs/cgroup/pids.max)"
  echo "pids.current=$(cat /sys/fs/cgroup/pids.current)"
'

关键文件含义:

文件 含义 Docker 参数
memory.max 硬上限,超出触发 OOM --memory
memory.high 高水位线,超出后内核加大回收压力 无直接 CLI 参数
memory.current 当前使用量(含 page cache) docker stats MEM USAGE
cpu.max quota period 格式,如 150000 100000 表示 1.5 CPU --cpus
pids.max 进程/线程数上限 --pids-limit

14.3 memory.high 的实际意义

memory.high 是 cgroup v2 引入的重要机制。它不是硬上限,而是"高水位线":

  • 使用量超过 memory.high 时,内核会对该 cgroup 施加更强的内存回收压力。
  • 进程不会被杀死,但可能因为频繁回收而出现延迟抖动
  • 只有使用量超过 memory.max 时,才触发 cgroup OOM kill。

很多生产中的"容器变慢但没有 OOM"问题,其实是 memory.high 触发了持续回收。Docker CLI 目前没有直接设置 memory.high 的参数,但编排平台或手工写 cgroup 文件可以使用它。

14.4 memory.events:内存事件统计

docker exec api cat /sys/fs/cgroup/memory.events

输出示例:

low 0
high 42
max 3
oom 1
oom_kill 1
oom_group_kill 0
字段 含义
low 使用量降到 memory.low 以下的次数
high 使用量超过 memory.high 的次数(频繁说明回收压力大)
max 使用量触及 memory.max 的次数
oom OOM 事件次数
oom_kill 因 OOM 被杀死的进程次数

排障时 high 计数持续增长但 oom_kill 为 0,说明容器处于"没死但在挣扎"的状态,应考虑增大内存或优化应用。

14.5 cpu.stat:CPU 限流统计

docker exec api cat /sys/fs/cgroup/cpu.stat

输出示例:

usage_usec 1523456
user_usec 1234567
system_usec 288889
nr_periods 15234
nr_throttled 423
throttled_usec 8765432
字段 含义
nr_periods 经过的调度周期总数
nr_throttled 被限流的周期数
throttled_usec 累计被限流的微秒数

限流比例 = nr_throttled / nr_periods。超过 10-20% 通常说明 CPU 配额不足或应用存在 CPU 密集型热点。

15. 容器内的 CPU 和内存视图:为什么 nprocfree 不准确

15.1 问题现象

在一个限制了 2 CPU 和 512 MB 内存的容器内:

docker run --rm --cpus 2 --memory 512m ubuntu bash -c '
  echo "nproc: $(nproc)"
  echo "free:"
  free -m
'

你会发现 nproc 返回的是宿主机全部 CPU 核数(比如 16),free 返回的是宿主机全部内存(比如 64 GB)。这不是 Bug,而是设计如此。

15.2 原因

nprocfreetophtop 等工具读取的是 /proc/cpuinfo/proc/meminfo。Linux 的 /proc 文件系统反映的是宿主机内核视图,不会自动根据 cgroup 限制调整数据。cgroup 是资源限制机制,而 /proc 是内核信息接口,两者不联动。

验证:

docker run --rm --cpus 2 --memory 512m alpine sh -c '
  echo "--- /proc 视图(宿主机数据)---"
  echo "nproc: $(nproc)"
  grep MemTotal /proc/meminfo

  echo ""
  echo "--- cgroup 视图(真实限制)---"
  echo "cpu.max: $(cat /sys/fs/cgroup/cpu.max)"
  echo "memory.max: $(cat /sys/fs/cgroup/memory.max)"
'

15.3 影响:运行时的错误资源计算

这个问题最常见的后果是应用运行时按宿主机资源初始化,实际被 cgroup 限制后性能异常或 OOM:

Java(8u191 之前):JVM 默认按 /proc/meminfo 计算最大 heap。一台 64 GB 宿主机上的 512 MB 容器,JVM 可能尝试分配 16 GB heap,随即被 cgroup OOM kill。

# Java 8u191+ / 11+ 默认开启容器感知
java -XX:+PrintFlagsFinal 2>&1 | grep UseContainerSupport
# 建议显式设置
java -XX:MaxRAMPercentage=75.0 -jar app.jar

Goruntime.NumCPU() 返回宿主机核数,GOMAXPROCS 默认等于该值。16 核宿主上限制 2 CPU 的容器,Go 会启动 16 个 OS 线程竞争 2 CPU 配额,产生不必要的上下文切换和 throttling。

// 使用 uber-go/automaxprocs 自动适配 cgroup
import _ "go.uber.org/automaxprocs"

或者手动设置环境变量:

docker run --cpus 2 -e GOMAXPROCS=2 example/api:1.0.0

Node.jsos.cpus().length 同样返回宿主机核数。cluster 模式按此 fork worker,会在有限 CPU 配额上创建过多进程。

15.4 解决方案

方案 适用场景 说明
运行时容器感知 Java 8u191+、Go automaxprocs 运行时直接读取 cgroup 限制
环境变量 GOMAXPROCSUV_THREADPOOL_SIZE 在 Compose 或 docker run 中显式设置
手动读 cgroup 通用 cat /sys/fs/cgroup/cpu.max 解析 quota/period
LXCFS 需要 /proc 兼容的遗留应用 挂载模拟的 /proc/cpuinfo/proc/meminfo

LXCFS 通过 FUSE 文件系统重写 /proc 中的资源信息,让遗留应用无需修改即可看到"正确"的数值。但它增加了运维复杂度,现代应用优先使用运行时原生的容器感知能力。

16. docker stats 深入:每列含义与 cgroup 指标的关系

16.1 基本用法

docker stats                    # 持续刷新
docker stats --no-stream        # 只打印一帧
docker stats --no-stream api db redis
docker stats --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}'

16.2 各列含义

含义 注意事项
CPU % 相对于宿主机全部 CPU 的百分比 4 核宿主上 --cpus 2 的容器满载时显示约 200%,不是 100%
MEM USAGE / LIMIT 容器当前内存使用 / cgroup memory.max USAGE 包含 page cache
MEM % USAGE / LIMIT 的百分比 未设 limit 时显示相对于宿主总内存
NET I/O 容器网络接口的累计收发字节 从容器启动开始累计,不是速率
BLOCK I/O 块设备累计读写字节 受存储驱动和 direct/buffered I/O 影响
PIDS 当前进程/线程数 对应 cgroup pids.current

16.3 MEM USAGE 包含 page cache

docker stats 显示的内存使用量来自 cgroup memory.current,它包含了 page cache(文件系统缓存)。这意味着:

  • 一个读取大量文件的容器,MEM USAGE 可能远高于应用实际 RSS。
  • 内存压力下 page cache 会被回收,不一定意味着应用内存不足。

要区分实际 RSS 和 cache:

docker exec api cat /sys/fs/cgroup/memory.stat | grep -E '^(anon|file|shmem) '

其中 anon 大致对应应用实际使用的匿名内存(heap、stack、mmap 匿名页),file 是文件映射和 page cache。

16.4 与 cgroup 指标对照

docker exec api sh -c '
  echo "=== 内存 ==="
  echo "memory.current=$(cat /sys/fs/cgroup/memory.current)"
  echo "memory.max=$(cat /sys/fs/cgroup/memory.max)"
  echo ""
  echo "=== CPU ==="
  cat /sys/fs/cgroup/cpu.stat
  echo ""
  echo "=== PIDs ==="
  echo "pids.current=$(cat /sys/fs/cgroup/pids.current)"
  echo "pids.max=$(cat /sys/fs/cgroup/pids.max)"
'

docker stats 是快照工具,适合临时查看。生产环境应使用 Prometheus + cAdvisor、Datadog 或类似的时序监控方案,才能看到资源使用的趋势、峰值和关联告警。

16.5 CPU % 的计算和误解

docker stats 的 CPU % 是相对于宿主机全部 CPU 核数的百分比。在一台 8 核宿主上:

  • 容器 --cpus 2,满载时 CPU % 约 200%(不是 100%)。
  • 要计算"相对于限制的使用率",需要自己换算:200% / (2 * 100%) = 100%

或者直接用 cgroup 数据:

docker exec api cat /sys/fs/cgroup/cpu.stat
# nr_throttled > 0 且持续增长 → 说明在碰 CPU 天花板

17. 可复现实验

启动一个有初始限制的容器:

docker run -d --name update-lab \
  --cpus 0.5 \
  --memory 256m \
  --pids-limit 128 \
  --restart no \
  alpine:3.20 sleep 1d

记录 PID 和限制:

docker inspect update-lab | jq '.[0] | {
  pid: .State.Pid,
  memory: .HostConfig.Memory,
  nano_cpus: .HostConfig.NanoCpus,
  pids: .HostConfig.PidsLimit,
  restart: .HostConfig.RestartPolicy
}'

docker exec update-lab sh -c '
  echo memory.max=$(cat /sys/fs/cgroup/memory.max)
  echo cpu.max=$(cat /sys/fs/cgroup/cpu.max)
  echo pids.max=$(cat /sys/fs/cgroup/pids.max)
'

在线更新:

pid_before=$(docker inspect -f '{{.State.Pid}}' update-lab)

docker update \
  --cpus 1.25 \
  --memory 384m \
  --pids-limit 256 \
  --restart on-failure:3 \
  update-lab

pid_after=$(docker inspect -f '{{.State.Pid}}' update-lab)
printf 'pid_before=%s pid_after=%s\n' "$pid_before" "$pid_after"

docker exec update-lab sh -c '
  echo memory.max=$(cat /sys/fs/cgroup/memory.max)
  echo cpu.max=$(cat /sys/fs/cgroup/cpu.max)
  echo pids.max=$(cat /sys/fs/cgroup/pids.max)
'
docker inspect update-lab --format '{{json .HostConfig.RestartPolicy}}'

预期 PID 不变,cgroup 文件和 restart policy 变成新值。实验结束:

docker rm -f update-lab

不要在远程生产 context 上做资源压力实验;执行前先运行 docker context show

18. docker update 排障清单

命令被拒绝
├── 参数是否受当前 OS/Engine 支持?       docker update --help
├── 宿主是否启用对应 cgroup controller?  docker info + /sys/fs/cgroup
├── memory、reservation、swap 是否冲突? inspect 当前值
├── cpuset 是否属于允许且在线的 CPU?     lscpu + cgroup cpuset
└── 是否连到了错误 Docker context?       docker context show

命令成功但业务异常
├── 是否收紧 CPU 导致 throttling?         cpu.stat + 应用延迟
├── 是否收紧内存触发回收/OOM?            memory.events + dmesg
├── PIDs 是否导致线程/fork 失败?          pids.current/max + 日志
├── I/O 权重是否被存储后端支持?           io.stat + iostat
└── 是否产生 Compose 配置漂移?            compose config + inspect

19. 本篇小结

docker update 是单机容器资源管理的核心工具:它通过修改 cgroup 控制文件实现 CPU、内存、PIDs 和 I/O 的在线调整,不重启进程、不重建容器。但它不能修改镜像、端口、挂载和环境变量,也不是跨节点的编排能力。

使用资源限制时要记住三件事:cgroup 限制的是内核视角的资源消耗(包含 page cache),/proc 中的信息不反映 cgroup 限制,而 docker stats 的百分比是相对于宿主机全部资源。生产环境必须在限制前后对照应用指标,而不是只看 docker inspect 的配置变化。


上一篇 下一篇
04-重启策略与健康检查 06-Dockerfile 与镜像构建