Dockerを使ってみる

この記事では、有名なコンテナ技術の一つであるDocker(ドッカー)の基本的な使い方について解説しています。

近年、多くの企業がデジタルトランスフォーメーション(DX)に取り組んでおり、サービス提供のためのソフトウェア開発に対してスピード感が求められるようになったと感じています。

アジャイル開発、DevOpsやCI/CDは、社会ニーズの変化に機敏に対応するために必要な開発・運用維持プロセスであり、ソフトウェア開発を行うエンジニアリングチームでは、もはや避けて通ることができない課題となっています。

Dockerに代表されるコンテナ技術は、システム開発や運用の効率化を可能とする合理的手段の一つです。この他にも、VMwareやHyper-Vによる仮想化技術もパブリッククラウド利用によるシステムやサービスの最適化を実践する上で欠かすことのできないものとなっています。

コンテナ技術と仮想化技術には、大きな相違点があります。

コンテナ技術は、物理サーバにコンテナを配置して、各コンテナはホストOSを共有して動作します。このため、アプリケーションの起動までの時間は短く、ホストOSしかないため運用管理コストや工数の削減が見込むことができます。ただし、ホストOSを共有しているため、例えばWindowsなどホストと異なるOSをコンテナとして動作させることはできません。

一方、仮想化基盤技術は、物理サーバにインストールされたハイパーバイザー上に仮想マシン(Virtual Machine=VM)を配置して、それぞれ個別のOSを動作させます。このため、VM上のアプリケーションが起動するまでの時間は長くなります。また、ホストとVMそれぞれでOSが動作しているため、運用管理コストや工数の増加、作業手順の煩雑さがネックとなります。ただし、1台のサーバ上にLinuxやWindowsなど異なるOSを稼働させることができるため、コンテナ技術に比べて有利なポイントです。

コンテナ(左)と仮想マシン(右)の模式図

しかしながら、コンテナ技術や仮想化技術はメリットとデメリットがそれぞれ存在するものの、アジャイル開発、DevOpsやCI/CDの実践には欠かすことのできない技術要素です。特にコンサルやエンジニアリングチームは、それぞれの特徴やメリット・デメリットを正しく理解しておくことが重要です。

Dockerを使ってみる

Dockerは、LinuxのホストOS上に複数のコンテナを配置して、アプリケーションの開発、配備や実行を行うためのオープンソースプラットフォームです。

2013年にDocker社からリリースされ、2017年からは、Docker-CE(コミュニティエディション)とDocker-EE(エンタープライズエディション)としてリリースされています。

Dockerは、Linuxサーバの他にもWindowsやMACのパソコン上でも利用することができます。また、パブリッククラウド上でも利用することができるため、開発環境と本番環境の差異をなくすことができ、ソフトウェア開発と運用維持の合理化を図ることができます。

今回は、CentOS 7.8にDocker-CEをインストールして、コンテナを利用する方法について解説していきます。

Dockerのインストール

CentOSにDocker-CEをインストールするためには、Docker-CE公式のリポジトリをインストールする必要があります。

$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

リポジトリのインストールが完了したら、次にDocker-CEをインストールします。以下のようにDockerのバージョンが表示されればインストールは完了です。

$ yum -y install docker-ce

$ docker --version
Docker version 20.10.22, build 3a2c30b

Dockerのインストールが完了したら、rootユーザでDockerデーモンを起動します。

$ systemctl start docker

$ systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since 日 2023-01-22 17:24:01 JST; 2min 2s ago
・・・<省略>・・・

Dockerデーモンが管理している/var/run/docker.sockは、rootユーザかdockerグループに属しているユーザのみアクセス可能であるため、一般ユーザからDockerコマンドを実行することができません。

一般ユーザからDockerコマンドを利用できるようにするため、以下のように一般ユーザをdockerグループに追加する必要があります。

$ usermod -aG docker <追加するユーザ名>

再ログインすることで、dockerグループに追加した一般ユーザからDockerコマンドが実行できるようになります。

$ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

コンテナイメージの取得方法

Dockerは、アプリケーションと依存関係にあるすべてのソフトウェアをカプセル化したコンテナイメージをDockerエンジン上のコンテナに配備して実行しています。

最も簡単な方法は、docker pullコマンドを使用してDocker HUBにあらかじめ準備されているコンテナイメージを取得することです。

例えば、Webサーバとして人気の高いNginxのコンテナイメージをpullする場合は、以下のようになります。

