Publicité

コンテナの作り方「Dockerは裏方で何をしているのか?」

Engineer / Technology Evangelist à SAKURA Internet, Inc.
13 Dec 2019
Publicité

Contenu connexe

Présentations pour vous(20)

Similaire à コンテナの作り方「Dockerは裏方で何をしているのか?」(20)

Publicité

Plus de Masahito Zembutsu(20)

Dernier(20)

Publicité

コンテナの作り方「Dockerは裏方で何をしているのか?」

  1. コンテナの作り方 「Dockerは裏方で何をしているのか?」を理解する入門テキスト Sakura internet, Inc. Masahito Zembutsu @zembutsu CloudNative Days Kansai 2019 #CNDK2019 2019, Nov 28
  2. 2 この資料は、「Dockerコンテナ」の初学者を対象とした発表資料を、公開用として 再編集し、解説を加えたものです。 オリジナルは2019年11月28日開催の「CloudNative Days KANSAI2019」です。 ご来場の皆さま、登壇者の皆さま、スタッフの皆さん、大変ありがとうございました。 本資料以外にも、SlideShare で関連するスライドを公開していますので、ご興味 ありましたらご覧ください → https://www.slideshare.net/zembutsu/ ちなみに #CNDK2019 の来場者属性(アンケートより) 初心者が迷いがちな部分にマーク
  3. @zembutsu 前佛 雅人 zembutsu@zembutsu さくらインターネット株式会社 技術本部 Technology Evangelist / Developer Advocate ⚫ 石狩市への小学校プログラミング教育支援プロジェクト → さくらの学校支援プロジェクト (2019~) ⚫ 仮想化基盤チーム(クラウドチーム・VPSチーム) ⚫ エバンジェリストチーム ⚫ 略歴 • 1986年 はじめてパソコンに触る • BASIC挫折 • 1993年 富山高専(電気工学科)で学び始める パソコン通信・インターネットとの遭遇 • 2000年 富山のIT企業に就職 • とあるホスティング&ISPで勤務 NOC対応・運用・サポート業務に携わる • 2007年 東京へ • システム運用とか監視をいろいろ、企画 • 自動化ツール • 2019年 大阪在住 何をしたいの?:普通の人が当たり前に計算資源を活用して、 豊かな生活を実現できるように支援する 本発表は「コンテナとは何なのか?」「Dockerは何をしているのか?」の2点に絞り、初学者が混乱しがちな部分を整理します
  4. コンテナを作る 4 #とは コンテナ?
  5. 5 Nginxのコンテナを作っておいたよ~ おそらく、皆さんのプロジェクトや研究室などで、こんな会話を耳にしたことはありませんか?
  6. 6 Nginxのコンテナを作っておいたよ~ 「コンテナ」を「作る」とは、一体どのような意味があるのでしょうか
  7. 7 docker-compose.yml Dockerfile ご存じの方は、技術的には 「Dockerfileなりdocker-compose.ymlでDockerイメージを準備すること」 ですが、 ドッカーファイル ドッカーコンポーズ・ヤムル ドッカーファイル ドッカーコンポーズ・ヤムル
  8. 8 コンテナの「気持ち」を理解しよう 初学者の方へのアドバイス コンテナは友達さ! まずは、コンテナの「気持ち」を理解しようと努めることが、理解の促進につながります。コンテナの気持ちとは、
  9. 9 コンテナの「気持ち」を理解しよう 例えると、こんな状態。布団の中で横たわっているのが動いていないプロセスであり、、
  10. 10 コンテナの「気持ち」を理解しよう 布団から出られない人のいらすと https://www.irasutoya.com/2014/04/blog-post_2419.html Copyright 寒い冬は、布団でぬくぬくしていたいですよね、「布団から出たくない人」の気持ちこそが、 「コンテナ状態」として動くプロセスの気持ちです。デフォルトで、外とつながっていない。隔離されている状態。
  11. Docker とコンテナの違い Why Docker? 11 Docker
  12. Dockerとは何であるかの定義 12 “Docker allows you to package an application with all of its dependencies into a standardized unit for software development.” www.docker.com 全ての依存関係をパッケージ化して、コンテナとして動かす まずは、Dockerの「定義」からみていきましょう。 これは Docker のマスコットキャラクターで 名前は Moby です。 モビー ドッカー ドッカー
  13. Dockerとは何であるかの定義 13 “Docker allows you to package an application with all of its dependencies into a standardized unit for software development.” www.docker.com 全ての依存関係をパッケージ化して、コンテナとして動かす Dockerはプログラム実行に必要な「すべての依存関係」をパッケージにします。バイナリやライブラリ、設定ファイル等。
  14. Dockerとは何であるかの定義 14 “Docker allows you to package an application with all of its dependencies into a standardized unit for software development.” www.docker.com 全ての依存関係をパッケージ化して、コンテナとして動かす パッケージするのは、/ (ルート) ディレクトリ以下、 /bin や /etc や /var などの「Linuxファイルシステム」。 それと、「メタ情報」と呼ぶ、どのプロセスを自動実行するか、ポートを公開するなどの汎用情報も入ります。 Linuxファイルシステムを
  15. Dockerとは何であるかの定義 15 “Docker allows you to package an application with all of its dependencies into a standardized unit for software development.” www.docker.com 全ての依存関係をパッケージ化して、コンテナとして動かす Dockerイメージとして Linuxファイルシステムを Dockerは「Dockerイメージ」にパッケージ化。これは、仮想マシンの(ディスク)イメージとは全く異なる概念。 Dockerイメージとは、正確には「Dockerコンテナの実行に必要な、命令の入ったテンプレート」なのです。
  16. Dockerとは何であるかの定義 16 “Docker allows you to package an application with all of its dependencies into a standardized unit for software development.” www.docker.com 全ての依存関係をパッケージ化して、コンテナとして動かす Dockerイメージとして Linuxファイルシステムを そして、イメージの中にあるファイルを、「コンテナ」として「動かす」のが新しい概念です。コンテナとして動かすとは・・・?
  17. 17 Nginxのコンテナを作っておいたよ~ 先ほどの「Nginx」の例では、「Nginx」のバイナリ、設定ファイル、関連ファイルを Docker イメージにパッケージ化し それを、「NginxのDockerコンテナ」として実行します。コンテナの実行とは・・・・・? バイナリ 設定ファイル データ Nginxを実行するために依存関係がある ファイルすべてをパッケージ化 (この中身は、 Linux ファイルシステム) 「Nginx が入っている Docker イメージ」を使って、 「Nginx の Docker コンテナ」を「実行」する Nginx Docker イメージ Docker の仕事とは Docker イメージ ≠ Docker コンテナ
  18. 18 (物理または仮想) コンピュータ 一旦、コンテナではない、通常の Linux のプロセスを動かす(走らせる)状態を見てみましょう。
  19. 19 (物理または仮想) コンピュータ CPU メモリ 記憶装置 コンピュータ上に、ハードウェアとしてのCPUやメモリ、記憶装置が存在し、
  20. 20 (物理または仮想) Linux カーネル + システム・ライブラリ(libc)等 コンピュータ CPU メモリ 記憶装置 オペレーティングシステム (OS)の領域 OSの領域が記憶装置内のファイルシステム内にあり、 メモリ空間への読み込みや CPU で命令を実行します。
  21. 21 (物理または仮想) ユーザ空間 システム空間 Linux カーネル + システム・ライブラリ(libc)等 コンピュータ CPU メモリ 記憶装置 オペレーティングシステム (OS)の領域 バイナリ 設定ファイル ソースコード データ 一般的な プロセス実行 一般的なプロセスは、何らかのバイナリのプログラムを もとに、カーネルのユーザ空間で
  22. 22 (物理または仮想) ユーザ空間 システム空間 Linux カーネル + システム・ライブラリ(libc)等 コンピュータ CPU メモリ 記憶装置 オペレーティングシステム (OS)の領域 プロセス バイナリ 設定ファイル ソースコード データ プロセス 一般的な プロセス実行 プログラムを実行します。この実行状態のプログラムを プロセスと呼び、OS上の様々なリソースにアクセスします。
  23. 23 (物理または仮想) ユーザ空間 システム空間 Linux カーネル + システム・ライブラリ(libc)等 コンピュータ CPU メモリ 記憶装置 オペレーティングシステム (OS)の領域 バイナリ 設定ファイル ソースコード データ コンテナは 特別な状態の プロセスのこと isolate(隔離) プロセス isolate(隔離) プロセス 「コンテナ」としてのプロセスも、プログラムの実行という 意味では同じですが、Dockerの介在で、Linuxカーネル など諸機能によって “isolate” (隔離)したプロセスです。 アイソレート アイソレート アイソレート
  24. 24 isolate(分離)する ア イ ソ レ ー ト “名前空間”技術を使って namespace ネームスペース
  25. 25 isolate(分離)する ア イ ソ レ ー ト “名前空間”技術を使って namespace 大事なのは、Dockerで何かのプロセスを実行時、Linuxカーネルにある複数の名前空間技術を使い、 特別な状態のプロセス、つまり、様々な名前空間等をisolate(分離)して実行する点です。分離して実行。 日本語ではisolateを「隔離」と翻訳することもありますが、 意味としては「地理的に異なる場所に引き離す」のではなく、 壁や襖のように「分割」「区分けする」や「分離」するという 意味合いのほうが、適切と思います。 DockerはLinuxプロセスに対して、 様々な名前空間やリソース等、 「プロセスの実行環境」を ネームスペース アイソレート
  26. 26 isolate(アイソレート)の語源は、アイランド(island)とかアイル(isle)のように、断崖絶壁の「孤島」のようなイメージ。 プロセスはOS上で動いているのに、自分だけが孤島に一人いるかのような状態。
  27. 27つまりDockerコンテナはこんな状態。部屋がOS全体とすると、布団によってプロセス(人間)が分けられている状態。 人間に例えると、布団をかぶっていますので、外の様子は見えません。
  28. コンテナは特別なプロセスの状態 28 …/etc /bin ( / httpd PID N プロセスA プロセスB ruby PID M chris.rb PID O コンテナB 通常、Linux上で、プログラム をプロセスとして動かし続け るには、/ (ルート)ディレクトリ 以下のファイルシステム上に あるバイナリを、プロセスとし て起動します。 ホスト上
  29. コンテナは特別なプロセスの状態 29 コンテナAの ファイルシステム … … コンテナBの ファイルシステム /etc (/data/ubuntu/etc) /bin (/data/ubuntu/bin) /etc (/data/centos/etc) /bin (/data/centos/bin) / / httpd PID 1 プロセスA プロセスB ruby PID 1 chris.rb PID 2 コンテナA コンテナB 改めて「コンテナは特別な状態 =isolateしているプロセス」で、 お互いのプロセス空間だったり ファイルシステムやネットワー クなどがisolateしています。
  30. コンテナは特別なプロセスの状態 30 コンテナAの ファイルシステム … … コンテナBの ファイルシステム /etc (/data/ubuntu/etc) /bin (/data/ubuntu/bin) /etc (/data/centos/etc) /bin (/data/centos/bin) / / httpd PID 1 プロセスA プロセスB ruby PID 1 chris.rb PID 2 コンテナA コンテナB 名前空間の isolate ・プロセス ・ファイルシステム ・ネットワーク ・ホスト名 ・UID・GID ・プロセス間通信、等 cgroupでリソース制限 ・CPU ・メモリ ・I/O ・ディスク・クォータ、等 そして、ここで使われる技術が 名前空間(namespace)や、 cgroupであり、コンテナ内の プロセスは、お互いの状態を知 ることができません。
  31. 31 デフォルトで isolate あらためて、こんな感じの布団をかぶったような状態が、コンテナです。
  32. 32 デフォルトで isolate あらためて、こんな感じの布団をかぶったような状態が、コンテナです。布団空間内では、自分のプロセスしか見えない。 デフォルト(初期状態)からお互いにisolate(隔離・分離)しているプロセスの状態。 isolate 中にプロセス 中にプロセス
  33. PID名前空間 33 httpd PID 1 プロセスhttpd 名前空間 プロセスruby 名前空間 ruby PID 1 chris.rb PID 2 名前空間の代表的なものがPID名前空間。「httpd」「ruby」これらの2つのプロセスは、 それぞれの名前空間内では、それぞれが PID1 として独立しています。
  34. PID名前空間 34 httpd PID 1 プロセスhttpd 名前空間 プロセスruby 名前空間 ruby PID 1 chris.rb PID 2 /sbin/init PID 1 containerd PID 5 httpd PID 6 ruby PID 7 chris.rb PID 8 alice PID 2 bob PID 3 PPID 1 PPID 1 PPID 4 PPID 5 PPID 5 PPID 7 PPID 1 dockerd PID 4 ホスト上には存在 ただし、あくまでisolateな状態のなのは「同じ名前空間内」のみ。 ホスト上で実際のプロセスは、通常のPIDを持ちます。isolateされているので、名前空間内ではPIDが変換されます。
  35. PID名前空間 35 httpd PID 1 プロセスhttpd 名前空間 プロセスruby 名前空間 ruby PID 1 chris.rb PID 2 /sbin/init PID 1 containerd PID 5 httpd PID 6 ruby PID 7 chris.rb PID 8 alice PID 2 bob PID 3 PPID 1 PPID 1 PPID 4 PPID 5 PPID 5 PPID 7 PPID 1 dockerd PID 4 ホスト上には存在 また、各PID名前空間内で、PID 1は一番上の特別なプロセス。自分以外のPID名前空間内やホスト側は見えません。
  36. ファイルシステムを分ける (chroot) 36 ubuntuの ファイルシステム … … centosの ファイルシステム /etc /bin /etc /bin / / Dockerイメージはファイルシステムを、マウント名前空間(mount namespace)で分離します。chrootと似た概念。 マウント ネームスペース
  37. ファイルシステムを分ける (chroot) 37 ubuntuの ファイルシステム … … centosの ファイルシステム /etc /bin /etc /bin / / /data/ubuntu /data/centos / /etc /data/bin ホスト上には存在 コンテナが見えている自分のファイルシステムとは、chrootのようにホスト上をマウントしているため、 別のコンテナ用ファイルシステムや、ホスト上の上位ディレクトリにある場所はアクセスできません。
  38. コンテナは特別なプロセスの状態 38 httpd の専用ファイルシステム (Dockerイメージ) … … ruby の専用ファイルシステム (Dockerイメージ) /etc (/data/ubuntu/etc) /bin (/data/ubuntu/bin) /etc (/data/centos/etc) /bin (/data/centos/bin) / / httpd PID 1 httpdプロセス専用の PID名前空間 ruby プロセス専用の PID名前空間 ruby PID 1 chris.rb PID 2 httpd コンテナの名前空間 ruby コンテナの名前空間 名前空間の isolate ・プロセス ・ファイルシステム ・ネットワーク ・ホスト名 ・UID・GID ・プロセス間通信、等 cgroupでリソース制限 ・CPU ・メモリ ・I/O ・ディスク・クォータ、等 PID名前空間、マウント名前空間 以外にも、ネットワークなども分 離しています。さらに、それぞれの コンテナにcgroupでリソースの 制限も可。ただし、コンテナは仮 想マシンではありません。ハード ウェアの仮想化は行わず、あくま でも、プロセスを特別な状態 にしているだけです。 mount 名前区間 mount 名前区間
  39. 39 では、Dockerは コンテナを どうやって 作ってるの? 以上が一般的に「コンテナ」と呼ばれるものの正体。それでは次に、「Docker」は何をしているのでしょうか? コンテナ
  40. 40 技術と仕様 Technology Specification コンテナ Docker まず、コンテナは複数の「技術」総称であり、 Docker は、いわば「Docker仕様のコンテナ」を動かすためのプラットフォーム総称であり、プログラムの実装です。
  41. 41 ユーザ空間 システム空間 Linux カーネル + システム・ライブラリ(libc)等 オペレーティングシステム (OS)の領域 プログラム 設定ファイル ソースコード データ Docker イメージ ビルド pull Dockerイメージ Dockerイメージ ※異なるシステム、バージョン、ソースコード Dockerイメージを使って Dockerコンテナ(隔離状態)のプロセスを起動 Dockerは先ほどのコンテナ状態でプロセスを動 かす時、Linuxカーネルと通信したり、Dockerイ メージをとってきたりする役割があり、Linux サー バ上では dockerd という名前のデーモンが動き ます。これを「Docker エンジンと」呼びます。
  42. 42 ユーザ空間 システム空間 Linux カーネル + システム・ライブラリ(libc)等 オペレーティングシステム (OS)の領域 プログラム 設定ファイル ソースコード データ Dockerコンテナ プロセス Dockerコンテナ プロセス Docker イメージ ビルド pull Dockerイメージ Dockerイメージ ※異なるシステム、バージョン、ソースコード Dockerイメージを使って Dockerコンテナ(隔離状態)のプロセスを起動 「実装としての」Dockerイメージを用い、Docker コンテナとしてisolateされたプロセスを動かすの が Docker(エンジン)。実はDocker以外にもコン テナと呼ばれる実装は、LXCなり各種自作なりを 含めて複数のものがあります。
  43. Dockerはサーバ・クライアント型モデル 43 OS ( Linux ) 物理/仮想サーバ Docker エンジン ( dockerd デーモン ) Linux kernel コンテナ コンテナ コンテナ リモート API docker クライアント TCP あるいは Unix ソケットドメイン containerd Runtime: runC (OCI規格準拠) ・docker コマンド Linux, Mac OS X, Windows ・Kitematic (GUI) Mac OS X, Windows ・Docker Compose ・Docker Swarm Dockerコンテナを管理するDockerエンジン(dockerd)はAPIで制御でき、 通常は「docker」という名称のコマンドラインで、「docker run hello-world」のように実行します。
  44. 【参考】 Docker Engine のアーキテクチャ 44※ Docker Engine v1.11 以降 ユーザ (docker CLI等) Docker Container Engine dockerd containerd (docker-containerd) shim (docker-containerd-shim) shim (docker-containerd-shim) shim (docker-containerd-shim) runC (runtime-runc) コンテナ Docker Image コンテナ Docker Image コンテナ Docker Image JSON/REST API CNCF/OCI業界標準規格に準拠 runC (runtime-runc) runC (runtime-runc) gRPC エンドポイント Docker Engine トップレベルのデーモン (Moby プロジェクトの成果物) Docker イメージに含むファイルを、 パラメータに従い、コンテナとして実行 コンテナを実際に作成・起動する ランタイムのバイナリ・プログラム コンテナやイメージをはじめとし、 ネットワーク、ストレージを管理する 必要最小限のデーモン ランタイムが実行したコンテナを管理 厳密には、1つ1つのコンテナはrunCというランタイムが管理し、 これらを containerd というデーモンで管理し、docker コマンド の受付や全体の処理を dockerd が行います。 ランシー
  45. 45 Dockerイメージとは ここからはDockerの内部事情について。まずは、コンテナの元になる「Dockerイメージ」について理解します。 Docker イメージの構造は Docker コンテナを形作る実装と深い関係があります。
  46. docker image pull (docker pull) 46 $ docker image pull hello-world Using default tag: latest latest: Pulling from library/hello-world d1725b59e92d: Pull complete Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 Status: Downloaded newer image for hello-world:latest Docker Hub まず、Dockerイメージは、Docker Hubと呼ばれるイメージを共有・共同作業・自動構築するための 公開リポジトリ上を通して配布されており、ここからダウンロードしたり、アップロードしたりできます。 ドッカーハブ ドッカー イメージ プル ドッカー プル ※Dockerイメージを、ローカルにダウンロードするコマンド Dockerイメージを準備するには、 自分で構築(ビルド)する方法と ダウンロードする方法があります。
  47. 47 $ docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world d1725b59e92d: Pull complete Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 Status: Downloaded newer image for hello-world:latest 「docker pull イメージ名」コマンドの実行は、ユーザ名に相当する名前空間(スラッシュより前)が無ければ、 自動的に公式イメージ用の「library」というリポジトリからダウンロードします。 docker image pull (docker pull) Docker Hub ドッカー イメージ プル ドッカー プル ※Dockerイメージを、ローカルにダウンロードするコマンド 「pull」コマンドは「引っ張ってくる」 という意味です。Docker Hub から イメージを引っ張ってきます。 ライブラリ
  48. Dockerイメージはイメージ・レイヤの積み重ね 48 プログラムやライブラリと メタ情報(実行するプログラムやポートなど) Dockerイメージは、仮想マシンイメージのように、1つのファイルが存在するのではありませえん。 実際には複数のイメージ・レイヤ(層)の重なりで構成され、これを1つのファイルシステムとして使えます。 複数のイメージ・レイヤ(層) が重なり(実体としては、ホスト 上の複数のファイルやディレ クトリを、1つのファイルシステ ムに見せる技術UFSを使用)、 あたかも1つのファイルシステ ムとして、 Docker イメージが 存在しているように見えます。
  49. Dockerイメージはイメージ・レイヤの積み重ね 49基本となるのは、ベース・イメージと呼ばれる、様々な Linux ディストリビューションのファイルシステムです。 ...etc Docker Hub 上ある公式イメージ例
  50. Dockerイメージはイメージ・レイヤの積み重ね 50この上に、複数のイメージ・レイヤ(層)が積み重なり、
  51. Dockerイメージはイメージ・レイヤの積み重ね 51 プログラムやライブラリと メタ情報(実行するプログラムやポートなど) コンテナを動かすために必要な依存関係をパッケージ化したものが、Docker イメージです(読み込み専用)。
  52. Dockerイメージはイメージ・レイヤの積み重ね 52 利用時には 1つに見える 親 子 関 係 重要なのは、イメージ・レイヤは親子関係(親・イメージの情報)を持つのと、 利用時には複数のイメージ・レイヤ(実体として、ホスト上に複数のファイルやディレクトリ)が1つに見えます。
  53. Dockerイメージはイメージ・レイヤの積み重ね 53 利用時には 1つに見える 親 子 関 係 派生は親子関係 レイヤを共有可 利用時には 1つに見える プログラムやライブラリと メタ情報(実行するプログラムやポートなど) だから高速に移動できる・開発を高速化できる リソースを有効に使える “lightweight” な性質 gitでfork(分岐)するように、共通の親イメージを持つイメージ・レイヤも存在でき、ホスト上に余分な容量を必要としません
  54. 54 利用者からは 1つに見える docker image build -t <IMAGE:TAG> . (docker build) そして、Dockerflie の各行が、(抽象概念としての)イメージ・レイヤを構成しています。これは Alpine Linux です。 Dockerfile で Docker イメージを自動構築するコマンド: ドッカー イメージ ビルド 疑似tty イメージ・コロン・タグ 最後のドットがコンテクスト(Dockerfileのある場所)を指定 ドッカーファイル
  55. 55 利用者からは 1つに見える hello:v1 FROM alpine ENTRYPOINT ["/bin/echo"] CMD ["こんにちは!こんにちは!"] docker image build -t hello:v1 . (docker build) たとえば、このような Dockerfile を「バージョン1」として、
  56. 56 hello:v1 FROM alpine ENTRYPOINT ["/bin/echo"] CMD [“おはよう!おはよう!"] docker image build -t hello:v2 . hello:v2 3行目の「CMD」行だけ書き換えたものを「バージョン2」のイメージとしても、増えるのは「CMD」用のレイヤのみ。 また、ビルド済みイメージ・レイヤは「キャッシュ」として利用できるので、高速な構築が可能になります。
  57. Dockerfileで中間コンテナ実行・イメージ作成を自動化 ❶ まず Dockerfile を 書きます。あるいは、 GitHub等から取得 ❷ “docker build” で Docker はイメージを 自動構築開始 ❸完成したイメージで コンテナを起動したり DockerHubに送信を 命令1 命令2 命令3 $ mkdir myproject $ cd myproject $ vim Dockerfile $ docker build -t myproj . 読み込み イメージレイヤ群を自動構築 Dockerfile $ docker run -d myproj $ docker push DockerがDockerfileを読み込み 中間コンテナを起動して命令を実行 →docker commitでイメージ化 ((( commit commit commit 通常、Docker コンテナを作って 実行するまでは、このような流れ
  58. Dockerfile Dockerfile にイメージ構築に必要な全ての命令を書く • Dockerイメージは読み込み専用のイメージレイヤ群で構成 • 各イメージ・レイヤが Dockerfile の命令に相当する • 記述例 58 FROM ubuntu:18.04 ← “ubuntu:18.04”のイメージから、レイヤを作成 もう少し Dockerfile について掘り下げます。Dockerfile は自分でもテキスト・エディタ等で自由に書けます。
  59. Dockerfile Dockerfile にイメージ構築に必要な全ての命令を書く • Dockerイメージは読み込み専用のイメージレイヤ群で構成 • 各イメージ・レイヤが Dockerfile の命令に相当する • 記述例 59 FROM ubuntu:18.04 COPY . /app ← “ubuntu:18.04”のイメージから、レイヤを作成 ← “.” ディレクトリを、コンテナの “/app” にコピー レイヤは親子関係を持ち、依存・参照 Dockerfile は上の行から順番に処理が進みます。
  60. Dockerfile Dockerfile にイメージ構築に必要な全ての命令を書く • Dockerイメージは読み込み専用のイメージレイヤ群で構成 • 各イメージ・レイヤが Dockerfile の命令に相当する • 記述例 60 FROM ubuntu:18.04 COPY . /app RUN make /app ← “ubuntu:18.04”のイメージから、レイヤを作成 ← “.” ディレクトリを、コンテナの “/app” にコピー ← コンテナ内で “meke /app” を実行 レイヤは親子関係を持ち、依存・参照 Dockerfileがなくても、「docker history」コマンドでイメージの内容を調べられます。
  61. Dockerfile Dockerfile にイメージ構築に必要な全ての命令を書く • Dockerイメージは読み込み専用のイメージレイヤ群で構成 • 各イメージ・レイヤが Dockerfile の命令に相当する • 記述例 61 ← “ubuntu:18.04”のイメージから、レイヤを作成 ← “.” ディレクトリを、コンテナの “/app” にコピー ← コンテナ内で “meke /app” を実行 ← コンテナ実行時、デフォルトで実行するコマンドとして ”python /app/app.py” を指定 FROM ubuntu:18.04 COPY . /app RUN make /app CMD python /app/app.py
  62. Docker BuildKit を使う方法 • クライアントの環境変数 • Docker デーモン設定ファイル /etc/docker/daemon.json 62 { "features": { "buildkit": true }} export DOCKER_BUILDKIT=1 現在の Docker 18.03 以降では、 BuildKit を有効にすると、並列ビルドなどによって高速にイメージを構築できます。
  63. 63 Dockerイメージと Dockerコンテナの関係 Docker イメージは、複数のイメージ・レイヤによって構成される Linux ファイルシステムで これを使って「Dockerコンテナ」を「作成」した後、「Dockerコンテナ」としてのプロセスを「実行」します。
  64. Dockerコンテナ作成とはコンテナ用のレイヤを追加 64 元のレイヤに対する変更情報を記録 Copy on Write の性質 Dockerコンテナの作成とは、元となる Docker イメージのレイヤ上に、読み書き可能なイメージ・レイヤを追加します。 そのため、イメージ・レイヤ内のファイルやディレクトリに対する操作は、すべて新しいレイヤ上に記録されます。 コンテナ作成時、新しい「読み書き可能」なイメージ・レイヤを追加
  65. Dockerコンテナ作成とはコンテナ用のレイヤを追加 65 利用者からは 1つに見える 元のレイヤに対する変更情報を記録 Copy on Write の性質 コンテナ用のレイヤは、Docker イメージのレイヤと同様、1つのファイルシステムとして利用できる特性があるため、 Dockerイメージがローカルにある場合、Dockerコンテナの作成は高速になります。
  66. Dockerコンテナ作成とはコンテナ用のレイヤを追加 66 利用者からは 1つに見える 利用者からは 1つに見える だから高速に移動できる・開発を高速化できる リソースを有効に使える “lightweight” な性質 元のレイヤに対する変更情報を記録 Copy on Write の性質 また、複数のコンテナを作成しても、都度コンテナ用のレイヤを追加するだけです。 そのため、仮想マシンの作成に比べると、アプリケーションの実行環境を格段に早く準備できます。
  67. Dockerコンテナ実行とは? 67つまり、Dockerコンテナの実行とは、「Dockerイメージ」に「読み書き可能なイメージ・レイヤ」を追加し、 ファイルシステム内にあるバイナリを、名前空間を分離した特別な状態のプロセスとして実行することです。 バイナリ 設定ファイル ソースコード データ Dockerコンテナ プロセス isolateした特別な名前空間で プロセスを実行 Docker コンテナの「作成」 Docker コンテナの「実行」 docker container create docker container start + docker container run
  68. 68 Nginxのコンテナを作っておいたよ~ さて、改めて「Nginxのコンテナを作っておいたよ~」の意図を振り返ってみましょう。
  69. 69 Nginxのコンテナを作っておいたよ~ 「Nginx」の Docker イメージには、バイナリ、設定ファイル、関連ファイルをパッケージ化し、 名前空間でisolate(分離)した特別な状態としてのプロセスを「NginxのDockerコンテナ」として実行します。 バイナリ 設定ファイル データ Nginxを実行するために依存関係がある ファイルすべてをパッケージ化 (この中身は、 Linux ファイルシステム) 「Nginx が入っている Docker イメージ」を使って、 「Nginx の Docker コンテナ」を「実行」する Nginx Docker イメージ Docker の仕事とは Docker イメージ ≠ Docker コンテナ
  70. Docker ネットワーク概要 Docker network 70
  71. デフォルトはコンテナ外から通信不可 71 コンテナ (分離された名前空間) ホスト上 port 80 ethX コンテナのプロセスが名前空間によって 分離されているのと同様、ネットワークも デフォルトで分離されています。 コンテナ実行時、コンテナから外部への 通信は可能です(インターネットに疎通 しています)。 しかし、コンテナ内でポートを開いていた としても(例:ポート80をリッスン)、ホスト 上・ホスト外を問わず、コンテナ内のポー トにはアクセスできません。
  72. 72 3つの Docker 標準ネットワークモデル bridge (bridge) host (host) none (null) ブリッジ(bridge0 …) veth eth0 ethX Dockerでコンテナを実行すると、 プロセスの「ネットワーク」や「ホスト名」 もisolate(分離)した状態で起動。 docker network lsコマンドの実行で はじめから3つのネットワークが表示。
  73. 73 3つの Docker 標準ネットワークモデル bridge (bridge) ブリッジ(bridge0 …) veth eth0 ethX none (null) host (host) 複数のブリッジ(ネットワーク)を定義できる デフォルトのbridge0ブリッジは、旧仕様の ネットワークで、挙動が異なる デフォルトは「ブリッジ」ドライバを使う 「bridge」という名称のネットワークを 通して、ホスト側にポートをマッピング port 8080 port 80 docker run -p 80:8080
  74. 74 3つの Docker 標準ネットワークモデル bridge (bridge) host (host) none (null) ブリッジ(bridge0 …) veth eth0 ethX ホスト側のネットワークに直接接続 ブリッジのオーバーヘッドがない一方で、 セキュリティに対する考慮が必要 ホスト側のインタフェースを直接 使いたい場合、docker run のオプショ ンで --network=host を指定 port 8080 port 8080 コンテナでポートを開くと、 自動的にホスト側の公開 ポートを直接利用する
  75. 75 3つの Docker 標準ネットワークモデル bridge (bridge) host (host) ブリッジ(bridge0 …) veth eth0 ethX ネットワークを追加しない限り疎通できない none (null) コンテナ内からインターフェースが 見えず、他のコンテナや外部の ネットワークに対して疎通させない
  76. 76 3つの Docker 標準ネットワークモデル bridge (bridge) host (host) none (null) ブリッジ(bridge0 …) veth eth0 ethX NAT (iptables) + docker-proxy ホストと ネットワーク 共通 疎通しない コンテナはパブリックなIPアドレスを持ない ホスト側のポート番号を重複して、コンテナ のポート利用(マッピング)はできない 動的なネットワークの追加・変更・削除
  77. 77 コンテナは複数のネットワーク(ブリッジ)に接続できる ブリッジ1(bridge) veth eth0 ethX 各ネットワーク内部では、動的なコンテナ名 (サービス)の名前解決機能(サービス・ディス カバリ)を標準提供している eth0 eth1 eth0 ブリッジ2(bridge) veth192.168.0.1 172.18.0.2 172.18.0.3 172.19.0.2 172.19.0.3 172.19.0.1 172.19.0.0/16172.18.0.0/16 サービス・ディスカバリ連携の負荷分散 この画面では、2つのネットワークが 存在しています。コンテナは動的に ネットワークへ接続・切断できます。
  78. 78 デフォルトで isolate ネットワークもDockerコンテナは
  79. 【参考】 swarm mode のネットワーク機能 79 Multi Host Networking Worker node Worker node Worker node overlay network Ingress network コンテナ PublishPort Routing Mesh 80 443 80 443 80 443 負荷分散 swarm mode でクラスタを組む場合、複数のサーバ間で共通の ingress ネットワークを利用できます。 クラスタのどのノードにアクセスしても、内部ネットワークを通して、コンテナが存在するノードにルーティングし、 複数台のコンテナがある場合は負荷分散も行います(コンテナのサービス名で名前解決します)。 サービス・ディスカバリ (動的な名前解決) スウォーム・モード 公開ポート イングレス・ネットワーク オーバレイ・ネットワーク ワーカーノード ルーティング・メッシュ
  80. Docker ボリューム概要 Docker volume 80
  81. 81 データの扱い コンテナA専用 ファイル階層 File System … / /bin /etc /var コンテナB専用 ファイル階層 File System … / /bin /etc /var hello.txt HOST Root File System /var/lib/docker/overlay/ hello.txt 実際のホスト上におけるディレクトリ名やファイル 名はストレージドライバの実装によって異なる A BUFS( Union File System ) この2つのコンテナ(のプロセス)は、別々に独立した (isolateした)ファイル階層を持っています。
  82. 82 データの扱い コンテナA専用 ファイル階層 File System … / /bin /etc /var コンテナB専用 ファイル階層 File System … / /bin /etc /var hello.txt × HOST Root File System /var/lib/docker/overlay/ hello.txt A BUFS( Union File System ) 別の名前空間(Mount namespace)上にある ファイルは、原則として参照できません。 実際のホスト上におけるディレクトリ名やファイル 名はストレージドライバの実装によって異なる
  83. 83 データの扱い コンテナA専用 ファイル階層 File System … / /bin /etc /var コンテナB専用 ファイル階層 File System … / /bin /etc /var hello.txt × HOST Root File System /var/lib/docker/overlay/ hello.txt A BUFS( Union File System ) プロセスだけでなく、(名前空間がマウントして いる)ファイルシステムもisolate(独立)状態 実際のホスト上におけるディレクトリ名やファイル 名はストレージドライバの実装によって異なる
  84. 84 ボリューム コンテナA専用 ファイル階層 File System … / /bin /etc /var コンテナからはUFSを通して(マウントして)データ領域が見える ストレージ・ドライバのオーバヘッドを受けない 複数のコンテナでボリュームを共有できる volume /data / ボリューム Volume /var/lib/docker/volumes/HOST Root File System 例外として、「ボリューム」という抽象的な概念を持つ場所を、コンテナのファイルシステムにマウントできます。これは イメージのレイヤ構造と分かれているため、docker build や docker commit をしても、内容をイメージ化しません。
  85. 85 コンテナ ファイル階層 File System / UFS ( Union File System)… / /bin /var Docker イメージ Docker Image /var/lib/docker/image/ volume / ボリュームVolume /data コンテナ用 イメージ層 Container’s Image Layer / /var/lib/docker/volumes//var/lib/docker/containers/ ReadOnly このように、コンテナ上で見えるファイルシステムは、複数のディレクトリを1つに統合して操作可能にしています。
  86. 86 ボリュームは3分類 ホストをマウント 名前付き ホスト上のディレクトリ /docker/data /data 名前無し volume ボリュームの実体は、ホスト上のディレクトリ /var/lib/docker/volumes/ 以下 ボリュームはコンテナ間でデータを共有できる volume /data /data /etc docker run –v [ホスト上のパス]:[コンテナ上のパス]で、 コンテナ上からホスト上に直接接続(マウント)する方法と、 抽象概念としてのボリューム領域を指定する方法があります。 docker run –v /docker/data/:/data docker run –v data:/data Dockerでコンテナ間で動的な データ領域を共有するには、
  87. コンテナを作る まとめとふり返り 87 #とは コンテナ
  88. Dockerコンテナ実行とは? 88 バイナリ 設定ファイル ソースコード データ Dockerコンテナ プロセス isolateした特別な名前空間で プロセスを実行 Docker コンテナの「作成」 Docker コンテナの「実行」 docker container create docker container start + docker container run 改めて Docker の仕事は、アプリケーション実行に最低限必要なファイルを Docker イメージにパッケージ化し、 その中に含まれているバイナリを、(isolate=分離した)特別な状態のプロセスとして実行することです。
  89. 89 Nginxのコンテナを作っておいたよ~ 一般的に、コンテナを作って動かした場合は、
  90. 90 Nginxのコンテナを作っておいたよ~ バイナリ 設定ファイル データ Nginxを実行するために依存関係がある ファイルすべてをパッケージ化 (この中身は、 Linux ファイルシステム) 「Nginx が入っている Docker イメージ」を使って、 「Nginx の Docker コンテナ」を「実行」する Nginx Docker イメージ Docker の仕事とは Docker イメージ ≠ Docker コンテナ Nginxであれば、このような利用シーンです。Docker イメージで、Docker コンテナを実行。 そして、各イメージ・レイヤは親子関係を持ち、移動や再構築をスムーズに行う仕組みが整っています。
  91. 91 コンテナの「気持ち」を理解しよう
  92. 92 コンテナの「気持ち」を理解しよう
  93. 93 コンテナの「気持ち」を理解しよう 布団から出られない人のいらすと https://www.irasutoya.com/2014/04/blog-post_2419.html Copyright デフォルトで isolate 寒い冬は、布団でぬくぬくしていたいですよね、「布団から出たくない人」の気持ちこそが、コンテナの気持ち! (半分冗談ですが)
  94. Dockerとは? 94 Why Docker? 1 Dockerコンテナは 実行に必要な全て をパッケージして、 簡単に動かせる 2 Dockerイメージは 複数イメージ・レイヤと メタ情報の積み重なり 3 コンテナのプロセス はデフォルトで isolate(隔離・分離) された状態 ⚫ イメージ・レイヤ(image layer)は 読み込み専用 ⚫ 親子関係がある ⚫ イメージに対する変更はCopy on Write(CoW)処理が走る ⚫ コンテナ実行にはイメージが必要 で、Docker Hubから得られる ⚫ コンテナ実行時のみ、読み書きが 可能なレイヤを追加 ⚫ namespace(名前空間)でプロセ ス空間やファイルシステムやネッ トワーク等を分ける技術と、 cgroups(コントロール・グループ) でリソースの利用上限を指定 ⚫ コンテナはポートをデフォルトで 開かない ⚫ ネットワークはブリッジ、ホスト、 noneの3種類 ⚫ ボリュームはコンテナ間でファイル システムを共有できる。名前付き (named)とホスト・ボリューム ⚫ アプリケーションを簡単に開発し、 移動し、実行するためのプログラム とプラットフォームを提供するのが Docker ⚫ クライアント・サーバ型 https://docker.com プロセスを簡単にコンテナ化(isolate)し、 簡単かつ素早く開発・移動・実行できるプラットフォームが Docker Containerization 「プロセス・ファイルシステム・ネットワーク・等々」に対して Namespace・Cgroup Build Ship Run コンテナ化 名前空間 シーグループ
  95. 次のステップは? 95 チュートリアルを試して、 実際にコンテナを 操作しましょう Docker Meetup Kansai 19.06 ハンズオン手順 - Qiita https://qiita.com/zembutsu/items/322987181616a54c359a
  96. 私からは以上です。ありがとうございました。 【参考資料】 • https://slideshare.net/zembutsu • Dockerドキュメント日本語訳 http://docs.docker.jp • Docker Composeドキュメント日本語訳 http://docs.docker.jp/compose/ • 公式ドキュメント https://docs.docker.com 96
Publicité