このチュートリアルでは、Alibaba Cloud上のDockerコンテナのクリーンアップを実践的に体験できます。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
#準備
このチュートリアルに従うには、Dockerが既にインストールされているAlibaba Cloud Elastic Compute Service (ECS)サーバーが必要です。方法がわからない場合は、このチュートリアルを参考にしてください。
コンテナのクリーンアップについて学ぶために、クリーンアップするコンテナがいくつか必要です。
まず、https://hub.docker.com/ からいくつかのイメージが必要です。
このチュートリアルでは、画像の中に何が入っているかは全く問題ではありません。このチュートリアルを完全に理解するためには、Nginx、Redis、Alpineの経験は必要ありません。
Redisはオープンソースのインメモリデータ構造ストアで、データベースやデータキャッシュとして使用されています。ほとんどのプログラミング言語は、メモリ内のデータにほぼ瞬時にアクセスすることで、プログラムを高速化するために使用することができます。
NGINXは無料でオープンソースの高性能HTTPサーバーです。
Alpine Linuxは5MBのLinuxディストリビューションで、dockerユーザーに非常に人気があります。
Alpine Linuxは、dockerアプリケーションのベースイメージとして使用されています。これは、アプリを実行するための小さなLinux環境を提供します。
シェルプロンプトで次のように入力して、これらの4つのイメージをコンピュータにダウンロードしてください。
docker pull hello-world:latest
docker pull nginx:mainline-alpine
docker pull redis:alpine
docker pull alpine:3.8
docker pulコマンドはレジストリからDockerイメージをダウンロードします。docker レジストリには Docker イメージのコレクションが含まれています。
デフォルトでは、docker pull コマンドは Docker Hub: https://hub.docker.com/ から docker イメージをプル/ダウンロードします。
Dockerイメージは、実行中のコンテナを作成するために使用されます。Docker イメージには、特定のアプリケーションを実行するために必要なすべてのソフトウェアが含まれています。例えば、ダウンロードしたnginx:mainline-alpineイメージには、コンテナ内でNginxを実行するために必要なすべてのソフトウェアが含まれています。
docker pull nginx:mainline-alpineでは、nginx:mainline-alpineはプル/ダウンロードしたいイメージの名前です。画像名はnginxです。
mainline-alpineはタグです。タグは同じイメージの異なるバージョンを区別するために使われます。例えば、Docker Hubのリポジトリにはnginx:centos、nginx:ubuntu、nginx:debian8、nginx:debian9のイメージがあります。どのイメージをダウンロードするかを正確に指定するためにタグを使用しています。
docker pull alpine:3.8の場合、3.8タグはバージョン番号を表しています。
実行します。
docker ps -a
期待される出力。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
新鮮なdockerインストールサーバーでこれを実行している場合は、実行中のコンテナがありません。
混乱させて、いくつかのコンテナを作成して片付けてみましょう。以下のコマンドを入力します。
docker run --name nginx -d nginx:mainline-alpine
docker run --name redis -d redis:alpine
docker run -d hello-world
docker run -d hello-world
docker run -d hello-world
docker runは、以前にダウンロードした静的イメージを実行コンテナに変えてくれます。
コンテナとは、dockerイメージのランタイム版のことです。コンテナには、実行中のプロセスを含む完全な実行環境だけでなく、Dockerイメージのすべてのソフトウェアが含まれています。
このチュートリアルではnginxやredisの機能は必要ありません。必要なのは、多様なコンテナの興味深いリストだけです。そうすれば、コンテナを選択的に停止したり削除したりする方法をよりよく学ぶことができます。
nginx と redis を停止してみましょう。hello-world コンテナはメッセージを表示して終了するだけです。すでに停止しているので、停止させる必要はありません。
docker stop nginx
docker stop redis
このコマンドを入力して、すべてのコンテナを一覧表示します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97f95b11260e hello-world "/hello" 57 seconds ago Exited (0) 44 seconds ago determined_payne
91f69bd08bf8 hello-world "/hello" About a minute ago Exited (0) About a minute ago xenodochial_wiles
6f7b53de6ad7 hello-world "/hello" About a minute ago Exited (0) About a minute ago pedantic_bartik
62919b9e6d84 redis:alpine "docker-entrypoint.s? About a minute ago Exited (0) 3 seconds ago redis
49ca281f8a0c nginx:mainline-alpine "nginx -g 'daemon of? 2 minutes ago Exited (0) 14 seconds ago nginx
The CONTAINER IDs you get when you run these commands on your computer will be different.
現在、5つのコンテナが停止しています。
使用できません。
docker container prune
このコマンドは停止している全てのコンテナをプルーニング/削除します。ここでは、まだ nginx と redis のログを見たいと仮定します。そのため、hello-world コンテナだけを慎重にプルーニングしなければなりません。
hello-world コンテナだけのリストを作成してみましょう。実行します。
docker ps -a | grep "hello-world"
grep は、hello-world というテキストを含む出力行のみを選択します。
grep はほとんどの Linux ディストリビューションに搭載されている Linux シェルユーティリティです。40年前に書かれました。
grep is used to search plain-text input for lines that match its search expression.
The __ docker ps -a __ lists all containers, the pipe symbol | sends this list to grep. __ grep "hello-world" __ searches for the text __ hello-word __. grep only outputs the list of containers __ containing hello-word. __
Grep stands for: g/re/p (__g__lobally search a __re__gular expression and __p__rint)
In __ docker ps -a | grep "hello-world" __ grep searched the list of containers output by docker ps, and prints only the lines containing hello-world.
grep searches the input files for lines containing a match to a given pattern list. When it finds a match in a line, it copies the line to standard output (by default), or whatever other sort of output you have requested with options.
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97f95b11260e hello-world "/hello" About a minute ago Exited (0) About a minute ago determined_payne
91f69bd08bf8 hello-world "/hello" 2 minutes ago Exited (0) About a minute ago xenodochial_wiles
6f7b53de6ad7 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago pedantic_bartik
完璧です。プルーニングしたいコンテナのリストが必要です。
代わりに実行することもできます。
docker ps -a | egrep --invert-match "redis|nginx"
-invert-matchはマッチングを反転させ、マッチングしていない行のみを選択します。-v は --invert-match のショートカットです。
"redis|nginx "は、redisまたはnginxを含むテキストのみを選択する正規表現です。ここで、パイプ記号の|は、「または」を意味します。
ここで、egrepは、redisとnginxを含むテキストを除いた出力行のみを選択します。
ここではegrepを使用しています: このgrepは拡張正規表現をサポートしています。この場合、"redis|nginx "は拡張正規表現をサポートしています。
docker container __ rm __ = docker container __ remove __ / delete / prune
docker container rmのフォーマットは以下の通りです。
docker container rm [OPTIONS] CONTAINER [CONTAINER...]
docker コンテナ rm に渡すコンテナ ID のリストが必要です。
コンテナIDは出力の最初のフィールド番号です。 awk '{print $1}' は、渡された最初のフィールドだけを出力します。
AWKはテキスト処理のために設計されたプログラミング言語です。テキストデータを抽出したりフィルタリングしたりするのに使われます。ほとんどのLinuxディストリビューションにインストールされています。
AWKは1970年に作成されました。AWKの名前は作者のAlfred Aho, Peter Weinberger, Brian Kernighanの名字に由来しています。
awkとgrepはどちらもテキストをフィルタリングします。grepは入力された列を選択的に印刷することができません。これは awk だけが持っている機能です。そのため、grepとawkを使う必要があります。
awk '{print $1}' は、渡された最初のフィールドだけを表示します。 awk のデフォルトでは、フィールドは空白文字で区切られていると仮定しています。awk '{print $1}' __を使用すると、ここではコンテナのIDを表示しますが、これはdocker ps -aの出力の最初のフィールド/列です。
実行します。
docker ps -a | grep "hello-world" | awk '{print $1}'
期待される出力
97f95b11260e
91f69bd08bf8
6f7b53de6ad7
3つのhello-worldコンテナをすべて削除してみましょう。以下のコマンドのいずれかを選択して実行します。
docker ps -a | grep "hello-world" | awk '{print $1}' | __ xargs docker container rm __
或いは
docker ps -a | egrep -v "redis|nginx" | awk '{print $1}' | __ xargs docker container rm __
xargs docker container rmはコンテナIDを一つずつ受信して削除します。
期待される出力
97f95b11260e
91f69bd08bf8
6f7b53de6ad7
完璧です。 docker container rmには削除したコンテナIDが表示されています。
実行します。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62919b9e6d84 redis:alpine "docker-entrypoint.s? 4 minutes ago Exited (0) 2 minutes ago redis
49ca281f8a0c nginx:mainline-alpine "nginx -g 'daemon of? 4 minutes ago Exited (0) 2 minutes ago nginx
redis と nginx はまだ存在しています。
redis と nginx のログを調べて、それらのコンテナも削除できるようにしておきましょう。
dockerのログはコンテナのログを表示します。
docker logs redis
1:C 03 Oct 06:40:25.554 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 03 Oct 06:40:25.559 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 03 Oct 06:40:25.559 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 03 Oct 06:40:25.613 * Running mode=standalone, port=6379.
1:M 03 Oct 06:40:25.614 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 03 Oct 06:40:25.614 # Server initialized
1:M 03 Oct 06:40:25.614 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 03 Oct 06:40:25.615 * Ready to accept connections
1:signal-handler (1538548914) Received SIGTERM scheduling shutdown...
1:M 03 Oct 06:41:54.159 # User requested shutdown...
1:M 03 Oct 06:41:54.195 * Saving the final RDB snapshot before exiting.
1:M 03 Oct 06:41:54.233 * DB saved on disk
1:M 03 Oct 06:41:54.233 # Redis is now ready to exit, bye bye...
実行します。
docker logs nginx
何も表示されません。nginxコンテナも何も使っていませんでした。
ログの調査完了しました。これで全てのコンテナを削除することができます。
実行します。
docker container prune -f
Deleted Containers:
62919b9e6d844d6720301dd8be7d0dfb58defb593fe8e9fa1ea0984b7aa92baa
49ca281f8a0cdc3adaddd222a654c4e61b17861f3a20dd9b584d0073466c722d
Total reclaimed space: 0B
2つのコンテナIDが表示されています。これらのコンテナも削除されました。
実行します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
予想通り、コンテナの稼働も停止もありません。
概要
まず、コンテナを削除するには、必要なテキストだけを grepping してから awk でコンテナ ID だけを選択する方法を学びました。
次にコンテナIDをxargs docker container rmに渡すと、渡されたコンテナが削除されます。
docker ps -a | grep "hello-world" | awk '{print $1}' | xargs docker container rm
代用します:
docker ps -a | egrep -v "redis|nginx" | awk '{print $1}' | xargs docker container rm
#Docker Container Pruneを使用してコンテナーを削除
docker run -d hello-world
さらに2回実行して、3つのコンテナをクリーンアップするようにします。
docker run hello-world ; docker run hello-world
実行します。
docker container ls
実行中のコンテナしか表示されないので、何も表示されません。
実行します。
docker container ls -a
-aは全てのコンテナを表示します。
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60cc61444c0b hello-world "/hello" 45 seconds ago Exited (0) 37 seconds ago pensive_albattani
e820b8032706 hello-world "/hello" About a minute ago Exited (0) 51 seconds ago silly_lovelace
7e959fd100d0 hello-world "/hello" About a minute ago Exited (0) About a minute ago fervent_kilby
docker container prune
コマンドは停止しているコンテナをすべて削除します。
コマンド docker container prune --force
は停止しているコンテナをすべて削除しますが、確認のためのプロンプトは表示されません。
実行します。
docker container prune -f
期待される出力
Deleted Containers:
60cc61444c0b90c7f2b0ada1546c3913a93676bbb0ba0dfb1c9329268222df6d
e820b803270681be048b511d676af56e28778e92ef783a536a4272f7d9648bd6
7e959fd100d0a72311f25987a0d0b6d1960283f2b164e56c538baddad83e8446
総埋立面積:0B
3つのコンテナを削除しました。prune オプションの -f は --force のショートカットです。
#ラベルを使ったコンテナのプルーニング
ラベルは、関連するコンテナをグループ化するためにdockerで使用されます。そして、ラベルの値に基づいてそれを選択することで、コンテナを選択的に処理することができます。
コマンド docker container prune は、ラベルをフィルターとして使用したコンテナの削除をサポートしています。
現在サポートされているフィルタは以下の通りです。
until () - 指定されたタイムスタンプより前に作成されたコンテナのみを削除します。
label - 指定したラベルが付いている(label!=...の場合は付いていない)コンテナのみを削除します。
今回はラベルを使って3つのコンテナを作成してみましょう。
以下の3つのコマンドを実行します。
docker run -d --label hello-1 hello-world
docker run -d --label hello-2 hello-world
docker run -d --label hello-3 hello-world
docker ps -a コマンドはラベルを表示しません。ラベルを表示するには --format オプションを使う必要があります。
完全な --format のリファレンスは
https://docs.docker.com/engine/reference/commandline/ps/#formatting
実行します。
docker ps -a --format 'table {{.Image}}\t{{.Labels}}\t{{.Command}}\t{{.Status}}'
期待される出力
IMAGE LABELS COMMAND STATUS
hello-world hello-3= "/hello" Exited (0) 1 minutes ago
hello-world hello-2= "/hello" Exited (0) 1 minutes ago
hello-world hello-1= "/hello" Exited (0) 1 minutes ago
実行してhello-1コンテナだけを選択的にpruneしてみましょう。
docker container prune --force --filter "label=hello-1”
期待される出力
Deleted Containers:
1aa4c41c7a5b164edb4bb08cec4ec8c9769fb3e7dc311c825321fc7f87989ea9
Total reclaimed space: 0B
コマンドを再実行します。
docker ps -a --format 'table {{.Image}}\t{{.Labels}}\t{{.Command}}\t{{.Status}}'
IMAGE LABELS COMMAND STATUS
hello-world hello-3= "/hello" Exited (0) 4 minutes ago
hello-world hello-2= "/hello" Exited (0) 4 minutes ago
これで残りのコンテナは2つになりました。
この2つのコンテナを実行してプルーニングしてみましょう。
docker container prune -f
実行します。
docker ps -a
期待される出力
IMAGE LABELS COMMAND STATUS
すべてのコンテナをプルーニングしました。ラベルは、特定のラベルで1つのコンテナを選択的にプルーニングするのに便利です。
複数のコンテナが同じラベルを共有している場合には、複数のコンテナをプルーニング
するのと同じように便利です。
#Docker ps フィルタリングのリファレンス
https://docs.docker.com/engine/reference/commandline/ps/#filtering より
name:::コンテナ名
label::: キーまたはキーと値のペアを表す任意の文字列。または = のように表現される。
ancestor:::: 指定された画像を共有するコンテナをancestorとしてフィルタリングします。
volume:::指定されたボリュームまたはバインドマウントをマウントした実行中のコンテナをフィルタリングします。
network:::指定されたネットワークに接続されているコンテナをフィルタリングします。
publish or expose::: を実行しているコンテナをフィルタリングします。指定されたポートを公開または公開するコンテナをフィルタリングします。port[/protocol]で表現されます。
これら3つのコンテナは同じ祖先イメージを共有しています。hello-word:latest__は、このコマンド一つで簡単にプルーニングすることができました。
docker container prune --force --filter __ "ancestor=hello-word:latest" __
これら3つのコンテナが同じネットワークを使用している場合、例えば mytestnetwork__ のように、このコマンド一つで簡単にプルーニングできました。
docker container prune --force --filter __ "network=mytestnetwork" __
#終了ステータスを使用したコンテナのプルーニング
終了ステータスは、終了したコンテナ内のプロセスの成功ステータスを表します。
終了ステータスが0の場合、通常は成功を意味します(オペレーティングシステムやプログラミング言語では、終了ステータス0=成功)。
終了ステータスの特定の数値は、特定のプログラミング言語やプログラムで定義された値を持っています。例えば、404はNginxとApacheのウェブサーバでウェブページが見つからないことを意味します。
以下の123と9の終了ステータスは、単に乱数であり、異なる終了ステータスを持つコンテナをクリーンアップする方法を示すために使用されています。
以下のコマンドを実行して、4つの異なる終了ステータスコードを持つ5つのコンテナを作成します。
docker run -d alpine:3.8 /bin/sh -c 'exit 123'
docker run -d alpine:3.8 /bin/sh -c 'exit 9'
docker run -d alpine:3.8
docker run --name nginx -d nginx:mainline-alpine
docker run --name redis -d redis:alpine
以下を実行して、コンテナの一覧とステータスの終了コードを表示します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 13 seconds ago Up 3 seconds 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 26 seconds ago Up 15 seconds 80/tcp nginx
ef02229f40da alpine:3.8 "/bin/sh" 42 seconds ago Exited (0) 30 seconds ago epic_nobel
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" 59 seconds ago Exited (9) 46 seconds ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? About a minute ago Exited (123) About a minute ago pedantic_mirzakhani
nginxとredisが実行されていますが、まだ終了コードはありません。
では実行してみましょう。
docker ps -a --filter status=exited
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef02229f40da alpine:3.8 "/bin/sh" About a minute ago Exited (0) About a minute ago epic_nobel
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" About a minute ago Exited (9) About a minute ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 2 minutes ago Exited (123) About a minute ago pedantic_mirzakhani
--filter status=exitedを指定してから、3つの終了したコンテナだけが表示されました。
docker ps -a --filter 'exited=0’
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef02229f40da alpine:3.8 "/bin/sh" About a minute ago Exited (0) About a minute ago epic_nobel
終了したコンテナは1つだけ表示されます。
実行します。
docker ps -a --filter 'exited=123’
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 2 minutes ago Exited (123) 2 minutes ago pedantic_mirzakhani
終了したコンテナが1つだけ表示されています:exited status = 123
終了ステータス=0のコンテナを削除してみましょう。
docker ps -a --filter 'exited=0' | awk '{print $1}' | xargs docker container rm
実行します。
ef02229f40da
Error: No such container: CONTAINER
実行します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 4 minutes ago Up 3 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 4 minutes ago Up 4 minutes 80/tcp nginx
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" 4 minutes ago Exited (9) 4 minutes ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 5 minutes ago Exited (123) 4 minutes ago pedantic_mirzakhani
exited=0 コンテナの削除に成功しました。
なぜエラーが出るのか:
Error: そのようなコンテナはありません。: CONTAINER
実行してみてください。
docker ps -a --filter 'exited=9' | awk '{print $1}’
期待される出力
CONTAINER
857cf388b70c
そのCONTAINERヘッダーが問題です。xargs docker container rm にはコンテナ ID のリストだけを渡すべきです。
問題を修正するには、grep: grep -v CONTAINERを使ってCONTAINERヘッダの行を削除してください。
-v は --invert-match のショートカットです。
実行します。
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER
期待される出力
857cf388b70c
Success: CONTAINER ヘッダー行が表示されていません。
この2行は同じ結果になっています。
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER
ここでは、docker psは、9つのステータスコードコンテナを終了したフィルタリング、awkは最初のフィールドを表示し、grepは、CONTAINERの単語を除外して行を選択します。
代わりに:
docker ps -a --filter 'exited=9' | grep -v CONTAINER | awk '{print $1}'
ここでは、docker psは9つのステータスコードコンテナをフィルタリングし、grepはCONTAINERという単語を除いた行を選択し、awkは最初のフィールドを表示します。
一般的には、最初にgrepで選択を行い、最後のステップとしてawkで必要なカラムだけを表示します。論理的には、grepで選択し、最後にawkで結果を表示するという流れの方が良いでしょう。
ステータス9が終了したコンテナを、エラーメッセージを表示させずに削除してみましょう。
実行:
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
期待される出力
857cf388b70c
Success: コンテナが削除され、エラーは表示されません。
ステータス123が終了したコンテナを、エラーメッセージが表示されないように削除してみましょう。
実行:
docker ps -a --filter 'exited=123' | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
期待される出力
8b084d95a2fb
Success: コンテナが削除され、エラーは表示されません。
実行します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 10 minutes ago Up 10 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 10 minutes ago Up 10 minutes 80/tcp nginx
nginxとredisだけがまだ動いています。
#ステータスのコンテナを削除:作成済み
コンテナが作成された状態で終わってしまうことがあります。これは、コンテナが何かのエラーで実行中の状態に入れなくなったときに起こります。
ここでは、起動時のランフェーズで意図的にエラーを発生させて、作成状態のコンテナを作成してみましょう。
実行:
docker run -d alpine:3.8 <span class=error> zxgarbagez </span>
期待される出力
cc00b62dcb5078fed6d9e3fc48a9e5e7a9f3ef11d6722073781c3f5054696889
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \" <span class=error> zxgarbagez </span>\": executable file not found in $PATH": unknown.
実行:
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc00b62dcb50 alpine:3.8 "zxgarbagez" 28 seconds ago Created zealous_colden
9d4163879e17 redis:alpine "docker-entrypoint.s? 17 minutes ago Up 17 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 17 minutes ago Up 17 minutes 80/tcp nginx
zxgarbagezのエラーで作成された状態になってしまいます。
このように作成されたコンテナだけをリストアップしてみましょう。
docker ps --filter status=created
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc00b62dcb50 alpine:3.8 "zxgarbagez" 28 seconds ago Created zealous_colden
status=created にあるコンテナをすべて削除してみましょう。
実行:
docker ps --filter status=created | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
期待される出力
cc00b62dcb50
削除されたときに表示されるコンテナの名前。
実行します。
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 17 minutes ago Up 17 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 17 minutes ago Up 17 minutes 80/tcp nginx
nginxとredisだけがまだ動いています。
#ステータスでコンテナを削除します:一時停止
このセクションでは、コンテナを一時停止してから削除を試みます。
Dockerはコンテナ内の全てのプロセスを凍結/一時停止するためにcgroupsフリーザー機能を使用します。
cgroups フリーザー機能を使うと、コンテナ内のプロセスは気づかず、フリーズコマンドを防ぐことも無視することもできません。
実行:
docker run -d --name testme alpine:3.8 /bin/sh -c 'sleep 10m'
小さな alpine Linux ディストリビューションを使ってコンテナを起動します。/bin/sh コマンド ( /bin/bash の小型版) を使用しています。sleep コマンド (何もしない) を 10 分間実行します。これで、一時停止できるコンテナが起動しました。
実行:
docker pause testme
期待される出力
testme
docker pause showed the name of the container it just paused: testme
実行:
docker ps -a
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
637489e9b88d alpine:3.8 "/bin/sh -c 'sleep 1? 14 seconds ago Up 6 seconds (Paused) testme
一時停止状態になっていることに注意してください。
以下のコマンドを実行すると、同じ出力リストが得られます。
docker ps --filter status=paused
このコンテナを削除してみましょう。実行してみます。
docker ps --filter status=paused | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
期待される出力
Error response from daemon: You cannot remove a paused container 637489e9b88d5704b9e677ff26199a9fec41644d4310732943cab0a2c8b0d4a6. Unpause and then stop the container before attempting removal or force remove
出力を読んでみてください。実行してコンテナを停止してみましょう。
docker stop testme
期待される出力
testme
ttme が停止したことを示します。
一時停止したいコンテナが複数ある場合は、以下のようにして一気に停止させることができます。
docker ps --filter status=paused | awk '{print $1}' | grep -v CONTAINER | xargs docker container stop
これで一時停止状態のすべてのコンテナが停止します。
これでうまくいったかどうか調べてみましょう。
実行:
docker ps --filter status=stopped
期待される出力
Error response from daemon: Invalid filter 'status=stopped’
明らかに停止状態はありません。コンテナを停止すると終了状態になります。
コンテナの有効な状態の一覧: created, restarting, running, removing, paused, exited, or dead
今度は正しい状態である exited を使って、それがうまくいったかどうかを調べてみましょう。実行してみましょう。
docker ps --filter status=exited
期待される出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e8fb9e2c41d alpine:3.8 "/bin/sh -c 'sleep 1? 3 minutes ago Exited (137) About a minute ago testme
成功しました。これが現在終了しているコンテナのリストです。このコンテナIDのリストをdocker container rmに渡して、これらのコンテナを削除してみましょう。実行します。
docker ps --filter status=exited | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
期待される出力
3e8fb9e2c41d
成功しました これで、1つだけ終了したコンテナが削除されました。自分で docker ps -a を実行すると、このコンテナがリストに表示されなくなりました。
一時停止していたコンテナは、一時停止した場所で再開できるようになりました。停止しているコンテナは、停止した場所で再起動することはできません。コンテナを再起動すると、最初から始まります。
まとめ: 一時停止したコンテナのプルーニング/削除はできない - 一時停止を解除してからコンテナを停止する必要がある。
#終了時にコンテナを削除する
すでに、hello world のコンテナは手動で削除・プルーニングしなければならないことがわかりました。
コンテナを --rm オプションで実行すると、コンテナが終了したときに自動的に削除されます。
これで実践的な体験をしてみましょう。そうすると、便利な --rm オプションを必ず使うことになるでしょう。
以下の3つのコマンドを実行して、3つのhello worldコンテナを作成します。
docker run -d --rm hello-world
docker run -d --rm hello-world
docker run -d --rm hello-world
を使ってコンテナの一覧を確認してみましょう。
docker ps -a
期待される出力。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
終了したhello worldコンテナが表示されていません。rmはこれら3つのコンテナが終了すると自動的に削除します。クリーンアップの必要はありません。
これらのbash aliasesを定義してください。2つ目のaliasを使ってクイックテストを行うことができ、後のクリーンアップの手間を省くことができます。
alias dr='docker run'
alias drrm='docker run --rm'
bash のエイリアスは長いシェルコマンドの短縮版です。その目的は、長いコマンドを入力しないようにすることです。
#チュートリアルのクリーンアップ
このチュートリアルはここまでです。
以下のコマンドを実行して、使用しなくなった画像をすべて削除してください。
docker image rm hello-world:latest
docker image rm nginx:mainline-alpine
docker image rm redis:alpine
docker image rm alpine:3.8
#Dockerの全体的なクリーンアップ
もしかしたら、あなたの開発用 docker サーバーは混乱しているかもしれません。
すべてのコンテナを停止すべきかもしれません。
そんなときは、以下のような方法ですぐに実行できます。
docker stop $(docker ps -a -q) #stop ALL containers
docker ps -a -q builds a list of all container IDs - running and exited.
これらのIDをdocker stopに渡します。
すべてのコンテナが停止します。既に終了したコンテナに対してはエラーは表示されません。
すべてのコンテナを削除するには、次のように実行します。
docker rm -f $(docker ps -a -q) # remove ALL containers
#概要
これで、あなたの仕事にコンテナクリーンアップコマンドを適用して実験することができるようになりました。
安全のためのヒント: 常にコマンドを実行して、選択されたコンテナのリストを表示するようにしてください。その後、docker container rm を実行して、実際にコンテナを削除してください。
grep, awk, xargs はこのチュートリアルで幅広く使われています。これらのツールに慣れていない場合は、チュートリアルを読む価値があることがわかります。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