Dockerを使ったコンテナ環境構築、理解していますか?
Dockerの仕組みを基礎から理解しよう!
本記事ではDockerを利用したコンテナ環境構築について、意外と後回しにしてしまう基本的な考え方(Build、Ship、Run)を含めて、コンテナ環境構築の基本について説明したいと思います。
便利だけど実は結構複雑なコンテナの仕組み、流れをきちんと理解しよう!
今や多くのITエンジニアが利用しているDockerですが、一度Dockerfileを作ってしまえばその後はコマンド一つで簡単にコンテナを利用したアプリケーション実行環境が作れてしまいます。そんな手軽さもあるせいか、Dockerについてあまり理解せずに利用している人も多いのではないでしょうか。(私もその一人ですが。。)
なお、本記事を書くにあたり、以下の書籍を参考にしています。
2冊ともDockerの基本的な仕組みについて詳しく解説しているので、DockerやKubernetesについて理解を深めたい方はぜひ、目を通してみてください。
Dockerってなに?
Dockerとは、「コンテナ」という仮想化技術を利用することによってアプリケーションの開発や実行を行うためのサービス(OSS)です。またDockerは単一のマシン上におけるコンテナの管理やイメージの作成、イメージの共有などの、コンテナにおけるワークフローをサポートするサービスでもあります。
Dockerを理解する上での基本はBuild、Ship、Runの3つの処理
コンテナを理解する上では欠かせないのは、Docker社が提唱する3つの役割「Build、Ship、Run」によって構成されるワークフローです。
これら3つの役割は具体的には以下の通りです。
- Build:コンテナイメージの作成
- Ship:レジストリを利用したイメージの配布
- Run:コンテナの実行
では上記1~3について、具体的にどのようなことなのか、簡単に説明したいと思います。
Build:コンテナイメージの作成
まずはコンテナの実行に必要となる、コンテナイメージを作成します。コンテナイメージにはコンテナとして実行されるアプリケーションに必要とされる各種ライブラリなどや、コンテナ自体の環境情報などが保持されています。
コンテナイメージの作成においては、具体的にはdocker buildコマンドを実行します。docker buildコマンドを実行する際には以下の2つの部品が必要となります。
- Dockerfile:コンテナを作成する上で必要となる手順のようなもの
- コンテキスト:コンテナに格納されるファイル群
この2つを用意してdocker buildコマンドを実行すると、Dockerfileに記載されている手順に沿って、コンテナイメージが作成されます。
Run:コンテナの実行
上記のBuildで作成したコンテナイメージをdocker runコマンドで実行します。
Ship:レジストリによるコンテナイメージの配布
Docker Buildで作成したコンテナイメージを他のホストに配布する機能のことを指します。コンテナイメージは具体的にはdocker pushコマンドを利用してDocker Hubのようなレジストリサービスにイメージをpushして、他のホストからdocker pullコマンドによってイメージをpullするような形になります。
Dockerでコンテナを実行してみよう!
では実際にDockerを使ってコンテナを実行してみましょう!Dockerのインストールが完了していない方は、以下の過去記事を参考にDockerのインストールを行ってください。
簡単にできる!WSL2を利用したLinux開発環境構築手順-Dockerセットアップ編
1.作業用のディレクトリを作成
$ mkdir dockertest
2.ディレクトリ内にファイル(ここではtest.sh)を作成
$ touch ./dockertest/test.sh
test.shのファイルの中身は以下の内容を入力
#!/bin/bash echo "hello world!" exec sleep infinity
3.test.shのパーミッションを755に変更
$ chmod +x ./dockertest/test.sh
4.Dockerfileを以下の通り作成
$ touch ./dockertest/Dockerfile
FROM ubuntu:20.04 COPY ./test.sh /test.sh ENTRYPOINT [ "/test.sh" ]
5.docker buildコマンドを実行
$ docker build -t dockertest:v1 ./dockertest [+] Building 7.5s (8/8) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 111B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/ubuntu:20.04 4.2s => [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.0s => => transferring context: 86B 0.0s => FROM docker.io/library/ubuntu:20.04@sha256:fd92c36d3cb9b1d027c4d2a72c6bf0125da82425fc2ca37c414d4f010180dc19 3.0s => => resolve docker.io/library/ubuntu:20.04@sha256:fd92c36d3cb9b1d027c4d2a72c6bf0125da82425fc2ca37c414d4f010180dc19 0.0s => => sha256:fd92c36d3cb9b1d027c4d2a72c6bf0125da82425fc2ca37c414d4f010180dc19 1.42kB / 1.42kB 0.0s => => sha256:b2339eee806d44d6a8adc0a790f824fb71f03366dd754d400316ae5a7e3ece3e 529B / 529B 0.0s => => sha256:20fffa419e3aaca519dad480b21e86d9bcfbc7795abf9419adc5adce1198c95e 1.46kB / 1.46kB 0.0s => => sha256:d7bfe07ed8476565a440c2113cc64d7c0409dba8ef761fb3ec019d7e6b5952df 28.57MB / 28.57MB 1.4s => => extracting sha256:d7bfe07ed8476565a440c2113cc64d7c0409dba8ef761fb3ec019d7e6b5952df 1.2s => COPY ./test.sh /test.sh 0.1s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:44903b3b081ffd40a2cd0aca38a6a12f900ae698210b358d0c80ecd0cd99563c 0.0s => => naming to docker.io/library/dockertest:v1 0.0s $
6.docker imageコマンドでイメージの確認
$ docker image ls dockertest:v1 REPOSITORY TAG IMAGE ID CREATED SIZE dockertest v1 44903b3b081f 49 seconds ago 72.8MB $
7.docker runコマンドでコンテナを実行
$ docker run --name dockertest dockertest:v1 hello world!
8.別のターミナルを開き、docker exceでコンテナ内に入り、lsコマンドとpsコマンドを実行
$ docker exec -it dockertest /bin/bash root@a0823d7b259f:/# ls bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys test.sh tmp usr var root@a0823d7b259f:/# ps -Ao pid,cmd PID CMD 1 sleep infinity 8 /bin/bash 19 ps -Ao pid,cmd root@a0823d7b259f:/#
9.docker stopコマンドでコンテナを停止
$ docker stop dockertest dockertest $
10.docker rmコマンドでコンテナを削除
$ docker rm dockertest dockertest $
Dockerについては既存のOSやアプリケーションをコンテナ環境で運用することはもちろん、最近ではサーバレスなコンテナ実行環境のようなものがAWSやGCPなどのクラウドサービスとして存在し、より手軽にコンテナ環境を利用したアプリケーションの開発が可能となりました。
これらの技術を活用していくためにも、ぜひ本記事でご説明したような基本的な内容を押さえたうえで、積極的にDockerやk8sなどのサービスを利用してみるのが良いかと思います。