$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
8740c948ffd4: Pull complete
d2c0556a17c5: Pull complete
c8b9881f2c6a: Pull complete
693c3ffa8f43: Pull complete
8316c5e80e6d: Pull complete
b2fe3577faa4: Pull complete
Digest: sha256:b8f2383a95879e1ae064940d9a200f67a6c79e710ed82ac42263397367e7cc4e
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    a99a39d070bf   10 days ago   142MB

コンテナイメージの作成方法

Dockerのコンテナイメージには、OSコンテナイメージも存在します。コンテナ技術では、ホストOSを共有すると説明したのに変ですよね。

実は、OSコンテナイメージについてはKernel(カーネル)を含んでいないため、正確にはOSではありません。

OSコンテナイメージは、別のLinux OSのコマンドをホストOSに結び付けるためのコマンドの集合体であり、実際にはホストOSを共有して動作していることに間違いはありません。

簡単に言えば、ホストOSと異なるLinux OSのコマンドを模擬しているだけなんですね。

Docker HUBが提供しているOSコンテナイメージには、WebサーバやFTPサーバなどのパッケージは含まれていません。OSコンテナイメージにパッケージをインストールする方法は2種類あります。

一つ目は、OSコンテナイメージをコンテナ起動してから、パッケージマネージャを使ってインストールする方法です。新規に開発環境を構築する時や利用するパッケージが決まっていない場合は、この方法で都度パッケージをインストールしていくことになるでしょう。なお、変更したコンテナイメージは、docker commitコマンドを利用して保存することができます。

2つ目は、Dockerfileを使う方法です。この方法は、あらかじめ利用するパッケージが決まっている場合に手順を簡素化することができます。

次にDockerfileを利用した方法について解説します。

Dockerfileからコンテナイメージを作成する

Dockerfileは、docker buildコマンドを利用してコンテナイメージを作成するための定義ファイルです。まずは、Nginxを含むOSコンテナイメージを作成してみます。

$ vi Dockerfile

FROM alpine:latest

RUN apk update && apk add --no-cache nginx

Dockerfileの1行目は、Docker HUBから取得するベースコンテナイメージを指定しています。この例では、最新版のAlpine Linuxをpullします。

2行目は、Alpine Linuxのパッケージマネージャ「apk」を更新して、Nginxのパッケージをインストールするように指定しています。

Dockerfileを保存し、Dockerfileがあるディレクトリでdocker buildコマンドを実行します。「-t」オプションで、作成するコンテナイメージに名前とタグを付与しています。また、「-f」オプションで読み込むDockerfileの名前を指定しています。デフォルトはDockerfileであるため、省略することも可能です。最後の「.」は、Dockerfileがカレントディレクトリに存在することを示しています。

$ docker build -t test:1.0.0 -f Dockerfile .

・・・<中略>・・・

Successfully built 75247b8d6a82
Successfully tagged test:1.0.0

コマンドが成功したら、docker imagesコマンドを実行します。

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
test         1.0.0     75247b8d6a82   13 minutes ago   11.1MB
nginx        latest    a99a39d070bf   10 days ago      142MB
alpine       latest    042a816809aa   12 days ago      7.05MB

Dockerfileで指定したAlpine Linuxのベースコンテナイメージと、docker buildコマンドで指定した名前のコンテナイメージが追加されていることが確認できました。

コンテナを起動してみる

次に、作成したオリジナルのコンテナイメージを起動してみます。コンテナ起動は、docker runコマンドを使います。

「-it」オプションは、コンテナとホストOSの間で入出力を可能にします。「–intaractive」と「–tty」を組み合わせたオプションです。「-d」オプションでコンテナをバックグラウンド実行させます。「–name」オプションでコンテナに任意の名前を指定することができます。最後に起動するコンテナイメージの名前(リポジトリ)とタグをコロンで連結して指定します。

$ docker run -it -d --name alpine-linux test:1.0.0
3d8d844a09180e3912f3988014fa20b66176600c11f0577a7eab905e933a36d8

コンテナの起動状態を確認するためには、docker psコマンドを使用します。

$ docker ps
CONTAINER ID   IMAGE        COMMAND     CREATED              STATUS              PORTS     NAMES
c5ff2855f8e9   test:1.0.0   "/bin/sh"   About a minute ago   Up About a minute             alpine-linux

「–name」オプションで指定した名前のコンテナが起動していることが確認できました。

コンテナ内に入ってみる

次に起動したコンテナで動作しているAlpine Linuxに入ってみます。コンテナへのアクセスは、docker execコマンドを使います。

「-it」オプションは、コンテナ起動時と同じく「–intaractive」と「–tty」を組み合わせたオプションです。あとはコンテナの名前とログインシェルを指定します。

$ docker exec -it alpine-linux /bin/sh

コマンドが成功したら、Alpine LinuxにNginxが入っているか確認します。

