Slide 1

Slide 1 text

Linux コンテナ eBPF & コンテナ情報交換会 @ 福岡 加藤泰文 2024-02-17 1/35

Slide 2

Slide 2 text

自己紹介   加藤泰文(かとうやすふみ) TenForward • X: @ten_forward • Bluesky: tenforward.bsky.social • https://github.com/tenforward/ • コンテナ趣味人 • 仕事はセキュリティやってます 2/35

Slide 3

Slide 3 text

自己紹介 趣味の一環で技術評論社のサイト gihyo.jp で コンテナの連載をやっています。   LXC で学ぶコンテナ入門 -軽量仮想化環境を 実現する技術 その他、linuxcontainers.org プロジェクト のプロダクトやページ、マニュアル等の翻訳 をしています 3/35

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

自己紹介 もっと DeepDive したい方に向けて、サーク ル「Linux カーネルもくもく会」から 「cgroup の歩き方」を販売中 cgroup v1 のカーネルコードリーディングを している本です 5/35

Slide 6

Slide 6 text

自己紹介 趣味でコンテナやってます。コンテナの主にカーネル周辺の実装に興味があります。 2007 年 コンテナを使ったサービス開発(Virtuozzo) 2009 年 OpenVZ/LXC を触りだす 2013 年 第 1 回コンテナ型仮想化の情報交換会開催 LXC 日本語 man pages 翻訳&マージ (現在は Incus 関連の翻訳、linuxcontainers.org 翻訳もやってます) 2014 年 gihyo.jp で 「LXC で学ぶコンテナ入門 -軽量仮想化環境を実現する技術」 連載開始(現在も連載中) 2023 年 技術書典出展開始 “Linux Container Book” シリーズ販売 現在 CloudNative の波に乗り遅れる 6/35

Slide 7

Slide 7 text

本日の内容 Linux のコンテナの話をします。 • コンテナとは • コンテナを起動するときに使う Linux カーネルの機能 • コンテナを起動するときにどんな処理が行われているかをデモ 7/35

Slide 8

Slide 8 text

コンテナとは

Slide 9

Slide 9 text

コンテナとは プロセスです   でも普通のプロセスではない 8/35

Slide 10

Slide 10 text

コンテナとは セキュリティ機能で 完全武装したプロセス ホストのカーネルが持っている多数の様々な機能を使ったプロセス 9/35

Slide 11

Slide 11 text

Linux におけるコンテナ Linux でコンテナを使う場合 Linux にコンテナという機能があるわけでは ない(コンテナ機能をオンにする! というわ けではない) 10/35

Slide 12

Slide 12 text

どんな機能を使うのか

Slide 13

Slide 13 text

Namespace(名前空間) プロセスから見える Linux の各種リソースを隔離する (kubernetes で出てくる Namespace とは別です) 11/35

Slide 14

Slide 14 text

cgroup • プロセスのグループ化 • グループ化したプロセスに対して共通の管理を行う • リソース制限 • アクセス制限… • cgroup v2 では、制限に eBPF プログラムを使うことがある 12/35

Slide 15

Slide 15 text

Seccomp ユーザー空間のアプリケーションがカーネルの機能を使う場合、システムコールを使う • コンテナはカーネルが提供するシステムコールを全部使うとは限らない(使うと危険な システムコールがある) • 使わないシステムコールは Seccomp を使って禁止(フィルタリング)しておく • コンテナランタイムではデフォルトで使えるシステムコールが設定されている(こともある) • BPF を使ってフィルタープログラムを書いてフィルタリング 13/35

Slide 16

Slide 16 text

ケーパビリティ Linuxにおいて、rootは全能   でも、root が持つ権限全部必要? ↓ root が持つすべての権限を細分化= ケーパビリティ    • ケーパビリティ • root の持つ権限の一部だけ与えたり、一部だけ剥奪したりできる • root でも、持っていないケーパビリティが必要な処理は実行できない • (例)docker run -ti --cap-drop="cap_chown" ubuntu bash root の持つ権限のうち、必要最低限の権限だけを与えられる 14/35

Slide 17

Slide 17 text

その他セキュリティ機能 • 任意アクセス制御(普通の Linux のユーザー管理) • リードオンリーマウント • など… 様々な多数の機能の合せ技。 15/35

Slide 18

Slide 18 text

レイヤー構造のファイルシステム • イマドキのコンテナのファイルシステムはレイヤー構造が前提(Docker、OCI Image Format Specification) • 差分管理 • (でも、実際はレイヤー構造でなくてもコンテナのファイルシステムにはなる) • レイヤー構造が取れるファイルシステムが使われる • OverlayFS(重ね合わせができるファイルシステム=ユニオンファイルシステム) • btrfs(コピーオンライトファイルシステム) 16/35

Slide 19

Slide 19 text

