LoginSignup
1
2

Docker を使ってみた

Last updated at Posted at 2024-04-18

はじめに

友人(@digital24s さん)に誘われて、クラウドサービスで仮想マシン環境を作ってみました。

Google Compute Engine に Windows 環境を作ってリモートデスクトップ接続してみた #GoogleCloud - Qiita

続いて、コンテナ型の仮想環境の Docker も使ってみたいと思いました。

Docker を使ってみる

Linux マシンを用意する

Docker は Linux OS で稼動します。そのため Linux マシンを用意します。
自分は Google Cloud の Compute Engine を使って Ubuntu OS の仮想マシンを作りました。

Docker エンジンをインストールする

Ubuntu OS マシンに Docker エンジンをインストールします。

Docker Engine インストール(Ubuntu 向け) | Docker ドキュメント

Docker コンテナを作ってみる

以下のサイトを参考にしました。

Dockerコンテナの作成、起動〜停止まで #Docker - Qiita

Docker再入門 #Docker - Qiita

コンテナイメージをダウンロードする

Docker リポジトリからコンテナイメージをダウンロードします。
今回は CentOS を使ってみようと思います。

$ docker pull centos:latest

コンテナを作成する

イメージからコンテナを作成します。

$ docker create -it --name trydocker centos

-it オプションをつけて作成します。こうしないと、コンテナを起動した後で OS のシェルにコマンドを入力して出力結果を確認することができません。

--name オプションでコンテナに名前をつけておきます。名前は任意です。

作成されたコンテナが確認できます。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                      PORTS     NAMES
d6d964941a51   centos          "/bin/bash"   a minute ago     Created                               trydocker

コンテナを起動する

作成したコンテナを起動します。

$ docker start trydocker

コンテナの状態を確認してみます。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                      PORTS     NAMES
d6d964941a51   centos          "/bin/bash"   a minute ago     Up a minute ago                       trydocker

ステータスが「Up」になっています。つまり稼動しています。↑

コンテナ内で操作する

コンテナ内で OS が起動してシェルが使えるようになっています。これに接続します。

$ docker attach trydocker

コンテナ内の OS のシェルでコマンド入力できます。

# whoami
root

# cat /etc/*release
中略
NAME="CentOS Linux"
後略

Ubuntu OS 上の Docker 環境で CentOS が起動していることが分かります。使えるコマンドも違ったりします。

コンテナ内のシェルからホストのシェルに戻ります。↓

# exit

コンテナの状態を確認します。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                      PORTS     NAMES
d6d964941a51   centos          "/bin/bash"   a minute ago     Exited (0) a second ago               trydocker

ステータスが「Exited」になっています。つまり停止しています。↑

もう一度、起動して接続します。

$ docker start trydocker
$ docker attach trydocker

以下のキー入力します。

ctrl+P → ctrl+Q

ホスト側に戻りました。コンテナの状態を確認します。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                      PORTS     NAMES
d6d964941a51   centos          "/bin/bash"   a minute ago     Up a minute ago                       trydocker

ステータスが「Up」になっています。つまり稼動しています。↑

コンテナ内のコマンドを実行する

コンテナ内のシェルに接続してコマンド入力しましたが、ホスト側でダイレクトに実行することができます。

