用于 Docker、containerd 和 Podman 的混沌测试工具
Pumba 是一款用于 Docker、containerd 和 Podman 容器的混沌测试与网络模拟工具。受到 Netflix Chaos Monkey 的启发,Pumba 将混沌工程带入容器层面——杀死、停止、暂停和删除容器,注入网络延迟和数据包丢失,或对容器资源进行压力测试。
graph LR
A[Pumba CLI] -->|Docker API / containerd API / Podman compat API| B[Container Runtime]
B -->|List & Filter| C[Target Containers]
A -->|kill / stop / pause / rm| C
A -->|netem / iptables| D[Helper Container / Direct Exec]
D -->|Shares network namespace| C
D -->|Runs tc / iptables| E[Network Chaos]
| 运行时 | Socket(默认) | netem / iptables / stress | 备注 |
|---|---|---|---|
| Docker | /var/run/docker.sock | 以 root 身份或通过 socket 访问方式工作 | 默认运行时。 |
| containerd | /run/containerd/containerd.sock | 需要 root 权限(sidecar 使用 overlayfs 挂载) | 命名空间:k8s.io(Kubernetes)、moby(Docker 管理)、default(纯 containerd)。 |
| Podman | /run/podman/podman.sock(rootful) | 需要 rootful Podman(否则快速失败) | 使用 Podman 的 Docker 兼容 API;在 macOS 上 pumba 运行于 podman machine 内部(见下文)。 |
Pumba 面向 Linux 容器——每个混沌操作都依赖 Linux 原语(netns、cgroups v2、iptables、tc qdisc、容器运行时 socket)。发布的二进制文件:
| 操作系统 | amd64 | arm64 | 备注 |
|---|---|---|---|
| Linux | ✅ | ✅ | 主要目标平台。在与目标容器相同的内核上运行 pumba。 |
| macOS | ✅ | ✅ | 仅面向开发者的便利性。用于驱动远程的 Docker/Podman/containerd VM(例如 Colima、podman machine)。 |
| Windows | ❌ | ❌ | 不支持且无计划支持。 参见下文。 |
Windows 版本是有意不构建的。 混沌原语——Linux netns/cgroup 写入、tc/iptables sidecar 注入、POSIX 信号转发(containerd 运行时使用的 SIGCONT/SIGSTOP/SIGUSR1/SIGUSR2)——在 Windows 上没有对应实现。即使使用 Docker Desktop 的 WSL2 后端,Windows 也没有合理的用例,因此不发布 Windows 二进制文件。添加 Windows 支持的 PR 将不被接受;请在 Linux(原生、容器或 VM)上运行 pumba。
| 类别 | 命令 | 描述 |
|---|---|---|
| 容器混沌 | kill、stop、pause、rm、restart | 干扰容器生命周期 |
| 执行 | exec | 在容器内运行命令 |
| 网络延迟 | netem delay | 为出站流量添加延迟 |
| 数据包丢失 | netem loss、iptables loss | 丢弃数据包(出站和入站) |
| 网络效应 | netem duplicate、corrupt、rate | 重复、损坏或限制数据包速率 |
| 压力测试 | stress | 通过 stress-ng 进行 CPU、内存、I/O 压力测试(子 cgroup 或同 cgroup 注入) |
| 目标选择 | 名称、正则(re2:)、标签、--random | 灵活的容器选择 |
| 调度 | --interval | 按固定间隔重复混沌实验 |
为你的平台下载最新版本,或使用 Docker:
# Binary
curl -sL https://github.com/alexei-led/pumba/releases/latest/download/pumba_linux_amd64 -o pumba
chmod +x pumba
# Docker (recommended)
docker pull ghcr.io/alexei-led/pumba:latest
# Kill a random container matching "test" every 30 seconds
pumba --interval=30s --random kill "re2:^test"
# Add 3 seconds network delay to mydb for 5 minutes
pumba netem --duration 5m delay --time 3000 mydb
# Drop 10% of incoming packets to myapp for 2 minutes
pumba iptables --duration 2m loss --probability 0.1 myapp
# Stress CPU of mycontainer for 60 seconds
pumba stress --duration 60s --stressors="--cpu 4 --timeout 60s" mycontainer
# Kill a container by ID via containerd
pumba --runtime containerd --containerd-namespace k8s.io kill <container-id>
# Add network delay via containerd (requires tc in the container image)
pumba --runtime containerd --containerd-namespace moby \
netem --duration 5m delay --time 3000 <container-id>
Pumba 通过其 Docker 兼容 socket 与 Podman 通信。--podman-socket 是可选的——如果为空,pumba 会依次探测 $CONTAINER_HOST、$PODMAN_SOCK、podman machine inspect、/run/podman/podman.sock 和 $XDG_RUNTIME_DIR/podman/podman.sock。
# Kill a container by name via Podman (rootful socket auto-detected)
sudo pumba --runtime podman kill mycontainer
# Add network delay via Podman (requires rootful socket)
sudo pumba --runtime podman netem --duration 5m delay --time 3000 mycontainer
# Stress CPU via Podman (default child-cgroup mode)
sudo pumba --runtime podman stress --duration 60s --stressors="--cpu 4 --timeout 60s" mycontainer
# Explicit socket override
pumba --runtime podman --podman-socket unix:///run/podman/podman.sock kill mycontainer
netem、iptables 和 stress 需要 rootful Podman——rootless 模式会快速失败,并给出明确消息,指向 podman machine set --rootful(macOS)或 rootful systemd 单元(Linux)。
macOS 上的 Podman 运行在 Linux VM 内部。Pumba 必须与目标容器运行在同一内核上(读取宿主机侧的 /proc/<pid>/cgroup),因此请在 podman machine VM 内部运行 pumba 二进制文件:
# one-time setup
brew install podman
podman machine init --rootful --cpus 4 --memory 4096 --now
podman machine ssh sudo dnf install -y bats # optional, for bats tests
# copy a linux/arm64 or linux/amd64 pumba binary into the VM
podman machine ssh sudo cp /path/to/pumba /usr/local/bin/