Slide 1

Slide 1 text

開運研修 2024 Docker⼊⾨ (コンテナの利⽤価値と実践)社外公開版 開運研修 2024 Docker⼊⾨ (コンテナの利⽤価値と実践) 1

Slide 2

Slide 2 text

⽬次 ▌⾃⼰紹介 ▌第⼀部 コンテナの利⽤価値 ▌第⼆部 コンテナを活⽤した開発 ▌第三部 コンテナを活かすための知識 ▌参考リンク集 ▌補⾜資料 2

Slide 3

Slide 3 text

⾃⼰紹介 ▌⾼良 真穂 (たから まほ) ▌2023年4⽉ サイボウズ⼊社 前職を60歳で定年退職して、サイボウズで世話に… ▌所属 クラウド基盤本部 Necoチーム ▌趣味 l ワンコと散歩、ガーデニング、ドライブ 3 著書 韓国語翻訳版

Slide 4

Slide 4 text

コンテナの利⽤価値 学習の⽬標 ・どうしてIT業界とサイボウズはコンテナに注⽬するのか、 説明できるようになる。 ・コンテナを利⽤することで、ソフトウェア開発は、ど のように進化するのか、説明できるようになる。 4 第⼀部

Slide 5

Slide 5 text

はじめに、コンテナの利便性を体験 ▌WordPressをPCで起動してみよう。 l WordPressは,インターネットの全ウェブサイトの43%が利⽤するCMS (Content Management System:コンテンツ管理システム) l PHPのプログラムであるWordPressは、要求のあった記事をMySQLから取り出して、 HTMLを⽣成してブラウザに表⽰ 5 出典: https://kinsta.com/wordpress-market-share/ ブラウザ Web サーバー データベース サーバー WordPress MySQL ページを要求 コンテンツ を要求 コンテンツ を送信 ページを送信

Slide 6

Slide 6 text

マイPCにWordPressを起動してみよう︕ 6 git clone https://github.com/docker/awesome-compose cd awesome-compose/wordpress-mysql #ポート番号を変更 code compose.yaml # WordPressを起動 docker compose up -d • GitHub から git clone して、compose.yamlを編集して、WordPressを起動できる。 • このような Docker の機能は、開発環境をチームへ配布したり、開発の成果物をコンテ ナで共有するなど、いろいろな作業に適⽤可能。 起動までの⼿順 (Mac, Windows, Linux共通)

Slide 7

Slide 7 text

WordPressを起動するための compose.yaml 7 MySQL(MariaDB)のコンテナ をDocker Hubからプルして 起動 データ領域と認証情報をコン テナへ与える Composeファイルのリファレンス https://docs.docker.com/compose/reference/ WordPressのWeb 公開ポート番号は 8080へ変更する。 WordPressのコンテナを Docker Hubからプルして起動 接続先のMySQLのホスト名、 認証情報、Webサーバーの ポート番号をコンテナへ設定

Slide 8

Slide 8 text

Docker desktopのGUI画⾯ 8 WordPressのWeb 公開ポート番号は 8080へ変更する。 Docker desktop のGUI画⾯を併⽤すると便利です。

Slide 9

Slide 9 text

docker compose up から数分でWordPressが稼働する 9 ブラウザからアクセス http://localhost:8080/ 必要情報を設定して、ログインすると、 管理画⾯になるので、カスタマイズする。 Homeのアイコンクリックで、 公開⽤Web画⾯が表⽰

Slide 10

Slide 10 text

Docker Hub にアクセスして、 どんなコンテナが登録されているか確認しよう︕ 10 CPUアーキテクチャーの コンテナイメージが登録 されている。 LinuxとWindows のコンテナが登録 https://hub.docker.com/

Slide 11

Slide 11 text

Docker社が訴求する特徴的な3つの機能 Build コンテナに独⾃アプリのコードを追加して新たなイメージを作成 Share チームメンバーと共同作業するために、レジストリでイメージを共有 Run 開発と本番、オンプレとクラウドなど、様々な環境で簡単実⾏ 11 https://www.docker.com/

Slide 12

Slide 12 text

仮想サーバーとコンテナの⽐較 ▌ 仮想サーバーは、ハイパーバイザーとCPUの仮想化⽀援機能によって、⼀つの物理マシンを共有 ▌ コンテナは、カーネルの機能でプロセスを隔離して、アプリケーションにとって専有環境を提供 12 OSイメージを含むため、サイズが⼤きく、起動 に時間を要する。 コンテナは隔離されたプロセスのため、イメー ジのサイズが⼩さく、起動も早い。

Slide 13

Slide 13 text

コンテナのオーケーストレーション環境とは︖ ▌主な機能 l 本番サービスでコンテナを運⽤するプラットフォーム l 可⽤性、スケーラビリティ、可観測性、セキュリティなどを受け持つ ▌代表的なオーケストレーター l Kubernetes (主流であり、サイボウズの次世代プラットフォーム Neco) l Apache Mesos (Hadoop, Spark, Kafkaなどで利⽤) l Docker compose, swarm (主に開発とテスト⽤) 13

Slide 14

Slide 14 text

第⼀部 まとめ (コンテナの利⽤価値) ▌どうしてIT業界とサイボウズはコンテナに注⽬するのか︖ l OSS中⼼の開発スタイルに必要 (OSSの進化対応) l 継続的なアップデート (CICDの実践) l 安⼼と安全な⾼セキュリティなITサービス (脆弱性対応) ▌コンテナを利⽤することで、どのように進化するのか︖ l マイクロサービスアーキテクチャの推進 l 他社よりも早く、あらゆるニーズに答える、柔軟なサービス提供 14

Slide 15

Slide 15 text

コンテナを活⽤した開発 学習の⽬標 ・コンテナを利⽤した開発プロセスを理解する ・コンテナのビルドのためDockerfileを書ける ・コンテナの再利⽤ができる 15 第2部

Slide 16

Slide 16 text

Dockerの主な構成要素 ▌ Dockerクライアント l docker run/build/push などで、コマンドでDockerエンジンとユーザーを繋ぐUI ▌ Dockerエンジン(デーモン) l イメージ、コンテナ、ネットワーク、ボリュームなどDocker オブジェクトを管理 ▌ レジストリ l イメージが格納され共有に利⽤、パブリックと組織内プライベートがある ▌ イメージ l コンテナを作成するための⼿順を含む、読み取り専⽤のテンプレート ▌ コンテナ l イメージの実⾏可能なインスタンス 16 出典: https://docs.docker.com/get-started/overview/

Slide 17

Slide 17 text

