Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PythonにとってのよりよいDockerfileを考える
Search
RevComm_inc
February 07, 2023
Technology
7
8k
PythonにとってのよりよいDockerfileを考える
2022年8月に社内のTechTalkで発表したスライドです。
「良いコンテナイメージ」に関する考察とPythonを例にしたDockerfileのサンプルを示します。
RevComm_inc
February 07, 2023
Tweet
Share
More Decks by RevComm_inc
See All by RevComm_inc
“駆け出しPlatformチーム"の立ち上がりとこれから
revcomm_inc
0
48
Company Deck -English-
revcomm_inc
1
71
2024-02-07 ソフトウェアエンジニアリングの枠を超えて:テックブログ運営で見つけた自分の役割(DevRel/Tokyo #89 〜テックブログ運営〜)
revcomm_inc
0
46
エンジニア不足の中で どう技術的負債と向き合ったのか RevComm Research の場合 -
revcomm_inc
5
8.7k
Feature Flagについて本気出して考えて実践してみた
revcomm_inc
6
4.5k
快適なテスト体験を実現する、Djangoのテスト思想と工夫
revcomm_inc
0
1.5k
Djangoの特徴とRevCommにおける選定理由
revcomm_inc
1
800
会社紹介資料/Company Deck
revcomm_inc
3
42k
エンジニア向け_会社説明資料/Company Deck for Engineers
revcomm_inc
2
32k
Other Decks in Technology
See All in Technology
なぜCodeceptJSを選んだか
goataka
0
160
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
160
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
2
110
OpenAIの蒸留機能(Model Distillation)を使用して運用中のLLMのコストを削減する取り組み
pharma_x_tech
4
560
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
.NET 9 のパフォーマンス改善
nenonaninu
0
900
Amazon VPC Lattice 最新アップデート紹介 - PrivateLink も似たようなアップデートあったけど違いとは
bigmuramura
0
190
MLOps の現場から
asei
6
640
20241214_WACATE2024冬_テスト設計技法をチョット俯瞰してみよう
kzsuzuki
3
450
サイボウズフロントエンドエキスパートチームについて / FrontendExpert Team
cybozuinsideout
PRO
5
38k
re:Invent 2024 Innovation Talks(NET201)で語られた大切なこと
shotashiratori
0
310
Storage Browser for Amazon S3
miu_crescent
1
140
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
How GitHub (no longer) Works
holman
311
140k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Writing Fast Ruby
sferik
628
61k
Docker and Python
trallard
42
3.1k
How to Ace a Technical Interview
jacobian
276
23k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
98
Gamification - CAS2011
davidbonilla
80
5.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
Transcript
Copyright © 2022 RevComm Inc. よりよいDockerfileを考える ~Pythonの実例とともに~ RevComm Shota Kokado
Copyright © 2022 RevComm Inc. contents 1. はじめに 2. “よい
Dockerfile” とは 3. Let’s practice! 4. 実践事例の紹介
Copyright © 2022 RevComm Inc. はじめに 3 この資料の想定読者 • コンテナ技術に入門済みの人
• Dockerfile を書いたことがある人 • Web アプリケーション開発者(インタプリタ言語)
Copyright © 2022 RevComm Inc. はじめに 4 この資料の想定読者 • コンテナ技術に入門済みの人
• Dockerfile を書いたことがある人 • Web アプリケーション開発者(インタプリタ言語) この資料で話さないこと • コンテナとは何か?コンテナ技術の仕組み • ML/DL、バッチ処理用途のワークロード • コンパイル言語向けのこと(Java, Go, Rust) ◦ …Dockerfile の戦略が異なってくる (alpine とか distroless とか)
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 5
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 6 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 • 開発利便性 • 可搬性 / セキュリティ
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 7 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン (VM) と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 • 可搬性 / セキュリティ
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 8 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 9 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない ⇒Python アプリケーションを想定した実例とともに深堀り
Copyright © 2022 RevComm Inc. Let’s practice! 10
Copyright © 2022 RevComm Inc. 前提 11 • Django を動かすだけの簡単なアプリケーションを想定
• uWSGI でサーバー起動するまでを目標 JSON で応答を返す
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 12
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 13
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 14 ソースコード変更の度に「pip install …」が実行される
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する 開発利便性 - ビルド時キャッシュを活用する(1/2) 15 ソースコード変更後は 7行目から開始
Copyright © 2022 RevComm Inc. • 先頭で COPY ./ ./
をしない ◦ docker build で毎回(≒ソースコードを書き換える度)初めからになってしまう(= キャッシュを活用できない) ◦ ビルド過程で必要となる requirements.txt などを先に配置する ◦ パッケージマネージャを使用する場合 開発利便性 - ビルド時キャッシュを活用する(1/2) 16 • Pipenv ※以降、Pipenv を使用する前提のサンプルとする • Poetry
Copyright © 2022 RevComm Inc. • 必要な定型処理を先に実行する ◦ パッケージのインストールを先に行う 開発利便性
- ビルド時キャッシュを活用する(2/2) 17
Copyright © 2022 RevComm Inc. • 必要な定型処理を先に実行する ◦ パッケージのインストールを先に行う 開発利便性
- ビルド時キャッシュを活用する(2/2) 18 Pipfile / Pipfile.lock を変更した場合、 直後のビルドは7行目から開始する
Copyright © 2022 RevComm Inc. “よい Dockerfile” とは 19 コンテナイメージにとって重要な性質(抜粋)
参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. “可搬性” (Portability) … コンテナイメージを軽量に保つことで複数のホスト・基盤上で共有しやすくする。 軽量化には不要なパッケージ・ライブラリを含めないことが重要。結果、セキュリティ向上につながる。
可搬性 / セキュリティ 20
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 21
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • 同じ命令は可能な限りまとめる レイヤの数を最小にする > RUN
、 COPY 、 ADD 命令のみレイヤを作成します。他の命令では、一時的な中間イメージ(temporary intermediate images)を作成し、構築時の容 量は増えません。 1. RUN 可搬性 / セキュリティ (1/2) - レイヤの数は最小に 22 2. COPY 3. ADD ※COPY が推奨される
Copyright © 2022 RevComm Inc. • 同じ命令は可能な限りまとめる レイヤの数を最小にする > RUN
、 COPY 、 ADD 命令のみレイヤを作成します。他の命令では、一時的な中間イメージ(temporary intermediate images)を作成し、構築時の容 量は増えません。 1. RUN 可搬性 / セキュリティ (1/2) - レイヤの数は最小に 23 2. COPY 3. ADD ※COPY が推奨される 1行目の中間レイヤーを保持するため 3-4行目はイメージサイズ削減に効果が無い
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 24
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • ベースイメージ ◦ “buster” イメージを使っていませんか?(python:3.x-buster、python:3.x-slim-buster)
◦ No!最新は “bullseye” です(= Debian 11.0) ※2022年11月時点 ◦ ベースイメージには debian バージョンを指定しなくても良いかも(alias があるので) ▪ python:3.10.8 = python:3.10.8-bullseye ▪ python:3.10.8-slim = python:3.10.8-slim-bullseye ベースイメージとパッケージを最新化する 25
Copyright © 2022 RevComm Inc. • ベースイメージ ◦ “buster” イメージを使っていませんか?(python:3.x-buster、python:3.x-slim-buster)
◦ No!最新は “bullseye” です(= Debian 11.0) ※2022年11月時点 ◦ ベースイメージには debian バージョンを指定しなくても良いかも(alias があるので) ▪ python:3.10.8 = python:3.10.8-bullseye ▪ python:3.10.8-slim = python:3.10.8-slim-bullseye • パッケージ ◦ Docker 公式ドキュメントで「Dockerfile の中で apt-get upgrade しないように」と書かれていたのは昔の話 ◦ OWASP が提唱して、Docker コミュニティも修正済み ◦ Not installing security updates is bad advice by itamarst · Pull Request #614 · OWASP/CheatSheetSeries ◦ Stop telling people not to install security updates by itamarst · Pull Request #12571 · docker/docs ◦ パッケージは必ず最新化しましょう! ◦ 定期的にイメージを更新しましょう! ベースイメージとパッケージを最新化する 26
Copyright © 2022 RevComm Inc. (再掲) “よい Dockerfile” とは 27
コンテナイメージにとって重要な性質(抜粋) 参考: Dockerfile のベスト・プラクティス — Docker-docs-ja 20.10 ドキュメント • ※“コンテナ” 自体の理解 ◦ 仮想マシン(VM)と同じ使い方をしない ◦ (原則) 1コンテナ1プロセス • 開発利便性 ◦ ビルド時キャッシュを活用する • 可搬性 / セキュリティ ◦ .dockerignore で除外 ◦ レイヤの数は最小に ◦ ベースイメージとパッケージを最新化する ◦ 不要なパッケージをインストールしない
Copyright © 2022 RevComm Inc. • デフォルトのベースイメージには無駄なパッケージが(非常に)多い ⇒slim イメージを使いましょう •
slim イメージには gcc などビルドツール群が含まれないため、Python ライブラリをビルドできない場合がある ⇒マルチステージビルドを使う ◦ slim イメージに gcc をインストールするのは 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 28
Copyright © 2022 RevComm Inc. ここまでの整理 • slim イメージを使用する ◦
Python ライブラリの準備を “not slim イメージ” で行う (マルチステージビルド) 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 29
Copyright © 2022 RevComm Inc. ここまでの整理 • slim イメージを使用する ◦
Python ライブラリの準備を “not slim イメージ” で行う (マルチステージビルド) • 課題 ◦ パッケージマネージャー (Pipenv / Poetry) をアプリケーションに含めたくない ◦ dev-packages (テスト用ツールなど)を本番用イメージから分離した ▪ CI では dev-packages を使いたい 可搬性 / セキュリティ (2/2) - 不要なパッケージをインストールしない 30 アプリケーション自体に Pipenv は要らない (普通は)
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 31 こちらでも見れます
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 32 FROM [base image] AS [stage name] という形式 1つの FROM 命令のブロックが1ステージと対応
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 33 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv が不要となる
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 34 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 35 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意 3. ステージ: base ◦ 最終的なアプリケーション用の環境をセットアップ ◦ 必要なパッケージをインストール ◦ ※一般ユーザーを作成、スイッチなど(割愛) libpq5: PostgreSQL 接続に必要 libxml2: uWSGI 実行に必要
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 36 1. ステージ: export ◦ requirements.txt 形式のライブラリ一覧を生成する ◦ ⇒後続ステージにて Pipenv 不要となる 2. ステージ: builder / dev-builder ◦ requirements.txt を元にライブラリを準備する ◦ COPY --from=[stage name] … でステージ間でファイルを受け取る ◦ prod 用、dev 用の2通りを用意 3. ステージ: base ◦ 最終的なアプリケーション用の環境をセットアップ ◦ 必要なパッケージをインストール ◦ ※一般ユーザーを作成、スイッチなど(割愛) 4. ステージ: dev / prod ◦ Python ライブラリをインストール ◦ ソースコードを配置 ◦ ※dev / prod で CMD を分ける、など適宜 ◦ docker build --target [stage-name] .... でビルド対象ステージを 指定する
Copyright © 2022 RevComm Inc. • 結論 可搬性 / セキュリティ
(2/2) - 不要なパッケージをインストールしない 37
Copyright © 2022 RevComm Inc. 実践事例の紹介 38
Copyright © 2022 RevComm Inc. • とあるマイクロサービスに対して実践したところ、大幅に効果があった Before 実践事例の紹介 39
Copyright © 2022 RevComm Inc. • とあるマイクロサービスに対して実践したところ、大幅に効果があった Before 実践事例の紹介 40
①slim イメージを使っていない ②アプリケーション起動が root ユーザー
Copyright © 2022 RevComm Inc. After 実践事例の紹介 41 ①slim イメージを使用するように変更。
builder ステージでライブラリをでインストール・ビルドし、 runner ステージで利用。 ①一般ユーザーでアプリケーションを起動するように変更。 ※80番ポートを起動できないためポート番号も変更。
Copyright © 2022 RevComm Inc. • 開発利便性と軽量性/セキュリティ は両立できる(相反する性質ではない) • なるべく
slim イメージを使用しましょう • マルチステージビルドを活用することで「アプリケーションに必要十分な環境」が作りやすくなる ◦ 開発 / 本番用イメージを同一 Dockerfile で管理できる(DRY 原則を保てる) ※必要に応じて Dockerfile を分離して可読性を維持する(要はバランス) リンク • サンプルコード: GitHub revcomm/public-slide-docker-multistage-build-for-python ◦ dev コンテナ: ユニットテスト実行 ◦ prod コンテナ:アプリケーション起動、動作確認 • 仕事でPythonコンテナをデプロイする人向けのDockerfile (1): オールマイティ編 | フューチャー技術ブログ • 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog まとめ 42
Copyright © 2022 RevComm Inc. Have a good container life!
43