Slide 1

Slide 1 text

Linux コンテナの歴史を追うとコンテナの仕組みがわかる 大吉祥寺.pm 加藤泰文 2024-07-13 1/28

Slide 2

Slide 2 text

自己紹介(1)   加藤泰文(かとうやすふみ) • X: @ten_forward • Bluesky: tenforward.bsky.social • https://github.com/tenforward/ • これがなかったら、ここまで続けてなかった (Findy Engineer Lab モチベの泉) • 仕事はセキュリティやってます 2/28

Slide 3

Slide 3 text

自己紹介(2)〜 趣味 今日は趣味のお話をします。 • 推し活(K-POP 方面) • コンテナ ← 今日はコレ!! • 古墳 • WRC • 韓国ドラマ • Plamo Linux(メンテナ) • プログレ • ジャズ 3/28

Slide 4

Slide 4 text

自己紹介(3)〜 趣味 今日は時間が短いので概要だけお伝えします。もう少し深く知りたい! と思ったら、ぜひこ ちらをご覧ください。 趣味の一環で技術評論社のサイト gihyo.jp で コンテナの連載をやっています(2014 年〜) 「LXC で学ぶコンテナ入門 -軽量仮想化環境を 実現する技術」 その他、linuxcontainers.org プロジェクト のプロダクトやページ、マニュアル等の翻訳 をしています 4/28

Slide 5

Slide 5 text

自己紹介(4)〜 趣味   連載をもとに大幅に加筆した同人本を書き、技術書典に出展。販売中。 • サークル名:lxc-jp 5/28

Slide 6

Slide 6 text

自己紹介(5)〜 勉強会 コンテナ型仮想化の情報交換会(コンテ ナ技術の情報交換会)主宰 • 2014 年(!!)6 月 第 1 回(Docker リリース 3 ヶ月後) • 15 回開催(最後は 2021 年秋) 6/28

Slide 7

Slide 7 text

本日の内容 • 1970 年代から現在までのコンテナの歴史を、機能を説明しながらたどります • 時間があればデモ 7/28

Slide 8

Slide 8 text

コンテナとは

Slide 9

Slide 9 text

コンテナ コンテナとは? • プロセス • 他のプロセスから隔離された仮想的な空間で動くプ ロセス • カーネルのセキュリティ機能により完全武装したプ ロセス • さまざまなカーネル内の機能を組み合わせて起動 する • Linux には「コンテナ」という単一の機能はありま せん 8/28

Slide 10

Slide 10 text

Linux におけるコンテナ Linux でのコンテナ主要 2 大機能 • Namespace 隔離空間を作る(リソースごとに存在) • cgroup プロセスのグループ(コンテナ)に対して CPU、memory などのリソース制限をかける これだけではなく、他にカーネル内のさまざまな機能を使ってコンテナを作ります。 (必要な 機能だけを使ったコンテナが作れる) 9/28

Slide 11

Slide 11 text

昔のコンテナ

Slide 12

Slide 12 text

太古の昔 軽量な「仮想環境」としてのコンテナは古くから存在している • chroot: プロセスに対して任意のディレクトリをルートとして指定する • 1979 年 UNIX Version 7 で、1982 年 BSD へ導入 • 今では、代表的なコンテナエンジンでは chroot は使いません • 2000 年代初期に FreeBSD jail, Virtuozzo/OpenVZ(Linux 向け商用コンテナソフトと その OSS 版) 、Linux VServer • ホスティング業者などで軽量な「仮想マシン」として利用(リソース消費が少なく集積度を上 げられるという視点) • システムとしてコンテナを動かすいわゆる「システムコンテナ」 10/28

Slide 13

Slide 13 text

Linux Kernel へのコンテナ関連技 術の実装と LXC

Slide 14

Slide 14 text

ファイルシステム系の機能の実装期 かなり古くからコンテナ関連の機能の実装は始まります。まずはファイルシステム方面の機 能から。 • pivot_root(2.3.41/2000 年)→コンテナ専用の独立したファイルシステム • bind mount(2.4.0/2001 年)→任意のディレクトリをルートに pivot_root するのに 必要 • mount namespace(2.4.19/2002 年)→コンテナ間でマウント操作を分離できる この3つの機能でマウント操作を独立させたコンテナ専用のファイルシステムが作れます。 11/28

Slide 15

Slide 15 text

pivot_root を使った独立したファイルシステムツリー • chroot は抜け出せる • pivot_root は root ファイルシステム自体を取り替える(抜けるという概念がない) • chroot に比べて pivot_root できる条件は厳しい→マウントポイントである必要がある pivot_root 前 pivot_root 後 • 「新しい root ファイルシステム」からは抜け出せない • Docker や LXC/Incus などは pivot_root を使用している 12/28