コンテナの実⾏プロセスを体験しよう 17 Virtual Machine Linux Bin/libs Apps Docker Engine docker run hello-world Bin/libs Apps https://hub.docker.com/_/hello-world/ コマンド実⾏ イメージを ダウンロード Docker Hub 公式リポジトリ hello-world ① ② ③ ④メッセージ表⽰ macOS / Windows11 イメージ コンテナを⽣成して プロセスを実⾏

Slide 18

Slide 18 text

デモ1の内容 ▌コンテナイメージの取得 ▌コンテナの起動 ▌コンテナに⼊ってみる ▌ホストとのファイル共有 18 git clone https://github.dev.cybozu.co.jp/takara/docker101

Slide 19

Slide 19 text

よく使うDockerのサブコマンド ▌ run : コンテナの実⾏ ▌ stop : コンテナの停⽌ ▌ rm : コンテナの削除 ▌ ps : コンテナの確認 ▌ inspect : コンテナの詳細情報の取得 ▌ exec : コンテナ上でコマンドの実⾏ ▌ logs : コンテナのログを確認 ▌ build : コンテナイメージのビルド ▌ images : コンテナイメージの確認 ▌ rmi : コンテナイメージの削除 ▌ container prune : 停⽌コンテナの削除 ▌ image prune : 未使⽤イメージの削除 詳しくは docker --help 19

Slide 20

Slide 20 text

コンテナイメージの取得 20 # ローカルのコンテナイメージの表⽰ docker images # Docker Hubからコンテナイメージを取得する docker pull nginx # 再度、ローカルのコンテナイメージの表⽰ docker images

Slide 21

Slide 21 text

Webサーバーのコンテナの起動 21 # コンテナの起動 # -d: バックグラウンドで起動 # --name: コンテナに名前をつける(省略した場合は⾃動で名前がつく) # -p 8080:80: コンテナの80番ポートをホストの8080番ポートにバインド docker run -d --name mynginx -p 8080:80 nginx # 起動しているコンテナの確認 # コンテナの停⽌・削除 docker ps docker stop mynginx curl http://localhost:8080 docker rm mynginx docker logs mynginx

Slide 22

Slide 22 text

コンテナに⼊ってみる (コンテナ内のシェルと対話する) 22 # ubuntu-debugコンテナ上でbashを実⾏する # -i: STDINをオープンし続ける -t: 擬似端末を割り当てる # --rm: コンテナ終了時にコンテナを⾃動削除 docker run -it --rm quay.io/cybozu/ubuntu-debug:22.04 /bin/bash # いろんなコマンドを叩いて、コンテナ内のプロセスやファイルシステム、 # ネットワークの状態などを確認してみる ls hostname ip a ps aux

Slide 23

Slide 23 text

ホストとのファイル共有 23 # ホスト上で適当なHTMLファイルを作成 mkdir html touch . /html/index.html pwd # 絶対パスを取得 # ホストのhtmlをコンテナの/usr/share/nginx/htmlにバインド docker run -d --name mynginx -p 8080:80 ¥ -v <絶対パス>/html:/usr/share/nginx/html ¥ nginx:latest curl localhost:8080

Slide 24

Slide 24 text

コンテナのクリーンナップ(後⽚付け) ▌ docker ps -a で実⾏中と終了したコンテナをリスト ▌ 不要になったコンテナは docker rm 、または docker container prune で削除 24 $ docker ps –a # 終了コンテナも含めた全コンテナをリスト CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES dd5c68f55488 nginx:latest “/docker-entrypoint.…” About a minute ago Up About a minute mynginx 5dacebd03bfa hello-world "/hello" 6 minutes ago Exited (0) 6 minutes ago jolly_hypatia $ docker stop mynginx # コンテナ停⽌ mynginx $ docker rm mynginx # コンテナ削除 mynginx $ docker container prune # 不要コンテナの削除 WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Deleted Containers: dd5c68f55488aabbf69bf6c3cccdd7bf8341b311104c6137a478c54cb10ec6a6 5dacebd03bfaec641e0ac229ac39ea70a9bd5f5794da64b3dd5e50d80e1ca233 Total reclaimed space: 1.093kB

Slide 25

Slide 25 text

コンテナのクリーンナップ(後⽚付け つづき) ▌ コンテナとイメージを削除しても、ボリュームとビルドキャッシュが残って、領域が⼀ 杯になると dockerコマンドが動かなくなる。その時は以下の要領で整理する。 25 $ docker system df # Dockerデーモンが使っているストレージ量を表⽰ TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 5 1 1.254GB 1.254GB (99%) Containers 1 0 0B 0B Local Volumes 2 0 191.4MB 191.4MB (100%) Build Cache 12 0 132B 132B $ docker system prune –a # 不要なデータを削除 WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all images without at least one container associated to them - all build cache <以下省略> # 不要ボリュームの削除 $ docker volume ls $ docker volume prune $ docker volume rm wordpress-mysql_db_data

Slide 26

Slide 26 text

コンテナのライフサイクルとコマンドの関係 26 コンテナ イメージ ローカルリポジトリ 実⾏状態 docker run docker commit コンテナ 停止状態 docker kill docker stop コンテナ 終了/強制停⽌ docker start (テンプレート) (実⾏中) (停⽌中) コンテナ削除 docker rm イメージ削除 docker rmi docker ps 実⾏中コンテナリスト docker ps -a 停⽌状態を含むコンテナ イメージ レジストリサービス docker pull docker run docker images イメージリスト表⽰ (テンプレート) docker push docker logs ログ表⽰ Docker Hub、quay.io、ghcr.io プライベートレジストリ コンテナ実⾏

Slide 27

Slide 27 text

text ▌Dockerfileを元にコンテナのイメージができる コンテナを開発に利⽤するイメージ 27 OSライブラリ SWパッケージ アプリケーション (実⾏形式) Dockerエンジン Linux OS アプリ・コンテナ Dockerfile コンテナ レジストリ (ベースイメージ取得) ビルド アプリケーション ソースコード イメージ ローカル リポジトリ GitHub OSS リポジトリ docker build docker run アプリケーションの動作に必要なソフトウェア を揃えて、コンテナにパッケージする

Slide 28

Slide 28 text

