おはようございます。レモンです。
友人がDockerすげえ、やべえって言っててかつ一緒に作ってるサービスもDockerで運用する予定だと言い出したのでこれは僕もある程度触れるようになっておかないとまずいっちゅうわけで少し触ってみました、というお話。どっちかというと使い方というよりは所感と言った感じです。
そもそもDockerって何さ
さて、そもそもDockerとは何なんでしょうか?自分も彼に紹介されるまで全く知りませんでした。
詳しくは公式ページを見てもらえればいいのですが当たり前のように英語なのでちょっとわかりにくいですよね。
ざっくりというと、めっちゃ省スペースなVMと考えて差し支えないと自分は思いました。
細かく言うと従来の変更の度に既存のサーバに変更を加えるやり方ではなく、Immutable Infrastructureと呼ばれる既存の環境をイチから作り直し、古いものを切り捨ててしまうという考え方によるものであります。
これを実現するためにDockerではコンテナとイメージという単位でOSを管理していき、Gitのようにバージョン管理を行いながら逐次更新したり削除していきながらOSを操作していきます。
そして、これがすごいんですが、ある構築した環境を別のDockerがインストールされている環境へまるまるコピーができるわけです。こうすることで、環境移行のときにわざわざ前の設定を思い出しながらLinuxを泣きながらいじるという手間をDockerさえ入れてしまえばSkipできてしまう!というわけなんです。なぜ、省スペースなのか、というと元となるイメージが最小構成(bashくらいしか動いてない)なのと、差分で環境を管理しているためなんだそうです。そのため、起動や破棄、リソース量などが従来のVMと比べて軽い上、差分で管理しているためGitでDockerの設定状況を管理する!みたいなこともできるんだそうです。すげー。
コンテナとイメージ
さて、Dockerを使う上で必ず覚えなくちゃいけない概念がこのコンテナとイメージというものです。この2つをやりとりすることがDockerの基本的な操作になります。
詳しくは@IT様のこちらのページがわかりやすいなーと思いました。
まあ自分なりにも説明してみます。
まず、イメージというものはOSのモトとなるもので所謂テンプレートです。オブジェクト指向でいう「クラス」にあたりますね、このクラス、もといイメージからDockerはコンテナを作ることが出来ます。
ちょうど、クラスからオブジェクトを生成するのとおなじ感覚でいいと思います。自分はその感覚が完全にしっくり来ました。
オブジェクト指向と異なる部分はここからで、イメージから生成されたコンテナを作ってあげるとその中のOSを起動し、いじることができます。例えばapt-get updateをしてあげたり、vimをインストールしたり、apacheを入れたりと様々なLinuxでできる操作を行うことが出来ます。ホストOSとDockerで起動中のコンテナ上のOSもコマンド一発で行き来できます。(後述)
ある程度変更が完了したら、コンテナの変更状況をイメージに書き込みます。イメージに書き込んであげるとコンテナの変更状況を反映したイメージが再び生成されます。普通に生成してあげるともともとあったイメージと、新しく変更を反映したイメージどちらとも残ります。これらは作業の進行状況に合わせて削除したり残しておいたりすることができます。と言った感じです。
また、変更作業中以外は基本的にはコンテナは使いきりで、変更が終了したら必ずイメージに反映させ、中途半端な変更をしたコンテナを残さないようにすることで変更作業が混乱することがなくなるようです。
図示すると以下の様な感じでしょうか。
実際に使う
さて、じゃあ実際に使う場合にはどうすりゃいいのよって話なんですがそんなに難しくないです。
参考:いまさら聞けないDocker入門(2):ついに1.0がリリース! Dockerのインストールと主なコマンドの使い方 – @IT
参考ってか、これのインストール以降部分を噛み砕いて説明って感じです(・ω・`)
インストール
まず、Dockerをインストールしましょう。今回はCentOS7を使いましたが、Ubuntuとかでも多分大丈夫です。ただ、インストールが一番楽なのはCentOSなんだとか。
$ sudo yum install docker
これだけでOKです。ただ、バージョンが低いので最新版が欲しい場合はEPELを用いてパッケージを引っ張ってきてください。
dockerのベースイメージをダウンロードする
Dockerが入ったので元となるイメージをDockerから引っ張ってきましょう。現在安定しているOSがUbuntuしかないのでとりあえずUbuntuで。
他にも、CentOSや各サービス(MySQL,WordPress,PostgreSQL,nodejsなど)が引っ付いたUbuntuイメージも引っ張ってこれるのですが、今回はまっさらなUbuntuイメージを持ってきます。
また、CentOSは現在安定版が存在せず致命的なバグが多いためあまり使わないほうが懸命のようです。
「引っ張ってくる」のでdocker pullを使います↓
$ sudo docker pull ubuntu:latest
pullのあとにOS名:タグ名と入れてあげるとDLが可能です。タグ、というのはバージョンごとに付いている名前のようなものです。ここに載っています。
DLができたら確認をしましょう。
$ sudo docker images
これで現在インストールされているイメージの一覧を表示することが出来ます。
イメージからコンテナを生成する
イメージが引っ張ってこれたので今度はここからコンテナを作って実行してみます。
「実行」するのでdocker runですね。
$ sudo docker run -it --name ubuntu-container ubuntu /bin/bash
でOKです。これでubuntu-containerというコンテナを作成し、実行することが出来ます。オプションなどはDocker公式や@ITのページなどを参考にしてください。一応-itでコンテナの標準入力を開き(-i)、かつtty(端末デバイス)を確保する(-t)という意味みたいです。まあ、上のコマンドを最初のウチは呪文のように打っておいても問題なさそうです。
無事にrunできるとrootでDockerコンテナ上のOSのbashが起動し、いじることができるようになります。あとは、ここから普通のUbuntuと同じように色々インストールをしたり、ネットワーク設定をしたりしてあげればOKです。
また、Dockerコンテナ上のOSからホストOSに戻るにはCtrlを押しながらpを押した後、qを押します。
また、ホストOS上で現在起動しているコンテナを確認するためには以下のコマンドを実行します。
$ sudo docker ps -a
コンテナからイメージを生成する
さて、コンテナの調整ができたらイメージを作ってとりあえず作業は一段落ですよね。
ということでイメージを作ります。まず、ホストOS側にCtrl-p-qで戻りましょう。そして、現在起動しているdockerコンテナOSを停止させます。OSなので起動中にイメージの生成とかできません。
$ sudo docker stop ubuntu-container
イメージの生成ではdocker commitというコマンドを使います。Gitのリポジトリにcommitしている感覚でしょうか。コミット前にdocker psでコンテナがきちんと止まっているかも確認しておくと安心です。
$ sudo docker commit ubuntu-container myubuntu-image1
commitの後にコンテナの名前とイメージ名を入れればOKです。上ではmyubuntu-image1というイメージ名で作成しました。
この後に、
$ sudo docker images
と打ってあげれば作ったイメージが在ることが確認できるかと思います。
既存のイメージを削除したいときには
$ sudo docker rmi (イメージ名)
と打てばOKです。
また、止めてしまったコンテナはdocker startというコマンドで再開することもできます。
$ sudo docker start -i ubuntu-container
基本的には以上の操作の繰り返しなんだそうです。ここまでくれば、作ったイメージからまたコンテナ作っていじってイメージ作っていらないイメージ消してーといったやりとりが出来ますよね。
僕がいじったのはここまでなので他のことはあんまし言えません。他にもDockerfileなるものとかもあるみたいですが、今回は触れていないので、No Touch!で。
所感
友人の彼いわく、これの実用的な使い方としてはテスト用の鯖と本番用の鯖を2つ同じような環境(例えば同ネットワーク内など)に用意して、両方にDockerを入れ、変更をテスト用の鯖にDockerを使って反映しながらテストを行い、それがうまく行ったら本番用の鯖を一瞬止めてテスト用鯖で作ったイメージを本番用鯖に突っ込み、コンテナを生成&起動してしまえばメンテ時間がめちゃくちゃ短くなる!みたいなことを語気荒く説明してくれました。
もしこれが本当に実用で使うようになればサーバ管理に革命が起きそうだなーと思います。このDockerなんでもまだ作られて1年立ってないとからしいのでめちゃくちゃHOTなサービスです。今後も注目ですねー(`・ω・´)