Slide 16

Slide 16 text

Linux コンテナ完成期第一期 2006〜2008 年にかけてかなりの機能が追加され、Namespace は主要なものが揃った: • コンテナごとに: • 独自のホスト名が付けられるようになった→ UTS Namespace(2.6.19/2006 年) • プロセス間通信を隔離できるようになった→ IPC Namespace(2.6.19/2006 年) • 独立した PID が付けられるようになった→ PID Namespace(2.6.24/2008 年) • 独立したネットワーク I/F、アドレス、ポート、ルーティング、フィルタリングが持てるよう になった→ Network Namespace(2.6.24/2008 年) • コンテナ用の仮想インターフェースが持てるようになった→ veth(2.6.24/2008 年) 、 macvlan(2.6.23/2007 年) • CPU のリソース制限がかけられるようになった→ cgroup cpu, cpuacct, cpuset コント ローラー(2.6.24/2008 年) • LXC の誕生(2008 年) • カーネルに機能が充実してきたもののそれを開発者が試す環境がないので誕生 • 0.8 くらいまでは C、シェル、Python プログラムの寄せ集め(イマイチ使いづらい) 13/28

Slide 17

Slide 17 text

PID Namespace による独立したプロセス空間 • コンテナ内でどんなプロセスを実行しているか、他のコンテナから見えたらイヤ • コンテナごとに独立して PID を持ちたい • ただし、ホスト (親 Namespace) からコンテナ (子の Namespace) のプロセスは見え ます 14/28

Slide 18

Slide 18 text

veth インターフェース • Virtuozzo/OpenVZ 由来 • 作成すると対となるインターフェースが生成さ れる。その対となるインターフェース間で通信 を行う= L2 のトンネル • 対の片方をホスト、片方をコンテナの Namespace に所属させる(異なる Namespace 間でないと通信不可) 15/28

Slide 19

Slide 19 text

コンテナの転換期

Slide 20

Slide 20 text

コンテナ機能の充実 2009〜2013 年ごろ • コンテナごとに: • メモリー制限がかけられるようになった → cgroup memory コントローラー(2.6.29/2009 年) • I/O 制限がかけられるようになった → cgroup blkio コントローラー(2.6.33/2010 年) • 任意のシステムコールのフィルタリングができるようになった(3.5/2012 年、 seccomp、後述) • コンテナ外からコンテナ内に入ってコマンド実行できるようになった→ setns システム コール(3.0/2011 年) • ただし、すべての Namespace に対して setns できるようになったのは 3.8 カーネル (2013 年) コンテナでシステムやアプリケーションを動かす主要な機能が一通りそろった 16/28

Slide 21

Slide 21 text

Docker の登場 • Docker の登場(初期 Docker は裏側で LXC を使用) (2013 年) • ユニオンファイルシステム使用でコンテナイメージを効率的に管理 • ネットワーク経由のコンテナ管理 • Docker 登場後は「コンテナ」≒ 「アプリケーションコンテナ」 一躍「コンテナ」が話題の技術に!! コンテナ時代の到来 17/28

Slide 22

Slide 22 text

コンテナ機能の充実期

Slide 23

Slide 23 text

コンテナ機能の充実期 2014 年以降、Docker の登場による「コンテナ」の盛り上がりで、カーネルにコンテナ関連 機能が入りやすい環境になった。 コンテナに直接関係しない機能でも、コンテナへ導入することで、コンテナ環境を改良でき る機能が多数導入された。 18/28

Slide 24

Slide 24 text

OverlayFS 3.18/2014 年。今やコンテナになくては ならないファイルシステム。 • コンテナイメージの標準(OCI Image Format Specification)で定 められたレイヤー構造を実現するた めに必要なファイルシステム • 複数のディレクトリーの内容を重ね 合わせて 1 つのファイルシステムに 見せるユニオンファイルシステム • (ただし、レイヤー構造はコンテナ に必ず必要な要件ではない) 19/28

Slide 25

Slide 25 text

cgroup v2 • cgroup v1 • コンテナがメジャーでない時期に導入が進んだので、控えめに遠慮がちに機能が実装される • →コンテナ利用の拡大とともに問題点が明らかに • 詳しくは LXC で学ぶコンテナ入門 第 37 回をご覧ください • cgroup v2(4.5/2016 年) • v1 とのインターフェースの互換性をある程度保って、cgroup をあるべき姿に実装しなおした • インターフェースが全く変わっている機能もある(eBPF を使って制限をかけるコントロー ラーとか) • 現実的なリソース制限がかかるようになった • PSI(4.20/2018 年) • CPU, Memory, IO の負荷が増大しリソースが不足している状況を観測可能 20/28

