Slide 1

Slide 1 text

ίϯςφ IBUFOBJOUFSO !

Slide 2

Slide 2 text

͜ͷߨٛʹ͍ͭͯ • コンテナ技術がどのように実現されているかを理解する • ⽇常で利⽤しているコンテナがどう動いているか想像できる ようになる • コンテナを利⽤するに当たってどのような点に注意すべきか 判断できるようになる • コンテナ技術の発展についても説明します IBUFOBJOUFSO !

Slide 3

Slide 3 text

ίϯςφ֓؍ IBUFOBJOUFSO !

Slide 4

Slide 4 text

ͳͥίϯςφΛར༻͢Δͷ͔ • 仮想化が実現できる • 可搬性が⾼い • ⾼速‧低コストである これらを実現するのがプロセスの隔離とコンテナイメージによる 環境の構築 IBUFOBJOUFSO !

Slide 5

Slide 5 text

ϓϩηεͷִ཭ • コンテナ技術の根幹となる概念の⼀つ • あるプロセスから⾒えるリソース‧利⽤可能なリソースを制限 する • プロセス間の⼲渉がなくなり、複数のプロセスを安定して稼 働させられる • 不要なリソースを利⽤させないことで、安全性を⾼められる IBUFOBJOUFSO !

Slide 6

Slide 6 text

ίϯςφΠϝʔδ • 隔離されたプロセスの実⾏環境 • 次のようなものが含まれる • プロセスが動作するために必要なライブラリ等をまとめた ファイルシステム • 環境変数など実⾏時の設定 • メタ情報 IBUFOBJOUFSO !

Slide 7

Slide 7 text

ίϯςφΛ࣮ݱ͢Δٕज़ IBUFOBJOUFSO !

Slide 8

Slide 8 text

ίϯςφΛ࣮ݱ͢ΔϓϩμΫτ • 2000年 FreeBSD jails • 2008年 LXC (Linux Containers) • 2013年 Docker • 2019年 Podman これらのプロダクトも、概ね次ページ以降で紹介する技術(や、 相当の機能)を組み合わせて実現されている IBUFOBJOUFSO !

Slide 9

Slide 9 text

Ϧιʔεͷ੍ݶ • コンテナはプロセスが利⽤できるリソースを制限する技術を組 み合わせて実現されている • 何を制限するかによって複数の要素技術がある • リソースの可視性: Namespace (PID, Mount, User, ...) • リソースの利⽤上限: Namespace (cgroup) • 特権‧システムコール等: capability, seccomp, ... IBUFOBJOUFSO !

Slide 10

Slide 10 text

Namespace • Linux Kernelの持つ機能。Namespaceごとにリソースを隔離し て、Namespace内のプロセスに対して独⽴した環境に⾒せる • それぞれのプロセスが⼲渉することがなくなる • どのリソースを隔離するかによって様々なNamespaceが存在す る • PID, Mount, Network, User, IPC, UTS, Time, Cgroup IBUFOBJOUFSO !"

Slide 11

Slide 11 text

Namespace PID • プロセスID番号空間の隔離 • 名前空間内で最初のプロセスはpid : 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 !!

Slide 12

Slide 12 text

Namespace User • UID/GID を分離する • ケーパビリティ(後述)を分離する • 異なる NameSpace で同じ UID のユーザを作成できる • ホストからは⼀般ユーザ、コンテナ内では root というユーザが作成できる • マッピング IBUFOBJOUFSO !"

Slide 13

Slide 13 text

Namespace Cgroup • コンテナ内のプロセスの集合に対してリソース使⽤量を制限す る仕組み • CPU使⽤量、メモリ使⽤量、プロセス数など • 監視も⾏うことができ、docker top はこれを利⽤している IBUFOBJOUFSO !"

Slide 14

Slide 14 text

Namespace • Mount: マウントポイントを分離する • Network: ネットワークデバイス、ルーティングテーブル、IPア ドレス、ポート番号などを隔離する • Time: ホストとコンテナの時間を分離する • IPC: 共有メモリを分離する • UTS: ホスト名とドメイン名を分離する IBUFOBJOUFSO !"

Slide 15

Slide 15 text

