inductor's blog

nothing but self note :)

Kubernetes Meetup #24 2つ目のスライドのやつ

Debug application inside Kubernetes using Linux Kernel tools

Agenda

  • oci-ftrace-syscall-analyzerの紹介
  • Kubernetes上でプロセスのコアダンプを取る方法の紹介

Kuberetesの全体像

oci-ftrace-syscall-analyzerの紹介

軽量でセキュアなruncベースのコンテナ環境を組み込み向けに開発した

サードパーティ向けにセキュア(制限があってルートレスな)コンテナを立ち上げる要件

ftraceベースのシステムコールアナライザを作った

既存のKuberentesデバッグ方法

デバッグツールをPodに入れる デバッグ用イメージを作る プロセスの名前空間を共有した状態でデバッグサイドカーを入れる

カーネルツールを透過的にアプリケーションをトレースするために使う

既存のツールは便利だけど、ケーパビリティやファイルの権限、seccompなどのセキュリティ要件を満たすのが難しい部分もある

トレース周りのカーネル技術

図がすごい。今回はftraceを使うようにした。eBPFなどの話もしていたが頭が追いつかないw

syscallの解析に使ったカーネル技術

統合に必要な準備

  1. ftraceリングバッファを分割する(下記コンテナランタイム勉強会の資料参照)

  2. ftraceをコンテナ内部で立ち上げる

speakerdeck.com

コンテナ起動時にftraceを仕込む方法

コンテナが動く前にftraceを注入する

  • OCI runtime specの中でprestartからhookできると記述があるので、それを使った
  • poststopまでをcollect logする

    PID processをコンテナ内部で取得する方法

    コンテナ内のPID1プロセスをホスト側の実PIDをとるには

  • OCI runtime specの中でstdinでjson形式でコンテナのステートが入っているよという記述がある
  • それを取ると根本のPIDがわかる

ftraceで何やってるか

  • トレースしたいシステムコールをenable
  • 取得したホスト側のPIDをセット
  • trace processes which PID of set_event_pid forked
    • コンテナ起動時のプロセスしか取れないので、kubectl execとかしたときのプロセスのsyscallはとれない

ここまででrunc周りのインテグレーションが終わった。

Kuberetesで導入するには

  • Kuberentesのラインタイムに対してどう頑張るか
    • poststartの段階で頑張るのは難しいと言うのが分かった

Containerdではどうか

  • KubernetesレベルでだめならHigh level container runtimeのレベルでどうなんだろうか。という話
    • PRレベルでは動いてるが、今の時点では厳しいみたい

CRI-oではどうか

oci hooks機能があって、それを書いてあげるとruncのhookもできるようになる

CRI-Oでできるかのデモ(サンプルコードもあるよ!)

とりあえず動く事がわかった

関連ツール

  • oci-seccomp-bpf-hook

    • コンテナのシステムコールをもとに、eBPFを使ってseccompのプロファイルを生成する
  • kubectl-trace

    • 聞き逃し

↑基本的にはこれ強いけど、oci-ftrace-syscall-analyzerは

  • ユーザーに特権を渡したくないときに有用そう
  • eBPFの設定がカーネルにちゃんと入ってない場合にそれに依存せず使えそう

これらの解決策で今抱えてる問題は?

  • コンテナは独自のnamespaceがあってカーネルのnamespaceを使ってない

    • カーネルコードに対するパッチは有るけどマージされてない
  • Kuberenetesにアドオンを使って解決しようという方法

    • これもマージされてない

まとめ

  • CRI-OベースのKubernetes環境であればHook出来ることがわかった
    • まだまだ課題があるので頑張るぞい
  • コアダンプについてはなにもわからn(おしえて)

今後の課題

  • Containerdとの連携
  • 社内のコンテナツールで取得できるユーザー空間のログをがんばる
  • syscallの引数を取るためにkprobesを使ったsystemcall hookができるようにしたい
  • seccomp generatorを作りたい
  • OCIのprestartで取ってるのでruncが動くまでの他の不要なsyscallまで取れちゃう
    • workaroundありそうだけどこれは本当に正しいのかがよくわかってない