Slide 26

Slide 26 text

セキュリティ機能 ホスト上でカーネルを共有して起動するプロセスであるコンテナを安全に使うには様々なセキュリティ 機能の助けが必要 • seccomp • システムコールがフィルタリングできる機能 • 任意のシステムコールのフィルタリングができるようになった(3.5/2012 年、seccomp、 後述) • seccomp notify(5.0/2019 年)→システムコールの実行可否をユーザー空間のプログラム 側で判断できる • capability(2.2/1999 年) • root が持つ特権を細分化して必要に応じてプロセスに権限を付与できる • コンテナごとに権限を細かく与えたり剥奪したりできる • User Namespace(3.8/2013 年) • コンテナ内外の UID/GID をマッピングする。コンテナ内では root、ホスト上では一般ユー ザーということが可能→コンテナ内で root 権限が必要であっても安全にコンテナを実行可能 • rootless コンテナ • LSM(SELinux, AppArmor,...) 21/28

Slide 27

Slide 27 text

その後の新機能、改良 コンテナとは直接関係なさそうな機能もコンテナにとっては重要かも(コンテナ関係の開発 者が手がけていたりする) • cgroup の pids コントローラー(4.3/2015 年) • コンテナ内のプロセス数の制限 • pidfd(5.3/2019 年) • PID の循環問題の解決(目的と違うプロセスにシグナル送ってしまう危険性) • Time Namespace(5.6/2020 年) • 独立した uptime(CLOCK_MONOTONIC/CLOCK_BOOTTIME) • clone3 システムコールを使ったコンテナプロセス生成のコスト低減(5.7/2020 年) • 親プロセスと異なる cgroup にプロセスを生成できる • ID mapped Mount(5.12/2021 年) • コンテナイメージをマウントする際、コンテナイメージ内のファイルの所有権を変更 22/28

Slide 28

Slide 28 text

eBPF 今一番ホットな機能(?)である eBPF。コンテナでの活用も進みます。 • eBPF プログラムを cgroup にアタッチできるようになった(4.10/2017 年) • cgroup 内のタスクに対してのみ eBPF プログラムを実行できるようになった • フィルタリング、アカウンティング、ルーティングなど • cgroup v2 でのデバイスコントローラー(コンテナからデバイスへのアクセス制御) (4.15/2018 年) 23/28

Slide 29

Slide 29 text

デモ

Slide 30

Slide 30 text

Mount Namespace と PID Namespace Mount Namespace と PID Namespace を作り、マウントとプロセスだけ独立したコンテ ナを作る。 1. Mount Namespace と PID Namespace を作成する 2. コンテナイメージの/をコンテナの/にバインドマウントする 3. コンテナの/で proc ファイルシステムをマウントする 4. pivot_root を実行する 5. 元の/をアンマウント(マウント解除)する(←コンテナのファイルシステムの完成) 6. Mount Namespace と PID Namespace を確認する https://asciinema.org/a/asTutVrEw7ZZpTMHkF8X9hcQP 24/28

Slide 31

Slide 31 text

Network Namespace と veth インターフェース Network Namespace と veth インターフェースを作り、片方のインターフェースを Namespace に所属させ、通信する。 1. Network Namespace を作成する 2. veth インターフェース(ペア)を作成する 3. ペアの片方を作成した Network Namespace に所属させる 4. ペアそれぞれにアドレスを割り当て、インターフェースを UP する 5. ペア間で ping が飛ぶのを確認する https://asciinema.org/a/9xpUmUqh55Dl8BgwfQRYtr9M1 25/28

Slide 32

Slide 32 text

まとめ

Slide 33

Slide 33 text

まとめ • コンテナは多くの機能を組み合わせて作られている(今回紹介したのは一部です) • 必要な機能だけを使ってコンテナを作れる • たまにはそんなコンテナが起動してくる時に使う機能に思いを馳せると良いシステムを 作る役に立つかもしれませんよ(全く役に立たないかもしれませんよ) コンテナに関係する Linux カーネルの新機能を追いかけるのは楽しいけど、最近はとても追 いかけるのが難しいので、みなさんもぜひカーネルの新機能を一緒に追いかけましょう(ま とめになってませんが…) 26/28

Slide 34

Slide 34 text

コンテナは 仮想じゃないよ 隔離だよ   ご清聴ありがとうございました 27/28

Slide 35

Slide 35 text

参考 • 連載 LXC で学ぶコンテナ入門(gihyo.jp) • seccomp だけをテーマにした勉強会(第 14 回コンテナ技術の情報交換会@オンライ ン) (動画視聴可) • Introduction to Seccomp (@mrtc0 さん)←基礎から深層まで短時間で学べる非常にすご い資料(動画も見れます) 28/28