Pumba(パンバ)は、Dockerなどのコンテナを対象に、プロセス停止・ネットワーク遅延・パケットロス・CPU負荷といった障害をコマンド1行で注入するオープンソースのカオステストツールです。開発はAlexei Ledenev氏で、GitHubのalexei-led/pumbaで公開されています。2026年9月時点の最新版は1.2.1(2026年8月23日公開)で、各版の変更点はPumbaのGitHubリリース一覧で確認できます。
なお、検索語の「pumba」はInstagramで知られるカラカル(猫科の動物)の名前や、映画『ライオン・キング』のイボイノシシも指します。ライオン・キングのキャラクターの綴りは「Pumbaa」でaが2つです。この記事は、コンテナ向けツールのPumbaを扱います。
まとめ:Pumbaでできることと使う前に知っておく制約
- 注入できる障害は、コンテナの停止系(kill・stop・pause・rm・restart・exec)、ネットワーク系(netem・iptables)、リソース負荷(stress)の3系統です。
- 対応ランタイムはDocker・containerd・Podmanです。containerd対応は1.0.0(2026年2月)、Podman対応は1.1.0(2026年4月)で入りました。Windows向けバイナリは提供されておらず、今後も作らないと公式に明記されています。
- netemは送信(egress)側だけに効きます。受信側のパケットロスは
iptables lossで作ります。 - netemとiptablesは
--durationが必須です。対象名が1件も一致しなくても終了コードは0なので、CIに組み込むときは--dry-runのログで対象を確かめてください。 - Kubernetesでは、公式マニフェストの
pumba_kube.ymlがDockerソケット前提です。containerdで動く現行のクラスタでは--runtime containerdと特権コンテナの構成に書き換えます。
以下、導入から各コマンドの挙動、他ツールとの使い分けの順に説明します。
Pumbaの仕組みと対応ランタイム・動作環境
Pumbaはコンテナランタイムのソケット(Dockerなら/var/run/docker.sock)に接続し、対象コンテナを名前やラベルで選んで操作します。停止系のコマンドはランタイムのAPIを呼ぶだけです。ネットワーク系は、tcやiptablesを含むヘルパーコンテナを対象コンテナと同じネットワーク名前空間で起動し、そこでルールを入れます。READMEには、NetflixのChaos Monkeyに着想を得てカオスエンジニアリングをコンテナの単位に持ち込んだツールだと書かれています。
注入できる障害とコマンドの対応
| 系統 | コマンド | 起きること |
|---|---|---|
| コンテナ停止 | kill |
既定でSIGKILLを送る |
| コンテナ停止 | stop |
既定でSIGTERM、5秒以内に停止しなければSIGKILL |
| コンテナ停止 | pause |
指定時間だけ全プロセスを一時停止 |
| コンテナ停止 | rm |
既定で強制削除し、ボリュームも削除 |
| コンテナ停止 | restart |
コンテナを再起動 |
| コマンド実行 | exec |
既定でkill 1を実行 |
| ネットワーク | netem |
送信の遅延・損失・重複・破損・帯域制限 |
| ネットワーク | iptables loss |
受信パケットの破棄 |
| リソース負荷 | stress |
stress-ngでCPU・メモリ・I/O負荷 |
既定値は1.2.1の--helpで確認したものです。execの既定値がkill 1である点は、後の章で扱う事故につながります。
Docker・containerd・Podmanの対応状況とWindows非対応
| ランタイム | 既定ソケット | netem・iptables・stressの条件 | 対応版 |
|---|---|---|---|
| Docker | /var/run/docker.sock |
rootかソケットへのアクセス権 | 初期から |
| containerd | /run/containerd/containerd.sock |
root必須 | 1.0.0 |
| Podman | /run/podman/podman.sock |
rootful必須 | 1.1.0 |
配布バイナリはLinuxとmacOSのamd64・arm64の4種類です。READMEはmacOS版を「開発者の利便性のため」と位置づけ、ColimaやPodman machineなどのLinux VMを操作する用途に限っています。Pumbaは対象コンテナと同じカーネル上で動かす必要があるため、Podmanの場合はPumbaのバイナリをVMの中にコピーして実行します。Windows版は、Linuxのnetnsやcgroupへの書き込みに相当する仕組みが無いことを理由に「サポートせず、予定もない」と明記されています。WSL2上のDocker Desktopでも同じ扱いです。
Pumbaのインストール方法(バイナリ・Homebrew・コンテナイメージ)
導入方法は3つです。どれも1.2.1を入手できます。
# Linux:単体バイナリ(tar.gzではなく実行ファイルそのものが配布される)
curl -sL https://github.com/alexei-led/pumba/releases/latest/download/pumba_linux_amd64 -o pumba
chmod +x pumba
./pumba --version
# 以降の例を pumba コマンドで実行するため、PATH上へ配置
sudo install -m 0755 pumba /usr/local/bin/pumba
# macOS:Homebrew(homebrew-coreのformula)
brew install pumba
# コンテナとして実行(READMEの推奨)
docker pull ghcr.io/alexei-led/pumba:latest
docker run -it --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/alexei-led/pumba --version
イメージの正規の配布先はGitHub Container Registryのghcr.io/alexei-led/pumbaです。READMEではDocker Hub側を非推奨(Deprecated)としています。古い解説記事に出てくるヘルパーイメージgaiadocker/iproute2は、Docker Hubでの最終更新が2016年9月です。1.2.1のヘルパーの既定値はghcr.io/alexei-led/pumba-alpine-nettools:latestなので、古い指定は書き写さないでください。
コンテナで動かす場合、PumbaはDockerソケット経由でホストのコンテナを操作できるため、実質的にホストのroot権限を持ちます。共有の検証環境では、実行できる人を限定してください。
Pumbaの基本構文と対象コンテナの指定方法
構文はpumba [グローバルオプション] コマンド [コマンドオプション] 対象コンテナです。--interval・--random・--label・--dry-runはグローバルオプションなので、コマンド名より前に置きます。netemやiptablesの--durationは、delayなどのサブコマンドより前に置きます。
名前・re2正規表現・ラベルでの絞り込み
# 名前で指定(複数並べられる)
pumba kill myapp mydb
# RE2正規表現は "re2:" を先頭に付ける
pumba kill "re2:^test"
# ^test に一致するコンテナから1つだけ無作為に選び、30秒ごとに停止
pumba --interval=30s --random kill "re2:^test"
# ラベルで絞る(複数指定はAND条件)
pumba --label app=db kill "re2:.*"
--labelはDocker APIのfiltersパラメータとして渡されます。Docker Composeで起動したコンテナは、Compose v2の既定ではプロジェクト名-サービス名-連番という名前になります。名前が変わりやすい環境では、com.docker.compose.service=dbのようなラベル指定のほうが安定します。
dry-runで事前に対象を確かめる手順
--dry-runを付けると、実際の障害は起こさず、どのコンテナに何をするかだけをログに出します。検証用にDocker APIを模したサーバーを用意し、1.2.1で次のコマンドを実行したところ、以下のログになりました。
$ pumba --log-level info --dry-run netem --duration 10s delay --time 1000 mydb
level=info msg="running netem on container" command="[delay 1000ms 10ms 20.00]" dryrun=true name=/mydb
level=info msg="stopping netem on container" dryrun=true name=/mydb
$ pumba --dry-run kill nonexistent
level=warning msg="no containers found"
$ echo $?
0
1つ目は--jitterを指定していないのに、±10ミリ秒の揺らぎと相関20%が入っています。netem delayの既定値がjitter 10ミリ秒・相関20%だからです。遅延を固定値で入れたいときは--jitter 0を明示します。
2つ目は、対象名を打ち間違えても警告が出るだけで終了コードは0です。CIのジョブで障害注入をしても、名前の変更に気づかないまま「障害に耐えた」という誤った結果になります。本番の実行前に同じ引数で--dry-runを走らせ、name=の行が期待どおり出るかを確認する手順を入れてください。
コンテナ障害の注入(kill・stop・pause・rm・restart・exec)
# SIGKILLで強制終了(--signal SIGTERM などに変更可)
pumba kill --signal SIGKILL myapp
# 5秒間だけ一時停止し、自動で再開
pumba pause --duration 5s myapp
# 停止して20秒後に起動し直す
pumba stop --restart --duration 20s myapp
# 削除(既定で稼働中も強制削除し、関連ボリュームも消える)
# ボリュームを残すなら --volumes=false を明示
pumba rm --volumes=false myapp
kill・stop・pauseはランタイムのAPIを呼ぶだけで、ヘルパーコンテナを使いません。--limitで一度に操作する台数を絞れます(0は一致した全台)。
stopのdurationとrestartの併用条件
stopの--durationは、--restartを付けたときだけ使われます。dry-runでstop --duration 2s myappを実行すると停止のログだけが出ました。--restartを付けると、2秒後にstarting containerのログが続きます。「一定時間止めて戻す」つもりで--restartを落とすと、コンテナは止まったままになります。
execのcommand・args指定と既定のkill 1
execは、実行する内容を--commandと--argsで指定します。docker execと同じ感覚でpumba exec myapp -- touch /tmp/testfileと書くと、--以降は無視されます。dry-runのログではcommand="kill 1"となり、既定値のkill 1、つまりコンテナのPID 1を終了させる処理が選ばれていました。
# 正しい書き方
pumba exec --command "touch" --args "/tmp/testfile" myapp
ファイルを作るつもりでコンテナを落とす事故になるので、execを使うときは必ずdry-runでcommandの値を確認してください。
ネットワーク障害の注入(netemとiptables)
netemはLinuxカーネルのトラフィック制御(tc qdisc netem)を使います。効くのはコンテナの送信側(egress)だけです。受信側を落としたい場合はiptablesコマンドを使います。
netemの遅延・損失・帯域制限と既定値
# 3秒の遅延を5分間
pumba netem --duration 5m delay --time 3000 mydb
# 送信パケットの5%を破棄
pumba netem --duration 5m loss --percent 5 mydb
# 送信帯域を1Mbitに制限
pumba netem --duration 10m rate --rate 1mbit mydb
# 10%を破損・10%を重複
pumba netem --duration 5m corrupt --percent 10 mydb
pumba netem --duration 5m duplicate --percent 10 mydb
netemは--durationを省略できません。省略するとunset or invalid duration valueで終了します。--intervalと併用する場合は、durationをintervalより短くします。--interval 3sに--duration 5sを渡すとduration must be shorter than intervalで起動しません。
損失をまとまって発生させたい場合は、4状態マルコフモデルのloss-stateか、Gilbert-Elliottモデルのloss-gemodelを使います。無線回線のように、損失が連続して起きる状況に近づけられます。
netem combineによる単一qdiscへの複合効果の設定
1.2.0でnetem combineが追加され、遅延と損失のような複数の効果を1つのqdiscにまとめて設定できるようになりました。
# 100msの遅延と20%の損失を同時に
pumba netem --duration 5m combine \
--delay --delay-time 100 \
--loss --loss-percent 20 \
-- mydb
dry-runではcommand="[delay 100ms 10ms 20.00 loss 20.00]"となり、ここでもjitter 10ミリ秒の既定値が入ります。効果を1つしか指定しないとat least two netem effects are requiredで拒否されます。
1.2.0では、Pumbaが作るqdiscに予約ハンドル504d:を付けるようになりました。Pumba以外が作ったqdiscや、前回の実行で残ったqdiscは書き換えずに拒否します。設定途中の失敗時には巻き戻しを試みます。ただし、Pumba自体がSIGKILLで終了した場合は後処理できません。対象インターフェースを確認し、Pumbaが作ったハンドル504d:のroot qdiscだけを手動で除去します。
targetで特定の通信先だけ劣化させる方法とIPv6非対応
--targetを付けると、指定した通信先への通信だけを劣化させられます。IPv4アドレス、CIDR、稼働中のコンテナ名またはIDを指定でき、1.2.0からはコンテナ名を実行のたびにIPアドレスへ解決します。
# service-a から service-b への通信だけに1秒の遅延
pumba netem --duration 10m --target service-b delay --time 1000 service-a
「DBへの通信だけ遅い」状況を再現できるので、コンテナ全体を遅くするより原因の切り分けがしやすくなります。IPv6は対象外で、--target 2001:db8::1を渡すとIPv6 --target "2001:db8::1" is not supportedで終了します。
iptables lossによる受信パケットの破棄
# 受信パケットの10%を2分間破棄
pumba iptables --duration 2m loss --probability 0.1 myapp
# 192.168.1.100から8080番ポートへのTCPを5パケットに1つ破棄
pumba iptables --duration 5m --protocol tcp --source 192.168.1.100 --dst-port 8080 \
loss --mode nth --every 5 myapp
1つ目をdry-runすると、開始時に-I INPUT -i eth0 -m statistic --mode random --probability 0.10 -j DROPを挿入し、終了時に同じ条件を-Dで削除する計画が出ます。--probabilityは0.0〜1.0の割合で、netemの--percentとは単位が違います。
ヘルパーイメージとminikubeでの制約
対象コンテナにtcやiptablesが入っていなくても、Pumbaがヘルパーコンテナを起動して処理します。ヘルパーはNET_ADMINケーパビリティ付きで起動されます。独自イメージを--tc-imageで指定する場合は、sh・grep・tcに加え、Docker・Podmanではwhichとtail、containerdではsleepも含める必要があります。Pumbaのデプロイガイドは、minikubeのVMにはsch_netemカーネルモジュールが無くnetemが動かないと注意しています。minikubeで試す場合は、ノードのカーネルでsch_netemを使えるかを先に確認してください。
CPU・メモリ負荷の注入(stressとinject-cgroup)
# 2コアのCPU負荷と256MBのメモリ確保を30秒
pumba stress --duration 30s --stressors="--cpu 2 --vm 1 --vm-bytes 256M" myapp
# 対象と同じcgroupに入れて負荷をかける
pumba stress --inject-cgroup --duration 60s --stressors="--cpu 2 --timeout 60s" myapp
stressはghcr.io/alexei-led/stress-ng:latestをサイドカーとして起動して負荷をかけます(Dockerの場合)。サイドカーがどのcgroupに置かれるかは、次のとおりcgroupドライバで変わります。--stressorsは=で値を渡します。
systemdドライバの既定モードとリソース制限の非共有
既定モードは、Dockerの--cgroup-parentでサイドカーの配置先を決めます。cgroupドライバがcgroupfsなら対象の子cgroupに入り、対象のCPU・メモリ制限を共有します。systemdドライバでは子cgroupを作れないため、サイドカーはsystem.sliceの兄弟cgroupに置かれます。この場合、対象コンテナの制限は共有されません。
ホストのドライバはdocker infoの「Cgroup Driver」欄で確認できます。systemdのホストで既定モードのまま「メモリ上限に達したときの挙動」を試しても、対象コンテナは上限に届きません。対象と同じcgroupで負荷をかけるには--inject-cgroupを使います。このモードには、stress-ngイメージのタグ0.20.01(2026年2月27日公開)以降に含まれるcg-injectが必要です。古いlatestがローカルに残っていると動かないので、docker pullで更新してください。--inject-cgroupではOOMの範囲も対象と共有するため、対象コンテナ自体がOOMで終了する可能性があります。
KubernetesでPumbaを使うときのDaemonSet構成
公式リポジトリのdeploy/pumba_kube.ymlは、各ノードの/var/run/docker.sockをマウントするDaemonSetです。イメージも旧名のgaiaadm/pumbaのままです。Kubernetesは1.24でdockershimを削除したため、containerdをランタイムにしている現在のクラスタでは、このマニフェストはそのままでは使えません。Kubernetesの最新バージョンを使っているなら、Pumba公式のデプロイガイドにあるcontainerd向け構成に書き換えます。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pumba-containerd
namespace: pumba # 事前に kubectl create namespace pumba で作成
spec:
selector:
matchLabels:
app: pumba
template:
metadata:
labels:
app: pumba
spec:
hostPID: true
containers:
- name: pumba
image: ghcr.io/alexei-led/pumba
args:
- --runtime
- containerd
- --containerd-namespace
- k8s.io
- --label
- io.kubernetes.pod.name=target-pod
- --interval
- 30s
- netem
- --duration
- 20s
- --tc-image
- ghcr.io/alexei-led/pumba-alpine-nettools:latest
- delay
- --time
- "3000"
securityContext:
privileged: true
volumeMounts:
- name: containerd-socket
mountPath: /run/containerd/containerd.sock
volumes:
- name: containerd-socket
hostPath:
path: /run/containerd/containerd.sock
Dockerソケット版との違いは、containerdのソケットをマウントする点、名前空間にk8s.ioを指定する点、privileged: trueとhostPID: trueが必要な点です。対象Podはio.kubernetes.pod.nameやio.kubernetes.pod.namespaceのラベルで絞ります。Pumba自身のPodにはcom.gaiaadm.pumba: "true"ラベルを付けてください。Pumbaはこのラベルを持つコンテナを対象から外すため、正規表現で広く指定しても自分自身を停止しません。
この構成はノード上の全コンテナを操作できる特権DaemonSetです。対象をnodeSelectorで検証用ノードに限定し、本番クラスタの常設には使わないでください。
Pumbaを選ぶ場面と他のカオスツールを選ぶ場面
| ツール | 主な対象 | 提供形態 | 最新版(2026年9月時点) |
|---|---|---|---|
| Pumba | 単一ホストのコンテナ | OSS・CLI | 1.2.1(2026-08-23) |
| Chaos Mesh | Kubernetes | OSS・CRD(CNCF Incubating) | v2.8.4(2026-08-18) |
| LitmusChaos | Kubernetes | OSS・CRD(CNCF Incubating) | 3.31.0(2026-07-15) |
| Toxiproxy | TCP通信 | OSS・プロキシ | v2.12.0(2025-03-18) |
| Gremlin | ホスト・コンテナ・Kubernetes | 商用SaaS | サービス型 |
| AWS FIS | AWSのリソース | マネージド | サービス型 |
最新版はGitHub Releases APIの値、CNCFの成熟度はCNCFのプロジェクトページの値です(Chaos Meshは2022年2月、LitmusChaosは2022年1月にIncubatingへ移行)。Gremlinは公開定価が無くサービス単位の見積もりで、クレジットカード不要の30日間トライアルが用意されています。
Pumbaが向いているのは、Docker ComposeやCIの結合テストで「DBが3秒遅れたら」「キャッシュが落ちたら」を再現する場面です。クラスタにコンポーネントを入れる必要がなく、バイナリ1つかイメージ1つで始められます。Dockerのコンテナ起動コマンドで環境を立ち上げ、そのままPumbaで障害を入れる流れが最も手軽です。
Kubernetesのクラスタ全体で実験を管理するなら、Pumbaは選ばないほうがよいです。PumbaにはPod単位の実験定義、実験履歴、自動停止条件がありません。特権DaemonSetを置く運用も重くなります。この場合はCRDで実験を宣言できるChaos MeshかLitmusChaosを使います。AWSのマネージドサービスを止める実験は、コンテナの外側で起きるためPumbaでは作れません。AWS Fault Injection Service(FIS)の領域です。
Toxiproxyはアプリとの間にTCPプロキシを挟む方式で、コンテナの権限を必要としません。アプリの接続先をプロキシに向けられるなら、NET_ADMINや特権を避けたいCI環境ではToxiproxyのほうが扱いやすい場合があります。実験設計や停止条件の決め方はカオステストの実験設計とツール選定でまとめています。
よくある質問
Pumbaという名前にはどういう意味がありますか?
ツール名の由来は、READMEや公式ドキュメントには書かれていません。検索で「pumba」と調べると、Instagramで人気のカラカルや、『ライオン・キング』のイボイノシシ(綴りはPumbaa)の情報も表示されます。この記事で扱うPumbaは、GitHubのalexei-led/pumbaで公開されているコンテナ向けのカオステストツールです。
PumbaはDockerコンテナとして実行できますか?
できます。READMEが推奨する方法で、docker run -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/alexei-led/pumbaの後ろにPumbaのコマンドを続けます。イメージはscratchベースで、中身はPumbaのバイナリだけです。
PumbaのGitHubリポジトリとライセンスは?
リポジトリはgithub.com/alexei-led/pumba、ライセンスはApache License 2.0で、Go言語で書かれています。2026年9月時点でスター数は約3,100、最新版は1.2.1です。
WindowsでPumbaは使えますか?
使えません。Windows向けバイナリは配布されておらず、READMEにはWindows対応のプルリクエストも受け付けないと書かれています。Windows端末から使う場合は、Linux VMの中でPumbaを実行してください。
PumbaとChaos Monkeyの違いは何ですか?
Chaos Monkeyは、Spinnakerで管理しているクラウドのインスタンスを無作為に終了させるツールです。PumbaはChaos Monkeyに着想を得ていますが、対象はコンテナで、終了だけでなくネットワーク遅延やCPU負荷も注入できます。Spinnakerも必要ありません。