見出し画像

Dockerについてまとめてみた

Dockerとは

コンテナ型仮想環境を作成し、コンテナを実行/管理するためのプラットフォームで、Dockerを利用すればコンテナ上でプログラムを実行することが可能になります。Dockerソフトウエアを使うことで素早くコンテナを起動し、様々なアプリを実行でき、かつ異なる環境で同じ仮想環境を用意できるといった点が強みです。

画像12

Dockerユースケース

・開発環境を構築するといったケースでDockerが使用されています。開発者個人個人のPCで開発中のアプリケーションを全く同じ環境で用意することが可能です。
・Dockerで作成した環境・アプリケーションをDocker Imageに固め、Dockerリポジトリというイメージを管理するサーバへアップロードする。そのイメージをダウンロード&イメージからコンテナを起動する形で開発したときと同じ環境を持っていくことができます。(Dockerの可搬性

画像12


・各種プログラミング言語の実行環境、ミドルウエアの環境構築といった様々なコンテナを立ち上げることができる。(例えば、Javaの実行環境が用意されたDockerImageをリポジトリから取得しコマンドを1つ打つだけでJavaがインストールされたLinux仮想環境を用意できます。)
・Webサーバ(Apache、nginx)、データベース(MySQL、PostgreSQL)の構築も用意。

Dockerのメリット

①プログラミングの実行環境を素早く立ち上げられる。
②設定ファイルを共有することでメンバー間で同じ環境を立ち上げられる。
(インフラ環境をコードで定義したものをInfrastracture as a codeと呼ぶ。設定ファイルを見ればインストールされているものもわかる。)
③開発者と同じ環境を一瞬でそろえられるので、環境の違いででる差異を解消できる。(再現性)
④インストールなどが必要なくホストのライブラリやミドルウエアが汚れない。
⑤ネットに便利なコンテナが提供されており、記述する必要がない。

コンテナとは

コンテナとは、プロセスの実行空間を隔離するための技術です。コンテナと似たような概念に「ホスト型仮想化」というのがあり、VMWareやVirtualBoxなどが代表的な例ですが、それらの違いを理解することが大切です。
コンテナを説明する前にまずホスト型仮想化について説明をし、コンテナとの違いを明確にすることで、Dockerを理解していきます。

画像7

インフラストラクチャー:PCやサーバなどのハードウエア層
ホストOS:物理的なPCやサーバにインストールされたOS、WindowsやMacOSなど、サーバでいうとWindowsServerやLinuxなどが一般的なホストOS。
ハイパーバイザ:ホストOS上に仮想マシンを動作せるためにホストOSとゲストOSの中間でやり取りを行う部分。仮想マシンのハードウエアのエミュレーションをしたりOSが使用するCPU、メモリ、ハードウエアなどを制御するソフトウエアとなります。

ホスト型仮想化環境

ホストOSのハイバーバイザ上で複数のVM(仮想環境)を動作させホストOSとVMのOSが隔離された環境で動作し、ホストOSがなんであるかによらずVMごとに任意のゲストOS(Windows、Linux)を動作せることができます。
個々のVMのOS上に任意のアプリケーションをインストールさせるので、物理的なサーバと同じように動作させることが可能です。
こういった構想の仮想化のことをホスト型仮想化と呼びます。

画像9

ホスト型仮想化環境のデメリット

・物理サーバにOSをインストールしたものと近い環境を作る代わりにイメージサイズが大きいため、VMの作成やイメージの移動に時間がかかる。
・通常のOS起動と同様にそれなりに時間がかかる。

コンテナ型仮想化環境

コンテナ型仮想化環境では、ゲストOSは動作させずホストOSの1プロセスとしてコンテナが動作します。完全なOSを用意する必要がないのでアプリケーションを実行するための最低限のライブラリやバイナリを用意すればよく、コンテナで用意するイメージサイズを少なくできます。

画像10

CentOSやUbuntuなどのイメージも提供されていますが、ゲストOSと違い、コンテナ上でゲストOSを動作させているのではなく、LinuxコマンドをホストOSのカーネルで実行しています。実行したいライブラリはコンテナ側に存在して、ホスト側のカーネルを使用して動作するという仕組みです。

※ホストOSのカーネルを使用してコンテナコマンド、ライブラリを実行するということは、カーネルを共有できないOS(Widnows環境)では動作させることができないということになる。Windows環境でどのようにしてLinux環境を動作させているかについては「WindowsでLinuxコンテナを利用できる理由」の欄をご覧ください。

ホスト型仮想化,コンテナ型仮想化の違い

ざっとホスト型仮想化環境とコンテナ型仮想化環境の違いをまとめましたのでご覧ください。

画像8

オーバーヘッド:リソース(CPU、メモリ使用率)が過度に使用してしまわないか。

再現性:アプリケーションを異なる環境で実行したときに、同じように動作するか。

WindowsでLinuxコンテナを利用できる理由

LinuxコンテナはLinuxOSのカーネル上でしかどうさせることができないはずですが、なぜWindowsでLinuxコンテナを使用できるのでしょうか。

PC環境ではまず以下のいずれかのソフトウエアをインストールしDockerを利用します。
・DockerDesktop
・DockerToolbelt

Docker Containerの作成・起動・停止・削除などはDockerEngine(上記ソフトウエア)を介して実行します。Docker Toolboxを使用する場合、Docker QuickStart Terminalといったツールを起動することでDockerEngineを起動する。

いずれをインストールした場合でもDockerデーモンは必ずLinux仮想マシン上で動作しています。ソフトウエアにはWindowsやMacで動作させるために内部的に軽量なLinuxOSであるtinyCoreLinuxというOSが含まれているのがLinuxコンテナを扱える理由だったんです。つまり、コンテナにゲストOSというものはなく、ホストOSのコア部分であるカーネルを使用してコンテナのアプリケーションを実行しています。

画像13

※仮想化ソフトウエアはインストールしたDockerソフトウエアによって何が使用されるかは異なります。

仮想化ソフトウエアは一般的に下記の通りです。
・MacOSのDockerDesktopではHyperKit
・WindowsのDockerDesktopではHyper-V
・DockerToolboxの場合はVirtualBox。

※VirtualBoxだけはOSに標準でインストールされていないので追加でインストールが必要です。サーバで動作させる場合、直接LinuxのホストOS上で動作させるが通常の流れです。

Docker Image

コンテナ実行に必要なファイルをまとめたファイルシステムです。オブジェクト指向でいうClassを指します。

Docker Container実行

Docker Image(仮想マシンでいうところのVMイメージ)は、Web上のDocker Hubで公開されています。Dockerイメージを取得してくれば、すでに必要なミドルウェアなどがインストールされた状態のDockerコンテナを起動でき、すぐに使用できます。

最新のイメージを取得~コンテナを起動~実行まで行うコマンド

(ローカルPC)
# docker run <コンテナ名>
# docker run hello-world
# docker run --name <コンテナ名> -v <ホスト側ディレクトリ>:<コンテナ側ディレクトリ> -d -rm -p <ホスト側のポート番号>:<コンテナ側のポート番号> <Dockerイメージ名> 
# docker run --name test-nginx -v /Users/i3_l1/Desktop/Docker/html/index.html:/usr/share/nginx/html:ro -d --rm  -p 8080:80 nginx 

Dockerイメージをプル(PULL)

最新のイメージを取得するコマンド

(ローカルPC)
# docker pull <コンテナ名>
# docker pull hello-world
pullしてくるタグはlatestとは限らない。

Dockerコンテナのプロセス確認

コンテナのプロセスを確認するコマンド

(ローカルPC)
# docker ps -a
※「docker ps」(「-a」を付けない)と実行すると、停止中のコンテナは表示されない。

イメージ一覧取得

コンテナ仮想化環境に存在するイメージを確認するコマンド

(ローカルPC)
# docker images
※リポジトリ(REPOSITORY)から拾ったバージョン(TAG )、イメージID(IMAGE ID )、作成日(CREATED)、サイズ(SIZE)、が取得可能

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB

イメージにタグ付けをする

同じイメージに対してイメージ名称を複数設定するコマンド

(ローカルPC)
# docker tag <元のイメージ名> <新しいイメージ名>
# docker tag hello-world my-hello

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB
my-hello            latest              bf756fb1ae65        10 months ago       13.3kB

同じイメージに対して、タグ名称を分けて管理できる。

(ローカルPC)
# docker tag <元のイメージ名> <新しいイメージ名>:<新しいタグ名>
# docker tag hello-world my-hello:tst1
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB
my-hello            latest              bf756fb1ae65        10 months ago       13.3kB
my-hello            tst1                bf756fb1ae65        10 months ago       13.3kB

イメージの詳細取得

ホスト名、環境変数、os情報、サイズ、ファイルシステムなどのコンテナ詳細を表示するコマンド

(ローカルPC)
# docker inspect <コンテナ名>
# docker inspect hello-world

コンテナ削除

ローカルで起動しているコンテナを削除するコマンド

# docker rm hello-world

イメージ削除

Dockerイメージを削除するコマンド

# docker rmi <コンテナ名>  または <IMAGE ID> 
# docker rmi hello-world

> docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:e7c70bb24b462baa86c102610182e3efcb12a04854e8c582838d92970a09f323

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my-hello            latest              bf756fb1ae65        10 months ago       13.3kB
my-hello            tst1                bf756fb1ae65        10 months ago       13.3kB

イメージ強制削除

イメージを強制削除するコマンド。※複数のタグが存在する場合、latestタグのイメージが削除される。

(ローカル)
# docker rmi -f <コンテナ名>  または <IMAGE ID> 
# docker rmi -f my-hello
Untagged: my-hello:latest

> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

my-hello            tst1                bf756fb1ae65        10 months ago       13.3kB

イメージファイル作成

イメージを構築するにはdockerfileというイメージの定義ファイルを作成します。dockerfileからイメージファイルを作成することをイメージビルドと呼ぶ。

(Dockerfile)
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf

イメージビルド方法

イメージファイルのビルドを行うコマンド

(ローカル)
# docker build -t <タグ名称> <ビルドコンテキスト>
# docker build -t nginx:test1 .

「.」はビルドコンテキストを表しています。ビルドコンテキストとは、イメージを作成する際にアクセスできるディレクトリやファイルを表しています。イメージ内に含めたいファイル/ディレクトリがある場合は、ビルドコンテキストのファイルから参照できます。ビルドコンテキスト外のファイルはイメージ構築時に参照できません。

Dockerfileが作成されていることを確認します。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx                test1               7fbf7e04654c        7 minutes ago       133MB

ビルドコンテキストはイメージビルド時にビルドコンテキストのファイルやディレクトリがまとめてDockerデーモンに送信されるため大きなファイルがコンテキストに含まれると送信に非常に時間がかかります。不要なファイルは極力削除しておくことをお勧めします。

2回目以降のビルドについて

Dockerfileが更新された場合、ビルドすると更新部分以降のビルドが行われる。1から改めてビルドしたい場合は、--no-cacheコマンドを使用する。

# docker build --no-cache -t <タグ名称> <ビルドコンテキスト>
# docker build --no-cache -t nginx:test1 .

Docker Hub RepositoryへPush

リポジトリにイメージがないことを確認

図1

レジストリサーバ(DockerHubもしくは他のリポジトリ)へログインする方法
# docker login
# docker login <レジストリサーバURL>

DockerHubリポジトリへプッシュ
# <Docker ID>/<イメージ名>:<タグ名>
# docker push nukoit/hello-world:latest

リポジトリにイメージが追加されている

図4

リポジトリの内容を確認

図2

図3

リポジトリからプルしてみる

①Docker イメージをローカルから削除
# docker rmi nukoit/docker-nuko
Untagged: nukoit/docker-nuko:latest
Untagged: nukoit/docker-nuko@sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042

②Dockerイメージをリポジトリからプル
# docker pull nukoit/docker-nuko
Using default tag: latest
latest: Pulling from nukoit/docker-nuko
Digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042
Status: Downloaded newer image for nukoit/docker-nuko:latest
docker.io/nukoit/docker-nuko:latest

③DockerImageが存在すること
# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
nukoit/docker-nuko   latest              bf756fb1ae65        10 months ago       13.3kB

ファイルコピー

(ホスト→コンテナ内)
# docker cp <ホスト側のファイル> <コンテナ名>:<コンテナ内のコピー先ディレクトリ>
# docker cp /Users/i3_l1/Desktop/Docker/html/index.html test-nginx:/usr/share/nginx/html
(コンテナ内→ホスト)
# docker cp <コンテナ名>:<コンテナ内のコピー元ファイル> <ホスト側のコピー先ディレクトリ>
# docker cp test-nginx:/etc/nginx/conf.d/default.conf ./

コンテナのライフサイクル

コンテナが起動している間はホストマシンの1プロセスとして動作します。コンテナが作成されてから削除されるまでにいくつかのステータスがあります。イメージ図をご覧ください。少しわかりずらいかと思うので少しずつ更新していきます。

画像13

以上、Dockerについてでした。またDockerについてUpしたいと思います。参考になったと思う方は是非いいねお願いいたします。(*'ω'*)

この記事が気に入ったらサポートをしてみませんか?