- docker の世界では
- image と呼ばれる
- aufs の layer 履歴を管理したもの(がほとんど)
- 作り方は
$ docker pull
してよそから持ってくる$ dokcer build
で新規に作成する$ docker run
した結果をcommit
する
/var/lib/docker/{graph,devicemapper}
配下に追加されていく$ docker images
で現在保有している image 一覧が確認できる$ docker rmi <image id>
で削除できる- layer は42枚がデフォルトの limit なので、運用上気をつけた方が良いかも
- ubuntu:14.04 でもすでに6枚使ってる
- 変更を入れる時は Dockerfile で basic image から作り直す運用が望ましい
- 変更 ps を commit する(≒新しくlayer をかぶせる)のではなく
- パフォーマンス的にも layer は少ない方がベター
-
基本的に1ジョブ(コマンド)を1コンテナで動かす思想
$ docker run <image id> <run command>
- ジョブが完了したらそのコンテナは終了
- 長期間駆動するワーカーとして実行する場合は
-d
(daemon mode) で駆動させる- daemon mode のコンテナは
$ docker attach <container id>
で接続できる$ docker kill <container id>
でシグナルを送れる
- daemon mode のコンテナは
-
$ docker run
が終了しても container 自体は残っている- 実態は image と同等
$ docker commit
で image として昇格させられる
- fs 的な変更がなくても、(サイズは小さいが)常に生成される
$ docker run <image id> ls
とかでも生成される
/var/lib/docker/containers
配下に追加されていく$ docker ps -a
で確認できる$ docker rm <container id>
で削除できる$ docker run --rm
で自動的に削除させられる- ただし
-d
(daemon mode) で$ docker run
させる場合には指定できない - 思想的理由がよくわからないが、
Conflicting options: -rm and -d
って言われる… - ゴミを掃除する仕組みは必要になるかも
- ただし
- 実態は image と同等
- 各コンテナは docker の世界に閉じたローカルな IP アドレスを持つ
- ただし、各コンテナにどのようなアドレスが割り当てられているか知ることが困難
- 駆動中のコンテナがもつ情報を、別コンテナ駆動時に渡してあげることはできる
$ docker run --link=<running container id>:<ref tag> ...
- 立ち上がったコンテナの環境変数に
<ref tag>_
から始まる環境変数がいくつか設定される - 中身は
<running container id>
で指定したコンテナの IP addr 等
- 立ち上がったコンテナの環境変数に
- 各コンテナが docker の世界より外と通信する場合は
- HostOS の docker0 IF を通じて通信をする
- NAT のように動作し、コンテナからはローカルな IP アドレスで通信しているように見える
- 実際には HostOS 上でブリッジの機能(brctl まわり)を使っている
- LISTEN する場合は、HostOS が LISTEN するポートと、コンテナのポートをペアリングする
- HostOS の 8080 をコンテナの 80 とペアリングする場合は以下
$docker run -d -p 8080:80 tcnksm/apache
- 外部通信をする場合、あくまで HostOS が LISTEN する点は留意
- 80 などの特定の1ポートで LISTEN できるのは1コンテナだけということ
- 複数コンテナで受けるならロードバランサとかプロクシとかの仕組みと組み合わせて
- Ubuntu 14.04 on VirtualBox on OSX
- 1 CPU (2.93 GHz Interl Core i7 の 1 core)
- 6G memory
以下の Dockerfile を元に $ docker build -t test-container .
でビルド
Dockerfile
FROM ubuntu:14.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y update
RUN apt-get -y install ruby
RUN apt-get -y install git
RUN apt-get -y install curl
RUN gem install awesome_print
RUN git clone https://github.com/kiyohara/docker_deploy_test.git
CMD [ "ruby", "docker_deploy_test/test.rb" ]
docker_deploy_test.git/test.rb
#!/usr/bin/env ruby
require 'awesome_print'
require 'webrick'
include WEBrick
puts 'running test.rb'.cyan
here = File.dirname(__FILE__)
server = HTTPServer.new(
Port: 8080,
DocumentRoot: File.join(here, 'public_html')
)
trap('INT') do
server.shutdown
end
server.start
- シナリオ
- コンテナ内容 =
while true; do echo hello world; sleep 1; done
- vagrant up した直後
- 100 コンテナ起動(1回目)
- 全コンテナ停止
- 100 コンテナ起動(2回目)
- 全コンテナ停止
- 100 コンテナ起動(3回目)
- 全コンテナ停止
- コンテナ内容 = 前述の Ruby 製 http server
- vagrant up した直後
- 100 コンテナ起動(1回目)
- 全コンテナ停止
- 100 コンテナ起動(2回目)
- 全コンテナ停止
- 100 コンテナ起動(3回目)
- コンテナ内容 =
※ $ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
※ $ docker run -d -p 8080 test-container
- 結果
phase | time | top の used | docker.io の VSS/RSS | コンテナ内プロセス の VSS/RSS |
---|---|---|---|---|
1-1 | - | 0.319G | 248M / 19M | - |
1-2 | 42.4s | 1.010G | 3,112M / 79M | 4.34M / 0.63M |
1-3 | 10.3s | 0.643G | 3,130M / 81M | - |
1-4 | 40.5s | 1.245G | 3.153M / 96M | 4.44M / 0.67M |
1-5 | 10.3s | 0.872G | 3.170M / 98M | - |
1-6 | 42.3s | 1.458G | 3.178M / 106M | 4.44M / 0.67M |
1-7 | 10.7s | 1.089G | 3.177M / 105M | - |
phase | time |
top の used |
docker.io の VSS/RSS | コンテナ内プロセス の VSS/RSS |
---|---|---|---|---|
2-1 | - | 0.341G | 253M / 33M | - |
2-2 | 52.5s | 2.481G | 3.145M / 86M | 52.78M / 11.52M |
2-3 | 9.9s | 0.733G | 3.162M / 90M | - |
2-4 | 53.3s | 2.747G | 3.176M / 103M | 52.78M / 11.53M |
2-5 | 9.7s | 1.034G | 3.176M / 106M | - |
2-6 | 59.8s | 3.036G | 3.184M / 113M | 52.78M / 11.53M |
2-7 | 10.3s | 1.301G | 3.184M / 115M | - |
※top
の used はホストOS上から観測
※VSS/RSS はホストOS上で ps
を用いて計測
※コンテナ内プロセスの VSS/RSS は 100個のうち1つをランダム抽出
-
シナリオ
- 前述のRuby製 http server コンテナを n1 個起動
- http client コンテナを 1 個起動し、内部で curl を 100 回実施した時間を計測
time docker run --link <container_id>:xxx test-container /bin/sh -c 'for i in `seq 1 100`; do curl http://${XXX_PORT_8080_TCP_ADDR}:8080/index.html; done'
-
結果
n1 | time 結果(3回平均) |
---|---|
10 | 2.845s |
100 | 3.295s |
- 基本
docker run <docker image ID> <run command>
- バックグラウンドで走らせる時
JOB_ID=$(docker run -d <docker image ID> <run command>)
docker log ${JOB_ID}
で標準出力が見られるdocker kill ${JOB_ID}
で SIGKILL
- 大体はここにのってる
- docker の操作は docker グループに所属する user でなければならない
- もしくは root (sudo)
- vagrant 環境なら、以下のように vagrant ユーザーを docker グループに追加するとよい
$ sudo gpasswd -a vagrant docker