仮想ネットワークインターフェース • 物理インターフェースをコンテナに割り当てることもできる→でも、起動するコンテナ 分インターフェースが必要 • 通常は仮想的なネットワークインターフェースを使用 veth インターフェース ペアで作成され、お互い L2 で繋がっている仮想的なインターフェース 17/35

Slide 20

Slide 20 text

なぜコンテナなのか • 「プロセス」なので起動が早い(VM のように仮想的なホストと OS を起動する必要が ない) • レイヤー構造のイメージにより、ベースのイメージとの差分のみを管理すれば良いので、 イメージ構築や取得が速い • 多数のコンテナを管理する kubernetes をはじめとするエコシステムが確立し、成長し ている 18/35

Slide 21

Slide 21 text

デモ... の前に

Slide 22

Slide 22 text

色々な Namespace Linux が起動したあとのさまざまな OS リソースごとに Namespace があります Namespace の名前 隔離されるリソース 実装された カーネルバージョン Mount Namespace マウントの集合、操作 2.4.19 UTS Namespace ホスト名、ドメイン名 2.6.19 PID Namespace プロセス ID(PID) 2.6.24 IPC Namespace SysV IPC オブジェクト、POSIX メッセージキュー 2.6.19 User Namespace UID、GID 3.8 Network Namespace ネットワークデバイス、アドレス、ポート、ルーティングテー ブル、フィルタなど 2.6.26 cgroup Namespace cgroup ツリー 4.6 Time Namespace 起動してからの時間 5.6 19/35

Slide 23

Slide 23 text

色々な cgroup cgroup には v1 と v2 があり、今後は v2 が主流になっていきます。v1 のみに存在するコン トローラーがあります。 コントローラー 機能の概要 実装された バージョン cpu グループに割り当てる CPU 時間や割合を制御 2.6.24 cpuset グループへの CPU、メモリーノードの割当 2.6.24 devices グループ内のタスクのデバイスへのアクセスの許可、禁止の指定 2.6.26 memory グループ内のタスクが消費するメモリーリソースのレポートと制限 2.6.29 blkio(v2 では io) ブロックデバイスに対する制限 2.6.33 pids グループ内で起動できるプロセス数を制限 4.3 misc 汎用コントローラー 5.13 (主なコントローラーのみ) ネットワーク、デバイス系は v2 では eBPF を使って制御します。 20/35

Slide 24

Slide 24 text

pivot_root root ファイルシステム自体を取り替えることで、コンテナのファイルシステムに切り替える pivot_root 前 pivot_root 後 21/35

Slide 25

Slide 25 text

bind mount • ディレクトリツリーの一部を別のディレクトリ以下にマウント • マウントしたディレクトリ以下は元と同じモノが見える • ホストのディレクトリをコンテナと共有する場合にも使用 • pivot_root するにはマウントされたファイルシステムが必要→ bind mount することで 「マウントされたファイルシステム」状態が作れる 22/35

Slide 26

Slide 26 text

ユニオンファイルシステム • システム上のディレクトリーの中身を重ね合わせできるファイルシステム • 重ね合わせをする仕組みのみ実装しており、実際の I/O は他のファイルシステム(ex. ext4, xfs)などが行う • 書き込みは一番上のレイヤーに対して行う • コンテナでは OverlayFS が使われることがほとんど 23/35

Slide 27

Slide 27 text

準備ができたのでデモ

Slide 28

Slide 28 text

コンテナの起動 普段は皆さんはコンテナを起動するとき、 # docker run -ti ubuntu # incus launch images:alpine/3.19 みたいにするか、   そもそもマニフェストを作って kubernetes にお任せ! って感じでしょう、きっと(当たり前 w) 。 そんな感じでシュッっとコンテナが起動してきますが、その際にどういう処理が行われてい るか? の一部分をシェル上でコマンドを使って紹介してみましょう。 24/35

Slide 29

Slide 29 text

デモで作るコンテナ • OverlayFS で重ね合わせのファイルシステムを作成し、コンテナのルートファイルシス テムにする • Mount, UTS, PID, Network Namespace を作成し、ホストとは別のマウント、ホスト 名、ネットワーク、プロセスの空間を作成する • veth インターフェースを作成し、ホストとコンテナの間で通信する • CPU 制限をかけ、CPU を使い尽くさないようにする 25/35

Slide 30

Slide 30 text

コンテナファイルシステムの作成 OverlayFS を使って、レイヤー構造のファイルシステムを作ります。ホスト OS は Ubuntu 22.04 です。   下層のレイヤー(lowerdir) /var/lib/container/bookworm(debootstrap で作った Debian bookworm) 上層のレイヤー(upperdir) /var/lib/container/upperdir OverlayFS がワーク領域に使う /var/lib/container/workdir ディレクトリー(workdir) OverlayFS を使って重ね合わせる /var/lib/container/overlay ファイルシステムをマウントする場所 実際のコンテナのファイルシステム /var/lib/container/mycontainer にする場所 # mount -t overlay \ > -o lowerdir=/var/lib/container/bookworm,upperdir=/var/lib/container/upperdir,workdir=/var/lib/container/workdir \ > overlay /var/lib/container/overlay • チェックすべきポイント • OverlayFS でマウントしたディレクトリー以下に書き込むと upperdir に書き込まれている こと。lowerdir には変化がないこと 26/35

