今回は Chaos Mesh を紹介します。 Chaos Mesh は Kubernetes 環境向けの Chaos Engineering ツールです。

Chaos Mesh によるカオスエンジニアリング

Yoshinori Teraoka

2020.6.2

Sreake の寺岡です。今回は Chaos Mesh を紹介します。
Chaos Mesh は Kubernetes 環境向けの Chaos Engineering ツールです。

カオスエンジニアリングの原則

カオスエンジニアリングと言えば本番環境で発生しうる Node 障害を日常のものにするということが元々の目的だったのではないかと思いますが、今日では意図的に障害を発生させること全般が対象となっているように感じます。まれに発生するトラブルを開発環境で意図的に発生させてコードの品質を上げるということが含まれてきているようです。

ここで紹介する Chaos Mesh も、開発元である PingCAP が TiDB の品質を上げるべく作り始めたもののようです。そのため、分散データベースで必要とされるような機能が盛り込まれています。

それでは Chaos Mesh でどんなことができるのかを順に紹介します。

Experiments の種類

Chaos Mesh で挿入可能な障害には2020年5月の時点で次の種類があります。最初に見た時には上の3つしかありませんでしたが、次々に増えました。Pod Chaos の中の Container Kill も後で追加されました。

  • Pod Chaos
  • IO Chaos
  • Network Chaos
  • Time Chaos
  • Kernel Chaos
  • Stress Chaos

ひとつずつ見ていきます。

Pod Chaos

  • Pod Failure
    Pod が起動に失敗するようにします(Container Image が存在しないものに書き換えられる)
  • Pod Kill
    Pod が削除される (kubectl delete pod 相当)
    正常な終了処理が行われるためスケールインのテストでしょうか
  • Container Kill
    SIGKILL で Pod ではなく Container を kill する

Pod Chaos の設定例はドキュメントにあります。そこから一例を転載します。以降の Chaos もほぼ同じような設定となります。(IO Chaos は例外)

apiVersion: pingcap.com/v1alpha1
kind: PodChaos
metadata:
  name: pod-failure-example
  namespace: chaos-testing
spec:
  action: pod-failure
  mode: one
  value: ""
  duration: "30s"
  selector:
    labelSelectors:
      "app.kubernetes.io/component": "tikv"
  scheduler:
    cron: "@every 2m"

PodChaos、IOChaos、NetworkChaos などの単位でカスタムリソースが定義されています

  • action で pod-failure や pod-kill 、 container-kill を指定
  • mode では selector で指定した対象 Pod のうち一つだけの one なのか、全部の all なのか、特定の数や割合なのかを指定
  • duration と scheduler でどのタイミングで開始し、どれだけの時間継続させるかを指定

リポジトリの examples ディレクトリにも設定例があります。

IO Chaos

HookFS を用いてファイルシステムに対する各種操作に対して Delay を挿入したり、任意もしくはランダムな errno を返すようにする。全ての呼び出しではなく割合をパーセンテージで指定することが可能。

これはちょっとセットアップが面倒ですが、分散 Database である TiDB の開発にはとても有用だったのでは無いでしょうか。そうでなくてもファイルへのアクセスを行うアプリで様々なケースのテストを行いたい場合には重宝しそうです。

面倒なセットアップ方法は書くと長くなるので省略。

よくある errno には次のようなものがあります。使えそうですよね。

  • 1: Operation not permitted
  • 2: No such file or directory
  • 5: I/O error
  • 6: No such device or address
  • 12: Out of memory
  • 16: Device or resource busy
  • 17: File exists
  • 20: Not a directory
  • 22: Invalid argument
  • 24: Too many open files
  • 28: No space left on device

docs/io_chaos.md

Network Chaos

  • Network Partition
    指定の Pod 間で通信ができないようにする
  • Network Emulation Chaos
    指定の割合で Packet Loss, Delay, Duplicate, Corrupt を発生させたり、帯域(bps)を制限する。Delay には遅延時間と jitter の指定が可能。ただし、これらは Outbound にしか影響しない

現状、外部の特定のホストとの通信をブロックするといった使い方はできません。また、Delay 時間や Packer Loss の割合を大きくしすぎると kubelet からの Liveness /Readiness Probe への影響も出てしまい、restart を繰り返すことになりかねません。

docs/network_chaos.md

Time Chaos

clock_gettime が返す値をずらします。TiDB で一部のインスタンスの時刻が少しだけずれてる場合への対応で必要になったみたいですが、そうでなくても時刻をずらしてテストしたいという状況には遭遇しますね。余談ですが、最近 faketime というコマンドの存在も知りました。

Go で書かれたサーバーで HTTP の Response Header にある Date が変わっていることは確認しましたが Time Chaos の Limitation には次のように書かれているため注意が必要です。

  • Time modification will only be injected into the main process of container.
  • Time chaos has no effect on pure syscall clock_gettime.
  • All injected vdso call will use pure syscall to get realtime, so clock related function call will be much slower.

docs/time_chaos.md

Kernel Chaos

これは試せていませんし、よく分かっていません?
BPF Compiler Collection (BCC) の inject.py に似ていると書いてあります。ドキュメントにある例では mount を失敗させているようです。kernel.org に Fault injection capabilities infrastructure というドキュメントがあるんですね。

docs/kernel_chaos.md

Stress Chaos

CPU とメモリの使用率を上げます。DaemonSet として実行されている chaos-daemon が裏でこっそり stress-ng コマンドを対象コンテナの cgroup で実行します(たぶん)。そのため kubectl top pod の出力には現れませんが、コンテナ内で使える CPU 時間やメモリが減っています。CPU 負荷の高い状態や、OOM を容易に発生させることができます。

docs/stress_chaos.md

Web UI

Chaos Mesh は活発に開発が行われており、Web UI から設定することが可能になりそうです。テスト担当の人が簡単に設定できるようになると便利そうです。https://github.com/pingcap/chaos-mesh/pull/541

Chaos Server (Dashboard) として 5/28 の Community Meeting で紹介されていました。

スケージュール実行

これは Chaos Mesh の良い面であり、不便な面でもあるのですが Chaos Mesh の設定には実行のスケジュールを github.com/robfig/cron 形式で書く必要があります。カオスエンジニアリングとしては定期実行は良いことですが、今からテストでしばらく実行しておきたいという場合にちょっと面倒です。pause 機能が追加されたため実行期間を長めにして pause で中断するということが出来るようにはなりました。デフォルトは cron じゃなくてずっと実行するようにしようという issue もあった気がします。

docs/pause.md

セットアップ手順

Deploy Chaos Mesh に書かれています。
Controller や Daemon の container image と CRD などで不整合が出ないように tag (執筆時の最新が v0.8.0) を checkout してインストールするのが良いと思われます。まだ、master branch しかなかった時に deploy していたものがいつの間にか動かなくなったと思ったら image だけ更新されていました。

More

YouTube に Community Meeting の動画も公開されていますWiki には週次で更新がまとめられています。

以上、Chaos Mesh の紹介でした。興味をもたれたら使ってみてください。

ブログ一覧へ戻る

お気軽にお問い合わせください

SREの設計・技術支援から、
SRE運用内で使用する
ツールの導入など、
SRE全般についてご支援しています。

資料請求・お問い合わせ