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

Linuxコンテナの仕組み / eBPF & Container Study in Fukuoka

tenforward
February 17, 2024

Linuxコンテナの仕組み / eBPF & Container Study in Fukuoka

「eBPF & コンテナ情報交換会 @ 福岡」の発表資料です。
参考となる情報にはPDF中からリンクをしていますが、資料中のリンクは Speaker Deck 上ではクリックできないので PDF をダウンロードしてご覧ください。
デモの動画は https://asciinema.org/a/BbYcyk5vaFXk5RbOXWStDvj2Y です。

tenforward

February 17, 2024
Tweet

More Decks by tenforward

Other Decks in Technology

Transcript

  1. 自己紹介   加藤泰文(かとうやすふみ) TenForward • X: @ten_forward • Bluesky: tenforward.bsky.social

    • https://github.com/tenforward/ • コンテナ趣味人 • 仕事はセキュリティやってます 2/35
  2. 自己紹介 趣味の一環で技術評論社のサイト gihyo.jp で コンテナの連載をやっています。   LXC で学ぶコンテナ入門 -軽量仮想化環境を 実現する技術

    その他、linuxcontainers.org プロジェクト のプロダクトやページ、マニュアル等の翻訳 をしています 3/35
  3. 自己紹介 趣味でコンテナやってます。コンテナの主にカーネル周辺の実装に興味があります。 2007 年 コンテナを使ったサービス開発(Virtuozzo) 2009 年 OpenVZ/LXC を触りだす 2013

    年 第 1 回コンテナ型仮想化の情報交換会開催 LXC 日本語 man pages 翻訳&マージ (現在は Incus 関連の翻訳、linuxcontainers.org 翻訳もやってます) 2014 年 gihyo.jp で 「LXC で学ぶコンテナ入門 -軽量仮想化環境を実現する技術」 連載開始(現在も連載中) 2023 年 技術書典出展開始 “Linux Container Book” シリーズ販売 現在 CloudNative の波に乗り遅れる 6/35
  4. ケーパビリティ Linuxにおいて、rootは全能   でも、root が持つ権限全部必要? ↓ root が持つすべての権限を細分化= ケーパビリティ   

    • ケーパビリティ • root の持つ権限の一部だけ与えたり、一部だけ剥奪したりできる • root でも、持っていないケーパビリティが必要な処理は実行できない • (例)docker run -ti --cap-drop="cap_chown" ubuntu bash root の持つ権限のうち、必要最低限の権限だけを与えられる 14/35
  5. レイヤー構造のファイルシステム • イマドキのコンテナのファイルシステムはレイヤー構造が前提(Docker、OCI Image Format Specification) • 差分管理 • (でも、実際はレイヤー構造でなくてもコンテナのファイルシステムにはなる)

    • レイヤー構造が取れるファイルシステムが使われる • OverlayFS(重ね合わせができるファイルシステム=ユニオンファイルシステム) • btrfs(コピーオンライトファイルシステム) 16/35
  6. 色々な 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
  7. 色々な 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
  8. コンテナの起動 普段は皆さんはコンテナを起動するとき、   # docker run -ti ubuntu #

    incus launch images:alpine/3.19   みたいにするか、   そもそもマニフェストを作って kubernetes にお任せ! って感じでしょう、きっと(当たり前 w) 。 そんな感じでシュッっとコンテナが起動してきますが、その際にどういう処理が行われてい るか? の一部分をシェル上でコマンドを使って紹介してみましょう。 24/35
  9. デモで作るコンテナ • OverlayFS で重ね合わせのファイルシステムを作成し、コンテナのルートファイルシス テムにする • Mount, UTS, PID, Network

    Namespace を作成し、ホストとは別のマウント、ホスト 名、ネットワーク、プロセスの空間を作成する • veth インターフェースを作成し、ホストとコンテナの間で通信する • CPU 制限をかけ、CPU を使い尽くさないようにする 25/35
  10. コンテナファイルシステムの作成 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
  11. 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
  12. 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
  13. コンテナのホスト名の変更 UTS Namespace を使ってホスト名を変更する   # hostname container 

     • チェックすべきポイント • コンテナ内だけホスト名が変わっていること(コンテナホスト上のホスト名は変わってい ない) 30/35
  14. コンテナ用の 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
  15. まとめ Linux では、コンテナはさまざまな機能を組み合わせて作られます • OS リソースを隔離するために Namespace • 特定のコンテナがリソースを使い尽くさないように cgroup

    • セキュアにコンテナを動作させるために、Seccomp やケーパビリティを使い、コンテナ に最低限の権限のみを与える • コンテナイメージの管理を効率的に行うためにレイヤー構造が取れる OverlayFS などの ファイルシステム 33/35