シンプルなDockerfileの例 28 FROM ubuntu:xenial-20190222 RUN apt update && apt install figlet ADD ./message /message CMD cat /message | figlet Hello World ファイル名 Dockerfile.simple ファイル名 message (注意)このDockerfile.simpleは、真似してはいけない例です。 なぜ︖真似を勧めないのかこれから⾒ていきます。 FROM ベースイメージを指定(付け加える⼟台となるOS) RUN コンテナ上でコマンドを実⾏して、アプリやパッケージを追加 (figletコマンドを追加) ADD ファイルやディレクトリをコピー(ファイル messageをコンテナへコピー) CMD コンテナの起動時に実⾏するコマンド (messageファイルをfigletの標準⼊⼒へインプット) 各命令( FROM,RUN,ADD/COPY,CMD)は、レイヤーを作成する。 参考: Docker公式ドキュメント Dockerfile reference

Slide 29

Slide 29 text

コンテナのビルドと実⾏ 29 材料となるファイル ビルドの実⾏ イメージの確認 コンテナの実⾏ $ ls Dockerfile.simple message $ docker build -t test:1 . -f Dockerfile.simple [+] Building 15.1s (8/8) FINISHED => [internal] load .dockerignore => => transferring context: 2B <中略> => exporting to image => => exporting layers => => writing image sha256:6e1121ad0bf42c17e53c21227e2f20e95086 => => naming to docker.io/library/test:1 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE test 1 6e1121ad0bf4 7 seconds ago 150MB $ docker run test:1 _ _ _ _ __ __ _ _ | | | | ___| | | ___ ¥ ¥ / /__ _ __| | __| | | |_| |/ _ ¥ | |/ _ ¥ ¥ ¥ /¥ / / _ ¥| '__| |/ _` | | _ | __/ | | (_) | ¥ V V / (_) | | | | (_| | |_| |_|¥___|_|_|¥___/ ¥_/¥_/ ¥___/|_| |_|¥__,_|

Slide 30

Slide 30 text

コンテナイメージの履歴を確認 ▌ 「docker history」は、RUN,COPY等でUnionFSに追加されたレイヤーの履歴を表⽰ ▌ イメージに使われるUnionFSは、複数のファイルシステム のファイルやディレクトリを透過的に 重ねることができる技術。これにより複数のレイヤーで、単⼀のファイルシステムを形成する。 ▌ 同⼀ファイル名やディレクトリ名は、後から追加されたレイヤーが優先される。 30 $ docker history test:1 IMAGE CREATED CREATED BY SIZE 6e1121ad0bf4 21 minutes ago CMD ["/bin/sh" "-c" "cat /message | figlet"] 0B 21 minutes ago ADD ./message /message # buildkit 12B 21 minutes ago RUN /bin/sh -c apt update && apt install fig… 32.4MB 4 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B 4 years ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B 4 years ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B 4 years ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B 4 years ago /bin/sh -c #(nop) ADD file:c02de920036d851cc… 118MB FROMの ベースイメージ Dockerfileで 追加した層 コマンド「docker history」は、 イメージサイズが⼤きくなった時に、 原因を調べるのに便利じゃ

Slide 31

Slide 31 text

正しくDockerfileを書かなければならない ▌なんでDockerfileを正しく書く必要がある︖ l UnionFSで作られるイメージのサイズを適正に保つ ▌無駄に⼤きなコンテナイメージの問題 lストレージ容量、ネットワーク帯域の無駄な消費 lビルドやコンテナ起動の時間が⻑くなる l攻撃を受ける表⾯積(attack surface)が増える 31

Slide 32

Slide 32 text

正しいDockerfileを書くために ▌Dockerfileなどの「ベストプラクティス」を熟読 ▌忙しいから出来ないと感じる⼈はリントを使うと良い l Lintまたはlinter は、プログラミング エラー、バグ、スタイル エラー、疑わしい構造を判別す る静的コード分析ツール ▌Hadolint の実⾏例 https://github.com/hadolint/hadolint 32 $ docker run --rm -i hadolint/hadolint < Dockerfile.simple -:2 DL3027 warning: Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead -:3 DL3020 error: Use COPY instead of ADD for files and folders -:4 DL3025 warning: Use arguments JSON notation for CMD and ENTRYPOINT arguments Hadolintは「Dockerfile 作成のベスト プラクティス」のルールを適⽤してレポートする PS C:¥Users¥takara¥temp¥docker101¥lesson-3> cat .¥Dockerfile.simple | docker run --rm -i hadolint/hadolint Windowsの場合

Slide 33

Slide 33 text

