Slide 1

Slide 1 text

R&D Center System Technology Development Division Base System Development Department Copyright 2019 Sony Corporation ftrace を使ったコンテナ内デバッグの準備 Kenta Tada R&D Center Sony Corporation

Slide 2

Slide 2 text

About me ⚫System Software Engineer ⚫低レイヤな仕事をしています。

Slide 3

Slide 3 text

本日のアジェンダ ⚫strace や GDB を使えない or 使いたくない環境でコンテ ナ内のアプリケーションをデバッグしたい。

Slide 4

Slide 4 text

ptrace ベースのデバッグツール(strace、 GDB)の課題 ⚫(特に組み込みでは)仕組み上、重たい。 ⚫システムグローバルな情報が取れない。 • (コンテナ内のアプリケーション起因で)カーネル側に影響 を与える問題の解析が出来ない。 • 例 : dentry キャッシュの増大化 https://qiita.com/kentaost/items/a2e882d2978fba9e17d3

Slide 5

Slide 5 text

そこで ftrace ⚫ftrace とは • カーネル内に組み込まれているトレーシング機構 • カーネル内関数やシステムコールの呼び出しを含む様々 な情報をカーネル内リングバッファに取得し続ける。

Slide 6

Slide 6 text

ftrace だと何を取得できるの? ⚫たとえば • カーネル内関数の呼び出し • カーネル内関数のコールグラフ •最大の割り込み禁止区間 •システムコールの呼び出し ← 今日はこれをコンテナ内で 取得してみる …

Slide 7

Slide 7 text

まずはコンテナ外で ftrace を使う

Slide 8

Slide 8 text

ftrace によるシステムコールトレース設定(not コンテナ環境) ⚫tracefs のマウント • 本スライドでは /sys/kernel/debug/tracing にマウント ⚫システムコールイベントをトレース対象にする • /sys/kernel/debug/tracing/events/syscalls の中からシステム コール毎に enable ⚫PIDを限定 • # echo [PID] > /sys/kernel/debug/tracing/set_event_pid • 動作中のプロセスではなく、起動時から取得するに は?? → 次ページで説明 ⚫トレーススタート • # echo 1 > /sys/kernel/debug/tracing/tracing_on

Slide 9

Slide 9 text

プロセス起動時からトレースする ⚫set_event_pid に指定する PID がプログラム実行前にわ かれば良い。 → 解析対象プログラムを最後に exec するラッパースクリ プトを作成して、 exec 前に ftrace の設定をすれば OK

Slide 10

Slide 10 text

コンテナ外のシステムコールトレースの例 : ls コマンド

Slide 11

Slide 11 text

コンテナ内で ftrace を使うには?

Slide 12

Slide 12 text

runC のおさらい ⚫runC • 低レイヤコンテナランタイム ⚫runC でコンテナを立ち上げるには • config.json • コンテナの rootfs

Slide 13

Slide 13 text

ftrace 環境を config.json に書く時の懸念点 ⚫tracefs のマウント → 懸念点1 : ftrace のリングバッファはシステムグローバ ル ⚫システムコールイベントをトレース対象にする ⚫PIDを限定 ⚫トレーススタート → 懸念点2 : pid namespace を分割していたら(普通してい る)どうしよう??

Slide 14

Slide 14 text

懸念点1 : ftrace のリングバッファや設定について ⚫通常 ftrace のリングバッファはシステムグローバル • トレーススタートタイミングは、コンテナ毎に異なる。 • コンテナAとコンテナBが共に ftrace を使うと、両方のログ が混合される。 –コンテナ側にリングバッファを見せる場合、機微情報等 が入ってたりすると困る。 ⚫コンテナの中で ftrace の設定をいじられたくない • コンテナ内からリングバッファのサイズを変更したり、 トレース対象の PID を変更できてしまう。

Slide 15

Slide 15 text

懸念点1 : 解決案 ⚫通常 ftrace のリングバッファはシステムグローバル • ftrace にはリングバッファを分割する機能がある(ftrace instances)。 –instances ディレクトリ(例 : /sys/kernel/debug/tracing/instances) で mkdir すると専用のバッファが出来る。 –例 : /sys/kernel/debug/tracing/instances/containerA • コンテナ毎にリングバッファを作成して、コンテナ毎の ユーザに chown して bind mount ⚫コンテナの中でftraceの設定をいじられたくない • bind mount の単位をファイルレベルに細かくする

Slide 16

Slide 16 text

懸念点2 : pid namespace 分割問題 ⚫ホスト上の PID を set_event_pid に指定する必要がある。

Slide 17

Slide 17 text

懸念点2 : 解決案 ⚫ホスト上の PID を set_event_pid に指定する必要がある。 • runC は自身を exec してコンテナの init process になる。 • runC の preStart にて、将来コンテナの中で動く PID (runc init)を探してその PIDを set_event_pid に指定するスクリプ トを実行する。 "hooks": { "prestart": [ { "path": "/hookpath/set_ftrace.sh", "args": [ "set_ftrace.sh" ] } ] },

Slide 18

Slide 18 text

コンテナ内のシステムコールトレースの例 : ls コマンド

Slide 19

Slide 19 text

デモ : 実際にコンテナ内からログを出してみる

Slide 20

Slide 20 text

今後の課題 ⚫preStart から実際に exec されるまでにトレースされる情 報がログに入ってしまう。 • そもそも preStart でやるべきことでもない気がする。 → preExec 的なものが欲しいなあ・・・ ⚫どのファイルが読めなくてエラーになってるか知りた い。 → (参考) kprobes で表示可能 https://events.linuxfoundation.org/wp-content/uploads/2017/12/oss-eu-2018- fun-with-dynamic-trace-events_steven-rostedt.pdf ⚫ログのシステムコールのエラーメッセージが欲しい。

Slide 21

Slide 21 text

コンテナ内で ftrace を使うには? ⚫ftrace instances をコンテナ単位で割り当てる ⚫runC の preStart で将来コンテナの中で動く PID を取得 し、その PID を ftrace の set_event_pid に設定する まとめ

Slide 22

Slide 22 text

SONYはソニー株式会社の登録商標または商標です。 各ソニー製品の商品名・サービス名はソニー株式会社またはグループ各社の登録商標または商標です。その他の製品および会社名は、各社の商号、登録商標または商標です。