Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Docker 虎の巻

Docker 虎の巻

何故Dockerを使うべきか

Why Should I Care (For Developers)

"Dockerが面白いのはシンプルな環境に隔離性と再現性をもたらしてくれることだ.ランタイムの環境を一度作れば、パッケージにして別のマシンでも再利用することできる.さらに,すべてはホスト内の隔離された環境で行われる(VMのように).最も素晴らしい点は,シンプルかつ高速であることだ."

Dockerで使われている技術

仮想環境構築に docker を使う

LXC

"Xen とか VirtualBOX みたいにホスト内に仮想マシンを立ち上げるんじゃなくて、ホスト内の隔離された環境で仮想マシンを動かす技術。物理マシンをシミュレーションしているんじゃないってことは、VPS とか EC2 とかの仮想マシン上でも問題なく動くし、マシンを起動するプロセスが不要となるので、一瞬で使い始められるというメリットにつながっている。"

AUFS

"UnionFS(ディレクトリを重ね合わせることができる)の実装の一つ。元の仮想マシンイメージを書き換えないで、更新が発生した部分は別の場所に書き込んでいくようになっている。これにより、仮想マシンの立ち上げ時にイメージのコピーが発生しないので、すぐに使い始められる。"

Dockerで開発環境をセットアップする

OSXでDockerを利用するための準備

VirtualBoxとVagrantを準備する.dmgでインストール可能であるが,HomebrewBrew Caskを使えば,コマンドラインからインストールすることも可能.

Homebrewのインストール

ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Virtualboxとvagrantのインストール

brew tap phinze/homebrew-cask
brew install brew-cask
brew cask install virtualbox
brew cask install vagrant

インストール

今回は,Dotcloudが準備したVagrantfileを用いる: docker/Vagrantfile(訳者注: 原典ではDocker friendlyなvagrant boxを使っているが,こちらを使ったほうが簡単なので改変).

git clone https://github.com/dotcloud/docker
cd docker
vagrant up
vagrant ssh

Hello world

docker run ubuntu /bin/echo hello world

コンテナ

Your basic isolated Docker process. コンテナのVMに対する関係は,スレッドに対するプロセスの関係とみなすことができる. もしくはコンテナをchrootと見なすこともできる.

いくつかの誤解:

  • コンテナは一時的なものではない. docker run はあなたが考えているものではない.
  • コンテナは単一のコマンドやプロセスに限定されない 奨励されているだけ.

ライフサイクル

コンテナを起動し,それに接続したい場合は,docker startしてからdocker attachする.

完全に一時的なコンテナを作りたい場合は,docker run -rmで作成すれば停止(docker stop)後にコンテナは破棄される.

ホストのディレクトリをコンテナ内にマウントしたい場合は,docker run -v $HOSTDIR:$DOCKERDIR IMAGE COMMANDとする.

各種情報の表示

  • docker ps 起動中のコンテナを表示する.
  • docker inspect コンテナの全情報を表示する(IPを含む).
  • docker logs コンテナのログを表示する.
  • docker events コンテナ内のイベントを表示する.
  • docker port コンテナのportを表示する.
  • docker top コンテナのプロセスを表示する.

docker ps -a 起動中と停止中のコンテナを表示する.

インポート/エクスポート

  • docker cp コンテナ内のファイルをホストにコピーする.
  • docker export コンテナのファイルシステムを出力する.

イメージ

イメージとは単にdockerコンテナのためのテンプレート.

ライフサイクル

  • docker pull レジストリからdockerイメージ,もしくはレポジトリを取得する.
  • docker import ファイルシステムのtarballからイメージを取得する.
  • docker tag イメージにタグをつける.(タグ名は<username>/<imagename>が奨励されている)
  • docker build Dockerfileからイメージを作成する.
  • docker commit コンテナからイメージを作成する.
  • docker rmi イメージを削除する.
  • docker insert URLからイメージにファイルを取り込む.
  • docker load 標準入力としてtarファイルからレポジトリを取り込む.タグとイメージを含む(バージョン0.7現在)