Dockerfileの改善例 (Hadolintで指摘された) ▌ 出来る限り信頼できる最新のベースを選択 ▌ 使⽤するベースイメージ、パッケージは、バージョンを明記する ▌ RUNでは apt-getを使い、不要なモジュールをインストールしない、マメにキャッシュを消す ▌ COPY を使⽤する。単機能で透明性の⾼いため、⼀⽅ADDはエラー扱い ▌ CMDでは、シェル形式ではなく、JSON表記を⽤いる 33 FROM ubuntu:22.04 RUN apt-get update && apt-get install --no-install-recommends -y figlet=2.2.5-3 ¥ && apt-get clean ¥ && rm -rf /var/lib/apt/lists/* COPY ./message /message CMD ["cat","/message", "|", "figlet"] 最新latestではなくタグでバージョンを指定 apt-getの使⽤が推奨 依存関係だけをインストール ADDを使わない JSON表記にする バージョンを指定 ⾮対話型 キャッシュと 作業ファイル を消す

Slide 34

Slide 34 text

改善したDockerfileで再ビルド 34 $ docker build -t test:2 -f Dockerfile . [+] Building 1.3s (9/9) FINISHED => [internal] load .dockerignore => => transferring context: 2B => [internal] load build definition from Dockerfile => => transferring dockerfile: 254B => [internal] load metadata for docker.io/library/ubuntu:22.04 => [auth] library/ubuntu:pull token for registry-1.docker.io => [1/3] FROM docker.io/library/ubuntu:22.04@sha256:dfd64a3b4296d8c9b62aa3309 984f8620b98d87e47492599ee20739e8eb54fbf => [internal] load build context => => transferring context: 28B => CACHED [2/3] RUN apt-get update && apt-get install --no-install-recommends -y figlet=2.2.5-3 && apt-get clean && rm -rf /var/lib/apt/lists/* => CACHED [3/3] COPY ./message /message => exporting to image => => exporting layers => => writing image sha256:aa78b505a57cf265ab3ccd99e4ab6f144e9fef20866bcbb644 e6a6c17b83576d => => naming to docker.io/library/test:2

Slide 35

Slide 35 text

ベストプラクティスに従って作成したイメージの例 これによって、イメージのサイズを抑えることに加えて、コード量を減らすことで脆弱性が含まれる 可能性(攻撃の表⾯積︓attack surface)を減らすことができる。 35 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE test 2 568b4400e3f7 3 hours ago 79.4MB test 1 6e1121ad0bf4 4 hours ago 150MB $ docker history test:2 IMAGE CREATED CREATED BY SIZE 568b4400e3f7 3 seconds ago CMD ["cat" "/message" "|" "figlet"] 0B 3 seconds ago COPY ./message /message # buildkit 12B 3 seconds ago RUN /bin/sh -c apt-get update && apt-get ins… 1.56MB 7 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B 7 weeks ago /bin/sh -c #(nop) ADD file:c8ef6447752cab254… 77.8MB 7 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B 7 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B 7 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B 7 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B 32.4 → 1.56へ減少 118 → 77.8へ減少 改善後のtest:2では 半分近くまで減少

Slide 36

Slide 36 text

Aqua Trivyよる脆弱性検査結果 改善前の検査結果は重要度 Mediumが複数存在,画⾯に表⽰できないほど多くの脆弱性を検知、 改善後ではMediumレベルは無く、LowやNegligibleも減少した。 36 改善前 test:1 改善後 test:2 Anchore grypeコンテナの実⾏⽅法 検査結果 Total: 79 ,LOW: 40, MEDIUM: 39 検査 Total: 15 , LOW: 15 # trivy 脆弱性スキャンをコンテナで実⾏する⽅法 docker run -v /var/run/docker.sock:/var/run/docker.sock ¥ --rm aquasec/trivy image --no-progress <イメージ>:<タグ>

Slide 37

Slide 37 text

補⾜ 脆弱性について ▌ 「脆弱性」は、プログラムの不備を悪⽤される「情報セキュリティ上の弱点」 ▌ OSのライブラリやパッケージに含まれることもあり「開発者だけの責任ではない」 ▌ 潜在的な脆弱性を突いた新たなクラッキングの⼿⼝が「時間の経過ともに発⾒」 ▌ 開発当初は無くても、時間経過ととも⼿⼝が発⾒されるため「継続的に対策が必要」 37 参考︓ 総務省 国⺠のための情報セキュリティサイト 「脆弱性とは」

Slide 38

Slide 38 text

脆弱性検査ツールの紹介 ▌docker scan l Docker組込みのSnykの脆弱性スキャナ 無料プランで10回/⽉まで利⽤可能 l https://matsuand.github.io/docs.docker.jp.onthefly/engine/scan/ ▌Aqua Trivy l 脆弱性と設定ミスのスキャナー OSSプロジェクト l https://www.aquasec.com/products/trivy/ 他にも⾊々な脆弱性検査のサービスやOSSがあるので、探してみてください。 38 参考資料 Qiita コンテナ・セキュリティ⼊⾨ 脆弱性

Slide 39

Slide 39 text

Docker Desktopにも脆弱性検査の機能 39

Slide 40

Slide 40 text

text ▌レジストリサービスのリポジトリにpushすることで、他開発者と共有 開発したコンテナを共有する 40 OSライブラリ SWパッケージ アプリケーション (実⾏形式) Dockerエンジン Linux OS アプリ・コンテナ Dockerfile コンテナ レジストリ ビルド アプリケーション ソースコード イメージ ローカル リポジトリ GitHub OSS リポジトリ docker build アプリケーションの動作に必要なソフトウェア を揃えて、コンテナにパッケージする docker push

Slide 41

Slide 41 text

レジストリ登録⼿順 ▌ ログイン (docker login) l レジストリにログインする。⼀度ログインしておけばログアウトするまで維持される l Neco開発⽤レジストリはログインしなくても利⽤可能(外部と切り離された環境のため) ▌ タグ付け (docker tag) l ローカルのイメージ名にレジストリでの別名を付与 l ユーザー名は予めレジストリに登録しておく、Neco開発⽤レジストリでは事前登録不要 ▌ プッシュ (docker push) l レジストリでの別名を指定して実⾏ 41 docker login レジストリ:ポート番号 docker tag イメージ名[:タグ] レジストリ/ユーザー名/リポジトリ名[:タグ] docker push レジストリ/ユーザー名/リポジトリ名[:タグ]

Slide 42

Slide 42 text

イメージをレジストリに登録する実⾏例 42 登録イメージはココ *1 Neco 開発⽤プライベートレジストリ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE test 2 aa78b505a57c 21 minutes ago 79.4MB test 1 d7a4d820c31c 21 minutes ago 150MB # タグ付け (参考URL*1) $ docker tag test:2 registry-local.registry.stage0.cybozu-ne.co/takara/test:2 # レジストリへのプッシュ $ docker push registry-local.registry.stage0.cybozu-ne.co/takara/test:2 The push refers to repository [registry-local.registry.stage0.cybozu-ne.co/takara/test] adc8b1715e64: Layer already exists d66f12a09500: Pushed b8a36d10656a: Pushed 2: digest: sha256:660a9a34b90a26fb8f576083ac81e09bf44514c8b4e40a810f3f430301cea179 size: 946 # 登録の確認 (参考URL*2) $ curl -s https://registry-local.registry.stage0.cybozu-ne.co/v2/takara/test/tags/list {"name":"takara/test","tags":["2"]} *2 HTTP API V2 Docker Registry HTTP API V2 参考URL この部分は ⾃⾝の名前で置き 換えてください

Slide 43

Slide 43 text

サイボウズ Necoチームで開発しているコンテナ ▌レジストリ l https://quay.io/organization/cybozu ▌NecoチームのDockerfile l https://github.com/cybozu/neco-containers 43

Slide 44

Slide 44 text

第⼆部 まとめ ▌コンテナを利⽤した開発プロセスを理解する l ベースイメージにアプリを追加 l ビルド、実⾏、レジストリ登録 ▌コンテナのビルドのためDockerfileを書ける l レイヤー数やサイズを最⼩にする l 正しく記述するためにリントを活⽤ ▌コンテナの再利⽤で⽣産性アップ︕ 44

Slide 45

Slide 45 text

第3部 コンテナを活かすための知識 学習の⽬標 ・コンテナのベストプラクティスを知る ・マルチステージビルドと効果 ・Kubernetesでの運⽤のためのコンテナ要件 ・情報リンク集を知る 45 第3部

Slide 46

Slide 46 text

公式ドキュメントに書かれたベストプラクティス ▌Docker 開発のベスト プラクティス • https://docs.docker.com/develop/dev-best-practices/ ▌Dockerfile を作成するためのベスト プラクティス • https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ • https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html ▌セキュリティのベスト プラクティス • https://docs.docker.com/develop/security-best-practices/ 46 ⼀次情報は難しいけど 確信がある技術知識 になるのじゃ

Slide 47

Slide 47 text

「Docker 開発のベスト プラクティス」の要約 イメージが⼩さいほど、ネットワーク経由でのプルが⾼速になり、脆弱性にも有利、コ ンテナの開始時に起動が⾼速になる。 ▌ イメージを⼩さく保つための⽅法 l 「適切なベースイメージ」を選択、「マルチステージビルド」を使⽤ l 共通点が多いイメージは、「ベースイメージを共通化」する。共通的COPY/RUNは前の⽅へ l 「タグを活⽤」する (バージョン,⽬的,安定性など、世代や派⽣関係などを意味づけ) ▌ データの永続化 l コンテナにアプリの「データを保存しない」 l 「構成ファイル」や「機密情報」をコンテナに「保存しない」 ▌ テストとデプロイにCI/CDを使⽤ l ソースへの変更やプル リクエストを作成したりする時は「CI/CDパイプライン」を使⽤ 47

Slide 48

Slide 48 text

「Dockerfile を作成するためのベスト プラクティス」の要約 Dockerは、Dockerfileから、順番にコマンドを読んで、イメージを⾃動でビルドする。そこに記述 されたFROM, COPY/ADD, RUN, CMDによって、イメージに読み取り専⽤レイヤーが追加される。 ▌ 「コンテナは⼀時的な存在」であり、変更が必要な時は廃棄して再ビルド ▌ ワークロード特性でコンテナを分離する。原則「1アプリ/1コンテナ」 ▌ 保守が容易な Dockerfile の作成するために「適切なコマンドを利⽤」する ▌ 「マルチステージビルド」、「不要なパッケージを⼊れない」、「レイヤー数を最⼩に する」は前⾴と共通 48

Slide 49

Slide 49 text

「セキュリティのベスト プラクティス」の要約 脆弱性は⼀度発⾒されなければ安全ではなく、時間経過と共に、新たな脆弱性が発⾒され、対応が勧 告されます。そのため、過去に作られたコンテナイメージには、脆弱性が発⾒されている。また、⼩ さなコンテナは、総コード量が減るため、脆弱性のリスクが軽減される。 ▌ 「信頼できる提供元からの適切なベースイメージ」(保守されてるイメージ) ▌ 「マルチステージ ビルドの使⽤」 (コンテナをコンパクトにする) ▌ 「イメージの再構築」 (最新で脆弱性対応が進んだコードを利⽤) ▌ 「頻繁に脆弱性をチェック」 (過去はOKで、今は違うかも) 49

Slide 50

Slide 50 text

Dockerへ影響を与えている資料紹介 ▌The Twelve-factor App l SaaS Herokuの開発運⽤者の実践から得たメソドロジー(⽅法論) l Kubernetesなど多くのドキュメントからも参照 l Docker関連のベストプラクティスも、⼤きな影響を受けている ▌Brendan Burns, David Oppenheimerらの論⽂「Design patterns for container-based distributed systems」の要約 l Kubernetesの開発メンバーが書いた論⽂、Brendanは後にMicrosoft DEに就任 l Kubernetesのコンテナの実⾏単位 Podの有⽤性を説く l 単機能のコンテナを複数組み合わせる設計パターンを紹介 50

Slide 51

Slide 51 text

ベストプラクティスから「マルチステージビルド」を紹介 ▌ これにより、苦労なく⼤幅に中間レイヤーとファイルを削減できる l ビルド⽤コンテナとランタイム⽤コンテナを分割 l ビルドした実⾏形式をランタイム⽤コンテナへコピー 51 # Stage1: ビルド⽤コンテナ FROM quay.io/cybozu/golang:1.20.3.1_jammy AS build COPY main.go /work/main.go WORKDIR /work RUN CGO_ENABLED=0 go build -o server ./main.go # アプリをビルド # Stage2: ランタイム⽤コンテナ FROM scratch COPY --from=build /work/server /server # 実⾏形式をstage1からコピー EXPOSE 8000 ENTRYPOINT ["/server"]

Slide 52

Slide 52 text

マルチステージビルドと普通のビルド⽐較 ▌ マルチステージとシングルステージのDockerfileで、出来たイメージのサイズを⽐較 ▌ Dockerfile.multiは、ビルド⽤コンテナとランタイム⽤コンテナの2つのステージを利⽤ ▌ Dockerfile.singleは、ビルドしたコンテナを実⾏⽤にも利⽤ 52 # Stage1: ビルド⽤コンテナ FROM quay.io/cybozu/golang:1.20.3.1_jammy AS build COPY main.go /work/main.go WORKDIR /work RUN CGO_ENABLED=0 go build -o server ./main.go # Stage2: ランタイム⽤コンテナ FROM scratch COPY --from=build /work/server /server EXPOSE 8000 ENTRYPOINT ["/server"] # シングルステージ FROM quay.io/cybozu/golang:1.20.3.1_jammy COPY main.go /app/main.go WORKDIR /app RUN CGO_ENABLED=0 go build -o /app/server main.go EXPOSE 8000 ENTRYPOINT ["/app/server"] Dockerfile.multi (再掲) Dockerfile.single

Slide 53

Slide 53 text

マルチステージビルドの効果の確認2(サイズ) ▌ マルチステージとシングルステージのDockerfileで、出来たイメージのサイズを⽐較 ▌ マルチステージで出来たイメージ(test:3)は「6.62MB」、シングルステージでビルドした イメージ(test:4)は「1.04GB」の歴然の差が出る。 53 $ docker build –t test:3 –f Dockerfile.multi . <中略> $ docker images test:3 REPOSITORY TAG IMAGE ID CREATED SIZE test 3 70b0fcb4564d 8 hours ago 6.62MB $ docker build -t test:4 -f Dockerfile.single . <中略> $ docker images test:4 REPOSITORY TAG IMAGE ID CREATED SIZE test 4 1f915f98d2e1 25 minutes ago 1.04GB

Slide 54

Slide 54 text

マルチステージビルドの効果の確認3(レイヤー) ▌ マルチステージ(test:3)とシングルステージ(test:4)で出来たイメージのレイヤー数を⽐較 ▌ test:3は3レイヤー、test:4は29レイヤーとなり、劇的な削減となっていることが判る。 54 $ docker history test:3 IMAGE CREATED CREATED BY SIZE COMMENT 70b0fcb4564d 9 hours ago ENTRYPOINT ["/server"] 0B buildkit.dockerfile.v0 9 hours ago EXPOSE map[8000/tcp:{}] 0B buildkit.dockerfile.v0 9 hours ago COPY /work/server /server # buildkit 6.62MB buildkit.dockerfile.v0 $ docker history test:4 IMAGE CREATED CREATED BY SIZE 1f915f98d2e1 About an hour ago ENTRYPOINT ["/app/server"] 0B About an hour ago EXPOSE map[8000/tcp:{}] 0B About an hour ago RUN /bin/sh -c CGO_ENABLED=0 go build -o /ap… 67.6MB About an hour ago WORKDIR /app 0B About an hour ago COPY main.go /app/main.go # buildkit 271B 4 weeks ago CMD ["/bin/bash"] 0B 4 weeks ago RUN |2 TARGETARCH=amd64 GO_VERSION=1.20.3 /b… 0B 4 weeks ago WORKDIR /work 0B 4 weeks ago RUN |2 TARGETARCH=amd64 GO_VERSION=1.20.3 /b… 57.3MB <以下省略> 注意) quay.io/cybozu/golang:1.20.3.1_jammyは実⾏⽤に作られたイメージではない。

Slide 55

Slide 55 text

マルチステージビルドの効果の確認4(脆弱性) ▌ マルチステージとシングルステージで出来たイメージをtrivyで脆弱性を⽐較 ▌ マルチステージ(test:3)では脆弱性が検知されない。シングルステージ(test:4)では多数を検知 55 $ docker run -v /var/run/docker.sock:/var/run/docker.sock --rm aquasec/trivy image --no-progress test:3 2023-05-08T11:54:43.402Z INFO Need to update DB <中略> 2023-05-08T11:54:47.999Z INFO Number of language-specific files: 0 # 脆弱性の検知なし $ docker run -v /var/run/docker.sock:/var/run/docker.sock --rm aquasec/trivy image --no-progress test:4 2023-05-08T11:51:50.003Z INFO Need to update DB <中略> 2023-05-08T11:52:04.867Z INFO Detecting Ubuntu vulnerabilities... 2023-05-08T11:52:04.870Z INFO Number of language-specific files: 17 2023-05-08T11:52:04.870Z INFO Detecting gobinary vulnerabilities... 2023-05-08T11:52:04.875Z INFO Detecting gomod vulnerabilities... 2023-05-08T11:52:04.879Z INFO Detecting node-pkg vulnerabilities... test:4 (ubuntu 22.04) ===================== Total: 186 (UNKNOWN: 0, LOW: 116, MEDIUM: 67, HIGH: 3, CRITICAL: 0) <以下省略>

Slide 56

Slide 56 text

Kubernetesでの運⽤を前提とした Dockerコンテナに対する設計要件 シグナル処理 装備するべきインタフェース 56

Slide 57

Slide 57 text

text コンテナの停⽌コマンドとシグナル 57 コンテナ SIGTERM SIGKILL コンテナ内部 のプロセス 上位API 下位API Docker デーモン docker stop docker kill 終了要求 強制終了 SIGTERMを受信後、 DBアクセスがある場合など データを書き込み後に終了 SIGKILLは、実⾏中のプログラムを強 制停⽌する。そのため、終了処理す る猶予を与えない 正常終了 強制終了 Kubernetesで kubectl delete pod を実⾏した 場合、SIGTERMが送られるが、⼀定時間内 に停⽌しない場合は、SIGKILLで強制終了と なる。 終了処理が必要なコンテナの場合、 必ずSIGTERMの受信処理が必要となる。

Slide 58

Slide 58 text

text ▌ラッパースクリプトを利⽤する場合、execで起動する ▌execを⼊れないケースと⼊れたケースで⽐較 コンテナ内のプロセスが確実にシグナルを受信するために 58 $ cat wrapper.sh /a.out $ cat wrapper.sh exec /a.out $ docker exec a5fd91768450 ps -ax PID TTY STAT TIME COMMAND 1 pts/0 Ss+ 0:00 /bin/sh /wrapper.sh 7 pts/0 S+ 0:00 /a.out $ docker exec 056030d1d2e9 ps -ax PID TTY STAT TIME COMMAND 1 pts/0 Ss+ 0:00 /a.out ラッパーシェルに直接コマンドを書いたケース execを⼊れた書いたケース コンテナをビルド&起動後に、プロセスを確認 この場合、シグナルを受けるのはシェル a.out はPID = 1となりシグナルを受信できる

Slide 59

Slide 59 text

ここからは、 Kubernetesを勉強しな いと意味が解らない部 分があります。 今⽇は、こんな要件が ある事を記憶の⽚隅に 置いて頂ければ良いと 思います。 59

Slide 60

Slide 60 text

text ▌コンテナをKubernetesで運⽤する時、全てが必要ではありませんが、考慮があれば問題を回避できます。 ▌詳細は以降の各ページの参考URLで確認してください。 K8sで実⾏するコンテナが装備するべき I/F 概要 60 ポッド (コンテナ) SIGTERM SIGKILL 環境変数 標準出⼒ コンテナ ログ コンテナ起動 ログ 終了要求 強制終了 永続 データ 標準エラー出⼒ 引数 コンテナ終了 サービス ポート番号 ヘルスチェック 準備チェック 稼働チェック フック 開始イベント 終了イベント 設定 ファイル 終了ステータス 終了コード 成功 = 0 失敗 ゼロ以外 メモリ CPU時間 ネットワーク他I/O メトリックス 起動チェック ボリューム

Slide 61

Slide 61 text

K8sで実⾏するコンテナが装備するべきI/F 「コンテナ起動」 ▌コンテナの外部から動作条件などを与えることで、コンテナの再利⽤性 を⾼める ▌環境変数は「ConfigMap」,「Secret」で環境から取得 ▌コンテナの起動引数はYAMLにベタ書きできる ▌Kubernetes Docsの参考URL l コンテナの環境変数の定義 l ConfigMap and Pods l Secrets l Define a Command and Arguments for a Container 61

Slide 62

Slide 62 text

K8sで実⾏するコンテナが装備するべきI/F 「ヘルスチェック」 ▌Kubernetes には3つのヘルスチェックがある l Liveness Probe デッドロック状態を検知してコンテナを再スタート l Readiness Probe コンテナが要求トラフィックを受け⼊れられる状態を検知 l Startup Probe コンテナアプリケーションの起動が完了したかを認識 ▌コンテナは、必要に応じて、これらのプローブに対応する機能を実装 ▌Kubernetes Docsの参考URL l Liveness Probe、Readiness ProbeおよびStartup Probeを使⽤する l Podのライフサイクル 62

Slide 63

Slide 63 text

K8sで実⾏するコンテナが装備するべきI/F 「コンテナ終了」 ▌Kubernetes でもコンテナの終了要求はシグナルで伝えられる l SIGTERM 終了要求としてコンテナランタイムは各コンテナのメインプロセスに TERMシグナルを送信、猶予時間として30秒が与えられる l SIGKILL 猶予時間を超過した時はSIGKILLで強制終了 ▌コンテナはSIGTERMを受けて、必要な処理を終えてEXITしなければなら ない。 ▌Kubernetes Docsの参考URL l Podのライフサイクル Podの終了 63

Slide 64

Slide 64 text

K8sで実⾏するコンテナが装備するべきI/F 「サービス」 ▌ポッド(コンテナ)のサービスを公開するためにポート⽤いる ▌ポッド停⽌でもIPアドレスが変わらない「サービス」を作成 ▌「サービス」の名前とIPアドレスは、K8s内部DNSと環境変数で提供 ▌コンテナをビルドするDockerfileにEXPOSEでポート番号を明⽰する ▌参考URL l Docker docs EXPOSE l Kubernetes docs サービスとアプリケーションの接続 l Kubernetes docs サービス 64

Slide 65

Slide 65 text

K8sで実⾏するコンテナが装備するべきI/F 「フック」 ▌Kubernetesはコンテナに「ライフサイクルフック」を提供、対応するラ イフサイクルフックが実⾏されたときにハンドラに実装されたコードを 実⾏ l PostStart フックはコンテナが作成された直後に実⾏ l PreStop 管理イベントが原因でコンテナが終了する直前に呼び出される ▌コンテナは必要に応じて、フックのハンドラを実装 ▌Kubernetes Docsの参考URL l コンテナライフサイクルフック 65

Slide 66

Slide 66 text

K8sで実⾏するコンテナが装備するべきI/F 「ボリューム」 ▌ コンテナがクラッシュまたは停⽌すると、コンテナの実⾏中に、コンテナ内部で作成/変更されたファ イルは失われる。また、複数のコンテナが ファイルを共有する必要があるケースもある。これらの課題 を解決するために、ボリュームが⽤いられる。 l ボリュームには複数の種類があり、設定ファイルや秘密データは、ConfigMapやSecretをボ リュームとして読取り専⽤でマウントすることができる。 l アプリはコンテナ内部にファイルを書くべきではない。代わりとして永続ボリュームを⽤いる l コンテナの開発時には、Docker Volume や Bind mount を利⽤する。 ▌ Kubernetes Docsの参考URL l ボリューム l 永続ボリューム ▌ Docker Docsの参考URL l Volumes l Bind mounts 66

Slide 67

Slide 67 text

K8sで実⾏するコンテナが装備するべきI/F 「終了ステータス」 ▌終了コードの種類 l Exit Code = 0 : Kubernetesでは正常終了 l Exit Code = 1 : アプリの異常終了 l 問題判別に役⽴つExit Codeは参考URLを参照 ▌コンテナ上のアプリは終了コードを管理しなければならない ▌参考URL l Kubernetes Pod In CrashLoopBackOff State l Understanding Docker Container Exit Codes 67

Slide 68

Slide 68 text

K8sで実⾏するコンテナが装備するべきI/F 「ログ」 ▌コンテナ化されたアプリケーションで、最も簡単で最も採⽤されて いるロギング⽅法は、標準出⼒と標準エラー出⼒への書き込み ▌コンテナは、ログを永続ボリュームに書き出すのではなく、標準出 ⼒と標準エラー出⼒へ書き出す ▌参考URL l ロギングのアーキテクチャ 68

Slide 69

Slide 69 text

K8sで実⾏するコンテナが装備するべきI/F 「メトリックス」 ▌ Kubernetesではクラスタ全体のCPU、メモリ、ファイルシステムなどの使⽤率 をPrometheusで管理 ▌ コンテナのアプリケーションで、資源の消費状況を監視したい場合は、 GrafanaとPrometheusを利⽤ ▌ ポッドのコンテナがメモリ使⽤制限容量より多く使⽤した場合、強制停⽌とな り、ステータスにOOMKilled(終了コード137)が記録 ▌ コンテナの資源使⽤量はGrafanaで⾒れるが、メモリ消費量はアプリで管理し なければ、OOMKilled が発⽣することもある ▌ 参考URL l リソースメトリクスパイプライン l コンテナおよびPodへのメモリーリソースの割り当て 69

Slide 70

Slide 70 text

第3部 まとめ ▌コンテナ開発やDockerfile作成のベストプラクティスは重要 ▌マルチステージビルドを実践すると、軽量化と脆弱性低減 ▌ラッパーシェルでexecを利⽤、シグナルを確実に受けるため ▌コンテナをKubernetesで運⽤するための9つのI/F要件 70

Slide 71

Slide 71 text

参考資料 71

Slide 72

Slide 72 text

サイボウズ社内のドキュメント ▌ コンテナイメージの管理 https://github.com/cybozu-private/neco-users-wiki/blob/main/ja/howto_container_image.md ▌ コンテナイメージ運⽤ポリシー https://github.com/cybozu-private/neco-wiki/blob/main/docs/policy_container_image.md ▌ コンテナイメージの管理⽅法 https://github.com/cybozu-private/neco- wiki/blob/main/docs/procedure_container_management.md ▌ Containerd Clients https://github.com/cybozu-private/neco-wiki/blob/main/docs/tutorial_containerd_clients.md ▌ Dockerfile Howto https://github.com/cybozu-private/neco-wiki/blob/main/docs/dockerfile.md ▌ Docker Guide http://wiki.dev.cybozu.co.jp/display/DEV/Docker%20Guide 72

Slide 73

Slide 73 text

参考情報1 ▌ Docker: Up & Running, 2nd Edition ▌ 分散システムデザインパターン ▌ Software Design 2019年6⽉号 「IT業界ビギナーのためのDocker+k8s⼊⾨講座」 ▌ Dockerfileを改善するためのBest Practice 2019年版 ▌ Dockerfileを書くためのベストプラクティス解説編 ▌ Base Image Journey 2018 ▌ Best practices for building containers ▌ Best Practices for Operating Containers ▌ The Twelve-Factor App ▌ コンテナ技術⼊⾨ - 仮想化との違いを知り、要素技術を触って学ぼう 73

Slide 74

Slide 74 text

参考資料 2 (過去に⾼良が書いたQiitaの関連記事) ▌設計関連 l Kubernetes導⼊にあたり知っておきたいコンテナの基礎知識(要約) l コンテナ・デザイン・パターンの論⽂要約 l 12FactorをKubernetesのアプリ開発へ適⽤するコメント ▌セキュリティ関連 l コンテナ・セキュリティ⼊⾨ 脆弱性 l コンテナ・セキュリティ⼊⾨ と Kubernetes l コンテナ開発のセキュリティとOpenShift特有のガイド 74

Slide 75

Slide 75 text

補⾜資料 75 本⽇は説明しませんが、本編の理解に役だてばと思い添付しました。

Slide 76

Slide 76 text

コンテナの開発環境 DockerとPodman ▌コンテナを開発するためのソフトウェア 76 Docker社が開発した。3つの機能がある。 ・イメージのビルド(⽣成) ・イメージからの展開とコンテナとして実⾏ ・イメージの共有 他のファミリー製品 compose / swarmなどがある。 Red Hat社が買収したCoreOS社が開発 ・Dockerコマンド互換 ・デーモンレス、Dockerではバックエンドの常駐プロセス Dockerd が実⾏を担うが、podmanでは常駐プロセス不要 ・他にファミリー製品 buildahなどがある。

Slide 77

Slide 77 text

Docker/Podman と コンテナランタイム ▌レジストリからイメージをダウンロード、ディスク上に展開 ▌ルートファイルシステムとしてコンテナを起動する。 77 コンテナ containerd client runc runc ConMon コンテナ containerd-shim レジストリ レジストリ コマンド コマンド

Slide 78

Slide 78 text

コンテナランタイム (実⾏環境) ▌Kubernetesでコンテナを実⾏するために使⽤されるもの 78 Docker社が開発、Dockerd から分離されCNCFへ寄贈さ れた。多くのクラウドのKubernetesサービスで利⽤され、 デファクト・スタンダードになっている。 Red Hat、IBM、Intel、SUSEが、Kubernetes⽤のコンテ ナランタイムとして開発したが、その後CNCFへ寄贈され た。Red Hat社のOpenShiftで利⽤される。 OCIが開発するLinuxコンテナを⽣成するコマンド。OCI には⼤⼿IT企業が出資しており、ContainerdやCRI-Oに よって実⾏される。 ノードのOS コンテナ ランタイム コンテナ オーケストレーター Kubernetes

Slide 79

Slide 79 text

コンテナランタイムの内部構造 ▌ポッドとコンテナは、最終的にruncコマンド実⾏ 79 Kubelet コンテナ マネージャー コンテナ ランタイム kube-apiserver kubectl Container Pod shims CRI OCI準拠 containerd, CRI-O, Dockerd Linuxコンテナでは runc が⼀般的、 Windows コンテナは runhcs.exeとなる。 また、Kataの場合はkata-runtime。 Container Registry Service イメージのプル 上位コンテナ ランタイム 下位コンテナ ランタイム OCI準拠 (常駐プロセス) (コマンド) Kubernetes では containerd-shim OpenShift では ConMan

Slide 80

Slide 80 text

業界標準 CRIとOCI 80 CRI OCI CRI (Container Runtime Interface)は、kubelet がさまざまな コンテナー ランタイムを使⽤できるようにするプラグイン イン ターフェイスです。通信プロコトルとしてgRPCが使われています。 https://kubernetes.io/docs/concepts/architecture/cri/ https://opencontainers.org/ CCI (Open Container Initiative)は、コンテナのフォーマットなど の業界標準を作成するために設⽴された。この業界標準には、ラン タイム仕様 (runtime-spec)、イメージ仕様 (image-spec)、ディ ストリビューション仕様 (distribution-spec) の 3 つの仕様が含ま れています。

Slide 81

Slide 81 text

runc は、Linux機能を活⽤するコマンド ▌ 「runc」はOCI仕様 に従って開発されたリファレンス実装 ▌ 以下の表は「runc」がコンテナを実現する3⼤Linux技術 81 機能名 概 要 UnionFS (オーバーレイファイルシステム) 複数の断⽚的なピースを重ねて⼀つのファイルシステムとして利⽤できるため、オー バーレイファイルシステムとも呼ばれる。コンテナのベースイメージにファイルを重ね て追加する機能は、UnionFSの改良型のOverlay2が推奨されている。 コンテナを更新する場合には、この技術によって差分だけを転送すれば良く、ネット ワークの帯域節約と、コンテナ起動の⾼速化に寄与している。runcはOverlay2などに よって展開されたrootファイルシステムでコンテナを⽣成する。 Linux Namespaces (Linux名前空間) カーネルの名前空間に割り当てられたプロセスは、他の名前空間のプロセスから隔離 される。名前空間には次に挙げる8つのタイプがある。 マウント(mnt)、プロセスID(pid)、ネットワーク(net)、プロセス間通信(ipc)、ドメ インとホスト名(UTS)、ユーザーID(user)、コントロールグループ(cgroup)、時間 (Time)。 これらを組み合わせて、プロセスを他のプロセス群から隔離することで、コンテナを 実現している。コンテナのホストとなるLinuxの/procのファイルにプロセスIDごとに 属する名前空間の情報が集約される。 Linux cgroups (コントロールグループ) コントロールグループ(cgroups)は、Linuxカーネルの機能で、リソースの使⽤制限、 CPU、メモリ、ディスクI/O、ネットワークなどの資源の隔離、使⽤制限、使⽤量計測 を実施する。 この機能により、コンテナのメモリやCPUの使⽤量上限を設定できる。⼀つのLinux OSに複数のコンテナを稼働させ、共存影響を抑えることができる。

Slide 82

Slide 82 text

内部構造 Containerd ▌ Docker社からCNCFへ寄贈されたContainerdは様々なモジュールを差し替え可能な構造 82 containerd-shim Runtime runc Google Cloud Platform docker IBM Cloud Microsoft Azure Alibaba Cloud AWS Cloud Foundry Rancher CRI Runtime containerd client Kubelet Docker Engine containerd client BuildKit containerd client ctr containerd client CRI API GRPC API Service containerd API Metrics API Core Backend Containerd クライアント runhcs kata Firecracker gVisor v2 shim client Windows / Linux オペレーティングシステム コンテナ プラットフォーム Containerd サーバー gRPC OCI準拠 コンテナ⽣成 コマンド Services Metadata Content Store Snapshotter overlay btrfs Container Registry Service イメージのDL イメージをOS上に展開 コンテナとして 隔離プロセスを実⾏ コンテナの実⾏要求

Slide 83

Slide 83 text

内部構造 CRI-O ▌CRI-Oは Containerdに⽐べるとプリミティブな構造(軽量) 83 特徴 ・Red Hat社のサポート ・単純な構造により攻撃の表⾯積を 減らすことができる。 ・最終的にruncを利⽤する

Slide 84

Slide 84 text

END 84