capability • ネットワーク操作など、処理を⾏うために特権が必要な操作が存在する • 特定の操作ためにあらゆる特権を取得するのは過剰 • 例: pingコマンドの実⾏のために特権を取得したら、pingコマンドでPCの再起動までできるように なってしまった • Linux Kernelでは操作の種類に応じた権限としてcapabilityという概念があり、プロセスに対して許可 する権限を個別に選択できる • 上記の例で⾔えば、CAPNETRAWとCAPSYSBOOTを分離して、pingコマンドにはCAPNETRAWを付 与し、CAPSYSBOOTは付与しないことで、特権処理の⼀つであるRAWソケットの利⽤を許可しなが ら、PCの再起動は許可しない • capabilityの⼀覧はman capabilities(7)で確認できる IBUFOBJOUFSO !"

Slide 16

Slide 16 text

capability (2) • 特権操作を必要とするプロセスに対しても、特権を渡すのではなくcapabilityを付与する • capabilityによって許可される操作はNamespaceで隔離された範囲に閉じないことが あるので注意する必要がある • コンテナランタイムはコンテナで実⾏するプロセスに対していくつかのcapabilityをデ フォルトで付与する • デフォルトの権限は 公式ドキュメント や pscap コマンドで確認できる • 設定によって追加のcapabilityを付与することもできる • docker の場合、--cap-add, --cap-drop オプションや --priviledged オプションがある IBUFOBJOUFSO !"

Slide 17

Slide 17 text

seccomp • システムコールの中にはNamespaceで分離されていないリソースに⼲渉するものも あり、コンテナ内のプロセスから呼び出されると仮想化が崩れてしまう • seccompはプロセスの発⾏できるシステムコールを制限する仕組みで、コンテナラ ンタイムはseccompを利⽤してコンテナ内のプロセスがこれらのシステムコールを 呼び出すことを防ぐ • Dockerでデフォルトで制限されているシステムコールは公式ドキュメントに⼀覧 されている • 設定でプロファイルを渡すことによって呼び出しを制限するシステムコールを制 御できる IBUFOBJOUFSO !"

Slide 18

Slide 18 text

