Share
Embed
Transcript
51 slides
-
͜ͷߨٛʹ͍ͭͯ • コンテナ技術がどのように実現されているかを理解する • ⽇常で利⽤しているコンテナがどう動いているか想像できる ようになる • コンテナを利⽤するに当たってどのような点に注意すべきか 判断できるようになる •
コンテナ技術の発展についても説明します IBUFOBJOUFSO ! -
ϓϩηεͷִ • コンテナ技術の根幹となる概念の⼀つ • あるプロセスから⾒えるリソース‧利⽤可能なリソースを制限 する • プロセス間の⼲渉がなくなり、複数のプロセスを安定して稼 働させられる •
不要なリソースを利⽤させないことで、安全性を⾼められる IBUFOBJOUFSO ! -
ίϯςφΛ࣮ݱ͢ΔϓϩμΫτ • 2000年 FreeBSD jails • 2008年 LXC (Linux Containers)
• 2013年 Docker • 2019年 Podman これらのプロダクトも、概ね次ページ以降で紹介する技術(や、 相当の機能)を組み合わせて実現されている IBUFOBJOUFSO ! -
Ϧιʔεͷ੍ݶ • コンテナはプロセスが利⽤できるリソースを制限する技術を組 み合わせて実現されている • 何を制限するかによって複数の要素技術がある • リソースの可視性: Namespace (PID,
Mount, User, ...) • リソースの利⽤上限: Namespace (cgroup) • 特権‧システムコール等: capability, seccomp, ... IBUFOBJOUFSO ! -
Namespace • Linux Kernelの持つ機能。Namespaceごとにリソースを隔離し て、Namespace内のプロセスに対して独⽴した環境に⾒せる • それぞれのプロセスが⼲渉することがなくなる • どのリソースを隔離するかによって様々なNamespaceが存在す る
• PID, Mount, Network, User, IPC, UTS, Time, Cgroup IBUFOBJOUFSO !" -
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 !! -
Namespace User • UID/GID を分離する • ケーパビリティ(後述)を分離する • 異なる NameSpace
で同じ UID のユーザを作成できる • ホストからは⼀般ユーザ、コンテナ内では root というユーザが作成できる • マッピング IBUFOBJOUFSO !" -
Namespace Cgroup • コンテナ内のプロセスの集合に対してリソース使⽤量を制限す る仕組み • CPU使⽤量、メモリ使⽤量、プロセス数など • 監視も⾏うことができ、docker top
はこれを利⽤している IBUFOBJOUFSO !" -
Namespace • Mount: マウントポイントを分離する • Network: ネットワークデバイス、ルーティングテーブル、IPア ドレス、ポート番号などを隔離する • Time:
ホストとコンテナの時間を分離する • IPC: 共有メモリを分離する • UTS: ホスト名とドメイン名を分離する IBUFOBJOUFSO !" -
capability • ネットワーク操作など、処理を⾏うために特権が必要な操作が存在する • 特定の操作ためにあらゆる特権を取得するのは過剰 • 例: pingコマンドの実⾏のために特権を取得したら、pingコマンドでPCの再起動までできるように なってしまった •
Linux Kernelでは操作の種類に応じた権限としてcapabilityという概念があり、プロセスに対して許可 する権限を個別に選択できる • 上記の例で⾔えば、CAPNETRAWとCAPSYSBOOTを分離して、pingコマンドにはCAPNETRAWを付 与し、CAPSYSBOOTは付与しないことで、特権処理の⼀つであるRAWソケットの利⽤を許可しなが ら、PCの再起動は許可しない • capabilityの⼀覧はman capabilities(7)で確認できる IBUFOBJOUFSO !" -
capability (2) • 特権操作を必要とするプロセスに対しても、特権を渡すのではなくcapabilityを付与する • capabilityによって許可される操作はNamespaceで隔離された範囲に閉じないことが あるので注意する必要がある • コンテナランタイムはコンテナで実⾏するプロセスに対していくつかのcapabilityをデ フォルトで付与する
• デフォルトの権限は 公式ドキュメント や pscap コマンドで確認できる • 設定によって追加のcapabilityを付与することもできる • docker の場合、--cap-add, --cap-drop オプションや --priviledged オプションがある IBUFOBJOUFSO !" -
seccomp • システムコールの中にはNamespaceで分離されていないリソースに⼲渉するものも あり、コンテナ内のプロセスから呼び出されると仮想化が崩れてしまう • seccompはプロセスの発⾏できるシステムコールを制限する仕組みで、コンテナラ ンタイムはseccompを利⽤してコンテナ内のプロセスがこれらのシステムコールを 呼び出すことを防ぐ • Dockerでデフォルトで制限されているシステムコールは公式ドキュメントに⼀覧
されている • 設定でプロファイルを渡すことによって呼び出しを制限するシステムコールを制 御できる IBUFOBJOUFSO !" -
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 !" -
ͦͷଞͷػೳ これまで紹介してきた機能以外にもコンテナの可搬性‧安全性に寄与する技術が提案‧利⽤されている • AppArmor / SELinux • ポリシーに基づいてさらに強固にプロセスの挙動を制約する • gVisor
• ユーザ空間カーネルを実装し、システムコール呼び出しをホストマシンに伝搬させないことで隔 離性能を⾼める • Kata Containers • コンテナをqemu, Firecrackerなどで⽣成した仮想マシン内で実⾏する IBUFOBJOUFSO !" -
UnionϑΝΠϧγεςϜ • 複数の異なるファイルシステムを重ね合わせて利⽤できる仕組み。OverlayFSなどの実装 がある • ベースとなる下位ディレクトリ(Lower Dir)に対して差分を上位ディレクトリ(Upper Dir) として重ね合わせる •
コンテナイメージに含まれるファイルシステムはLower Dir、コンテナ上で変更される ファイルシステムをUpper Dirとする • Lower Dirは変更されないので1つのコンテナイメージを複数のコンテナインスタンス で共有できる • 変更を個々のコンテナインスタンス毎のCopy on Writeレイヤー(Upper Dir)に適⽤する IBUFOBJOUFSO !" -
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 !" -
ίϯςφΠϝʔδͷߏΛΈΔ 以下の Dockerfile をビルドしてイメージを作成 FROM ubuntu RUN echo "hoge" >
hoge.txt RUN rm hoge.txt 作成したイメージを出⼒して解凍 $ docker save $CID > image.tar $ tar xf image.tar IBUFOBJOUFSO !" -
ΠϝʔδϨΠϠʔ Dockerfileの命令毎にレイヤーが別れている . ├── 3fe352f27d6d9b899da69b9799728c4492690186797a106cbfa029264b6ebcf7 │ ├── VERSION │ ├──
json │ └── layer.tar ├── aa8c0471e58774435617a2efb80b963d0288bdbdfdd7ded778776c3051664569.json ├── af197d5ca08b03ffdfd8c1285260360fbbc237328d421b73c2abc3f07bb054d9 │ ├── VERSION │ ├── json │ └── layer.tar ├── b3ea71bd7712c8534c4e3440a02a2217d0049fc8acacac191cf875bc21ab9f6a │ ├── VERSION │ ├── json │ └── layer.tar └── manifest.json IBUFOBJOUFSO !" -
layer.tar • 下位のレイヤに対しての差分がまとめられている b3ea71bd7712c8534c4e3... 以下の layer.tar の中⾝をみてみる % tar xf
layer.tar -C ./tmp % ls ./tmp hoge.txt % cat ./tmp/hoge.txt hoge IBUFOBJOUFSO !" -
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 !" -
ϨΠϠΩϟογϡ # 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 !" -
ΠϝʔδͷϏϧυ • Dockerfileからコンテナイメージを作成するにはビルダーを利 ⽤する • BuildKit, Kaniko, Buildahなどのツールがある • ビルダーはDockerfileに記述されている命令に従ってイメージ
レイヤーを積み重ねてコンテナイメージを作る IBUFOBJOUFSO !" -
BuildKit • Docker Engine -..0からdocker buildで使われているビルダ • buildctl というCLIツールからも利⽤できる •
イメージの並列ビルドやマルチプラットフォーム対応イメージ のビルドが可能 • Dockerfileの最新の構⽂に対応している IBUFOBJOUFSO !" -
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 !" -
ߴϨϕϧϥϯλΠϜ • Docker, containerd, CRI-Oなど • コンテナイメージや複数台のコンテナを管理する • ユーザインタフェースとなるツールや、コンテナオーケストレーションツールと通 信する
• CRI(Container Runtime Interface) という規格がある • 低レベルランタイムと通信してコンテナを起動する‧低レベルランタイムにコンテ ナ環境の設定を送信する • Dockerは低レベルランタイムとの通信にcontainerdを利⽤している IBUFOBJOUFSO !" -
ϨϕϧϥϯλΠϜ • runc, gVisorなど • 個々のプロセスを起動し、Namespaceを隔離してコンテナとし て実⾏する • OCI Runtime
Spec(Open Container Initiative Runtime Specification)によって標準的な仕様‧挙動が定義されている IBUFOBJOUFSO !" -
Open Container Initiative(OCI) • コンテナの業界標準を定める団体 • 現在Runtime Spec, Image Spec,
Distribution Spec が定義さ れている IBUFOBJOUFSO !" -
Open Container Initiative(OCI) Runtime Specification • コンテナランタイムの実現すべき挙動が主に定義されている • コンテナの原則(The C
principles of Standard Containers) • コンテナのライフサイクルや、コンテナに対して実⾏可能な操作 • 付与するcapabilityや、namespace, cgroupによるリソースの制 限の指定⽅法など IBUFOBJOUFSO !" -
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 !" -
Open Container Initiative(OCI) Image Specification • コンテナイメージに含まれるデータの種類や、その配置について定 義されている • 主たるデータはFilesystem
Layer, Image Index, Image Configuration。他にもImage Manifestなどが含まれる • Image ManifestごとのFilesystem LayerやImage Configuration が含まれており、それらの配置がImage Indexに記載されている IBUFOBJOUFSO !" -
1 ίϯςφ 1 ϓϩηε • 単⼀の機能として分離して⽔平スケールしやすくする • 再利⽤性、透明性 • 依存関係を減らす
IBUFOBJOUFSO !" -
εςʔτϨεͰΠϛϡʔλϒϧʹ͢Δ • 状態を持たず不変 • 実⾏しているコンテナ内でアプリケーションを変更しない • 永続データはコンテナ外部のコンポーネントに任せる • ログは stdout/stderr
に出⼒する • ログをファイルに書き出さない IBUFOBJOUFSO !" -
Πϝʔδܰྔʹ͢Δ • 実⾏に必要な依存関係のみを持つイメージを作成する • 軽量なので実⾏までのコストが⼩さくなる。依存関係が減ると攻撃されうる対象 も減る • マルチステージビルドを活⽤する • 軽量なベースイメージを選択する
• buildpack-depsやdistrolessをベースとして、必要なランタイムとアプリケー ションだけインストールする • SlimToolkitで軽量化する IBUFOBJOUFSO !! -
ൿີͷʢγʔΫϨοτʣΛίϯςφΠϝʔ δʹؚΊͳ͍ • コンテナイメージ経由でシークレットが漏洩する可能性がある • シークレットの更新のためにコンテナイメージを再度⽣成する必要がある • 代わりに以下のような⽅法をとる • コンテナ起動後にネットワーク経由で取得する
• 環境変数経由でコンテナにシークレットを渡す • _`-factor Appではこの⽅法を推奨している • コンテナがマウントされるボリュームに書き込む IBUFOBJOUFSO !" -
ίϯςφΠϝʔδͷϏϧυ࣌ʹγʔΫϨοτ Λར༻͢Δ • イメージのビルド時にプライベートリポジトリにアクセスする必要がある場合など • Buildkitの--secretオプションを利⽤する • DockerfileでRUN --mount=type=secretを指定し、ビルド時に--secretオプションでシークレットのパ スを渡すことで、ビルド後のイメージレイヤに値を残さない
• マルチステージビルドを⾏う • 別のコンテナイメージからファイルをコピーできる機能 • シークレットを利⽤しつつ、最終的に必要なファイルをビルドするイメージと、その成果物を利⽤して 動作するイメージを分けることでシークレットを残さない IBUFOBJOUFSO !" -
ΠϝʔδͷεΩϟϯ • Dockerfileの書き⽅の不備や、イメージ内に含まれるファイ ル‧パッケージに含まれる脆弱性をスキャンできるツールが存 在する • Trivy, Claier, Anchoreなどのツールや、AWS ECR,
DockerHub の機能、docker scout svesコマンドが利⽤できる IBUFOBJOUFSO !" -
ΠϝʔδͷεΩϟϯ 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 !" -
·ͱΊ • コンテナはプロセスを隔離し、コンテナイメージ上で実⾏して実現されて いる • Namespace, seccomp, OverlayFSなど • コンテナランタイムの挙動は標準化されつつある
• CRI, OCI Runtime Spec, OCI Image Spec など • コンテナを軽量かつステートレスに設計することでスケールしやすくなる • ! コンテナオーケストレーション講義 IBUFOBJOUFSO !"