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
7.6k
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
30
Company Deck -English-
revcomm_inc
0
59
2024-02-07 ソフトウェアエンジニアリングの枠を超えて:テックブログ運営で見つけた自分の役割(DevRel/Tokyo #89 〜テックブログ運営〜)
revcomm_inc
0
40
エンジニア不足の中で どう技術的負債と向き合ったのか RevComm Research の場合 -
revcomm_inc
4
5.8k
Feature Flagについて本気出して考えて実践してみた
revcomm_inc
5
3.9k
快適なテスト体験を実現する、Djangoのテスト思想と工夫
revcomm_inc
0
1.4k
Djangoの特徴とRevCommにおける選定理由
revcomm_inc
1
760
会社紹介資料/Company Deck
revcomm_inc
3
37k
エンジニア向け_会社説明資料/Company Deck for Engineers
revcomm_inc
2
29k
Other Decks in Technology
See All in Technology
フルカイテン株式会社 採用資料
fullkaiten
0
36k
10分でわかるfreee エンジニア向け会社説明資料
freee
18
520k
IaC運用を楽にするためにCDK Pipelinesを導入したけど、思い通りにいかなかった話
smt7174
1
110
CAMERA-Suite: 広告文生成のための評価スイート / ai-camera-suite
cyberagentdevelopers
PRO
3
270
Emacs x Nostr
hakkadaikon
1
150
[AWS JAPAN 生成AIハッカソン] Dialog の紹介
yoshimi0227
0
150
新卒1年目が挑む!生成AI × マルチエージェントで実現する次世代オンボーディング / operation-ai-onboarding
cyberagentdevelopers
PRO
1
160
Jr. Championsになって、強く連携しながらAWSをもっと使いたい!~AWSに対する期待と行動~
amixedcolor
0
190
신뢰할 수 있는 AI 검색 엔진을 만들기 위한 Liner의 여정
huffon
0
300
プロダクトチームへのSystem Risk Records導入・運用事例の紹介/Introduction and Case Studies on Implementing and Operating System Risk Records for Product Teams
taddy_919
1
170
Nix入門パラダイム編
asa1984
2
200
ネット広告に未来はあるか?「3rd Party Cookie廃止とPrivacy Sandboxの効果検証の裏側」 / third-party-cookie-privacy
cyberagentdevelopers
PRO
1
130
Featured
See All Featured
Done Done
chrislema
181
16k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
228
52k
4 Signs Your Business is Dying
shpigford
180
21k
GitHub's CSS Performance
jonrohan
1030
460k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Fireside Chat
paigeccino
32
3k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Mobile First: as difficult as doing things right
swwweet
222
8.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