Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

OCIランタイムの筆頭「runc」を俯瞰する

3,544 views

Published on

Container Runtime Meetup #1の発表資料です。
コンテナを使うひとならほぼ全員が使っている(であろう)コンテナランタイムの筆頭「runc」を俯瞰します。

- 前半では、コンテナの標準化団体OCIの定めるコンテナランタイムの標準仕様OCI Runtime Specificationとruncの概要、及びその関係について述べています。
- 後半では、runcがコンテナをシステム上に作り出す流れをコードレベルで俯瞰しています。runcの持つサブコマンドの中でも、特にコンテナ作成処理が網羅されているrunサブコマンドに注目し、その実装に迫ります。

Published in: Software
  • Be the first to comment

OCIランタイムの筆頭「runc」を俯瞰する

  1. 1. Copyright(c)2019 NTT Corp. All Rights Reserved. OCIランタイムの筆頭「runc」を俯瞰する 2019/9/24 日本電信電話株式会社 ソフトウェアイノベーションセンタ 徳永 航平 Container Runtime Meetup #1
  2. 2. Copyright(c)2019 NTT Corp. All Rights Reserved. 名前 徳永 航平 所属 NTT ソフトウェアイノベーションセンタ 興味 コンテナランタイム、イメージ @TokunagaKohei
  3. 3. Copyright(c)2019 NTT Corp. All Rights Reserved. Pod Containers 3 Container Runtime Meetup #1 kubelet  いろいろなランタイムやその標準仕 様(CRI、OCI)に関する情報交換  トラブルシューティングに役立ちそ う な カ ー ネ ル 周 辺 知 識 の 共 有  ランタイムへのコードレベルの理解 この周辺について 語り合うMeetupです。 ・・・  第一 回 は輪 読 的に 発 表者 を 回し てい き ま す  発 表 の ス タ イ ル に つ い て は 、 自 由 で す  形式については今後も柔軟に改善していきます
  4. 4. Copyright(c)2019 NTT Corp. All Rights Reserved. 4 いろいろなコンテナランタイム  kubeletからCRI(Dockerの場合はdockershim) 経由でPod作成等の指示を受ける。  ネットワーク設定、イメージの送受信等担当  コンテナ作成にOCIランタイム使用(使い分け可)。  高レベルランタイム/Dockerの指示でコンテナ作成。  標準仕様としてOCI Runtime Specがある。  セキュリティ等の目的で、様々なランタイムが実行環 境の隔離手法を提案しており群雄割拠。 Pod 低レベルランタイム (OCIランタイム) 実行 kubelet 高レベルランタイム (CRIランタイム) 高レベル(CRI)ランタイム 低レベル(OCI)ランタイム runc Kata Containers gVisor Nabla Containers Containers CRI/ dockershim unix socket … … 拙過去資料P4より(一部改訂):https://www.slideshare.net/KoheiTokunaga/ss-123664087
  5. 5. Copyright(c)2019 NTT Corp. All Rights Reserved. OCIランタイムの基礎知識1. 2. runc runコードを俯瞰する 3. まとめ
  6. 6. Copyright(c)2019 NTT Corp. All Rights Reserved. 6 Open Container Initiative. “The 5 principles of Standard Containers”, https://github.com/opencontainers/runtime- spec/blob/master/principles.md The 5 principles of Standard Containers ②Content-agnostic①Standard Operations 作成、削除等標準の操作 が定義されており、標準 の ツ ー ル を 使 用 可 能 。 中 身 に か か わ ら ず Standard Operationは同 様 の 効 果 を 持 つ 。 ③Infrastructure- agnostic ④Designed for automation ⑤Industrial-grade delivery OCIでサポートされるど のインフラストラクチャ 上 で も 動 作 す る 。 中身やインフラに関わら ずStandard Operationを 持つので自動化しやすい。 これら性質を最大限活用 することでデリバリパイ プラインを自動化できる。 ? by Open Container Initiative
  7. 7. Copyright(c)2019 NTT Corp. All Rights Reserved. 7 OCI Runtime Specification FileSystem Bundleの定義 プロセスkill コンテナのライフサイクルや可能な操作等を定義した標準仕様 create kill delete Operationsの定義 コンテナ削除 start コンテナ実行 隔離環境作成 ライフサイクル の定義  コンテナのrootfsディレクトリ  実行時環境の定義ファイル(spec) state、create、 start、kill、delete Open Container Initiative. “Open Container Initiative Runtime Specification”, https://github.com/opencontainers/runtime-spec/blob/master/spec.md 実行時環境のconfig 環境変数、実行コ マンド、ユーザ… 隔離方法は定義されない namespace・cgroup等での隔離 が一般的だがVMやUserspace kernelやunikernelでも良い。実際 にいくつかランタイム実装がある。
  8. 8. Copyright(c)2019 NTT Corp. All Rights Reserved. 8 OCIランタイムの筆頭「runc」  OCIによるOCIランタイムのリファレンス的実装。  統計は無いがたぶんコンテナを使う人ほぼ全員が使っていると思う。  Linuxのリソース分離やセキュリティ機能を活用してプロセスの実行環境隔離を実現。  前身は、Dockerの一部だったlibcontainerで、DockerがOCP(現OCI)発足の際に譲渡。 namespaces PID、UTS、IPC、マウ ントポイント、ネット ワ ー ク 、 ユ ー ザ 、 cgroupsについてシス テムのリソースを隔離 各コンテナごとに見える ファイルシステムを制限 pivot_root Linuxの セキュリティ機能 memory,cpu,cpuset, pids…などのハード ウェアリソースを各コ ンテナに対し制限可能 AppArmor,SELinux,s eccompを用いてコン テナの動作を制限可能 runc process runc Host kernel 直近約1年のコミット数推移 cgroups [Open Container Initiative. “Open Container Initiative Runtime Specification”. https://github.com/opencontainers/runtime-spec/blob/master/spec.md; runc Contributors. “Container Specification - v1”. https://github.com/opencontainers/runc/blob/master/libcontainer/SPEC.md] [https://github.com/opencontainers/runc] [https://github.com/opencontainers/runc/graphs/commit-activity] 2019.9.17取得 拙過去資料P15より(一部改訂):https://www.slideshare.net/KoheiTokunaga/ss-123664087
  9. 9. Copyright(c)2019 NTT Corp. All Rights Reserved. 9 runcのrunサブコマンドに注目 OCI Runtime Specで定義された operation等がサブコマンドとして実装されている create startstate kill delete ・・・ $ mkdir -p bundle/rootfs $ tar xf rootfs.tar -C bundle/rootfs $ runc spec -b bundle # runc run --bundle bundle demo1 # runc kill demo1 KILL (# runc delete demo1) FileSystem Bundle作成 コンテナの作成実行 コンテナの停止削除 サブコマンドrun  operationのうち、createとstart を同時に行えるコマンド。  spec fileとrootfsが配置された Filesystem bundleを渡して実行。  端末まわりなどの難しいところを 考えずに手元でインタラクティブ にruncを操作するのに便利。  実装としてはcreateとstartの組 み合わせなので、コンテナ作成の 流れを俯瞰するruncコード読みの 題材にちょうど良い。
  10. 10. Copyright(c)2019 NTT Corp. All Rights Reserved. OCIランタイムの基礎知識1. 2. runc runコードを俯瞰する 3. まとめ
  11. 11. Copyright(c)2019 NTT Corp. All Rights Reserved. 11 紹介するファイル func main() { ・・・ app := cli.NewApp() ・・・ app.Commands = []cli.Command{ checkpointCommand, createCommand, deleteCommand, eventsCommand, execCommand, ・・・ if err := app.Run(os.Args)・・・ サ ブ コ マ ン ド 実 装 ユ ー テ ィ リ テ ィ 等 var runCommand = cli.Command{ Name: "run", ・・・ Action: func(context・・・ 本稿ではrunc 1.0.0-rc-8を参照 main.go init.go run.go utils_linux.go libcontainer container_linux.go process_linux.go factory_linux.go init_linux.go init_linux.go nsenter nsenter.go standard_init_linux.go / 核 と な る コ ン テ ナ 操 作 用 ラ イ ブ ラ リ ↑namespace分離処理 main.go サブコマンド群の登録 run.go runサブコマンドの実装 以降runCommandから追ったrunサブコ マンド実装の要点をピックアップする
  12. 12. Copyright(c)2019 NTT Corp. All Rights Reserved. 12 runc runの流れ runc init実行 runc run runc init Entrypoint command exec libcontainer 隔離環境 1 隔離環境初期化2 Entrypoint 実行指示・実行 3
  13. 13. Copyright(c)2019 NTT Corp. All Rights Reserved. runc run側 *runnerrunCommand *linuxContainer*initProcess *Cmd 13 1. libcontainerでrunc init実行 Action() run() container Run() Start() start() type: libcontainer.Container start() cmd type: *exec.Cmd Start() Path =“/proc/self/exe” =[]string{os.Args[0], "init"}Args func (p *initProcess) start() error { ・・・ err := p.cmd.Start() specのロード linuxContainer作成 linuxContainer実行 runc initを実行する ためのexec.Cmdと 通信用FIFOを作成 runc initコマンドの実行 run.go utils_linux.go libcontainer/container_linux.golibcontainer/process_linux.go os/exec runcを指している *initProcess .start() *runner.container.Run() *runner.run() *Cmd.Start() メソッド(一部) フィールド (一部) 構造体名
  14. 14. Copyright(c)2019 NTT Corp. All Rights Reserved. LinuxFactoryinitCommand *linuxStandardInit 14 2. runc initで隔離環境の初期化 Action() StartInitialization() Init() config 既にnamespaceの中 rootfsの準備・NW設定など実行環境を初期化した後、Entrypoint実行の指示を待つ type: libcontainer.initConfig func (l *linuxStandardInit) Init() error {・・・ if err := prepareRootfs(l.pipe, l.config); ・・・ fd, err := unix.Open(fmt.Sprintf(“/proc/self/fd/%d”, l.fifoFd)・・・ 反対側のFIFOのopenを待つ _ "github.com/opencontainers/runc/libcontainer/nsenter" init.go go runtimeに先んじてcgoで書いたnamespace分離処理を実行 libcontainer/nsenter/nsenter.go #cgo CFLAGS: -Wall extern void nsexec(); ・・・init(void) { nsexec();・・・ init.go libcontainer/factory_linux.go libcontainer/standard_init_linux.go LinuxFactory .StartInitia lization() *linuxStandardInit.Init() runc init側 fifoFd type: int
  15. 15. Copyright(c)2019 NTT Corp. All Rights Reserved. Init() libcontainer/standard_init_linux.go *linuxContainer 15 3. runc runからrunc initにentrypoint実行指示 exec() *linuxStandardInit func (l *linuxStandardInit) Init() error {・・・ fd, err := unix.Open(fmt.Sprintf(“/proc/self/fd/%d”, l.fifoFd)・・・ ・・・ if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { Entrypointをexecする ①でrunc initを実行した直後に自身のexec()メソッドを実行する func awaitFifoOpen(path string) <-chan openResult { fifoOpened := make(chan openResult) go func() { f, err := os.OpenFile(path, os.O_RDONLY, 0)・・・ FIFOをopenする runc init側 libcontainer/container_linux.go runc run側 Entrypoint実行の指示(FIFOのopen)を待っていた config type: libcontainer.initConfig fifoFd type: int initConfig Args Env Cwd Capabilities ・・・ libcontainer/init_linux.go
  16. 16. Copyright(c)2019 NTT Corp. All Rights Reserved. OCIランタイムの基礎知識1. 2. runc runコードを俯瞰する 3. まとめ
  17. 17. Copyright(c)2019 NTT Corp. All Rights Reserved. 17 まとめ プロセスkill create kill delete コンテナ削除 start コンテナ実行 隔離環境作成 ライフサイクル の定義 OCI Runtime Spec. runc run runc init Entrypoint command exec libcontainer 隔離環境 今回の 注目サブコマンド 1 2 3 runc run

×