Upgrade to Pro — share decks privately, control downloads, hide ads and more …

カーネルから見る OCIランタイム

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for 0n1shi 0n1shi
March 22, 2019
1.1k

カーネルから見る OCIランタイム

Avatar for 0n1shi

0n1shi

March 22, 2019
Tweet

Transcript

  1. 自己紹介 大西 和貴 (@_k_onishi_) SAKURA Internet Inc. アプリケーショングループ レンタルサーバーチーム Linux

    / Kernel / CPU / Container / Virtualization / Pwn / C / Assembly / Python Linux Kernel 勉強会
  2. 目次 • コンテナとは • Cgroupsとは • CFS Bandwidth Controlの概要と実装 •

    Completely Fair Schedulerの概要と実装 • カーネルの独自パッチ • まとめ
  3. Cgroupsとは • cpu: CPUへのアクセス • cpuacct: CPUについての自動レポートを生成 • cpuset: マルチコアCPUのコア単位およびメモリノードを割り当て

    • memory: メモリに対する制限設定と自動レポートの生成 • blkio: ブロックデバイスの入出力アクセス • devices: デバイスへのアクセス • net_cls: ネットワークパケットへのタグ付け • net_prio: ネットワークトラフィックの優先度を動的に設定 • freezer: タスクを一時停止または再開 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5
  4. Cgroupsとは • cpu: CPUへのアクセス • cpuacct: CPUについての自動レポートを生成 • cpuset: マルチコアCPUのコア単位およびメモリノードを割り当て

    • memory: メモリに対する制限設定と自動レポートの生成 • blkio: ブロックデバイスの入出力アクセス • devices: デバイスへのアクセス • net_cls: ネットワークパケットへのタグ付け • net_prio: ネットワークトラフィックの優先度を動的に設定 • freezer: タスクを一時停止または再開 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5
  5. Cgroupsとは • cpu: CPUへのアクセス 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5 # cgroupの作成 $ cgcreate

    -g blkio,memory,cpu,pids:test # 指定のプロセスをcgroupに参加させる。 $ echo $$ 2006 $ cgclassify -g blkio,memory,cpu,pids:test 2006 # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_period_us=1000000 test $ cgset -r cpu.cfs_quota_us=500000 test
  6. CFS Bandwidth Controlの実装 参考: kernel/sched/core.c #ifdef CONFIG_CFS_BANDWIDTH { .name =

    "cfs_quota_us" , .read_s64 = cpu_cfs_quota_read_s64, .write_s64 = cpu_cfs_quota_write_s64, }, { .name = "cfs_period_us" , .read_u64 = cpu_cfs_period_read_u64, .write_u64 = cpu_cfs_period_write_u64, }, -rw-r--r-- 1 root root 0 Mar 22 09:14 /sys/fs/cgroup/cpu,cpuacct/test/cpu.cfs_period_us -rw-r--r-- 1 root root 0 Mar 22 09:14 /sys/fs/cgroup/cpu,cpuacct/test/cpu.cfs_quota_us
  7. CFS Bandwidth Controlの実装 • tg_set_cfs_bandwidth() ◦ __cfs_schedulable() // 対象タスクグループ配下に制限値を反映 ◦

    period及びquotaを更新 ◦ __refill_cfs_bandwidth_runtime() // quota マイクロ秒のランタイムプールを補 充 ◦ start_cfs_bandwidth() // period 用のタイマーを起動 ▪ sched_cfs_period_timer() • __refill_cfs_bandwidth_runtime() // quota マイクロ秒のランタイム プールを補充 参考: kernel/sched/core.c
  8. CFS Bandwidth Controlの実装 参考: kernel/sched/core.c void __refill_cfs_bandwidth_runtime (struct cfs_bandwidth *cfs_b)

    { u64 now; if (cfs_b->quota == RUNTIME_INF) return; now = sched_clock_cpu (smp_processor_id ()); cfs_b->runtime = cfs_b->quota; cfs_b->runtime_expires = now + ktime_to_ns(cfs_b->period); cfs_b->expires_seq ++; }
  9. Completely Fair Schedulerの実装 • タイマtick割り込み(schedule_tick() or hrtick()) ◦ task_tick_fair() ▪

    update_curr() • 実行した時間(delta_exec)の算出 • vruntimeの加算 • cgroup_account_cputime() // 統計情報(cpuacct)の更新 • account_cfs_rq_runtime() // CFS BW 関連の処理 ◦ __account_cfs_rq_runtime() if(bandwidth が有効) ▪ 残存するランタイム (runtime_remaining) から実行時間を減算 ▪ expire_cfs_rq_runtime() // if(! 残存するランタイムが有 効){runtime_remaining = 0;} ▪ assign_cfs_rq_runtime() if(残存するランタイムが 0) • start_cfs_bandwidth() // period 用のタイマーを起動 • ランタイムプールから残存するランタイムに補充 • 補充した分をランタイムプールから減算 ▪ 残存するランタイムが 0の場合、再度スケジューリング ▪ ... 参考: kernel/sched/core.c
  10. 独自パッチ URL: https://github.com/k-onishi/linux-4.20.16/compare/c017e5c...b14af01 # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_period_us=1000000 test

    $ cgset -r cpu.cfs_quota_us=500000 test # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_bandwidth_percent=50 test
  11. 独自パッチ URL: https://github.com/k-onishi/linux-4.20.16/compare/c017e5c...b14af01 #ifdef CONFIG_CFS_BANDWIDTH { .name = "cfs_quota_us" ,

    .read_s64 = cpu_cfs_quota_read_s64, .write_s64 = cpu_cfs_quota_write_s64, }, { .name = "cfs_period_us" , .read_u64 = cpu_cfs_period_read_u64, .write_u64 = cpu_cfs_period_write_u64, }, { /* New !! */ .name = "cfs_bandwidth_percent" , .read_s64 = cpu_cfs_bandwidth_read_u64, .write_u64 = cpu_cfs_bandwidth_write_u64, }