Docker便利ですね。
いらなくなったDocker imagesは手動で削除していますか?
毎日起動するたびにイメージがたまっていくので定期的に掃除が必要ですよね。
インフラのコード化のためにDocker導入したのだとしたら、定期削除もbashでさくっと書いてcronで仕掛けましょう。
本稿ではDocker imagesコマンドの出力結果をbashでうまく取り扱うテクニックを紹介します。
別途、シェル化して自動運用するところまで記事化したいですが、そこまで余裕が無いのでまずはここまで。
まずはコマンドラインで
Dockerイメージがあります。
[fk2000@office dockers]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/golang 1.6-onbuild c4f87d4e5dc0 3 weeks ago 748.5 MB
docker.io/mysql latest 78cdcf394b4e 4 weeks ago 400.1 MB
docker.io/mongo latest a3bfb96cf65e 6 weeks ago 402 MB
docker.io/ubuntu 12.04 f0d07a756afd 7 weeks ago 103.6 MB
docker.io/redis latest d59dc9e6d0bf 7 weeks ago 182.9 MB
docker.io/postgres latest 0e24dd8079dc 7 weeks ago 264.8 MB
docker.io/memcached latest af4e963abb12 7 weeks ago 126.1 MB
docker.io/debian latest 19134a8202e7 7 weeks ago 123 MB
| cut -d' ' で単一の空白区切りで扱うと、出力結果がばらばらに
docker imagesコマンドだと行によって空白の数が違い、このままだと扱いづらいです。
[fk2000@office dockers]$ docker images | cut -d' ' -f1
REPOSITORY
docker.io/golang
docker.io/mysql
docker.io/mongo
docker.io/ubuntu
docker.io/redis
docker.io/postgres
docker.io/memcached
docker.io/debian
[fk2000@office dockers]$ docker images | cut -d' ' -f2
[fk2000@office dockers]$ docker images | cut -d' ' -f3
[fk2000@office dockers]$ docker images | cut -d' ' -f4
latest
[fk2000@office dockers]$ docker images | cut -d' ' -f5
latest
[fk2000@office dockers]$ docker images | cut -d' ' -f6
[fk2000@office dockers]$ docker images | cut -d' ' -f7
1.6-onbuild
12.04
latest
[fk2000@office dockers]$ docker images | cut -d' ' -f8
latest
latest
latest
[fk2000@office dockers]$ docker images | cut -d' ' -f9
[fk2000@office dockers]$ docker images | cut -d' ' -f10
そこで、sedで整形する
cutする前にsedで空白を複数まとめてひとつに整形してしまえば単に区切りとして整頓されます。
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f1
REPOSITORY
docker.io/golang
docker.io/mysql
docker.io/mongo
docker.io/ubuntu
docker.io/redis
docker.io/postgres
docker.io/memcached
docker.io/debian
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f2
TAG
1.6-onbuild
latest
latest
12.04
latest
latest
latest
latest
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f3
IMAGE
c4f87d4e5dc0
78cdcf394b4e
a3bfb96cf65e
f0d07a756afd
d59dc9e6d0bf
0e24dd8079dc
af4e963abb12
19134a8202e7
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f4
ID
3
4
6
7
7
7
7
7
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f5
CREATED
weeks
weeks
weeks
weeks
weeks
weeks
weeks
weeks
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f6
SIZE
ago
ago
ago
ago
ago
ago
ago
ago
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f7
748.5
400.1
402
103.6
182.9
264.8
126.1
123
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f8
MB
MB
MB
MB
MB
MB
MB
MB
[fk2000@office dockers]$ docker images | sed 's/\s\{1,\}/ /g'| cut -d' ' -f9
でもまだヘッダが値の行と一致していないくてじゃまですね。
では、| tail -n +2 してしまいましょう。
単位の列はcutコマンドのオプションで前列の数値に結合します。(-f4-6、-f7,8 のようにハイフンやカンマで指定します)
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f1
docker.io/golang
docker.io/mysql
docker.io/mongo
docker.io/ubuntu
docker.io/redis
docker.io/postgres
docker.io/memcached
docker.io/debian
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f2
1.6-onbuild
latest
latest
12.04
latest
latest
latest
latest
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f3
c4f87d4e5dc0
78cdcf394b4e
a3bfb96cf65e
f0d07a756afd
d59dc9e6d0bf
0e24dd8079dc
af4e963abb12
19134a8202e7
```shell-session:出力例4-6
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f4,5
3 weeks
4 weeks
6 weeks
7 weeks
7 weeks
7 weeks
7 weeks
7 weeks
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f7,8
748.5 MB
400.1 MB
402 MB
103.6 MB
182.9 MB
264.8 MB
126.1 MB
123 MB
[fk2000@office dockers]$ docker images | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f9
まとめ
シェルでrmiするよりも、Docker1.13バージョンのdocker systemコマンドでやったほうが楽ですね。
追記
シェル化して、cronでぶん回してディスクスペースに余裕ができましためでたしめでたし。
#!/bin/sh
TODAY=$(date +%Y%m%d)
START_LOG="#time:`date +%Y%m%d_%H-%M-%S` [start] "
echo ${START_LOG} 2>&1 | tee -a ./logs/$TODAY.log
echo "before:" && docker images ${DOCKER_ENDPOINT}/${SERVICE} | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f1-3
# デリミタを退避
IFS_BACKUP=$IFS
IFS=$'\n'
# 2世代以上のdocker imagesのimageIDを配列に格納
ARGS=($(docker images ${DOCKER_ENDPOINT}/${SERVICE} | tail -n +4 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f3))
echo "${ARGS[@]}" 2>&1 | tee -a ./logs/$TODAY.log
if [ ${#ARGS[*]} -gt 0 ] ; then
#echo "${ARGS[@]}"
docker rmi "${ARGS[@]}"
else
echo "No arguments supplied" 2>&1 | tee -a ./logs/$TODAY.log
fi
# デリミタを元に戻す
IFS=$IFS_BACKUP
echo "after:" && docker images ${DOCKER_ENDPOINT}/${SERVICE} | tail -n +2 | sed 's/\s\{1,\}/ /g'| cut -d' ' -f1-3
END_LOG="#time:`date +%Y%m%d_%H-%M-%S` [end] "
echo ${END_LOG} 2>&1 | tee -a ./logs/$TODAY.log