単にイメージ内にログインしたい場合は,docker run -rm -t -i IMAGE /bin/bashとする.

docker importdocker commit はファイルシステムをセットアップするだけで,DockerfileのようなCMDやENTRYPOINT,EXPOSEは含まない.bug.

各種情報の表示

参照

Dockerのイメージはどこにある?

レジストリとレポジトリ

レポジトリ(repository)は,ホストされた タグ付きのイメージの集合.

レジストリ(registry)は,ホスト -- レポジトリを保持し,[レポジトリのアップロードやダウンロードのためのHTTP APIを提供する](http://docs.docker.io/en/l\ atest/use/workingwithrepository)サーバ.

Docker.ioは,自身のindexをレジストリにホストしており,多くのレポジトリが存在している. (自分のレポジトリをhttps://index.docker.io/に作成することも可能)

  • docker login レジストリにログインする.
  • docker search レジストリのイメージを検索する.
  • docker pull レジストリからdockerイメージ,もしくはレポジトリを取得する.
  • docker push イメージをレジストリにプッシュする.(レポジトリ名は/<repo_name>)

Dockerfile

configurationファイル.docker buildとすることでDockerコンテナのセットアップを行う.docker commitよりも好ましい.

http://github.com/wsargent/docker-devenvを読むが良い.より詳細にはbest practicesが良い.

訳者の例、Dockerで複数バージョンのrubyがインストールされたイメージを作る

Layers

DockerのAufsはLayersに基づく. Layersはファイルシステムのためのgit commitsもしくはchangesetsのようなものである.

Links

Linksは,Dockerコンテナ同士が通信するための仕組みである.Linking into Redisが唯一の実例.

例えば,CONTAINERという名前のついたコンテナがあり,以下のようにDockerfileに外部に晒すポートが設定されているとする.

EXPOSE 1337

このとき,LINKEDという名前の別のコンテナを以下のように作成すると,

docker run -d -link CONTAINER:ALIAS -name LINKED user/wordpress

外部に晒したポートとコンテナのエイリアスが以下の環境変数でLINKEDコンテナに現れる.

$ALIAS_PORT_1337_TCP_PORT
$ALIAS_PORT_1337_TCP_ADDR

Linksを削除するには,docker rm -linkとする.

Volumes

Dockerのvolumesは流動的な(free-floating)なファイルシステムである.volumesは特定のコンテナに接続されていなくてよい.

volumesは,linksが使えない状況で便利である.例えば,2つのDockerインスタンスの通信をそのファイルシステムと切り離して行う必要があるときなど.

docker run -volume-fromとすれば,同時に複数のDocker コンテナでそれらをマウントすることができる.詳細はadvanced volumes

Tips

参考

最後に実行したコンテナのIDを取得する

毎回コンテナのIDを保持するのは面倒

ID=$(docker run ubuntu /bin/echo hello world)
docker commit $ID hello-world

以下のaliasを設定すると便利

alias dl='docker ps -l -q'
docker run ubuntu echo hello world
docker commit `dl` helloworld

起動コマンドを含めてコミットする(Dockerfileが不要)

Cmdは起動後のコンテナで実行するコマンド

docker run -i -t ubuntu bash
apt-get install posgresql
exit
docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' `dl` postgres

IPアドレスを取得する

docker inspect `dl` | grep IPAddress | cut -d '"' -f 4

もしくは

wget http://stedolan.github.io/jq/download/source/jq-1.3.tar.gz
tar xzvf jq-1.3.tar.gz
cd jq-1.3
./configure && make && sudo make install
docker inspect `dl` | jq -r '.[0].NetworkSettings.IPAddress'

イメージの環境変数を取得する

docker run -rm ubuntu env 

古いコンテナを一気に削除する

docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm

停止中のコンテナを一気に削除する

docker rm `docker ps -a -q`

イメージの依存関係を表示する

docker images -viz | dot -Tpng -o docker.png
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment