これで解決!Docker for macのディスク容量を小さくしよう(ベータ)

先日、Docker for macでDocker.qcow2というファイルが肥大化する件というのを書かせていただきましたが、こちらの件、Docker for macの最新版ベータにて、ある程度自動で解消されるような処理がマージされたようです。

New Data Management commands #26108
https://github.com/docker/docker/pull/26108

Docker for mac のベータチャンネルにも降ってきましたので、試してみました。

今回ベータチャンネルで降ってきた内容は多いのですが、その中でReclaim disk size on rebootというのが今回の対応になってそうです。

DataManagement commands周りの主な対応内容としては、VM内のdfを表示するコマンド(docker system df)と、お掃除用のコマンド(docker system prune)が出来たといった感じでしょうか。

というコマンドで、今現在のVM内のディスク使用状況が以下のように表示出来ます。

RECLAIMABLEという列が、再利用可能な容量、といったところでしょうか。

早速、実際にpruneしてみます。

このような確認事項が表示されて

[y]を選択すると処理が始まります。

という感じにログが表示され、4.931 GB空いたようです。

prune後にDockerを再起動

メニューからrestartを選択すると再起動します。

起動したら、先ほどのdfを確認してみます。

docker system df

再利用化出来たようです。

実際のVMのサイズの変化は

prune実行前は

という巨大なVMになってしまっています。

prune実行後は

約2GBほど縮小されたようです。

これが正式版に入れば、VMのコンソールに入ったり

ディスクの変換をかけたりする必要がなくなり、dockerのコマンドで解消出来るので良さそうです。


追記

後日、何度かDocker for macを再起動してたら、さらにサイズが小さくなってました。

断片的に縮小していく感じなのかもしれません。

Reclaim disk size on rebootという位なので、もしかしたらDocker for macの再起動のたびに不要な領域が解放されていく、という事なのかもしれません。

そろそろ、自分のdocker-compose.yml周りを公開

docker便利ですね。

最近そんなことばかりしか言ってない気がします。

自分がdockerを使い始めた頃は、dockerってなんなのかわからない人が多く

話すと便利そうだけどプロダクションで使う想像がつかないとか

環境がめんど臭いとか

色々言われていました。

今現在は、開発環境として使うのであれば

docker for macというのがあって、これ入れるだけでかなり簡単にdockerが試せるようになりました。

環境を作るのが簡単になったのであれば、使えるdockerfileとかdocker-compose.ymlとかも

そろそろテンプレ的な何かがあった方が良いかな、と思い

今自分の手元でよく使っている構成でdocker-compose.ymlを公開してみます。

まずは、作りたい環境ですが

サーバサイドとしてRuby on Railsを使うことが多いので、Ruby on Railsを立ち上げる

という前提で行きます。

必要なコンテナとしては

  • Ruby on Railsが動くコンテナ

このコンテナの中には

/productsというディレクトリを作って、この中にRuby on Railsのプロジェクトを置くようにします。

  • mysqlが動くコンテナ

この二つが最低限なので、この構成を作って行きます。

まずは手元にRuby on Railsのプロジェクトを適当に作ります。

docker-compose-templateの中に入ってDockerfileを作成します。

主な構成ですが、プロジェクトのファイル以外に以下のようなファイルが追加になります。

それぞれのファイルについて中身とその解説をして行きます。

#Dockerfile

FROMのベースになるイメージは、officialのrubyにRuby on Railsで良く使うパッケージを追加したものを使用しています。

あと、特徴は

entrypoint.shという物を作成しており、ここで毎回コンテナ起動するたびに実行したい処理などを入れておきます。

#entrypoint.sh

bundle、db:migrate、pidファイル削除などを毎回起動時に行う

#Dockerfiles/mysql/conf.d/default.cnf

mysqlのコンテナで、新らし目のコンテナだとsocketの置き場所が変わったりしているので

後ほどdocker-compose.ymlでmysqlのバージョン指定はしますが、今回はdockerのofficialのmysql:5.5.54を前提に書きます。

#Dockerfiles/mysql/docker-entrypoint-initdb.d/init-user-db.sh

mysqlインスタンスの初回起動時に実行されるスクリプトになります。

これはofficialのmysqlで、コンテナ内の

/docker-entrypoint-initdb.d

というディレクトリに置かれたシェルはインスタンスの作成時に実行される

という仕組みがあるので、そこにファイルを置くように設定します。

(あとでdocker-compose.ymlでファイルを指定します)

最後、docker-compose.yml

#docker-compose.yml

ここまでで、docker-compose.ymlでRuby on Railsを起動するために必要なものは完成しました。

プロジェクトを起動するには

とやると、mysqlを起動して

init-user-db.shによってデータベースが作成され

その後にmainコンテナが起動して

entrypoint.shで初期化されて

プロジェクトが起動します。

init-user-db.sh

は、色々とカスタマイズすることで、すでにマイグレーションされたmysqlのダンプを置いて

それを初期データとして投入したり出来ます。

そうすると、

とするだけで、データベースの初期化が完了します。

また、entrypoint.shで細工しているので

の時はdocker-compose.ymlに指定したcommandが実行されてプロジェクトが起動します。

railsコマンドを叩きたい時は

とやると、コマンドが実行出来るようになっています。

なるべくシンプル構成でなるべく便利に使う想定で、今回このテンプレートっぽいファイルを作ってみました。

参考にしていただけたら幸いです。

一応githubリポジトリ

https://github.com/gendosu/docker-compose-template

 

Docker for macでDocker.qcow2というファイルが肥大化する件

Docker便利ですね。

Docker for macが出てからは、もうmac上には環境を作らない
なんて運用も可能じゃないかというくらいです。

実際、サーバサイド系の環境はほぼ全てDockerで運用してます。
gulpとかでブラウザのオートリロードとかしたい場合は
さすがに難しいので、そこはmac上に環境を作っておりますが。

ということで、ハードにDocker for macを使っていくと
ディスク容量が日々減っていくのが実感出来るかと思います。

これは、Docker for macも実体はVMであり
VMのディスクとして仮想ディスクがあり
この仮想ディスクが
~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux
に作成されています。

単純に考えると、docker imagesで表示されるイメージで容量を消費しているならば、docker rmiでイメージを消したら良いのでは?と思うのですが
そこはVM、仮想ディスクは一度領域を広げたら、通常運用では領域を解放してくれません。

ですので、この仮想ディスクを手で小さくしてあげないといけないです。

一番簡単な方法は

メニューバーに表示されているDocker for macのアイコンの中の
Preferancesからresetを開いてReset factory defaultsを選ぶこと。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-15-9-52-06

この仮想ディスクをクリアするコマンドでは、今までpullしたイメージや起動させたコンテナなども消してしまいます。

Dockerの運用ではあまりないかとは思いますが
コンテナにその場限りではあるけど変更を持ってて
コンテナとかを消したくない、といった場合はこの方法をとると
大切な変更が失われてしまいます。

そこで、仮想ディスクをshrinkする方法をとることで
現状を維持したまま
仮想ディスクを小さくする、といったことが可能になります。

方法ですが、
brewが入っている前提ですが

でqemuというツールをインストールします。
このqemuというのは、仮想マシンの一種になります。

仮想マシンで有名なところですと
VirtualBoxとかVMwareあたりになると思いますが、これらと
似たソフトウェアになります。

で、Docker for macで使用している仮想ディスクのフォーマットは
このqemuのディスクイメージフォーマットを採用しております。
なので
仮想ディスクのファイル名が
Docker.qcow2
となっています。

さて、qemuのインストールが完了したら
このツールの中の
仮想ディスクを操作するコマンドがあるので
そのコマンドを使って
Docker.qcow2
を変換かけます。

変換をかける前に、考慮する部分があり
通常ディスク上でファイルを削除した場合にはインデックス上で削除したという情報を管理して、実体は消えていない状態ですが
通常の場合だとそこに上書きすることになるので、容量があるという見え方になりますが、仮想ディスクはそのインデックス上では削除されているけれど、実体がある場合も、ディスク容量として消費していることになります。
この削除されているけれど実体がある部分を綺麗にしてから
変換をすることで、効率よくファイルを小さくする事が出来ます。

ということで、実際に変換するためのコマンドは
以下のようにします。

これを実行する際に、いらないコンテナ、イメージは全て削除しておくことをお勧めします。

で一覧表示されるコンテナの中からいらないものを全て削除します。
次に

で表示されるイメージで不要そうなものを全て削除します。

続いて、Docker for macの本体になるVMにログイン

仮想ディスク内で削除されているファイル群を削除します。

この方法の欠点は、ディスクフル(Docker.qcow2のディスクサイズ上限 or macのディスク上限)になるまでゼロ埋めファイルを作ってからそのファイルを消すということをやるので、macの容量が少ない場合は結構難しいです。
自分の場合は、ddでサイズ指定(例えば、Docker.qcow2の現在のファイルサイズの半分くらい)をして、消してます。

screenから抜けて

Docker for macを停止します。
Docker for macの停止の仕方は自分がまだ分かってないので、アレなのですが、
Docker for macのPreferenceから、Start Docker when you log inをoffにしてquitしてmacを再起動してます。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-15-9-59-53

それから仮想ディスクファイルをshrinkします。

実行時間は、そこそこ長いです。

実行が終わると、
Docker.qcow2.new
というファイルが出来上がっていると思います。

