Docker コンテナのライフサイクル : 「終了」と「破棄」は違う
以前の記事で、Docker コンテナについて、次のように書いた。
- 「
$ docker run
と$$ exit
で起動と終了を繰り返すと、毎回変更が破棄されてしまう」
実は、この表現は正しくない。$$ exit
による終了 = 即全てのデータが破棄される、というワケではなく、コレはただ「コンテナを終了させただけ」なのだ。
「でもその後 $ docker run
コマンドをもう一回叩くと、データ残ってないんだけど…?」と思うかもしれない。
今回は、コンテナの「生成」→「起動」→「終了」→「破棄」 というライフサイクルを確認してみよう。
目次
- 実際にやってみる
- 終了したコンテナはどこにあるの?
- 終了させたコンテナにもう一度アクセスしたい (アタッチ)
- コンテナを起動させたまま抜ける (デタッチ)
- 終了したコンテナが溜まっていく…「破棄」はどうするの?
- 以上
実際にやってみる
実際にコマンドを叩いて順を追って確認してみよう。
# まずはコンテナを生成・起動する
$ docker run -it centos:7 bash
# ホスト名を確認する。Docker が生成したランダムなホスト名が見える
[root@038be9cb96b3 /]# hostname
038be9cb96b3
# exit で抜ける
[root@038be9cb96b3 /]# exit
# 同じコマンドでコンテナを生成・起動する → 別の環境が立ち上がる
$ docker run -it centos:7 bash
# その証拠に、ホスト名が異なる
[root@ded8c658767b /]# hostname
ded8c658767b
# exit で抜ける
[root@ded8c658767b /]# exit
ココまでで何が起こっているかというと、「1つの Docker イメージ」を基に「2つの Docker コンテナ」を生成して、別々に保持している状態なのだ。物理的な比喩で言うと、「1つの CentOS のインストールディスク」を用いて「2つの CentOS サーバを立てて、両方の電源を切った」状態、といえる。
「Create (新規生成)」と「Start (起動)」がセットになっているのが docker run
コマンドである。
終了したコンテナはどこにあるの?
ココで疑問なのは、一度 exit
で抜けて終了させたコンテナはどこにあって、どうやったらまたアクセスできるの? ということだ。多分最初はコレが一番分かりにくいのだと思う。
一つのターミナルで Docker コンテナにアクセスしている間に、別のターミナルを開いて $ docker ps
と叩くと、起動中のコンテナが確認できる。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ede6d077be0c centos:7 "bash" 22 minutes ago Up 1 second silly_hamilton
一方、exit
で抜けて終了した Docker コンテナは、$ docker ps --all
コマンドで確認できる。
# `--all` は `-a` と省略できる
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ded8c658767b centos:7 "bash" 23 minutes ago Up About a minute silly_hamilton
038be9cb96b3 centos:7 "bash" 25 minutes ago Exited (0) 24 minutes ago hardcore_poitras
終了させたコンテナはココにいた。
終了させたコンテナにもう一度アクセスしたい (アタッチ)
じゃあ、これらのコンテナにアクセスするにはどうしたらいいの? という話。
まずは、この状態ではコンテナが終了しているので、再度起動させる。$ docker start
コマンドを使い、先程のコマンドで確認できた CONTAINER ID
を指定すれば、そのコンテナがまた起動できる。
$ docker start 038be9cb96b3
038be9cb96b3
で、起動したコンテナにアクセスすることを「アタッチ」と表現するのだが、$ docker attach
コマンドで、またシェルにログインできる。
$ docker attach 038be9cb96b3
[root@038be9cb96b3 /]# hostname
038be9cb96b3
このとおり。
コンテナを起動させたまま抜ける (デタッチ)
起動中のコンテナに入るのを「アタッチ」と呼ぶが、反対に、入っているコンテナから抜け出すことは「デタッチ」という。デタッチはコンテナ内部で行うので、docker
コマンドではなく、Ctrl + P
→ Ctrl + Q
と入力する。
# アタッチ
$ docker attach 038be9cb96b3
[root@038be9cb96b3 /]# hostname
038be9cb96b3
# デタッチ : Ctrl + P → Ctrl + Q と入力する
[root@038be9cb96b3 /]# read escape sequence
# デタッチしただけだとコンテナは終了していないので、`docker ps` で見える
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
038be9cb96b3 centos:7 "bash" 29 minutes ago Up About a minute hardcore_poitras
終了したコンテナが溜まっていく…「破棄」はどうするの?
こうした挙動を認識しておらず、バンバン $ docker run
しまくっていると、裏側には「終了したまま放置されているコンテナ」がゴミとして残ることになる。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e02b7b30296f centos:7 "/bin/bash" 23 seconds ago Exited (0) 22 seconds ago sad_pasteur
0552478e9e44 centos:7 "/bin/bash" 35 seconds ago Exited (0) 34 seconds ago practical_rosalind
ded8c658767b centos:7 "bash" 34 minutes ago Exited (137) 11 minutes ago silly_hamilton
038be9cb96b3 centos:7 "bash" 36 minutes ago Up 8 minutes hardcore_poitras
このままだと、それぞれのコンテナは前述の方法で再起動できるワケだが、これらを完全に削除して、本当にデータを破棄するには、$ docker rm
コマンドを使う。
$ docker rm e02b7b30296f
e02b7b30296f
こんな風にすると、破棄 = 削除できる。
試行錯誤している最中はいいとして、一段落したら、このようにゴミコンテナが残っていないか確認するといいだろう。
以上
コンテナをバンバンとっかえひっかえできるのはサーバ運用としてはメリットかもしれないが、どうも個人がコマンドラインから使っている範囲だと、分かりづらいように感じる。
自分の用途に応じて、コンテナのライフサイクルを意識して適宜エイリアスを作ったりすると良いかと思う。