$ cat /etc/alpine-release
3.17.1

# ls /etc/nginx
fastcgi.conf    http.d          modules         scgi_params
fastcgi_params  mime.types      nginx.conf      uwsgi_params

Alpine LinuxにNginxの設定ファイルが配置されています。Dockerfileに設定した内容でOSコンテナイメージが作成されたことが確認できました。

起動したコンテナを停止する

起動したコンテナの停止は、docker stopコマンドを使います。

$ docker ps
CONTAINER ID   IMAGE        COMMAND     CREATED          STATUS          PORTS     NAMES
4cde0600e4f2   test:1.0.0   "/bin/sh"   13 minutes ago   Up 13 minutes             alpine-linux

$ docker stop alpine-linux

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

また、停止したコンテナを再度起動する場合は、docker startコマンドを使用します。停止中のコンテナは、docker ps -aコマンドを使用して一覧表示することができます。

$ docker ps -a
CONTAINER ID   IMAGE        COMMAND     CREATED          STATUS                       PORTS     NAMES
4cde0600e4f2   test:1.0.0   "/bin/sh"   17 minutes ago   Exited (137) 2 minutes ago             alpine-linux

$ docker start alpine-linux

$ docker ps
CONTAINER ID   IMAGE        COMMAND     CREATED          STATUS          PORTS     NAMES
4cde0600e4f2   test:1.0.0   "/bin/sh"   19 minutes ago   Up 33 seconds             alpine-linux

コンテナを削除する

停止させたコンテナの削除は、docker rmコマンドを使います。起動中のコンテナに対してdocker rmコマンドを実行した場合はエラーとなるため、コンテナを停止してから削除します。

$ docker ps -a
CONTAINER ID   IMAGE        COMMAND     CREATED          STATUS                        PORTS     NAMES
4cde0600e4f2   test:1.0.0   "/bin/sh"   24 minutes ago   Exited (137) 18 seconds ago             alpine-linux

$ docker rm alpine-linux

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

コンテナ起動時に「–rm」オプションを指定すると、docker stopコマンドを実行した時点でコンテナの停止と削除が同時に実行されるようになります。

$ docker run -it -d --rm --name alpine-linux test:1.0.
0
14565615372f6e90a758fe9282f4dae389bf1123b08d2b238844f6fe3508d899

$ docker stop alpine-linux

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

コンテナイメージを削除する

不要となったコンテナイメージの削除は、docker rmiコマンドを使います。

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
test         1.0.0     5c518dbe9462   2 hours ago   11.1MB
nginx        latest    a99a39d070bf   11 days ago   142MB
alpine       latest    042a816809aa   12 days ago   7.05MB

$ docker rmi test:1.0.0 alpine:latest
・・・<中略>・・・
Untagged: alpine:latest
Untagged: alpine@sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a
Deleted: sha256:042a816809aac8d0f7d7cacac7965782ee2ecac3f21bcf9f24b1de1a7387b769

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    a99a39d070bf   11 days ago   142MB

削除するイメージは、イメージIDで指定することもできます。ホストサーバ上からコンテナイメージが完全に削除されるため、docker rmiコマンドを使用する場合は注意してください。

まとめ

いかがでしたでしょうか。Dockerのコンテナイメージの取得・作成方法と基本的なDockerの操作方法について解説しました。

今回の解説で登場したDockerコマンドは、以下の表のとおりです。しっかりと理解しておきましょう。

Dockerコマンド概要
docker pullコンテナイメージをDocker HUBから取得する
docker buildDockerfileを利用して、コンテナイメージをホストサーバ上に作成する
docker commitコンテナイメージを保存する
docker imagesホストサーバ上のコンテナイメージを一覧表示する
docker runコンテナイメージをコンテナ上で起動する
docker ps起動中のコンテナを一覧表示する
docker ps -a起動中及び停止中のすべてのコンテナを一覧表示する
docker stop起動中のコンテナを停止する
docker start停止中のコンテナを起動する
docker rmコンテナを削除する
docker rmiコンテナイメージを削除する
Dockerコマンドの概要

Dockerを学習していくと、DevOpsやCI/CDに対する様々なヒントを得ることができます。ソフトウェア開発やデリバリーにスピードが求められている時代にあって、今後もDockerを利用する機会は更に増加していくことでしょう。

参考になれば幸いです。

システムのお悩みについてご相談ください

本サイトの掲載内容に関するお問い合わせは、こちらから承ります。
SOHOのシステム運用管理に関するお悩みごとについて、なんでもお気兼ねなくご相談ください。
現役システムエンジニアのスタッフが、ボランティアでご相談にご対応させていただきます。