半分位になりましたね。

出来上がったら、一応ですが古い方はリネームしておいて
新しいものに差し替えます。

差し替えた状態で、Docker for macを起動します。
無事に起動して、dockerコマンドが通るようになれば、問題なくshrinkが完了しました。
古い方のDocker.qcow2を削除しましょう。

これで、溜まりに溜まったDocker.qcow2のディスクが綺麗になりました。

Docker for Mac bata(1.12)とpowが共存出来ない

Docker for Mac bataがリリースされ、早速インストールしてみました。

docker-app-icon

アプリケーションディレクトリに入れて、このアイコンをダブルクリックするだけで

Dockerの環境が自動的に構築されるようです。

docker-menu-iconメニューバーにはDockerのアイコンが表示されるようになります。

1.11以前にDocker ToolboxでDockerを使っていた場合、この初回の起動時に

既存環境を新しい環境で使えるように変換が行われます。(yesにした場合)

今回は、全く新しい環境にインストールをしているので

変換も何もなく、すぐにインストールが終わりました。

変換した場合には、既存環境に応じて、それなりのディスク消費があるので

ディスクの空きが少ない場合は要注意です。

さて、Dockerの環境としては、まだこれから試してみる事はたくさんありそうですが

ここで出てきた問題が、タイトルの通り

powと相性が悪そう、という点です。

powは、Rackサーバで、ローカルでバーチャルホストを提供します。

なので、test-appというプロジェクトであれば、http://test-app.devでアクセスができるようになりますが
test-app.devは127.0.0.1になるので、localhostです。

一方、Docker for Macもポートを80番で指定してコンテナを起動したりすると

http://localhost/でアクセスができるようになります。

Docker for Macは、今までのDocker toolboxとは違い

Mac上でネイティブにハイパーバイザーを使って環境を構築しているようです。

ですので、標準の設定のままだと、これらが衝突し、Dockerのコンテナにアクセスできない、といった状況が発生します。

自分でもこのあたりが今出来る設定で回避可能なのかどうかは、調査中ではありますが

覚書として書いてみました。

 

関連情報

http://pow.cx/

https://www.docker.com/

https://github.com/docker/hyperkit

http://bhyve.org/

Dockerを使っていく上で避けて通れないChef,ansibleとの付き合い方

こんにちは。

最近はローカルの開発環境も、ほとんどDockerに移行した感じです。

そこで、本番も見据えたDockerという事で気になることの一つ

構成管理ツール
chef、ansibleなどなどとの兼ね合い、どうするかな?

と言ったところ考えてみようと思います。

Dockerはコンテナ作成・管理ツールという性質上、コンテナ内部のパッケージやアプリの配備などをDockerfileで行う仕組みになっています。

ということは、端的に言ってしまうとchef、ansibleなどがなくてもコンテナを作れてしまいます。

わざわざDockerで作ったコンテナに対してchefを流して環境を作る、とか意味がありません。

では、Dockerfileの中でChefを呼ぶのはありか?という所ですが

個人的にはこれもあまり嬉しくないなと思います。

Dockerfileを見るだけで、そのコンテナがどんな環境になるのか、というのが一発でわかるようにしたいです。

また、構成管理ではないですが、Dockerでシェル叩いていたり、起動する単一プロセスに構成設定のシェルを指定しているDockerfileが割と多かったりしますが、これも実際何しているのか?というのをシェル見ないと分からなくなってしまうので避けるようにしています。

では、全く使わないのか?

と言われると、NOで

Dockerをそもそも動かすホストマシン側の構成管理については

Chef、ansibleが使える物と思っています。

最低限、Dockerが動かせる環境をChefで構築する

docker engine
docker machine
docker compose
docker swarm

あたりのインストールを自動化しとくのが良いと思います。

そうすることで、ホストマシンが自前だろうがAWSだろうがIDCFだろうがさくらだろうが

さらにOSがUbuntuでもCentOSでも、ホストマシンを自動で構築することも可能になってきます。

所定のdocker engineさえ入っていればコンテナが動くわけです。

なお、docker-machineを使う場合、docker-machineが対応しているクラウドサービスの場合は構成管理しなくても良い位手軽に起動する事が出来たりします。
これは、docker-machineのcreateで作成されるホストには、docker-machineが自動で上記のモジュール類を入れて環境設定してしまうためです。

Dockerを本気で使っている方々には当然の内容ではありますが、以上、一つの考え方として参考にしていただけたらと思います。

gendosu流、dockerの使い方(Docker composeを使う)

dockerを開発環境で使うに当たって

前回「gendosu流、dockerの使い方」という内容を書きました。

その内容だと、

