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

はてなインターンシップ2024 コンテナ講義資料

Hatena
October 31, 2024
43

はてなインターンシップ2024 コンテナ講義資料

Hatena

October 31, 2024
Tweet

More Decks by Hatena

Transcript

  1. ⾃⼰紹介 • id: SlashNephy • ねふぃー と呼んでくださいね • 職種 •

    Web アプリケーションエンジニア • 所属 • 東京オフィス • テクノロジーソリューション本部ゲームチー ム • 兼組織‧基盤開発本部サービスプラットフォ ームチーム IBUFOBJOUFSO !
  2. コンテナを実現するプロダクト • 2000年: FreeBSD jails • 2008年: Linux Containers (LXC)

    • 2013年: Docker • 2019年: Podman これらのプロダクトも、概ね以降で紹介する技術 (や、相当の機 能) を組み合わせて実現されています。 IBUFOBJOUFSO !"
  3. Namespace • Linux Kernel の持つ機能 • Namespace ごとにリソースを隔離して、Namespace 内のプロセ スに対して独⽴した環境に⾒せる

    • それぞれのプロセスが⼲渉することがなくなる • どのリソースを隔離するかによって様々な Namespace が存在する • PID, Mount, User, Network, IPC, UTS, Time, cgroup IBUFOBJOUFSO !"
  4. Namespace PID • プロセス ID 番号空間の隔離 • 名前空間内で最初のプロセスは PID 8

    ubuntu@utm:~$ ps PID TTY TIME CMD 1889 pts/0 00:00:00 bash 2711 pts/0 00:00:00 ps ubuntu@utm:~$ sudo unshare "#pid "#fork "#mount-proc ps PID TTY TIME CMD 1 pts/0 00:00:00 ps IBUFOBJOUFSO !"
  5. Namespace User • UID/GID を分離する • capability (後述) を分離する •

    異なる Namespace で同じ UID のユーザを作成できる • ホストからは⼀般ユーザ、コンテナ内では root というユーザが作成できる • マッピング IBUFOBJOUFSO !"
  6. Namespace • そのほか • Mount: マウントポイントを分離する • Network: ネットワークデバイス、ルーティングテーブル、IP アドレス、

    ポート番号などを隔離する • Time: ホストとコンテナの時間を分離する • IPC: 共有メモリを分離する • UTS: ホスト名とドメイン名を分離する IBUFOBJOUFSO !"
  7. capability • Linux Kernel では操作の種類に応じた権限として、capability とい う概念があり、プロセスに対して許可する権限を個別に選択できる • 先程の例では CAP_NET_RAW

    と CAP_SYS_BOOT を分離している • ping コマンドには CAP_NET_RAW のみを付与することで、特権処 理の1つである RAW ソケットの利⽤を許可しながら、PC の再起 動は許可しない • capability の⼀覧は man capabilities(7) で確認できる IBUFOBJOUFSO !"
  8. capability • 特権操作を必要とするプロセスに対しても、特権を渡すのではなく capability を 付与する • capability によって許可される操作は Namespace

    で隔離された範囲に閉じな いことがあるので注意する必要がある • コンテナランタイムはコンテナで実⾏するプロセスに対していくつかの capability をデフォルトで付与する • 設定によって追加の capability を付与することもできる • Docker の場合 !"cap-add, !"cap-drop, !"priviledged オプションがある IBUFOBJOUFSO !"
  9. seccomp • システムコールの中には Namespace で分離されていないリソースに⼲渉するもの もあり、コンテナ内のプロセスから呼び出されると仮想化が崩れてしまう • seccomp はプロセスの発⾏できるシステムコールを制限する仕組みで、コンテナラ ンタイムは

    seccomp を利⽤してコンテナ内のプロセスがこれらのシステムコールを 呼び出すことを防ぐ • Docker でデフォルトで制限されているシステムコールは公式ドキュメントに⼀覧さ れている • 設定でプロファイルを渡すことによって呼び出しを制限するシステムコールを制御 できる IBUFOBJOUFSO !"
  10. seccomp Docker で kill というシステムコールを制限してみる。 seccomp.json { "defaultAction": "SCMP_ACT_ALLOW", "syscalls":

    [ { "name": "kill", "action": "SCMP_ACT_ERRNO" } ] } slashnephy@Macbook $ docker run !"name ubuntu_bash \ !"rm -it !"security-opt seccomp=seccomp.json ubuntu bash root@f9d4b6ac2a8a:/# sleep 100 & [1] 10 root@f9d4b6ac2a8a:/# kill 10 bash: kill: (10) - Operation not permitted IBUFOBJOUFSO !"
  11. その他の機能 これまで紹介してきた機能以外にもコンテナの可搬性‧安全性に寄与する技術が提案‧利⽤されていま す。 • AppArmor / SELinux • ポリシーに基づいてさらに強固にプロセスの挙動を制約する •

    gVisor • ユーザ空間カーネルを実装し、システムコール呼び出しをホストマシンに伝搬させないことで隔離 性能を⾼める • Kata Containers • コンテナを qemu, Firecracker などで⽣成した仮想マシン内で実⾏する IBUFOBJOUFSO !!
  12. Union ファイルシステム • ベースとなる下位ディレクトリ (Lower Dir) に対し、差分を上位ディレクト リ (Upper Dir)

    として重ね合わせる • コンテナイメージに含まれるファイルシステムは Lower Dir、コンテナ上で 変更されるファイルシステムを Upper Dir とする • Lower Dir は変更されないので1つのコンテナイメージを複数のコンテナ インスタンスで共有できる • 変更を個々のコンテナインスタンス毎の Copy on Write レイヤー (Upper Dir) に適⽤する IBUFOBJOUFSO !"
  13. Dockerfile # syntax=docker/dockerfile:1 FROM golang:1.23-bookworm AS builder WORKDIR /services/blog COPY

    go.mod go.sum ./ RUN go mod download COPY . . RUN !"mount=type=cache,target=/root/.cache/go-build \ make build FROM debian:bookworm COPY !"from=builder \ /services/blog/bin/server \ /services/blog/bin/server RUN adduser -D -u 1000 app USER 1000 ENTRYPOINT ["/services/blog/bin/server"] • 単純なテキストベースのスクリプ トファイル • コンテナイメージを⽣成するため の命令が記述されている • イメージビルダによって Dockerfile がコンテナイメージへ と変換される IBUFOBJOUFSO !"
  14. コンテナイメージの構造を覗く 以下の Dockerfile をビルドしてイメージを作成する FROM ubuntu RUN echo "hoge" >

    hoge.txt RUN rm hoge.txt 作成したイメージを出⼒して解凍する docker save $CID > image.tar tar xf image.tar IBUFOBJOUFSO !"
  15. イメージレイヤー Dockerfile の命令毎にレイヤーが分かれている。 . ├── 3fe352f27d6d9b899da69b9799728c4492690186797a106cbfa029264b6ebcf7 │ ├── VERSION │

    ├── json │ └── layer.tar ├── aa8c0471e58774435617a2efb80b963d0288bdbdfdd7ded778776c3051664569.json ├── af197d5ca08b03ffdfd8c1285260360fbbc237328d421b73c2abc3f07bb054d9 │ ├── VERSION │ ├── json │ └── layer.tar ├── b3ea71bd7712c8534c4e3440a02a2217d0049fc8acacac191cf875bc21ab9f6a │ ├── VERSION │ ├── json │ └── layer.tar └── manifest.json IBUFOBJOUFSO !"
  16. layer.tar whiteout • ファイルの削除は whiteout file によって表現される • ファイルを削除したときは .wh.

    から始まる空のファイルが作られる • 特定のディレクトリの全てのファイルを削除した場合はそのディレクトリに opaque whiteout file .wh!"wh!"opq が作られる af197d5ca08b03ffdfd8c!!" 以下の layer.tar の中⾝を⾒てみる % tar tvf af197d5ca08b03ffdfd8c!!"/layer.tar -rw------- 0 0 0 0 7 31 19:35 .wh.hoge.txt IBUFOBJOUFSO !"
  17. レイヤーキャッシュ # syntax=docker/dockerfile:1 FROM golang:1.23-bookworm AS builder WORKDIR /services/blog COPY

    go.mod go.sum ./ # ͕͜͜มߋ͞Εͨ৔߹͸ ↓ ͷ෦෼Λ࠶࣮ߦ RUN go mod download COPY . . RUN "#mount=type=cache,target=/root/.cache/go-build \ make build • コンテナイメージのビルド時に は Lower Dir に対する変更を Upper Dir として新しいレイヤー ⽤の tar アーカイブを作成する • ⼀度実⾏した命令は Lower Dir として残っているので、Upper Dir による変更だけを⾏えばよ く、レイヤーキャッシュが利⽤ できる IBUFOBJOUFSO !!
  18. イメージのビルド • Dockerfile からコンテナイメージを作成するにはビルダーを利 ⽤する • BuildKit, Kaniko, Buildah などのツールがある

    • ビルダーは Dockerfile に記述されている命令に従ってイメージ レイヤーを積み重ねてコンテナイメージを作る IBUFOBJOUFSO !"
  19. BuildKit • Docker Engine -..0 から docker build で使われているビル ダ

    • buildctl という CLI ツールからも利⽤できる • イメージの並列ビルドやマルチプラットフォーム対応イメージ のビルドが可能 • Dockerfile の最新の構⽂に対応している IBUFOBJOUFSO !"
  20. BuildKit SBOM (Software Bill of Materials) • 利⽤しているソフトウェアを管理できるフ ォーマット •

    ライセンス管理や脆弱性管理に使われる • BuildKit では Syft scanner というプラグ インを利⽤してコンテナイメージに SBOM を追加できる • SBOM からコンテナイメージ内に存在 するソフトウェアの脆弱性を検出できる $ buildctl build \ !"frontend dockerfile.v0 !"local context=. !"local dockerfile=. \ !"opt attest:sbom=generator=docker/buildkit-syft-scanner \ !"output type=image,name=hatena/intern2023 [+] Building 16.7s (23/23) FINISHED !# [internal] load build definition from Dockerfile 0.0s !# !# transferring dockerfile: 844B 0.0s !!$ !# !# resolve docker.io/docker/buildkit-syft-scanner:latest 0.3s !# [linux/arm64] generating sbom using docker.io/docker/buildkit-syft-sc 0.1s !# exporting to image 0.5s !# !# exporting layers 0.4s !# !# exporting manifest sha256:d6e8bd451e080886f0b7a764e731347bd4b22cdd 0.0s !# !# exporting config sha256:0941190ee8cb0d7b70ecfba24f8281dde9497012c1 0.0s !# !# exporting attestation manifest sha256:677397d604ce5507cd5b54c79838 0.0s !# !# exporting manifest list sha256:c032b2a13f1de13780312229b9ba5bca0ce 0.0s IBUFOBJOUFSO !"
  21. ⾼レベルランタイム • containerd, CRI-O など • コンテナイメージや複数台のコンテナを管理する • ユーザインタフェースとなるツールや、コンテナオーケストレーションツールと通信 する

    • CRI (Container Runtime Interface) という規格がある • 低レベルランタイムと通信してコンテナを起動する‧低レベルランタイムにコンテ ナ環境の設定を送信する • Docker は低レベルランタイムとの通信に containerd を利⽤している IBUFOBJOUFSO !"
  22. 低レベルランタイム • runc, gVisor など • 個々のプロセスを起動し、Namespace を隔離してコンテナと して実⾏する •

    OCI Runtime Spec (Open Container Initiative Runtime Specification) によって標準的な仕様‧挙動が定義されている IBUFOBJOUFSO !"
  23. Open Container Initiative (OCI) • コンテナの業界標準を定める団体 • 現在 Runtime Spec,

    Image Spec, Distribution Spec が定義さ れている IBUFOBJOUFSO !"
  24. Open Container Initiative (OCI) Runtime Specification • コンテナランタイムの実現すべき挙動が主に定義されている • コンテナの原則

    (The C principles of Standard Containers) • コンテナのライフサイクルや、コンテナに対して実⾏可能な操作 • 付与する capability, Namespace, cgroup によるリソースの制 限の指定⽅法など IBUFOBJOUFSO !"
  25. Open Container Initiative(OCI) The % principles of Standard Containers •

    ". Standard operations • 起動‧停⽌‧削除やスナップショットの取得などの基本的な操作が可能 • L. Content-agnostic • コンテナに対する操作はコンテナの内容によらず同じ結果になる • b. Infrastructure-agnostic • OCI に準拠しているコンテナランタイム上で動くコンテナは、どのような場所やアーキテクチャの上でも同様に動作する • . Designed for automation • Ç. Industrial-grade delivery IBUFOBJOUFSO !"
  26. Open Container Initiative (OCI) Image Specification • コンテナイメージに含まれるデータの種類や、その配置について定義 されている •

    主たるデータは Filesystem Layer, Image Index, Image Configuration。他にも Image Manifest などが含まれる • Image Manifest ごとの Filesystem Layer や Image Configuration が含まれており、それらの配置が Image Index に記載されている IBUFOBJOUFSO !!
  27. イメージは軽量にする • 実⾏に必要な依存関係のみを持つイメージを作成する • 軽量なので実⾏までのコストが⼩さくなる。依存関係が減ると攻撃されうる対象 も減る。 • 軽量なベースイメージを選択する • -slim

    な flavor や distroless をベースとして、必要なランタイムとアプリケーシ ョンだけインストールする • SlimToolkitで軽量化する • 軽量化にこだわりすぎず、Seekable OCI でイメージを遅延読み込みするのも⼿ IBUFOBJOUFSO !"
  28. コンテナのユーザーは⼀般ユーザーにする • User namespace の分離と適切なマッピングを指定しない場 合、コンテナの root はホストの root に対応する

    • コンテナ内の脆弱性で root 権限を取得された場合、影響がホス トの root にまで及んでしまうことも • Dockerfile の USER 命令でコンテナを実⾏するユーザを指定す る IBUFOBJOUFSO !"
  29. イメージのスキャン • Dockerfile の書き⽅の不備や、イメージ内に含まれるファイル‧パッケ ージに含まれる脆弱性をスキャンできるツールが存在する • Trivy, Claier, Anchore などのツールや、AWS

    ECR, Docker Hub の機 能、docker scout sves コマンドが利⽤できる 脆弱性の発⾒されているソフトウェアが Docker イメージの中に⼊ってい ないか、スキャンします。 イメージをスキャンするには、そのためのツールやサービスを利⽤した り、レジストリが脆弱性スキャンを実施してくれるものもあります。 IBUFOBJOUFSO !"
  30. イメージのスキャン Trivy • https://github.com/aquasecurity/trivy • Docker イメージ、ファイルシステム、Git リポジトリに対してスキャンができる • イメージの

    SBOM からも脆弱性をスキャンできる $ trivy image !"severity HIGH hatena/apply-for-internship-2020:latest 2020-08-05T08:44:37.496+0900 WARN You should avoid using the :latest tag as it is cached. You need to specify '!"clear-cache' option when :latest image is changed 2020-08-05T08:44:40.616+0900 INFO Detecting Debian vulnerabilities!!$ hatena/apply-for-internship-2020:latest (debian 10.4) ===================================================== Total: 1 (HIGH: 1) +-----------+------------------+----------+-------------------+------------------+--------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +-----------+------------------+----------+-------------------+------------------+--------------------------------+ | perl-base | CVE-2020-10878 | HIGH | 5.28.1-6 | 5.28.1-6+deb10u1 | perl: corruption of | | | | | | | intermediate language state | | | | | | | of compiled regular expression | | | | | | | due to!!$ | +-----------+------------------+----------+-------------------+------------------+--------------------------------+ IBUFOBJOUFSO !"
  31. まとめ • コンテナはプロセスを隔離し、コンテナイメージをもとに実⾏して実現されています • Namespace, seccomp, OverlayFS など • コンテナランタイムの挙動は標準化されています

    • CRI, OCI (Runtime Spec, Image Spec) など • コンテナを軽量かつステートレスに設計することでスケールしやすくなります • ! 詳しくは次の「コンテナオーケストレーション」講義で! ご清聴ありがとうございました IBUFOBJOUFSO !!