Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
DockerCon SF19 で発表の、基礎→マルチ・ステージ・ビルド→最新動向まで
Sakura Internet, Inc.
Masahito Zembutsu @zembutsu
Docker Meetup Kansai #3 #dock...
DockerCon SF19 での発表に基づく内容
• Dockerfile Best Practices
https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices
2...
このスライドは何?
3
⚫ DockerCon 19 で発表された人気シリーズ
“Best Practices” を日本訳+解説の追加。
⚫ Dockerfile の改善を通して、現在利用できる
マルチ・ステージ・ビルドや BuildKit 紹...
Dockerfileのベストプラクティス
• "Best practices for writing Dockerfiles"
https://docs.docker.com/develop/develop-images/dockerfile_...
Dockerfile解説スライドもご覧ください
• ベストプラクティス日本語版に解説・図解を加えたバージョンを作りました
5
https://www.slideshare.net/zembutsu/explaining-best-practic...
Dockerfile とは?
6
ド ッ カ ー フ ァ イ ル
Dockerfile
• Docker は Dockerfile から命令を読み込み、イメージを自動構築
• テキスト形式のドキュメント
• docker build / docker image build で Dockerfile を読み込...
BuildKit: builder v2
• docker build は「イメージ・キャッシュ」があるため、素早く開発できる
• しかし、いくつかの制限があったため、buildKit プロジェクトで根本的に構築
• https://githu...
Docker BuildKit を使う方法
• クライアントの環境変数
• Docker デーモン設定ファイル /etc/docker/daemon.json
• 現時点では Windows は対応していない
• Windows support...
カイゼン Dockerfile
10
Dockerfile の改善領域
• 増大するbuild 時間
• イメージ容量
• 保守性
• 安全性
• 一貫性・反復性
11
(Incremental) build time
Image size
Maintainability
Secu...
サンプルの Dockerfile をカイゼンするぞ!
12
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh emacs
CM...
サンプルの Dockerfile をカイゼンするぞ!
13
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh emacs
CM...
サンプルの Dockerfile をカイゼンするぞ!
14
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh emacs
CM...
増大する構築(build)時間
ビルド・キャッシュと友達になろう
15
課題と対策
キャッシュする順番が重要
16
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
COPY . /app
CMD ["...
キャッシュする順番が重要
17
FROM debian
COPY . /app
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
COPY . /app
CMD ["...
キャッシュ破棄の影響を避けるため、範囲を狭く
18
FROM debian
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
COPY . /app
COPY tar...
キャッシュ破棄の影響を避けるため、範囲を狭く
19
FROM debian
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
COPY . /app
COPY tar...
行をまとめる: apt-get update & install
20
FROM debian
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
RUN apt-ge...
行をまとめる: apt-get update & install
21
FROM debian
RUN apt-get update
RUN apt-get –y install openjdk-8-jdk ssh vim
RUN apt-ge...
イメージ容量を減らす
より速くデプロイするには、イメージを小さく
22
課題と対策
不要な依存関係を削除
23
FROM debian
RUN apt-get update ¥
&& apt-get -y install --no-install-recommends ¥
openjdk-8-jdk ssh vim
COPY ...
不要なパッケージマネージャのキャッシュ削除
24
FROM debian
RUN apt-get update ¥
&& apt-get -y install –no-install-recommends ¥
openjdk-8-jdk ¥
&...
保守性
できるだけシンプルに保つ
25
課題と対策
できるだけDocker公式(official)パッケージを使う
• メンテナンスにかける時間を減らす
(問題があるたびに、繰り返す更新)
• 容量を減らす(イメージ間でのレイヤ共有によって)
• コンテナとして使うために、予め設定済み
• 賢い...
27
FROM debian
RUN apt-get update ¥
&& apt-get -y install –no-install-recommends ¥
openjdk-8-jdk ¥
&& rm –rf /var/lib/apt/...
タグを明示
28
FROM openjdk:latest
FROM openjdk:8
COPY target/app.jar /app
CMD ["java", "-jar", "/app/target/app.jar"]
"latest"タ...
適切なタグを探す
29
Docker Hub のドキュメントを読もう
https://hub.docker.com/_/openjdk
どのようなタグがあるかは、Docker Hub上のドキュメントで確認
必要最小限のものを探す
30
REPOSITORY TAG SIZE
openjdk 8 624MB
openjdk 8-jre 443MB
openjdk 8-jre-slim 204MB
openjdk 8-jre-alpie 83MB
ベ...
再利用性
Dockerfileは青写真であり、
ソースコードこそが本当の源(ソース)
31
課題と対策
32
一貫した環境を、ソースから構築する
• Dockerfile を設計図(青写真)にしよう:
• ビルド時するための構築環境を Dockerfile に記述
• 正しいバージョンのビルド・ツールをインストール
• 環境ごとの違いを発生させない
•...
一貫した環境を、ソースから構築する
34
FROM openjdk:8-jre-alpine
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY app.jar/app
COPY pom.xml .
CO...
一貫した環境を、ソースから構築する
35
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn –e –B package
CMD ["ja...
依存関係の解決は、ステップを分ける
36
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
RUN mvn –e –B dependency:resolve
COPY src ./s...
構築時のみの依存関係が判明
37
FROM maven:3.6-jdk-8-alpine
WORKDIR /app
COPY pom.xml .
RUN mvn –e –B dependency:resolve
COPY src ./src
R...
マルチ・ステージ・ビルドで、構築時の部分を削除
38
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn –e –B dependency:res...
マルチ・ステージ・ビルドで、構築時の部分を削除
39
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn –e –B dependency:res...
マルチ・ステージ Dockerfile
単に容量を減らすためだけではない
40
応用
プロジェクトごとに多くのステージがある
• Moby: 16 ステージ
https://github.com/moby/moby/blob/master/Dockerfile
• BuildKit: 44 ステージ
https://github...
マルチ・ステージの利用例
• 実行環境と構築(ビルド)環境を分ける(イメージ容量の縮小)
• イメージに対する影響を最小限に(DRY)
• 構築・開発・テスト・構文チェック…のような環境を明示
• 依存関係を一直線に処理しない(並列化)
• プ...
構築ステージを --target で指定
43
FROM image_or_stage AS stage_name
…
$ docker build --target stage_name
「AS ステージ名」を FROM 命令に書いておけば、...
イメージの flavor を変える
44
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=bu...
45
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=builder /app/target/...
46
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-jessie AS release-jessie
COPY --from=builder /app/target/...
47
ARG flavor=alpine
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-$flavor AS release
COPY --from=builder ...
様々な環境:構築、開発、テスト、構文チェック(lint)…
• ステージとしての検討例:
⁃ builder: 依存関係すべてをビルド
⁃ build(または binary): builder + ビルド成果物
⁃ cross: 複数のプラット...
様々な環境:構築、開発、テスト、構文チェック(lint)…
49
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-alpine AS lint
RUN wget htt...
様々な環境:構築、開発、テスト、構文チェック(lint)…
50
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM openjdk:8-jre-alpine AS release
COPY --fr...
様々な環境:構築、開発、テスト、構文チェック(lint)…
51
FROM maven:3.6-jdk-8-alpine AS builder
...
RUN mvn –e –B package –DskipTests
FROM builder...
並行性(Concurrency)
52
応用
一直線の Dockerfile ステージから …
• 全てのステージが順番(シーケンシャル)に実行
• この図では、上から下に一直線
• BuildKitがなければ、
不要なステージも無駄に実行し、破棄する
(無駄に時間がかかった)
53
s1...
BuildKit のマルチ・ステージ graph へ
• BuildKit は下(--target のステージ名)から上に辿っていくような流れ
• 右図では s2, s3, s4 ステージを同時並行処理
• 不要なステージは無視できる
• 右図...
Multi-srage: 並行ビルド (build concurrently)
55
FROM maven:3.6-jdk-8-alpine AS builder
...
FROM tiborvass/whalesay AS assets
RU...
Multi-srage: 並行ビルド (build concurrently)
56
FROM maven:3.6-jdk-8-alpine AS builder-base
…
FROM gcc:8-alpine AS builder-some...
ベンチマーク
• github.com/moby/moby Dockerfile, master ブランチ
• 小さいほうが優れている
57
Dockerfile Best Practices
https://www.slideshare.ne...
ベンチマーク
• github.com/moby/moby Dockerfile, master ブランチ
• 小さいほうが優れている
58
Dockerfile Best Practices
https://www.slideshare.ne...
ベンチマーク
• github.com/moby/moby Dockerfile, master ブランチ
• 小さいほうが優れている
59
Dockerfile Best Practices
https://www.slideshare.ne...
Dockerfileの最新機能
60
新機能
新機能を有効にするには?
61
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY . /ap...
詳細
• https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
62構文の詳細は、こちらのドキュメントを参照
コンテキスト・マウント(v18.09+ w/ BuildKit)
63
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WOR...
Dockerfile
hello
コンテキスト・マウント(v18.09+ w/ BuildKit)
64
ディレクトリ内容をコンテナに COPY しなくても、
ビルド時に docker build コマンドを実行しているディレクトリ(ここでは ...
65
コンテキスト・マウント(v18.09+ w/ BuildKit)
contest mounts
従来 “COPY . /app” BuildKit
Dockerfile
app用ディレクトリ
Build用ディレクトリ
“docker bu...
キャッシュの保持(BuildKitが無ければ)
66
FROM maven:3.6-jdk-8-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn -e –B dependency: re...
キャッシュの保持(v18.09+ w/ BuildKit)
67
# syntax=docker/dockerfile:1.0-experimental
FROM maven:3.6-jdk-8-alpine AS builder
WORKDI...
キャッシュの保持
• --mount=type=cache 例:
68
Dockerfile
# syntax=docker/dockerfile:1.0-experimental
FROM ubuntu
RUN --mount=type=ca...
BuildKit
キャッシュはホスト側で保持
69
Dockerfile
app用ディレクトリ
Build用ディレクトリ
コンテナ
マウント
キャッシュしたあとは
みーてーるーだーけーDockerのキャッシュ用ディレクトリ
“docker bu...
シークレット(これはダメな方法)
70
FROM baseimage
RUN …
ENV AWS_ACCESS_KEY_ID=…
ENV AWS_SECRET_ACCESS_KEY=…
RUN ./fetch-aseets-from-s3.sh...
シークレット(これもダメな方法)
71
FROM baseimage
RUN …
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
RUN ./fetch-aseets-from-s3.sh
RUN...
シークレット(v18.09+ w/ BiuldKit では、こうします)
72
# syntax=docker/dockerfile:1-experimental
FROM baseimage
RUN …
RUN --mount=type=se...
BuildKit
73
Dockerfile
大事なディレクトリ
Build用ディレクトリ
コンテナ
id指定対象を
マウント
構築ステップの間だけ
みーてーるーだーけー
“docker build” の対象構築ステップ時のみ、
ホスト側のシー...
• Dockerfile の mount secret 例:
Dockerfile
$HOME/secret
シークレット・マウント(v18.09+ w/ BiuldKit)
74
# syntax=docker/dockerfile:1.0-...
プライベート git リポジトリ(ダメぜったい)
75
FROM baseimage
COPY ./keys/private.pem /root/.ssh/private.pem
ARG REPO_REF=19ba8bcd9976ef8a9bd...
プライベート git リポジトリ(v18.09+ w/BuildKitの場合)
76
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir –p –m 0700 ~/.ssh &...
BuildKit
77
SSH マウント(v18.09+ w/ BiuldKit)
mounts
Dockerfile
.ssh
Build用ディレクトリ
コンテナ
鍵情報
参照
このステップがある間だけ
みーてーるーだーけー
“docker ...
• Dockerfile の mount=SSH 例:
Dockerfile
SSH マウント(v18.09+ w/ BiuldKit)
78
# syntax=docker/dockerfile:1.0-experimental
FROM a...
Dockerfile 改善のまとめ
• 従来
⁃ 構築・開発・テスト環境の矛盾
⁃ 膨れあがるイメージ容量
⁃ 構築時間がマシマシ(キャッシュ無効)になり時間がかかる
⁃ 構築が安全ではない
• これから( BuildKit の活用によって)
...
参考資料
• Advanced multi-stage build patterns – Tõnis Tiigi – Medium
https://medium.com/@tonistiigi/advanced-multi-stage-buil...
参考資料
• BuildKitによる高速でセキュアなイメージビルド
https://www.slideshare.net/AkihiroSuda/buildkit
81
DockerCon での発表
• Dockerfile Best Practices
https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices
82
• 動画
http...
Q&A
• 何か気になるところはありますか?
• Twitter: @zembutsu
• https://slideshare.net/zembutsu
• Dockerドキュメント日本語訳
http://docs.docker.jp
• D...
Prochain SlideShare
Chargement dans…5
×

Dockerfileを改善するためのBest Practice 2019年版

18 031 vues

Publié le

2019年5月24日(金)の発表資料をベースに解説等を加えたバージョンです。
Docker Meetup Kansai #3
https://dockerkansai.connpass.com/event/129089/

Publié dans : Logiciels
  • If you want to download or read this book, Copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Download or read that Ebooks here ... ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Download or read that Ebooks here ... ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes.........ACCESS WEBSITE Over for All Ebooks ..... (Unlimited) ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • (Unlimited)....ACCESS WEBSITE Over for All Ebooks ................ accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Dockerfileを改善するためのBest Practice 2019年版

  1. 1. DockerCon SF19 で発表の、基礎→マルチ・ステージ・ビルド→最新動向まで Sakura Internet, Inc. Masahito Zembutsu @zembutsu Docker Meetup Kansai #3 #dockerkansai May 24, 2019 Dockerfileを改善するための Best Practice 2019年版
  2. 2. DockerCon SF19 での発表に基づく内容 • Dockerfile Best Practices https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices 2 • 動画もご覧ください https://www.docker.com/dockercon/2019-videos?watch=dockerfile-best-practices オリジナルの発表は Tibor Vass 氏( @tiborvass) および Sebastian van Stijin 氏(@thajeztha) による、 DockerCon 毎回恒例人気セッション"Dockerfile Best Practices" であり、両者に感謝します。 I thank you both for your excellent presentation of DockerCon. I also appreciate your permission to translate the content. Please refer to this slides. And, this presentation video will also be helpful.
  3. 3. このスライドは何? 3 ⚫ DockerCon 19 で発表された人気シリーズ “Best Practices” を日本訳+解説の追加。 ⚫ Dockerfile の改善を通して、現在利用できる マルチ・ステージ・ビルドや BuildKit 紹介。 以上の内容です。 ※ "Docker Meetup Kansai #3" 発表時のスライドをベースに、 スライドそのままでは分かりづらい部分があるため、 一部で発表時と異なる表現・補足説明を用いている場合があります。 ゴール: 「Dockerfileの改善を具体的に理解」
  4. 4. Dockerfileのベストプラクティス • "Best practices for writing Dockerfiles" https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ 4 最新の日本語訳を公開しました。 そもそもの基本となるのは、"Dockerfileを書くためのベストプラクティス"です。
  5. 5. Dockerfile解説スライドもご覧ください • ベストプラクティス日本語版に解説・図解を加えたバージョンを作りました 5 https://www.slideshare.net/zembutsu/explaining-best-practices-for-writing-dockerfiles もし、Dockerfileに慣れていないのであれば、前提として、こちらのスライドをご覧ください。
  6. 6. Dockerfile とは? 6 ド ッ カ ー フ ァ イ ル
  7. 7. Dockerfile • Docker は Dockerfile から命令を読み込み、イメージを自動構築 • テキスト形式のドキュメント • docker build / docker image build で Dockerfile を読み込み構築 • 「Docker イメージを作るための設計図」 • FROM、ADD、CMD など命令文で構成 • 例) 何のイメージをもとに、何を実行するか? • 誰でも確実にイメージを構築できる • イメージの構築過程を確認できる • Dockerfileは広く使われている • GitHub上に Dockerfile は100万以上 7 automate build blueprint Image by John Dortmunder from Pixabay 「Dockerfile」はDockerイメージを自動構築するために、必ず使うファイルです。
  8. 8. BuildKit: builder v2 • docker build は「イメージ・キャッシュ」があるため、素早く開発できる • しかし、いくつかの制限があったため、buildKit プロジェクトで根本的に構築 • https://github.com/moby/buildkit • "ゴールは Docker build のデフォルト" • BuildKit: 特長 • 同時へいれt性(concurrency) • 断片的なコンテキスト・アップロード (lazy context upload) • キャッシュの改良 • 新しい Dockerfile 機能の追加 8 ⚫並列性が無い ⚫docker run と同様に root で動作する必要性 ⚫ボリューム機能が無い 高速にイメージを作れる BuildKit という汎用ツールが開発途上です。
  9. 9. Docker BuildKit を使う方法 • クライアントの環境変数 • Docker デーモン設定ファイル /etc/docker/daemon.json • 現時点では Windows は対応していない • Windows support coming soon! 9 { "features": { "buildkit": true }} export DOCKER_BUILDKIT=1 BiuldKit は Docker とは別のプロジェクト (https://github.com/moby/buildkit ) ですが、 現在の Docker CE v18.09 では、BuildKit の一部機能が既に利用できる状態です。
  10. 10. カイゼン Dockerfile 10
  11. 11. Dockerfile の改善領域 • 増大するbuild 時間 • イメージ容量 • 保守性 • 安全性 • 一貫性・反復性 11 (Incremental) build time Image size Maintainability Security Consistency/Repetability ここからは、先日開催された DockerCon SF19での発表サンプルをベースにご紹介します。 サンプルのアプリケーションを使い、5つの視点で Dockerfile を改善する流れをみていきましょう。
  12. 12. サンプルの Dockerfile をカイゼンするぞ! 12 FROM debian COPY . /app RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh emacs CMD ["java", "-jar", "/app/target/app.jar"] これは、Javaで"Hello world"を表示するための、サンプルプログラム用の Dockerfile です。
  13. 13. サンプルの Dockerfile をカイゼンするぞ! 13 FROM debian COPY . /app RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh emacs CMD ["java", "-jar", "/app/target/app.jar"] vim まずすべきは、emacs を消して、vim を入れましょう。もちろんジョークですが!
  14. 14. サンプルの Dockerfile をカイゼンするぞ! 14 FROM debian COPY . /app RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh emacs CMD ["java", "-jar", "/app/target/app.jar"] vim まずすべきは、emacs を消して、vim を入れましょう。もちろんジョークですが!
  15. 15. 増大する構築(build)時間 ビルド・キャッシュと友達になろう 15 課題と対策
  16. 16. キャッシュする順番が重要 16 FROM debian COPY . /app RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim COPY . /app CMD ["java", "-jar", "/app/target/app.jar"] 頻繁に変更するものを後ろへ 構築時のキャッシュとは、変更箇所があれば破棄されます。この例の COPY では「.」(カレント)にある ファイルに変更があれば、毎回「apt-get update」と「install」が走るので、時間がかかってしまいます。 せっかくあrキャッシュを有効活用するには、頻繁に更新する可能性があるものを後ろにおきます。
  17. 17. キャッシュする順番が重要 17 FROM debian COPY . /app RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim COPY . /app CMD ["java", "-jar", "/app/target/app.jar"] 頻繁に変更するものを後ろへ 構築時のキャッシュとは、変更箇所があれば破棄されます。この例の COPY では「.」(カレント)にある ファイルに変更があれば、毎回「apt-get update」と「install」が走るので、時間がかかってしまいます。 せっかくあrキャッシュを有効活用するには、頻繁に更新する可能性があるものを後ろにおきます。 キャッシュ有効 キャッシュ破棄 … ホスト側「 ./ 」に変更時 キャッシュ破棄 … ホスト側「 ./ 」に変更時 時間がかかるので、キャッシュ活用すべし 時間かかる
  18. 18. キャッシュ破棄の影響を避けるため、範囲を狭く 18 FROM debian RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim COPY . /app COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] コピーに必要なものを明示する。 可能であれば "COPY ."を避ける コピーすべき場所を絞っておけば、キャッシュは破棄されません。 この例では「app.jar」しか「COPY」しませんので、他のファイルに変更があってもキャッシュを保持。
  19. 19. キャッシュ破棄の影響を避けるため、範囲を狭く 19 FROM debian RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim COPY . /app COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] コピーすべき場所を絞っておけば、キャッシュは破棄されません。 この例では「app.jar」しか「COPY」しませんので、他のファイルに変更があってもキャッシュを保持。 キャッシュ有効 キャッシュ有効 キャッシュ有効 ちょっとキャッシュする範囲が拡がるかもね キャッシュ対象の明確化 コピーに必要なものを明示する。 可能であれば "COPY ."を避ける
  20. 20. 行をまとめる: apt-get update & install 20 FROM debian RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim RUN apt-get update ¥ && apt-get -y install ¥ openjdk-8-jdk ssh vim COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] 古いパッケージ情報のキャッシュ利用を避ける パッケージ・マネージャを使う場合、「古い」パッケージ情報をキャッシュしがちです。 更新したいのに更新できないのを避けるには、情報の更新と、パッケージ追加・削除をまとめること。
  21. 21. 行をまとめる: apt-get update & install 21 FROM debian RUN apt-get update RUN apt-get –y install openjdk-8-jdk ssh vim RUN apt-get update ¥ && apt-get -y install ¥ openjdk-8-jdk ssh vim COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] 古いパッケージ情報のキャッシュ利用を避ける パッケージ・マネージャを使う場合、「古い」パッケージ情報をキャッシュしがちです。 更新したいのに更新できないのを避けるには、情報の更新と、パッケージ追加・削除をまとめること。 キャッシュ有効 古いものをキャッシュしてるかも! 時間かかる場合があっても、確実に処理
  22. 22. イメージ容量を減らす より速くデプロイするには、イメージを小さく 22 課題と対策
  23. 23. 不要な依存関係を削除 23 FROM debian RUN apt-get update ¥ && apt-get -y install --no-install-recommends ¥ openjdk-8-jdk ssh vim COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] デプロイを素早くするためには、イメージ容量の削減が重要であり、必須課題。 推奨パッケージ(必須ではない)を避けるためには、「--no-install-recommends」フラグを付ける。 Javaの実行に不要なパッケージも入れないので「ssh」「vim」も消す。
  24. 24. 不要なパッケージマネージャのキャッシュ削除 24 FROM debian RUN apt-get update ¥ && apt-get -y install –no-install-recommends ¥ openjdk-8-jdk ¥ && rm –rf /var/lib/apt/lists/* COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] パッケージ・マネージャのキャッシュ情報も、アプリケーションの実行に不要なので削除
  25. 25. 保守性 できるだけシンプルに保つ 25 課題と対策
  26. 26. できるだけDocker公式(official)パッケージを使う • メンテナンスにかける時間を減らす (問題があるたびに、繰り返す更新) • 容量を減らす(イメージ間でのレイヤ共有によって) • コンテナとして使うために、予め設定済み • 賢い人達が構築している 26パッケージ・マネージャのキャッシュ情報も、アプリケーションの実行に不要なので削除
  27. 27. 27 FROM debian RUN apt-get update ¥ && apt-get -y install –no-install-recommends ¥ openjdk-8-jdk ¥ && rm –rf /var/lib/apt/lists/* FROM openjdk COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] できるだけDocker公式(official)パッケージを使う Javaの実行であれば、「openjdk」イメージがあるため、debianでセットアップする必要はない
  28. 28. タグを明示 28 FROM openjdk:latest FROM openjdk:8 COPY target/app.jar /app CMD ["java", "-jar", "/app/target/app.jar"] "latest"タグは常に入れ替わる。 タグを指定しておけば、想定外の ベース・イメージ変更発生を防止。 何も指定しなければ「latest」(最新)になるため、常にタグ(主にバージョン)指定を忘れずに
  29. 29. 適切なタグを探す 29 Docker Hub のドキュメントを読もう https://hub.docker.com/_/openjdk どのようなタグがあるかは、Docker Hub上のドキュメントで確認
  30. 30. 必要最小限のものを探す 30 REPOSITORY TAG SIZE openjdk 8 624MB openjdk 8-jre 443MB openjdk 8-jre-slim 204MB openjdk 8-jre-alpie 83MB ベース・イメージの変更だけで 540MBも削減 どのイメージ(タグ)を選ぶかによって、容量がかなり異なる。 alpineタグは Alpine Linux という約 5MB の Linux ディストリビューションがベース
  31. 31. 再利用性 Dockerfileは青写真であり、 ソースコードこそが本当の源(ソース) 31 課題と対策
  32. 32. 32
  33. 33. 一貫した環境を、ソースから構築する • Dockerfile を設計図(青写真)にしよう: • ビルド時するための構築環境を Dockerfile に記述 • 正しいバージョンのビルド・ツールをインストール • 環境ごとの違いを発生させない • システム依存はあるかもしれない • "source of truth"(本当のソース)とは、 ソースコードである。ビルド成果物ではない。 33 Image by John Dortmunder from Pixabay blue print 開発環境、テスト環境、実行環境で共通する Dockerfile を目指す
  34. 34. 一貫した環境を、ソースから構築する 34 FROM openjdk:8-jre-alpine FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY app.jar/app COPY pom.xml . COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app/target/app.jar"] openjdk にかわり、Javaプロジェクト管理ツールであるMavenを開発環境として入れる
  35. 35. 一貫した環境を、ソースから構築する 35 FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app/target/app.jar"] このように、開発環境向けの Dockerfile を整えていく。
  36. 36. 依存関係の解決は、ステップを分ける 36 FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn –e –B dependency:resolve COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app/target/app.jar"] 開発関係だけに必要な依存関係を追加。
  37. 37. 構築時のみの依存関係が判明 37 FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn –e –B dependency:resolve COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app/target/app.jar"] しかし、この黄色い部分は「開発環境の構築」段階しか使わないものであり、本番稼働では無駄
  38. 38. マルチ・ステージ・ビルドで、構築時の部分を削除 38 FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn –e –B dependency:resolve COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app/target/app.jar"] FROM openjdk:8-jre-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app/target/app.jar"] そこで、マルチ・ステージ・ビルドで複数の「FROM」を使い、構築時(AS bilder)と実行時を分離 ←「builder」ステージから ファイルをコピー ←ステージ「builder」と名前を付ける
  39. 39. マルチ・ステージ・ビルドで、構築時の部分を削除 39 FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn –e –B dependency:resolve COPY src ./src RUN mvn –e –B package FROM openjdk:8-jre-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app/target/app.jar"] マルチ・ステージ・ビルドでは、「docker build」は全てのビルドを実行しますし、 「docker build –target builder」と指定すると「AS builder」の「FROM」ステージしか処理しません。
  40. 40. マルチ・ステージ Dockerfile 単に容量を減らすためだけではない 40 応用
  41. 41. プロジェクトごとに多くのステージがある • Moby: 16 ステージ https://github.com/moby/moby/blob/master/Dockerfile • BuildKit: 44 ステージ https://github.com/moby/buildkit/blob/master/hack/dockerfiles /test.buildkit.Dockerfile 41Docker 関連プロジェクトの Dockerfile にも、多くのステージ(FROM命令)がある
  42. 42. マルチ・ステージの利用例 • 実行環境と構築(ビルド)環境を分ける(イメージ容量の縮小) • イメージに対する影響を最小限に(DRY) • 構築・開発・テスト・構文チェック…のような環境を明示 • 依存関係を一直線に処理しない(並列化) • プラットフォーム固有のステージ 42 一般的な目的は、最終成果物の容量を削減
  43. 43. 構築ステージを --target で指定 43 FROM image_or_stage AS stage_name … $ docker build --target stage_name 「AS ステージ名」を FROM 命令に書いておけば、「docker build」時に「--target」でステージを指定
  44. 44. イメージの flavor を変える 44 FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-jessie AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . Debian jessie (8.x) をベースとするイメージと、Alpine Linux をベースとするイメージ。 特色(風味)
  45. 45. 45 FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-jessie AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . イメージの flavor を変える 特色(風味) しかし、 Dockerfile をよく見ると問題があり、
  46. 46. 46 FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM openjdk:8-jre-jessie AS release-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release-jessie . このように各ステージで、同じ命令が重複する箇所がある。 イメージの flavor を変える 特色(風味) どちらも 同じ
  47. 47. 47 ARG flavor=alpine FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-$flavor AS release COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] $ docker build --target release --build-arg flavor=jessie . 「ARG」を Dockerfile で指定しておくと、docker build 時に「--build-arg」を通して、変数のように展開 --build-arg で $flavor=xxx があれば、$flavor に xxx 代入 ↓何もなければ「flavor=alpine」が適用 イメージの flavor を変える (DRY / 汎用的な ARG) 特色(風味) ※ DRY = “Don’t Repeat Yourself”(自分では繰り返さない)という ソフトウェア開発の手法 引数 ←ARG命令は、docker build時に指定できる変数を定義 書式は「変数名」または「変数名=デフォルト値」。
  48. 48. 様々な環境:構築、開発、テスト、構文チェック(lint)… • ステージとしての検討例: ⁃ builder: 依存関係すべてをビルド ⁃ build(または binary): builder + ビルド成果物 ⁃ cross: 複数のプラットフォーム向けに構築 ⁃ dev: build(er) + 開発/デバッグツール ⁃ lint: 最小限の構文チェック用依存関係 ⁃ test: テストに関係する全ての依存関係 + テスト対象のビルド成果物 ⁃ release: ビルド成果物を含む、最終的な最小イメージ 48様々な「ステージ」が検討できる。ここでは定型的な例 各ステージでは、依存関係が最小となるようにする
  49. 49. 様々な環境:構築、開発、テスト、構文チェック(lint)… 49 FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-alpine AS lint RUN wget https://github.com/checkstyle/checkstyle/releases/download/checkstyle-8.15/checkstyle-8.15-all.jar COPY checks.xml . COPY src /src RUN java –jar checkstyle-8.15-all.jar –c checks.xml /src これはシンプルな Java 構文チェック(リント)の確認用の Dockerfile を「AS lint」と指定
  50. 50. 様々な環境:構築、開発、テスト、構文チェック(lint)… 50 FROM maven:3.6-jdk-8-alpine AS builder ... FROM openjdk:8-jre-alpine AS release COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] FROM builder AS dev RUN apk add --no-cache strace vim tcpdump ENTRYPOINT ["ash"] 開発用デバッグ環境であれば、「builder」ステージをベースにしながら「AS dev」と明示し シンプルにエディタ(vim)と tcpdump を入れている
  51. 51. 様々な環境:構築、開発、テスト、構文チェック(lint)… 51 FROM maven:3.6-jdk-8-alpine AS builder ... RUN mvn –e –B package –DskipTests FROM builder AS unit-test RUN mvn –e –B test FROM release AS integration-test RUN apk add --no-cache curl RUN ./test/run.sh 他にも単体テスト、統合テスト用の環境も作れます。
  52. 52. 並行性(Concurrency) 52 応用
  53. 53. 一直線の Dockerfile ステージから … • 全てのステージが順番(シーケンシャル)に実行 • この図では、上から下に一直線 • BuildKitがなければ、 不要なステージも無駄に実行し、破棄する (無駄に時間がかかった) 53 s1 s2 s3 s4 s5 s6 デフォルトでは、全てのステージを順番に実行する
  54. 54. BuildKit のマルチ・ステージ graph へ • BuildKit は下(--target のステージ名)から上に辿っていくような流れ • 右図では s2, s3, s4 ステージを同時並行処理 • 不要なステージは無視できる • 右図では s5 がビルド時に 不要であれば、何もしない 54 s1 s2 s3 s4 s5s6 Docker 17.05 からマルチ・ステージ・ビルドが利用可能になった。 18.06までは experimental 、18.09 は利用できるように組み込まれている グラフ ※グラフは点と点とのつながり (関係性)を表す
  55. 55. Multi-srage: 並行ビルド (build concurrently) 55 FROM maven:3.6-jdk-8-alpine AS builder ... FROM tiborvass/whalesay AS assets RUN whalesay "Hello DockerCon!" > /out/assets.html FROM openjdk:8-jre-alpine AS release COPY --from=builder /app/target/app.jar / COPY --from=assets /out /assets CMD ["java", "-jar", "/app.jar"] 「assets」は最終イメージ(release)に必要だが、別のステージとして処理できる そして、この Dockerfile は「builder」と「assets」のステージからのコピーを並行処理
  56. 56. Multi-srage: 並行ビルド (build concurrently) 56 FROM maven:3.6-jdk-8-alpine AS builder-base … FROM gcc:8-alpine AS builder-someClib … RUN git clone … ¥ ./configure --prefix=/out && make && make install FROM g++:8-alpine AS builder-someCPPlib … RUN git clone … ¥ cmake … FROM builder-base AS builder COPY --from=builder-someClib /out / COPY --from=builder-someCPPlib /out / 複数の COPY 命令を使う時には、特に効果を発揮し、時間を節約できる 並行処理が有用な典型的なパターンが 複数の COPY --from … の繰り返し
  57. 57. ベンチマーク • github.com/moby/moby Dockerfile, master ブランチ • 小さいほうが優れている 57 Dockerfile Best Practices https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices/52 v18.03 の docker build と BuiltKit では2倍の速さ
  58. 58. ベンチマーク • github.com/moby/moby Dockerfile, master ブランチ • 小さいほうが優れている 58 Dockerfile Best Practices https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices/52 キャッシュを有効にすると、7倍も速くなる
  59. 59. ベンチマーク • github.com/moby/moby Dockerfile, master ブランチ • 小さいほうが優れている 59 Dockerfile Best Practices https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices/52 最も大事なのは、ソースコードの変更時。再構築の速度はマルチ・ステージ・ビルドで 2.5 倍に改善。
  60. 60. Dockerfileの最新機能 60 新機能
  61. 61. 新機能を有効にするには? 61 # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY . /app RUN mvn -e –B package FROM openjdk:8-jre-alpine COPY --from=builder /app/target/app.jar / CMD ["java", "-jar", "/app.jar"] Dockerfile の新機能を有効にするには、この行を1行目に追加する必要がある ※experimental というのは、まだ Dockerfile の正式な構文では ないため
  62. 62. 詳細 • https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md 62構文の詳細は、こちらのドキュメントを参照
  63. 63. コンテキスト・マウント(v18.09+ w/ BuildKit) 63 # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY . /app RUN --mount=target=. mvn -e –B package -DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app/app.jar / CMD ["java", "-jar", "/app.jar"] 新機能を使って Dockerfile を書き換えていく。まずはマウント・オプション。 実行時に「.」(カレント・ディレクトリ内容)を Build Context として送信せず、マウントできる ※ Docker v18.09 以上かつ、BuildKit 有効化の状態で利用可能 contest mounts
  64. 64. Dockerfile hello コンテキスト・マウント(v18.09+ w/ BuildKit) 64 ディレクトリ内容をコンテナに COPY しなくても、 ビルド時に docker build コマンドを実行しているディレクトリ(ここでは 「target=.」で指定)を rw(読み書き可能な状態)で直接コンテナにマウントし、 コンテナ内で「cat hello > /hello.txt」を実行 → 構築したイメージの“/hello.txt” に “Hello world!” が書かれたファイルが作成される # syntax=docker/dockerfile:1.0-experimental FROM alpine RUN --mount=type=bind,target=.,rw cat hello > /hello.txt Hello world! ソースコードなど、ビルド・コンテクストのコピーが不要となり、より早いビルドができる contest mounts • Dockerfile の mount 例: ホスト側の docker build する場所に、 このファイルがあるとします
  65. 65. 65 コンテキスト・マウント(v18.09+ w/ BuildKit) contest mounts 従来 “COPY . /app” BuildKit Dockerfile app用ディレクトリ Build用ディレクトリ “docker build” 時、 「.」 以下の内容を Docker イメージ用レイヤとして構築するため 全て Docker に対して送る必要があった ※結果として Docker イメージの不本意な増加 ※あるいはマルチ・ステージ・ビルドで回避 Dockerfile app用ディレクトリ Build用ディレクトリ コンテナ コピー マウント よいしょ… みーてーるーだーけー “docker build” の特定ステップのみ参照するため、 ・ build 全体の時間を削減 ・ イメージ・レイヤの肥大化を抑制
  66. 66. キャッシュの保持(BuildKitが無ければ) 66 FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn -e –B dependency: resolve COPY src ./src RUN mvn –e –B package CMD ["java", "-jar", "/app.jar"] docker build 時にキャッシュが破棄されると、毎回依存関係の準備に時間がかかる
  67. 67. キャッシュの保持(v18.09+ w/ BuildKit) 67 # syntax=docker/dockerfile:1.0-experimental FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app RUN --mount=target=. --mount=type=cache,target=/root/.m2 ¥ && mvn package –DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app.jar / CMD ["java", "-jar", "/app.jar"] apt: /var/lib/apt/lists go: ~/.cache/go-build go-modules: $GOPATH/pkg/mod npm: ~/.npm pip: ~/.cache/pip キャッシュ用ディレクトリをマウントできるので、依存関係の準備にかかる時間を削減できる
  68. 68. キャッシュの保持 • --mount=type=cache 例: 68 Dockerfile # syntax=docker/dockerfile:1.0-experimental FROM ubuntu RUN --mount=type=cache,target=/var/cache/apt ¥ --mount=type=cache,target=/var/lib/apt ¥ apt-get update && apt-get install -y wget curl 「type=cache」で指定した「target」のディレクトリは、docker build を実行したホスト上でキャッシュ この例では apt-get install を含む「RUN」命令を書き換えたとしても、 一度キャッシュ(ビルド)済みであれば次回から高速なビルドが可能になる キャッシュ情報をクリアするには「docker builder prune」コマンドを実行する
  69. 69. BuildKit キャッシュはホスト側で保持 69 Dockerfile app用ディレクトリ Build用ディレクトリ コンテナ マウント キャッシュしたあとは みーてーるーだーけーDockerのキャッシュ用ディレクトリ “docker build” の対象構築ステップ時のみ、 ホスト側のキャッシュ用ディレクトリを一時的にマウント 何度 build しても、キャッシュを有効活用できるので 高速にイメージを作りやすい また、イメージ全体の容量も削減できる docker build ※ docker builder prune で消せる
  70. 70. シークレット(これはダメな方法) 70 FROM baseimage RUN … ENV AWS_ACCESS_KEY_ID=… ENV AWS_SECRET_ACCESS_KEY=… RUN ./fetch-aseets-from-s3.sh RUN ./build-scripts.sh シークレット(secret)とは、パスワードやAPIキー、SSH 鍵などの認証情報(機微情報) ENV に書くと docker history で丸見えですし、
  71. 71. シークレット(これもダメな方法) 71 FROM baseimage RUN … ARG AWS_ACCESS_KEY_ID ARG AWS_SECRET_ACCESS_KEY RUN ./fetch-aseets-from-s3.sh RUN ./build-scripts.sh $ docker build --build-arg ¥ AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID … ARGでも途中のRUNで変数の情報をダンプできますし、 シェルのhistoryからも辿れるリスクが出てきます(記録しない方法もありますが、運用カバー系作業) docker history
  72. 72. シークレット(v18.09+ w/ BiuldKit では、こうします) 72 # syntax=docker/dockerfile:1-experimental FROM baseimage RUN … RUN --mount=type=secret,id=aws,target=/root/.aws/credentials, required ./fetch-assets-from-s3.sh RUN ./build-scripts.sh $ docker build --secret id=aws,src=~/.aws/credentials . 最終イメージに混入させないための手法が「secret」としてのマウント。 対象ステップのみデータを参照できるよう一時的にマウントし、次のステップではマウントしません。 ↓idは docker build 時の –secret オプションで識別するため ↑targetで、この構築ステップのみ、 コンテナ内のこの場所に 一時的にファイルを設置する指示 ↑これはホスト側に存在するファイル。 ~より、 $HOME や絶対パスのほうが安全かも ↑次のステップでは、先の id=aws でマウントしたシークレットは見えない( 0 byte のファイル残骸のみ)
  73. 73. BuildKit 73 Dockerfile 大事なディレクトリ Build用ディレクトリ コンテナ id指定対象を マウント 構築ステップの間だけ みーてーるーだーけー “docker build” の対象構築ステップ時のみ、 ホスト側のシークレット(機微情報)ファイルを一時的にマウント 環境変数などで取り込んで認証などに利用する 一時的にホスト側を参照するだけなので イメージ内に大事な情報を残さない docker build SECRET_FILE シークレット・マウント(v18.09+ w/ BiuldKit) secret mounts id指定
  74. 74. • Dockerfile の mount secret 例: Dockerfile $HOME/secret シークレット・マウント(v18.09+ w/ BiuldKit) 74 # syntax=docker/dockerfile:1.0-experimental FROM alpine RUN --mount=type=secret,id=check,target=/root/secret,required ¥ cat /root/secret > /data.txt MYID=secretpass Dockerfile で当該 RUN 命令行のビルド時のみ、一時的にホスト側ファイルをマウントできる secret mounts ホスト側にIDとパスワードのような、 いわゆるシークレット(機微情報)を記録するファイルを設置 もちろん、パーミッションは 600 にするなど、十分なセキュリティ配慮が必要 $ docker build --secret id=check,src=$HOME/.data/credentials -t myimage . ↑srcで指定したパスはホスト上のファイル
  75. 75. プライベート git リポジトリ(ダメぜったい) 75 FROM baseimage COPY ./keys/private.pem /root/.ssh/private.pem ARG REPO_REF=19ba8bcd9976ef8a9bd086187df19ba7bcd997f2 RUN git clone git@githubcom:org/repo /work && cd /work ¥ && git checkout –b $REPO_REF これもイメージ内に大事なファイルが残ってしまう NG 例
  76. 76. プライベート git リポジトリ(v18.09+ w/BuildKitの場合) 76 FROM alpine RUN apk add --no-cache openssh-client RUN mkdir –p –m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts ARG REPO REF=19ba8bcd9976ef8a9bd086187df19ba7bcd997f2 RUN –-mount-type=ssh,required ¥ git clone git@github.com:org/repo /work && cd /work ¥ && git checkout –b $REPO_REF $ eval $(ssh-agent) $ ssh-add ~/.ssh/id_rsa $ docker build --ssh=default . この RUN 命令実行時のみ、 ホスト側の SSH 認証情報を読み込む方法が 利用できる
  77. 77. BuildKit 77 SSH マウント(v18.09+ w/ BiuldKit) mounts Dockerfile .ssh Build用ディレクトリ コンテナ 鍵情報 参照 このステップがある間だけ みーてーるーだーけー “docker build” の対象構築ステップ時のみ、 ホスト側のSSH agent 情報を一時的にマウント シークレット・マウントに近いけれど SSH の利用に特化 こんてなから GitHub や SSH 接続したい場合に有用 docker build id_rsa ssh-agent --mount=type=ssh SSH リモート・ホストや GitHub / GitLab 等
  78. 78. • Dockerfile の mount=SSH 例: Dockerfile SSH マウント(v18.09+ w/ BiuldKit) 78 # syntax=docker/dockerfile:1.0-experimental FROM alpine RUN apk update && apk add openssh RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan <host_IP> > ~/.ssh/known_hosts RUN --mount=type=ssh,required ¥ ssh <user>@<host_IP> ls -al / > /ls.txt GitHubやGitLabの認証だけでなk、別のホストにこのようにしてログイン&操作も可能 mounts $ eval $(ssh-agent) $ ssh-add ~/.ssh/id_rsa (パスフレーズを入力) $ docker build --ssh default=$SSH_AUTH_SOCK -t <image_name> .
  79. 79. Dockerfile 改善のまとめ • 従来 ⁃ 構築・開発・テスト環境の矛盾 ⁃ 膨れあがるイメージ容量 ⁃ 構築時間がマシマシ(キャッシュ無効)になり時間がかかる ⁃ 構築が安全ではない • これから( BuildKit の活用によって) ⁃ 構築・開発・テスト環境が一致 ⁃ イメージ容量は最小 ⁃ 構築が非常に速く、構築回数が増えていく ⁃ より安全に構築できる 79 export DOCKER_BUILDKIT=1重要なのは有効化に 新しいビルド時の一時マウント可能な bind、cache、tmpfs、secret、ssh マルチ・ステージ・ビルドの活用によって、段階ごとの FROM ステージ間のコピー機能により、最終成果物を小さく 並列ビルドの活用により、従来よりも素早い構築
  80. 80. 参考資料 • Advanced multi-stage build patterns – Tõnis Tiigi – Medium https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae • Build secrets and SSH forwarding in Docker 18.09 – Tõnis Tiigi – Medium https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09- ae8161d066 • Introducing BuildKit – Moby Blog https://blog.mobyproject.org/introducing-buildkit-17e056cc5317 • docker builder prune | Docker Documentation https://docs.docker.com/engine/reference/commandline/builder_prune/ • Docker v18.09 新機能 (イメージビルド&セキュリティ) – nttlabs – Medium https://medium.com/nttlabs/docker-v18-09-%E6%96%B0%E6%A9%9F%E8%83%BD- %E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%83%93%E3%83%AB%E3%83%89- %E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3- 9534714c26e2 80
  81. 81. 参考資料 • BuildKitによる高速でセキュアなイメージビルド https://www.slideshare.net/AkihiroSuda/buildkit 81
  82. 82. DockerCon での発表 • Dockerfile Best Practices https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices 82 • 動画 https://www.docker.com/dockercon/2019-videos?watch=dockerfile-best-practices
  83. 83. Q&A • 何か気になるところはありますか? • Twitter: @zembutsu • https://slideshare.net/zembutsu • Dockerドキュメント日本語訳 http://docs.docker.jp • Docker Composeドキュメント日本語訳 http://docs.docker.jp/compose/ • 公式ドキュメント https://docs.docker.com 83

×