はじめに
本記は「Dockerをこれから触ろう/学ぼうとしている人向け」の記事になります!
- Dockerの歴史
- 実際にDockerを動かすハンズオン
が記載されています!
Dockerとは
そもそもDockerて何もの?
一言でいうと、「軽量な仮想環境」を構築するツールです。
今までエンジニアが開発を行う際、「Hyper-V」や「Vagrant」「VirtualBox」など、PC上に仮想のPCを作成する仮想化ツール( ハイパーバイザー型)を利用してきました。
便利な上記のツールですが、それらは皆大きな課題を抱えていました。
「環境構築に時間がかかる」「起動にも時間がかかる」「ファイルサイズが大きい」
![スクリーンショット 2022-04-30 19.02.37.png (766.3 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F04%2F30%2F122490%2F441fea60-1ef2-46df-9d8b-46c3e1e7b4ac.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=d90c69ab35094c8e4e0f0f4a04c6c721)
そんな課題を解決してくれるのが、Dockerというコンテナ型の仮想化技術です。
従来のハイパーバーザー型の仮想化技術とは違い、アプリケーションの実行をホストOSが行っているため、「GuestOS」を起動・利用する必要がなくなりました。
またDockerはコンテナ型の仮想化技術 を用いていることから、実行されるアプリの単位を「コンテナ」と呼びます。
(※コンテナ型の仮想化技術を利用する場合、ホストOSはLinuxである必要があります。)
Q:なぜ「GuestOS」利用をする必要がないのか?
A:Linuxのカーネルを用いて、 コンテナ単位でアプリ(プロセス)を実行するためGuestOSが不要になります。
参考:Linuxのカーネルとディストリビューションについて
コンテナ型仮想化技術の歴史について
これだけ便利に見えるDocker(コンテナ型の仮想化)ですが、人気が出てきたのは割と最近な気がします。
ですがコンテナ技術自体は1980年頃から存在しているのです。
![スクリーンショット 2022-04-30 19.40.36.png (2.3 MB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F04%2F30%2F122490%2F81a84036-8bb5-492e-a8a2-2be4dbe06c14.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=912028073177deeceeba8e472b5b57d9)
コンテナ技術の原点「chroot」
1979年にコンテナ技術の原点である「chroot」が誕生しました。
名前の通り「root(/)ディレクトリを変える(change)」技術になります。
chrootでルートで区切ったディレクトリごとにユーザー権限の付与を行うことで、複数人がアクセスできる擬似的な仮想環境を作成することができます。
現在のコンテナ技術のように「1つのLinuxカーネル」を使って、複数の仮想環境を作成していたためコンテナ技術の原点と言われています。
またchrootによって区切られたディレクトリは外に出られないことから「chroot監獄」と呼ばれていたそうです。
![スクリーンショット 2022-05-01 19.59.21.png (637.1 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F05%2F01%2F122490%2F6c7ed5c8-a00d-40e4-8895-5c8ce2dcba3b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=e6036383e0fdd4f9519a3c31c2039783)
ただこの頃のchrootはセキュリティ上に問題があったため、後続の「FreeBSD Jail」からレンタルサーバーやホスティングの共用サーバーとして利用され始めたそうです。
chrootは二段階chrootで簡単に突破出来てしまうのでセキリュティの観点からは意味がないという話があったそうです。
https://www.gcd.org/blog/2007/09/132/
コンテナ技術のコアパーツ「Cgroup, Namespace」
先程のchroot等のおかげでコンテナ型の仮想化環境を作成することはできました。
ですがこれまでの仮想化技術はいくつかの課題が合ったのですが、その中でも「ホストとのプロセス分離が完全にできない」「ハードウェアリソース割当ができない」等の課題がありました。
それを解決する技術であるcgroup(Google社) と namespace(RedHat社) が公開されました。
Namespace
Namespaceはシステムのネットワークやプロセス等を分離する技術になります。
これが利用できるようになったことにより、コンテナ型の仮想化技術が完全に隔離された仮想環境として利用できるようになりました。
![スクリーンショット 2022-05-01 21.27.34.png (793.8 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F05%2F01%2F122490%2F9ad84fd4-1878-4502-8fbe-694dfec2b6fe.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=6504a0d275fa0130ba869f5deb55f41c)
Q:プロセスとは?
A:CPU上で実行されるのプログラムやアプリの単位ことです。
https://milestone-of-se.nesuke.com/sv-basic/architecture/cpu/
![スクリーンショット 2022-05-20 11.22.13.png (251.6 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F05%2F20%2F122490%2F875988ee-47b3-4268-96f8-eb928df21628.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a17d976e6b328fa7856198e4f67fa227)
cgroup
cgroupはハードウェアの物理的なリソースを分離する技術になります。
ハイパーバイザー型の仮想化技術を使ったことがある人は身に覚えがあると思いますが、仮想環境を作成する際にメモリやCPUの割当をやったことがあるのではないでしょうか?
メモリやCPUを仮想環境単位で分離・制限させる仕組みを実現するためにcgroupが利用されています。
そして現代へ「LXC, Docker」
これら仮想化のための技術が出てきた後、我々が今も利用しているようなコンテナ技術が世の中に出周ってきました。
その中でも特に有名なのが「LXC(Linux Container)」「Docker」になります。
LXC
2008年頃に「LXC(IBM社)」というnamespaceやcgroupを組み込んだ、最初のLinuxのコンテナエンジンが発表されました。
これはchrootでは実現できなかった、プロセスや物理リソースの分離ができるコンテナ型仮想化技術の原型になります。
現在でもLXCは「軽量なLinux仮想環境と構築するツール」として様々なところで利用されています。
Docker
お待たせしました。2013年、ついに**Docker(dotCloud社:現Docker社)**が発表されました。
DockerはLXCとは異なり、アプリケーションのデプロイを目的として作られた技術のため「1 コンテナ1プロセス」という仕組みが取られています。
「サードパーティの充実さ」や「導入敷居の低さ」も相まって、仮想化技術の覇権を握ることになりました。
またDockerのリリース当初はLXCの技術をベースに作られていたそうですが、時代が進むにつれてLXCとの依存関係を無くすため、libcontainerを利用するようになりました。
![スクリーンショット 2022-04-30 19.40.36.png (2.3 MB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F04%2F30%2F122490%2F81a84036-8bb5-492e-a8a2-2be4dbe06c14.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=912028073177deeceeba8e472b5b57d9)
参考記事:
- 【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その1:コンテナってなに?
- コンテナってなんだろう― 「コンテナ」の概要を知る - Think IT
- 【chroot】 なぜFTPでレンタルサーバーにアクセスしても、他のアカウントのファイルが見れないか?
Dockerを使ってみよう
前章でコンテナ型の仮想化技術について理解が深まったと思います。
本章から実際に手を動かしながらDockerの使い方を覚えていきます。
Dockerで利用される「イメージ」「コンテナ」について
先程、DockerはホストOSを利用して仮想化したアプリを起動すると説明しました。
その仮想化したアプリ*をどのように作成するのかを解説します。
Dockerを利用する私達は、2つのDocker用語を覚える必要あります。
- イメージ:コンテナを実行するためのテンプレートが記載されている
- コンテナ:イメージを用いて、仮想環境上でアプリを起動させる
イメージとは
Dockerの「イメージ」とは、コンテナを実行するためのテンプレートになります。
基本的にはDockerHubから取得したり、自身でカスタマイズしたイメージを利用します。
(CDのようなイメージ)
コンテナとは
先程説明したイメージを実行する環境になります。
イメージがなければコンテナの起動はできません。
(CD Playerのようなイメージ)
Docker環境を作成してみよう
Ubuntu環境をDockerHubからインストールし、nginxを起動させてみましょう。
まずはじめにDockerHub から、Ubuntuのイメージをインストールします。
docker pull ubuntu:latest
インストールしたUbuntu
イメージをコンテナで実行します。
# open browser 「localhost:8080」
docker run -it -d -p 8080:80 --name ubuntu ubuntu:latest
参考記事:
nginxのインストール・起動を行っていないため、Ubuntuにnginxを入れて実行させましょう。
# Ubuntu環境に侵入
docker exec -it ubuntu bash
# nginxのインストール
apt update && \
apt install -y -q curl gnupg2 && \
curl http://nginx.org/keys/nginx_signing.key | apt-key add - && \
apt install -y -q nginx
# nginxの起動
nginx
# reload browser 「localhost:8080」
起動させたコンテナを終了させる場合は、以下を実行
# コンテナの停止
docker stop [コンテナID]
# コンテナの削除
docker rm [コンテナID]
これまでの仮想化技術だったら数十分〜数時間かかっていた準備〜起動も、Dockerだと数秒〜数分で起動できる!(嬉しいね!)
参考:
Dockerfileを使おう
Dockerについて概要を理解できたでしょうか?
Dockerを便利に使うための機能として、「Dockerfile」というものが存在します。
その「Dockerfile」というものについて解説します。
DockerFileって何?
先程Dockerを使い、Ubuntuコンテナ内からNginxを起動させましたが
毎回Ubuntuに入ってNginxを起動させるのは煩わしい
ですので先程出てきました「イメージを自分で作る」という手段で、Ubuntu + nginxが起動する環境を作ります。
その際に使われるのが、「Dockerfile」になります。
![スクリーンショット 2022-03-29 13.35.54.png (250.2 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F03%2F29%2F122490%2F4f239c33-0295-4336-aa47-11b9a19a9f40.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=3abb2cb19a3a9f257000e77ae73654d6)
DockerFileからオリジナルイメージを作成しよう
今回作成するDockerfileの完成形はこちらになります。
お好きなディレクトリにDockerfile
(拡張子なし)というファイルを作成して以下を記載します。
# 利用する元のイメージを指定
FROM ubuntu:latest
# 必要なパッケージをインストール
RUN apt update && \
apt install -y -q curl gnupg2 && \
curl http://nginx.org/keys/nginx_signing.key | apt-key add - && \
apt install -y -q nginx
# nginx実行
CMD ["nginx", "-g", "daemon off;"]
以下のコマンドを実行することで、対象のDockerfileからイメージの作成を行います。
# 「-t」は作成するイメージに付ける名前。今回は「ubuntu-nginx」と名付けます。
docker build -t ubuntu-nginx:latest .
イメージの作成ができたので、以下のコマンドからコンテナを実行するとubuntu + nginxの環境が立ち上がります。
docker run --rm -p 8080:80 ubuntu-nginx:latest
![スクリーンショット 2022-03-29 13.40.15.png (283.6 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F03%2F29%2F122490%2Fa575fd4a-564f-48d3-a772-026b592957f0.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=46ae9fa7dbb500c835e1f0eaad806dfd)
イメージ作成が完了したので、これ以降はコンテナを起動させるだけでubuntu + nginxの環境が使えます!
Docker Composeを使おう
前項の内容でDockerfileを使い、自身のオリジナルイメージを構築する事ができました。
最後に、もっとDockerを便利に使うための機能として、「Docker Compose」というものを紹介したいと思います。
Docker Composeって何?
一言で言いますと、「Docker Compose」はコンテナのマネジメントツールです。
前項でDockerfileを使い、オリジナルの仮想環境(イメージ)を作成し、コンテナでイメージを実行しました。
しかし実際に開発を行う場合は、1 つのイメージ(コンテナ)だけで事足りるケースというのは少ないです。
- フロントエンドサーバー
- バックエンドサーバー
- DBサーバー
- セッションサーバー
など様々なアプリケーションの実行環境用意する必要があります。
ですが、その度にDockerのコンテナを1つずつ実行するのは大変億劫です。
そんな時「Docker Compose」を使うことで、複数のコンテナ環境をまとめて実行・管理する事ができます。
![スクリーンショット 2022-03-29 14.54.11.png (375.9 kB)](https://qiita-user-contents.imgix.net/https%3A%2F%2Fimg.esa.io%2Fuploads%2Fproduction%2Fattachments%2F10655%2F2022%2F03%2F29%2F122490%2F8b38e366-e577-47b2-87a3-4559690d6d51.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=05c470e760071919504a27585f124200)
Docker Composeを使って、複数のコンテナを動かしてみよう
今回作成するDocker Composeの完成形はこちらになります。
docker-compose.yml
というファイルを作成して以下を記載します。
先ほど作成したUbuntu+Nginx
のイメージの他に、PHPAdmin
とMySQL
のイメージを実行したいと思います。
version: '3'
services:
# 先程作成したイメージを指定
app:
# Dockerfileを指定することも可能
# https://qiita.com/kai_kou/items/eaafa3cb15e1496f50ec
image: ubuntu-nginx
ports:
- 8080:80
# 利用するイメージを追加
mysql:
image: mysql:8.0-oracle
environment:
- MYSQL_ROOT_PASSWORD=password
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=password
ports:
- 8081:80
以下のコマンドを実行することで、対象のdocker-compose.yml
に書かれたイメージからコンテナの作成を行います。
docker-compose up
停止するときは以下のコマンド
docker-compose down
DockerfileとDocker Composeを使うことで、1コマンドで様々な環境を作れるようになりました。
またDockerfileとDocker Composeはテキストファイルなので、Git管理できるのも嬉しいですね!
Dockerまとめ
Docker
- Linux上で利用することのできる、「軽量な仮想環境」を作れるツール
- 「イメージ」から「コンテナ」を作成し、プロセスの実行を行う
- 「DockerHub」というところにある、様々なイメージを利用することができる
Dockerfile
- DockerHubにあるイメージを自分好みにカスタマイズして、新しいイメージを作成する機能
- 「Dockerfile」というファイルに、自分のカスタマイズ環境を記載する
Docker Compose
- コンテナのマネジメントを行う機能
- 「docker-compose.yml」というファイルに、管理したい「イメージ」「コンテナ」の指定・設定を行う
- 利用できるイメージは「DockerHubにあるイメージ」、「ローカル環境で作成したイメージ」、「Dockerfile」のいずれか
最後に
弊社でQiitaEngineerFesta2023の記事投稿キャンペーンを実施してます。
参加&投稿お待ちしております!