$ docker exec trydocker cat /etc/*release
中略
NAME="CentOS Linux"
後略

参考:Dockerコンテナ内で操作 attachとexecの違い #Docker - Qiita

コンテナの実体を確認する

ホスト側のファイルを確認してみます。

参考:コンテナ仮想化Dockerの使い方 & 実体 | NagareLab

以下のディレクトリが確認できます。

/var/lib/
  ├─ docker/
  │  ├─ builder/
     ├─ buildkit/
     ├─ containers/
     │  ├─ d6d964941a51.../
     │  │  ├─ checkpoints/
     │     ├─ mounts/
     │     ├─ d6d964941a51...log
     │     ├─ config.v2.json
     │     ├─ hostconfig.json
     │     ├─ hostname
     │     ├─ hosts
     │     ├─ resolv.conf
     │     └─ resolv.conf.hash
     ├─ image/
     ├─ network/
     ├─ overlay2/
     │  ├─ 6d060f2e6ecc.../
     │  │  ├─ diff/
     │     ├─ work/
     │     ├─ link
     │     └─ lower
     ├─ plugins/
     ├─ runtimes/
     ├─ swarm/
     ├─ tmp/
     ├─ volumes/
     └─ engine-id

コンテナ内でファイルを作成します。

# mkdir /home/docker
# echo "Hello, Docker!" > /home/docker/hello.txt

ホスト側のファイルを確認します。

  ├─ docker/

     ├─ overlay2/
     │  ├─ 6d060f2e6ecc.../
        │  ├─ diff/
           │  ├─ home/
              │  └─ docker/
                    └─ hello.txt        

ここで確認できた hello.txt をホスト側で編集してみます。

$ sudo echo "Hello, World!" > /var/lib/docker/overlay2/6d060f2e6ecc.../diff/home/docker/hello.txt

コンテナ内で確認します。

# cat /home/docker/hello.txt
Hello, World!

ターミナルで使えるファイル管理ソフトを導入する

cdls コマンドを使ってもいいのですが大変なので、ファイラ(ファイル管理ソフト)を導入します。幾つか試してみましたが ranger がよさそうです。

ターミナルで使えるファイラrangerを使ってみる #Linux - Qiita

コンテナを停止する

実行しているコンテナを停止します。

$ docker stop trydocker

コンテナの状態を確認してみます。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                      PORTS     NAMES
d6d964941a51   centos          "/bin/bash"   a minute ago     Exited (0) a second ago               trydocker

ステータスが「Exited」になっています。つまり停止しています。↑

コンテナを削除する

コンテナが不要になったら削除できます。

$ docker rm trydocker

docker run で実行する

Docker の運用で、上記のように cretestartexec することは、ほとんどないそうです。
run コマンドで実行します。

$ docker run --name trydocker centos cat /etc/*release
中略
NAME="CentOS Linux"
後略

コンテナの状態を確認してみます。

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
746757caaf41   centos    "cat /etc/lsb-releas…"   a second ago     Exited (1) a second ago                trydocker

コンテナが作成されて停止しています。↑

コンテナは基本的に使い捨てるそうです。
なので、--name オプションをつけないで、さらにコンテナが残らないように --rm オプションをつけたりします。

$ docker run --rm centos cat /etc/*release

コンテナを起動してシェルに接続してみます。↓

$ docker run -it --rm centos /bin/bash

コンテナのデータを永続化する

docker run --rm で実行されたコンテナで作成されたデータは、コンテナが使い捨てられるので残りません。
コンテナが作り直されても、データが残るようにする=永続化する仕組が用意されています。

参考:「そのコンテナのデータ、消えるよ……」とさせないための、イメージ図+実践で理解するDockerストレージ【Dockerコンテナ・グレートジャーニー③】 #Docker - Qiita

ホスト側のディレクトリをコンテナにマウントする

ホスト側に共有するディレクトリを用意します。

$ mkdir /home/docker/share

これをコンテナ内で利用できるようマウントします。

$ docker run -it --mount type=bind,src=/home/docker/share,target=/home/share --name trymount centos /bin/bash

コンテナ内でディレクトリを確認します。

# ls /home/share/
何も表示なし

ホスト側でファイルを作ります。

$ echo "Hello, Docker!" > /home/docker/share/hello.txt

コンテナ内でディレクトリを確認して、ファイルを変更します。

# ls /home/share
hello.txt
# cat /home/share/hello.txt
Hello, Docker!
# echo "Hello, World!" > /home/share/hello.txt

ホスト側でファイルの内容を確認します。

$ cat /home/docker/share/hello.txt
Hello, World!

ボリュームコンテナを作ってコンテナにマウントする

予めボリュームコンテナを用意します。ボリュームコンテナは使い捨てません。

$ docker volume create shared_volume

ホスト側のファイルを確認してみます。

  ├─ docker/

     ├─ volumes/
     │  ├─ shared_volume/

これをコンテナ内で利用できるようマウントします。

$ docker run -it --mount type=volume,src=shared_volume,target=/home/share --name trymount1 centos /bin/bash

コンテナ内でファイルを作ります。

# echo "Hello, Docker!" > /home/share/hello.txt

上記のコンテナを破棄して、別のコンテナを実行します。

$ docker rm trymount1
$ docker run -it --mount type=volume,src=shared_volume,target=/home/share --name trymount2 centos

コンテナ内でファイルの確認します。

# cat /home/share/hello.txt
Hello, Docker!

Docker を理解する

自分は仕事でも趣味でも、Docker を使う機会はないと思っていました。なので、Docker について勉強してきませんでした。
とはいうものの、周囲の知人は Docker を使っていて、会話に出てくることがあります。このとき自分が話題についていけないのは、悔しいと思っていました。

よくある Docker の説明を見て考えたこと

入門といえる記事を検索して一通り読んでいきました。
ハイパーバイザ型の仮想マシンと比較してコンテナ型の Docker が説明されています。

説明1.png

参考:コンテナってなんだろう― 「コンテナ」の概要を知る | Think IT

これらの説明を読んで、次のように考えていました。

コンテナはホストの OS の機能を呼出するという。
であれば、ホストの OS に予めミドルウェアを入れれば、コンテナで利用できるのか。

コンテナとは、実行時に生成される仮想マシンなのか。それとも、ハイパーバイザ型の仮想マシンの仮想ディスクのようなものなのか。

空のコンテナを作って、コンテナ内で操作するとホスト側で差分情報が記録されて、これを配付して再利用できるのだろうか。

これらの疑問を Doker を利用している知人に聞いてみたが、どうも違っているらしい。けれど、説明を聞いてもよく分からない。使ってみれば分かるようになると言う。
自分は、Docker を使いたいのでなく、Docker がどんなものか分かりたいだけなので、上手い説明が欲しいと思っていました。

試してみて分かったこと。記事によっては書かれていなかったこと

実際に使って試しながら、他の記事を読んでいきました。その結果、分かったことがありました。いわゆる「入門」記事には書かれていなかったり、書かれていても分かりづらかったりしたことでした。

まず、UNIX 系 OS なら使えると思っていたが、Linux OS しか Docker は使えない。

ベースになるコンテナイメージが予め用意されていて、それを使ってコンテナを作る。

コンテナ内に OS のカーネルはなくて、ホスト機の OS のカーネルを呼出する。
ホスト機の OS のユーティリティソフトやミドルウェアは、コンテナから見えるようになっていない。コンテナ内にユーティリティソフトが用意される。
自分はユーティリティソフトを含めて OS(「広義の OS」)と言うスタンスなので、コンテナ内に OS がない説明を見て、勘違いしていた。

Docker のコンテナは、ホスト OS の所定のディレクトリにあるファイル群である。
コンテナ内で作成されたデータは、このディレクトリに作成される。

コンテナは基本的に使い捨てる運用する。
永続化したいデータはコンテナの外に置くようにする。

説明2.png

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2