seccomp(2) ྫ seccomp.json { "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "kill", "action": "SCMP_ACT_ERRNO" } ] } Docker で実⾏ noy72@noy72 $ 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 !"

Slide 19

Slide 19 text

ͦͷଞͷػೳ これまで紹介してきた機能以外にもコンテナの可搬性‧安全性に寄与する技術が提案‧利⽤されている • AppArmor / SELinux • ポリシーに基づいてさらに強固にプロセスの挙動を制約する • gVisor • ユーザ空間カーネルを実装し、システムコール呼び出しをホストマシンに伝搬させないことで隔 離性能を⾼める • Kata Containers • コンテナをqemu, Firecrackerなどで⽣成した仮想マシン内で実⾏する IBUFOBJOUFSO !"

Slide 20

Slide 20 text

ίϯςφΠϝʔδ IBUFOBJOUFSO !"

Slide 21

Slide 21 text

ϓϩηεͷ࣮ߦ؀ڥ • プロセスが利⽤するライブラリや読み書きするファイルも独⽴ していたい • スケーラビリティを確保するためにはこれらが素早く、再現性 を持って準備されていたい • これを実現するのがコンテナイメージ IBUFOBJOUFSO !"

Slide 22

Slide 22 text

ίϯςφΠϝʔδ • コンテナ化された環境で利⽤するファイルシステムなどをまと めたもの • 主な内容物はコンテナ化されるプロセスから参照されるMount Namespaceにマウントされるファイル群のtarアーカイブ • このtarアーカイブのrootを隔離したプロセスに対するルート ファイルシステムとしてpivot_rootする IBUFOBJOUFSO !!

Slide 23

Slide 23 text

UnionϑΝΠϧγεςϜ • 複数の異なるファイルシステムを重ね合わせて利⽤できる仕組み。OverlayFSなどの実装 がある • ベースとなる下位ディレクトリ(Lower Dir)に対して差分を上位ディレクトリ(Upper Dir) として重ね合わせる • コンテナイメージに含まれるファイルシステムはLower Dir、コンテナ上で変更される ファイルシステムをUpper Dirとする • Lower Dirは変更されないので1つのコンテナイメージを複数のコンテナインスタンス で共有できる • 変更を個々のコンテナインスタンス毎のCopy on Writeレイヤー(Upper Dir)に適⽤する IBUFOBJOUFSO !"

Slide 24

Slide 24 text

Dockerfile # syntax = docker/dockerfile:1 FROM golang:1.18-alpine AS builder RUN apk --update add make 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 alpine 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 !"

Slide 25

Slide 25 text

ίϯςφΠϝʔδͷߏ੒ΛΈΔ 以下の Dockerfile をビルドしてイメージを作成 FROM ubuntu RUN echo "hoge" > hoge.txt RUN rm hoge.txt 作成したイメージを出⼒して解凍 $ docker save $CID > image.tar $ tar xf image.tar IBUFOBJOUFSO !"

Slide 26

Slide 26 text

ΠϝʔδϨΠϠʔ Dockerfileの命令毎にレイヤーが別れている . ├── 3fe352f27d6d9b899da69b9799728c4492690186797a106cbfa029264b6ebcf7 │ ├── VERSION │ ├── json │ └── layer.tar ├── aa8c0471e58774435617a2efb80b963d0288bdbdfdd7ded778776c3051664569.json ├── af197d5ca08b03ffdfd8c1285260360fbbc237328d421b73c2abc3f07bb054d9 │ ├── VERSION │ ├── json │ └── layer.tar ├── b3ea71bd7712c8534c4e3440a02a2217d0049fc8acacac191cf875bc21ab9f6a │ ├── VERSION │ ├── json │ └── layer.tar └── manifest.json IBUFOBJOUFSO !"

Slide 27

Slide 27 text

layer.tar • 下位のレイヤに対しての差分がまとめられている b3ea71bd7712c8534c4e3... 以下の layer.tar の中⾝をみてみる % tar xf layer.tar -C ./tmp % ls ./tmp hoge.txt % cat ./tmp/hoge.txt hoge IBUFOBJOUFSO !"

Slide 28

Slide 28 text

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 !"

Slide 29

Slide 29 text

ϨΠϠΩϟογϡ # syntax = docker/dockerfile:1 FROM golang:1.18-alpine AS builder RUN apk --update add make 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 !"

Slide 30

Slide 30 text

ΠϝʔδͷϏϧυ • Dockerfileからコンテナイメージを作成するにはビルダーを利 ⽤する • BuildKit, Kaniko, Buildahなどのツールがある • ビルダーはDockerfileに記述されている命令に従ってイメージ レイヤーを積み重ねてコンテナイメージを作る IBUFOBJOUFSO !"

Slide 31

Slide 31 text

BuildKit • Docker Engine -..0からdocker buildで使われているビルダ • buildctl というCLIツールからも利⽤できる • イメージの並列ビルドやマルチプラットフォーム対応イメージ のビルドが可能 • Dockerfileの最新の構⽂に対応している IBUFOBJOUFSO !"

Slide 32

Slide 32 text

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 !"

Slide 33

Slide 33 text

ίϯςφϥϯλΠϜͷΞʔΩςΫ νϟͱඪ४ IBUFOBJOUFSO !!

Slide 34

Slide 34 text

ίϯςφϥϯλΠϜʢDockerʣΛߏ੒͢Δί ϯϙʔωϯτ • 低レベルランタイム:プロセスを隔離して実⾏する • ⾼レベルランタイム:コンテナイメージやコンテナの管理 • CLI/デーモンなど:ユーザにインタフェースを提供し、⾼レベルランタイムを操作する IBUFOBJOUFSO !"

Slide 35

Slide 35 text

ߴϨϕϧϥϯλΠϜ • Docker, containerd, CRI-Oなど • コンテナイメージや複数台のコンテナを管理する • ユーザインタフェースとなるツールや、コンテナオーケストレーションツールと通 信する • CRI(Container Runtime Interface) という規格がある • 低レベルランタイムと通信してコンテナを起動する‧低レベルランタイムにコンテ ナ環境の設定を送信する • Dockerは低レベルランタイムとの通信にcontainerdを利⽤している IBUFOBJOUFSO !"

Slide 36

Slide 36 text

௿ϨϕϧϥϯλΠϜ • runc, gVisorなど • 個々のプロセスを起動し、Namespaceを隔離してコンテナとし て実⾏する • OCI Runtime Spec(Open Container Initiative Runtime Specification)によって標準的な仕様‧挙動が定義されている IBUFOBJOUFSO !"

Slide 37

Slide 37 text

Open Container Initiative(OCI) • コンテナの業界標準を定める団体 • 現在Runtime Spec, Image Spec, Distribution Spec が定義さ れている IBUFOBJOUFSO !"

Slide 38

Slide 38 text

Open Container Initiative(OCI) Runtime Specification • コンテナランタイムの実現すべき挙動が主に定義されている • コンテナの原則(The C principles of Standard Containers) • コンテナのライフサイクルや、コンテナに対して実⾏可能な操作 • 付与するcapabilityや、namespace, cgroupによるリソースの制 限の指定⽅法など IBUFOBJOUFSO !"

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Open Container Initiative(OCI) Image Specification • コンテナイメージに含まれるデータの種類や、その配置について定 義されている • 主たるデータはFilesystem Layer, Image Index, Image Configuration。他にもImage Manifestなどが含まれる • Image ManifestごとのFilesystem LayerやImage Configuration が含まれており、それらの配置がImage Indexに記載されている IBUFOBJOUFSO !"

Slide 41

Slide 41 text

ίϯςφͷઃܭ IBUFOBJOUFSO !"

Slide 42

Slide 42 text

1 ίϯςφ 1 ϓϩηε • 単⼀の機能として分離して⽔平スケールしやすくする • 再利⽤性、透明性 • 依存関係を減らす IBUFOBJOUFSO !"

Slide 43

Slide 43 text

εςʔτϨεͰΠϛϡʔλϒϧʹ͢Δ • 状態を持たず不変 • 実⾏しているコンテナ内でアプリケーションを変更しない • 永続データはコンテナ外部のコンポーネントに任せる • ログは stdout/stderr に出⼒する • ログをファイルに書き出さない IBUFOBJOUFSO !"

Slide 44

Slide 44 text

Πϝʔδ͸ܰྔʹ͢Δ • 実⾏に必要な依存関係のみを持つイメージを作成する • 軽量なので実⾏までのコストが⼩さくなる。依存関係が減ると攻撃されうる対象 も減る • マルチステージビルドを活⽤する • 軽量なベースイメージを選択する • buildpack-depsやdistrolessをベースとして、必要なランタイムとアプリケー ションだけインストールする • SlimToolkitで軽量化する IBUFOBJOUFSO !!

Slide 45

Slide 45 text

ίϯςφͷϢʔβʔ͸ඇrootʹ͢Δ • User namespaceの分離と適切なマッピングを指定しない場 合、コンテナのrootはホストのrootに対応する • コンテナ内の脆弱性でroot権限を取得された場合、影響がホス トのrootにまで及んでしまう • DockerfileのUSER命令でコンテナを実⾏するユーザを指定する IBUFOBJOUFSO !"

Slide 46

Slide 46 text

ઃఆΛ؀ڥม਺ʹ֨ೲ͢Δ • コンテナイメージを作り直すことなく動作を変更できる • 複数の環境で同じDockerイメージが使える IBUFOBJOUFSO !"

Slide 47

Slide 47 text

ൿີͷ஋ʢγʔΫϨοτʣΛίϯςφΠϝʔ δʹؚΊͳ͍ • コンテナイメージ経由でシークレットが漏洩する可能性がある • シークレットの更新のためにコンテナイメージを再度⽣成する必要がある • 代わりに以下のような⽅法をとる • コンテナ起動後にネットワーク経由で取得する • 環境変数経由でコンテナにシークレットを渡す • _`-factor Appではこの⽅法を推奨している • コンテナがマウントされるボリュームに書き込む IBUFOBJOUFSO !"

Slide 48

Slide 48 text

ίϯςφΠϝʔδͷϏϧυ࣌ʹγʔΫϨοτ Λར༻͢Δ • イメージのビルド時にプライベートリポジトリにアクセスする必要がある場合など • Buildkitの--secretオプションを利⽤する • DockerfileでRUN --mount=type=secretを指定し、ビルド時に--secretオプションでシークレットのパ スを渡すことで、ビルド後のイメージレイヤに値を残さない • マルチステージビルドを⾏う • 別のコンテナイメージからファイルをコピーできる機能 • シークレットを利⽤しつつ、最終的に必要なファイルをビルドするイメージと、その成果物を利⽤して 動作するイメージを分けることでシークレットを残さない IBUFOBJOUFSO !"

Slide 49

Slide 49 text

ΠϝʔδͷεΩϟϯ • Dockerfileの書き⽅の不備や、イメージ内に含まれるファイ ル‧パッケージに含まれる脆弱性をスキャンできるツールが存 在する • Trivy, Claier, Anchoreなどのツールや、AWS ECR, DockerHub の機能、docker scout svesコマンドが利⽤できる IBUFOBJOUFSO !"

Slide 50

Slide 50 text

ΠϝʔδͷεΩϟϯ 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 !"

Slide 51

Slide 51 text

·ͱΊ • コンテナはプロセスを隔離し、コンテナイメージ上で実⾏して実現されて いる • Namespace, seccomp, OverlayFSなど • コンテナランタイムの挙動は標準化されつつある • CRI, OCI Runtime Spec, OCI Image Spec など • コンテナを軽量かつステートレスに設計することでスケールしやすくなる • ! コンテナオーケストレーション講義 IBUFOBJOUFSO !"