Slide 31

Slide 31 text

コンテナの作成 unshare コマンドで Mount,UTS,PID,Network だけホストから独立しているコンテナを作 ります # unshare --mount --fork --uts --pid --network -- /bin/bash 27/35

Slide 32

Slide 32 text

veth ペアの作成とホストコンテナ間の通信 • unshare で作成した Network Namespace に ip コマンドからアクセスできるように します • veth インターフェースのペアを作成します • veth インターフェースのペアの片方をコンテナに所属させます • インターフェースにアドレスを割り当てます • お互いに ping を実行して通信できることを確認 # ip netns attach netns01 1271 # ip netns コマンドを使えるようにするおまじない # ip link add veth0-host type veth peer name veth0-ns # veth ペアを作成 # ip link set veth0-ns netns netns01 # netns へ片方の veth0-ns 移動 (このあとアドレスを割り当てて ping) 28/35

Slide 33

Slide 33 text

Namespace(コンテナ)の作成とコンテナのファイルシステムの独立 pivot_root でルートファイルシステムを変更し、Mount, UTS, PID, Network が独立したコ ンテナを作ります。説明では “/var/lib/container” というパスは省きます。 1. OverlayFS でマウントされている overlay を、mycontainer に bind mount します 2. mycontainer 以下の/proc にシステム情報などが収められたファイルシステムである proc ファイルシステムをマウントします 3. mycontainer ディレクトリーに pivot_root します(元のルートは/old 以下にマウントされます) 4. 元の(ホストの)ルートディレクトリーを umount # mount --bind /var/lib/container/overlay /var/lib/container/mycontainer ... (1) # mount -t proc -o rw,nosuid,nodev,noexec,relatime proc proc ... (2) # mkdir old && pivot\_root . old ... (3) # umount -l /old ... (4) • チェックするポイント • マウントの状況がホストとは異なること=マウントが独立したコンテナになった 29/35

Slide 34

Slide 34 text

コンテナのホスト名の変更 UTS Namespace を使ってホスト名を変更する # hostname container • チェックすべきポイント • コンテナ内だけホスト名が変わっていること(コンテナホスト上のホスト名は変わってい ない) 30/35

Slide 35

Slide 35 text

コンテナとホストでプロセスの様子を比較 コンテナ内でプロセスの様子を確認してみましょう。そして、コンテナホスト上でもプロセ スの様子を確認してみましょう。 • コンテナ内ではコンテナ内のプロセスのみが見えていること • コンテナホスト上ではコンテナホスト上のプロセスだけでなく、コンテナ内のプロセス もみえていること 31/35

Slide 36

Slide 36 text

コンテナ用の cgroup を作り CPU 制限を設定 コンテナに対して CPU 制限を設定します。コンテナの制限なのでコンテナホスト上から設定 します。 1. コンテナ用の cgroup を作成します 2. コンテナプロセスを作成した cgroup に登録します 3. (コンテナ上で)cgroup Namespace を作成します 4. (コンテナ上で)cgroupfs をマウントします 5. CPU を 50%だけ使えるように cgroup を設定します(100ms ごとに 50ms だけ使えるように設定) host # mkdir /sys/fs/cgroup/mycontainer ... (1) host # echo [コンテナの PID] > /sys/fs/cgroup/mycontainer/cgroup.procs ... (2) container # unshare --cgroup -- /bin/bash ... (3) container # mount -t cgroup2 cgroup2 /sys/fs/cgroup/ ... (4) host # echo "50000 100000" > /sys/fs/cgroup/mycontainer/cpu.max ... (5)   • チェックすべきポイント • CPU を 50%だけ使っていること 32/35

Slide 37

Slide 37 text

まとめ

Slide 38

Slide 38 text

まとめ Linux では、コンテナはさまざまな機能を組み合わせて作られます • OS リソースを隔離するために Namespace • 特定のコンテナがリソースを使い尽くさないように cgroup • セキュアにコンテナを動作させるために、Seccomp やケーパビリティを使い、コンテナ に最低限の権限のみを与える • コンテナイメージの管理を効率的に行うためにレイヤー構造が取れる OverlayFS などの ファイルシステム 33/35

Slide 39

Slide 39 text

まとめ 仕組みを理解しなくてもコンテナは使えます。しかし、このような仕組みを理解することで • どのようなワークロードをコンテナで動かすべきかの判断 • コンテナのセキュリティを考える際の判断 • コンテナを使った安定的なサービス提供 • コンテナ環境で問題が起こったときに何が起こっているのかの理解 などが行いやすくなり、コンテナを使うスキルが一段上がるはずです。 34/35

Slide 40

Slide 40 text

以上 ご清聴ありがとうございました 35/35