通常Dockerコンテナを手動で起動するには
まず、Dockerfileを作って自分好みにイメージを作成
作成したイメージからdocker runコマンドでコンテナ起動
たとえば、memcachedとmysqlとredisを使った一通りの構成を手動で起動しようとした場合
それぞれにイメージ作成やdocker run(start)をして起動していかないといけないです。
コンテナ間にリンクを張っている場合は起動順序も考慮する必要があります。

面倒ですね。

そこで、今回はDocker-composeを使ってみたいと思います。
こちらのツールはDockerのオフィシャルで配布されているツールになります。

簡単に言うと、複数コンテナの情報を1ファイルに集約して、そのファイルを元に
1コマンドで全コンテナを起動できるようにするツール

という事になると思います。

早速

インストール

Docker composeのインストールは

https://docs.docker.com/compose/install/

をみて作業を進めます。

これでdocker-composeというコマンドが入りました。

docker-composeを使うには
コマンドを実行するディレクトリ配下にdocker-compose.ymlというファイルを作成します。

※ディレクトリ構成

今回は前回の構成
webとmysql
という2つのコンテナを起動するような構成でファイルを作ってみたいと思います。

Dockerfile(supervisordのディレクトリも)は前回の物を流用します。

# Dockerfile

EXPOSEとCMDは、次のdocker-compose.ymlで設定するので、ここでは設定してません。

# docker-compose.yml

これで設定ファイルの準備が完了しました。

起動はdocker-composeにオプションを指定して実行します。

docker-composeのオプションで、代表的な物は

  • up
    コンテナをイメージから作り直して起動する
  • stop
    すでに起動しているコンテナを終了する
  • start
    停止しているコンテナを起動させる

あたりかと思います。

起動してみます。

upというオプションを指定して起動させました。

Dockerfileのビルドが走った後に

各イメージからコンテナが生成されて起動された事が確認できると思います。

あとは、前回同様、ポート2200を指定してsshすることでwebコンテナへログインする事が出来ます。

gendosu流、dockerの使い方

以前よりローカルでの仮想環境の生成・破棄は容易になったような気がしますが

Vagrantでは、インスタンスの生成、破棄のコストが高い気がするので

そこのところをDockerを使ってやってみるようにしてみました。

gendosu流dockerの使い方

まずは、ベースになるマシンとしてUbuntu Server 14.10 64bitの仮想マシンを立ち上げます。

これは、VagrantでもVMwareでも問題ないです。

今後、頻繁にアクセスすることになるので、vmのIPをhostsに登録してしまいます。

hostsには

192.168.?.?    local-vm

として登録しちゃいます。

これで、vmに

ssh root@local-vm

という感じでログインできるようになりました。

ここから、dockerのセットアップをします。

ubuntu14では、

http://docs.docker.com/installation/ubuntulinux/

にあるとおりに

とやってインストールします。

これで、入ったので、dockerにコンテナを作ってみます。

ただ、普通にやるとコンテナ内へのアクセスが面倒なので

各コンテナ内にsshを起動してしまいます。

これで、ポート指定で外部からssh接続できるコンテナになります。

やり方ですが

Dockerfileを作ってイメージを作成するようにします。

# => Dockerfile

というファイルを作成します。

同じ階層にsupervisord/ssh.conf

を作成します。

こちらは

とします。

このDockerfileをdocker buildでイメージにします。

これで、sshdが起動するdockerコンテナのイメージが作成されました。

このイメージを元に、「run-ubuntu-ssh」という名前でコンテナを起動します。

これで、2200番のポートを指定してssh接続が出来るようになりました。

各コンテナでsshが起動するのは無駄な気がしますが

アクセスが容易になる分、開発環境では便利になるのではないでしょうか。

さて、sshdは起動しましたが、たいていの場合MySQLとかも同時に入れたりしたくなったりします。

MySQLの場合は、別のコンテナでMySQLだけが入ったものを用意します。

これは、Docker.ioのdockerhubから持ってきます。

https://registry.hub.docker.com/

この中に、MySQLというリンクがあるので、ここを開いて、手順通りにやると

MySQLの入ったコンテナが起動できます。

先ほど、「run-ubuntu-ssh」コンテナを起動したときに使ったコマンド

docker runに、別のコンテナへのリンクを追加するというオプションがあります。

今回はそのオプションを追加します。
※先ほどのdocker runを実行している場合、一度docker stop、docker rmでコンテナを破棄します。

mysqlという名のコンテナに対してリンクを張っています。

run-ubuntu-sshコンテナの内部からは、mysqlという名前でmysqlコンテナへ接続できるようになっています。

というコマンドでMySQLへ接続できていればOKです。

別のコンテナを起動する場合、先ほどのdocker runのコマンドで、-p 2200:22のところを2201:22という感じにインクリメントしていくことで、比較的容易にコンテナを管理できると思います。