lxc
- LXC - Wikipedia
- OSレベル の仮想化ソフトウェア
- 完全仮想化(ハードウェアをエミュレート、オーバーヘッド大) - KVM etc
- 準仮想化(ゲストOSがホストOSのAPIを使用、オーバーヘッド中) - Xen, Hyper-V etc。Virtualboxもこちらか
- 仮想機械ではなく、個別のプロセスとネットワークスペースを作り出す仮想環境
- ホストマシンの単一のカーネルの上で動作する。他の仮想化ソフトウェア(例えばXenとか)はVM単位で複数のカーネルが動く
- Linuxカーネル 2.6.29から利用可能
- cgroupsに依存(cgoups - プロセスグループのリソース(CPU、メモリ、ディスクI/Oなど)の利用を制限・隔離するLinuxカーネルの機能)
- 完全仮想化や準仮想化と比較して
- 実行速度が高速
- セキュリティ面で優位
- ハードウェアリソースの有効活用面で優位
- 最近のサーバの抽象化について - As a Futurist...
- 物理サーバの場合、「OS が プロセス へ リソース を割り振る」 = リソースコントロールやりづらい。ファイルシステム, CPU, RAM...
- 異なるOSを同居して使うことが出来ない(使いたいライブラリがDebian版しかない, etc)
- AWSのようなクラウドサービスは、 欲しいサーバーを欲しい時に素早く入手できる
- ただしパフォーマンス(特にI/Oの)とのトレードオフ
- Dockerは、 プロセスをあたかもLinuxのコンテナの様にしてしまう
- 軽量
- 柔軟なリソース割り振り
- じゃあ "どうやって" 割り振るか は今後の課題。Mesosのようなこれに特化したミドルを使うとか
- ホストとゲストでディストリビューションやそのバージョンが違ってても動く
- 他の仮想化と比較してオーバーヘッドもない(少ない)
- Dockerは イメージの使い回しが可能
- 自社の物理サーバーで稼働させていたコンテナイメージをAmazon EC2上に移す etcが容易
Share Images via Repositories - Docker Documentation
Docker is not only a tool for creating and managing your own containers – Docker is also a tool for sharing.
- central index Home | Docker Index で様々なイメージが公開されている
- central index上のイメージは
docker search
で検索可能 - 自作イメージを公開したければ、まず
docker login
でcentral indexにアカウントを登録 - イメージ作成/push時には、
登録したアカウント名/イメージ名
を使用するのが慣例
$ sudo docker commit CONTAINER [myname]/[image_name]
$ sudo docker push [myname]/[image_name]
-
githubのアカウントと連携することで、 Trusted Builds が使用可能
- githubにupしたDockerfileを含んだプロジェクト をdocker.ioが自動でビルドしてくれるサービス
- 結果は Builds | Docker Index にフィードバックされる
-
プライベートリポジトリも使用可能
- プレイベートリポジトリサーバーは dotcloud/docker-registry を使用して構築する
- central indexを含んだ複数のリポジトリを使用する場合、
$HOME/.dockercfg
ファイルにそれぞれの認証情報をJSON形式で記述
{ "https://index.docker.io/v1/": { // central indexのキーは "https://index.docker.io/v1/" 固定 "auth": "xXxXxXxXxXx=", // authには "[username]:[password]" をbase64エンコードした文字列を設定 "email": "[email protected]" }, "https://my-registry.com": { "auth": "XxXxXxXxXxX=", "email": "[email protected]" } }
Redirect Ports - Docker Documentation
- コンテナに割り振られるIPアドレスは、 ホストマシン内でローカルなもの
docker inspect
の出力で確認可能
- コンテナ(のポート)はホストマシン外部からはunreachable
- コンテナのIPアドレスが起動の度に変わるので「コンテナAからコンテナBのポートに接続したい」なんてケースも起動の度に設定をいじらないと駄目
- つまり単にdocker runしただけのコンテナでは、他コンテナやホストマシンetcとの相互通信が不可能/不便である
- ポートバインディング(like マッピング, フォワーディング)を使って解決
- 非ローカル(=ホストマシンやホストマシン内のコンテナ 以外)からコンテナのサービスに接続したい場合も同様
- docker run時に
-P
オプションを使用した場合、ホスト側でバインドするポートは49000..49900
の範囲で未使用のものが自動選択される- vagrantを使用している場合、Vagrantfileの
:forwarded_port
属性でこれらのポートフォワードを指定しておけば、ローカルマシン => VM => dockerコンテナ 間のポート通信(フォワード)を実現可能
- vagrantを使用している場合、Vagrantfileの
- もちろん明示的に指定することも可能で、docker runする際に
-p
オプションを使用すると、ホストマシン<=>コンテナ間の指定ポート同士がバインディングされる - 以上から、 dockerコンテナではホストとのポートバインディングだけ気にしておけばよくiptablesのようなアクセス制御は行わない・アクセス制御はホストマシン"だけ"で行う のがあるべき姿nのかなと
Configure Networking - Docker Documentation
- コンテナへの接続はブリッジ接続
- デフォルトでは
docker0
というブリッジを使う - dockerのデーモン起動時に、未使用のIP範囲を検索し、docker0ブリッジに割り当てられる
- コンテナ実行時にdocker0ブリッジと紐付いた仮想的なネットワークインタフェースが割り当てられる
- 同時にdocker0に割り当てられたIP範囲のIPアドレスが割り当てられる
- docker0のIPアドレスが、コンテナから見たgatewayアドレスとなる
- docker0はXenのxenbr0と似てるようで違う
- xenbr0は物理ネットワーク上に存在させる(ように見せる)為の仮想ブリッジ、docker0はそのような見え方はさせない
- ポートフォワードの項で書いたとおり外からはunreachable(ポートフォワードを使え というポリシー)
- コンテナ同士でover ブリッジな通信を可能にしたい場合は、
-icc=true
オプションを指定する(デフォルトはfalse)
- xenbr0は物理ネットワーク上に存在させる(ように見せる)為の仮想ブリッジ、docker0はそのような見え方はさせない
- docker0はIPv6が有効になってる模様
- コンテナを実行するとdocker0のブリッジ情報のインタフェース欄に
vethXXXX
というID?が表示される- ホストのvethXXXX と コンテナのeth0 が接続ペア
[vagrant@vmdocker1 ~]$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.fe239cee3696 no
[vagrant@vmdocker1 ~]$ ifconfig docker0
docker0 Link encap:Ethernet HWaddr FE:23:9C:EE:36:96
inet addr:172.17.42.1 Bc
ast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::c8e2:13ff:fee7:7766/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2940 errors:0 dropped:0 overruns:0 frame:0
TX packets:12169 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:120698 (117.8 KiB) TX bytes:14877602 (14.1 MiB)
[vagrant@vmdocker1 ~]$ docker run -t -i -d hoge /bin/bash
[vagrant@vmdocker1 ~]$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.fe239cee3696 no vethowR0mm # <= コンテナ実行中は仮想的なインタフェースが割り当てられる
- IPアドレス(のレンジ)を変更したりしたい場合
- docker用のブリッジを追加作成
- run時にそのブリッジを指定
# Stop Docker
$ sudo service docker stop
# Clean docker0 bridge and
# add your very own bridge0
$ sudo ifconfig docker0 down
$ sudo brctl addbr bridge0
$ sudo ifconfig bridge0 192.168.227.1 netmask 255.255.255.0
# Edit your Docker startup file
$ echo "DOCKER_OPTS=\"-b=bridge0\"" >> /etc/default/docker
# Start Docker
$ sudo service docker start
# Ensure bridge0 IP is not changed by Docker
$ sudo ifconfig bridge0
bridge0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.227.1 Bcast:192.168.227.255 Mask:255.255.255.0
# Run a container
$ docker run -i -t base /bin/bash
# Container IP in the 192.168.227/24 range
root@261c272cd7d5:/# ifconfig eth0
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.227.5 Bcast:192.168.227.255 Mask:255.255.255.0
# bridge0 IP as the default gateway
root@261c272cd7d5:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.227.1 0.0.0.0 UG 0 0 0 eth0
192.168.227.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
# hits CTRL+P then CTRL+Q to detach
# Display bridge info
$ sudo brctl show
bridge name bridge id STP enabled interfaces
bridge0 8000.fe7c2e0faebd no vethAQI2QT
- その他、コンテナ同士の複雑めのネットワーク設定を行いたい場合は、lxc用のSDNツール jpetazzo/pipework を使うとよろし
Automatically Start Containers - Docker Documentation
- upstart, systemd, supervisor といったプロセスマネージャでdockerコンテナ(の起動etc)を管理可能
-r=false
オプションを指定して、ホストサーバ再起動時のコンテナ自動起動を抑止しておく
- ホストマシンと1つ以上のコンテナの間でディレクトリを共有する data volume
- Union File System なる仕組みを使用
- 対象data volumeはコンテナ間で共有・再利用可能
- DBのバックアップやレプリケーションなんかに使うと良いよ。って話だけど、I/Oのパフォーマンス的にどうなんだろう・・・
- 対象data volumeはコピーオンライトのオーバーヘッドを発生させること無く直接変更可能
- 対象data volumeへの変更は次回のコミットには含まれない
- 対象data volumeはコンテナ間で共有・再利用可能
# コンテナ名=DATA のコンテナで共有ディレクトリを2つ作成 ※該当コンテナはディレクトリのマウントだけ実行してすぐ終了させる
[vagrant@vmdocker1 ~]$ docker run -v /var/volume1 -v /var/volume2 --name DATA a2ca5119cdcf true
# 作成した共有ディレクトリを別コンテナ1から参照
[vagrant@vmdocker1 ~]$ docker run -t -i -rm --volumes-from DATA --name client1 a2ca5119cdcf /bin/bash
bash-4.1# ls -l /var/ | grep volume
drwx------ 2 root root 4096 Mar 5 00:35 volume1
drwx------ 2 root root 4096 Mar 5 00:35 volume2
# さらに別のコンテナ2からコンテナ1の共有ディレクトリを参照
[vagrant@vmdocker1 ~]$ docker run -t -i -rm --volumes-from client1 --name client2 a2ca5119cdcf /bin/bash
bash-4.1# ls -l /var | grep volume
drwx------ 2 root root 4096 Mar 5 00:35 volume1
drwx------ 2 root root 4096 Mar 5 00:35 volume2
[vagrant@vmdocker1 ~]$ sudo mkdir /container
[vagrant@vmdocker1 ~]$ sudo touch /container/from_host
[vagrant@vmdocker1 ~]$ docker run -v /container:/container --name DATA a2ca5119cdcf true
[vagrant@vmdocker1 ~]$ docker run -t -i --rm --volumes-from DATA --name client1 a2ca5119cdcf /bin/bash
bash-4.1# ls -l /container/
total 0
-rw-r--r-- 1 root root 0 Mar 5 00:55 from_host
bash-4.1# touch /container/from_client1
[vagrant@vmdocker1 ~]$ ls -l /container/
total 0
-rw-r--r-- 1 root root 0 Mar 5 05:56 from_client1
-rw-r--r-- 1 root root 0 Mar 5 05:55 from_host
[vagrant@vmdocker1 ~]$ docker run -t -i --rm --volumes-from client1 --name client2 a2ca5119cdcf /bin/bash
bash-4.1# ls -l /container/
total 0
-rw-r--r-- 1 root root 0 Mar 5 00:56 from_client1
-rw-r--r-- 1 root root 0 Mar 5 00:55 from_host
bash-4.1# touch /container/from_client2
[vagrant@vmdocker1 ~]$ ls -l /container/
total 0
-rw-r--r-- 1 root root 0 Mar 5 05:56 from_client1
-rw-r--r-- 1 root root 0 Mar 5 06:09 from_client2
-rw-r--r-- 1 root root 0 Mar 5 05:55 from_host
Link Containers - Docker Documentation
- --name名前付けしたコンテナ同士は "リンク" 機能で 親子関係 を構築することが出来る
- 子コンテナ実行時に
--link 親name:alias
形式でオプション指定 - dockerデーモン起動時の
-icc=false
設定が効いてて、デフォルトではコンテナ間の通信は許可されない。(このおかげでコンテナがセキュアに保たれてる) - リンクを設定するとコンテナ同士で下記にアクセス可能になる
- 環境変数
- 使用しているポート
- 親側でポート8080のみ公開している場合、子側も同様に8080のみがアクセス可能になる。他のポートをコンテナ間通信で使用することは出来ない
- 例えばredis(ポート6379)のサーバとクライアントのコンテナを実行する場合、まず親(サーバ)を--name付きで実行した後、子(クライアント)を -pによるポートバインディングを使わず--link付きで実行 する
- こうすれば redisで必要な通信だけが許可された状態 を作ることが出来る
Link via an Ambassador Container - Docker Documentation
- 複数ホスト間にまたがるコンテナ同士の通信を手助けする 仕組み
- バランサー/proxy のようなもんか
docker link
によるリンク機能は単一のホストマシン内では良い感じに機能するが、例えばコンテナで稼働させるアプリケーションを複数ホストでスケールさせたい場合には不便(というか出来ない?)。ここでAmbassadorの出番- 例えば
(client) -> (redis)
のような接続において、redisのサーバー切り替えがあるとclientの設定書き換え と再起動 が必要になるかもしれない。AmbassadorでproxyしておけばAmboassadorの設定変更(+再起動)で済み、clientは稼働したままにしておける- 接続先であるサーバーの変更/移行が容易になる
# MySQLで複数ホスト/複数コンテナのイメージ
+--------------------------+ +---------------------------+
|Server Host | |Client Host |
| | | |
| +-----------------+ | | +------------------+ |
| | container sh1 | | | | container ch1 | |
| |-----------------| | | |------------------| |
| | MySQL | | | | (want to conn) | |
| +--------^--------+ | | +--------+---------+ |
| | | | | 3306 |
| +--------+--------+ | | +--------v---------+ |
| | container sh2 | | | | container ch2 | |
| |-----------------| | | |------------------| |
| | ambassador <-----------------+ ambassador | |
| +-----------------+ |3306 | +------------------+ |
+--------------------------+ +---------------------------+
Server Host $ docker run -d --name sh1 mysql_image
Server Host $ docker run -d -link sh1:sh1 -p 3306:3306 --name sh2 mysql_ambassador_image
Client Host $ docker run -d --expose 3306 -e MYSQL_PORT_3306_TCP=tcp://[Server Host IP]:3306 --name ch2 mysql_ambassador_image
Client Host $ docker run -t -i -rm -link ch2:ch2 --name ch1 app_image
Deploying Multi-Server Docker Apps with Ambassadors | CenturyLink Labs
Ambassadors are containers who’s sole purpose is to help connect containers across multiple hosts.
-
Fig | Fast, isolated development environments using Docker
- コンテナ間(ホスト間)の通信設定を
fig.yml
という名前のyamlに記述し、fig up
コマンドでコンテナ実行
web: build: . command: python app.py ports: - "5000:5000" volumes: - .:/code links: - redis redis: image: orchardup/redis""
$ fig up
$ fig stop
- コンテナ間(ホスト間)の通信設定を
ver1.4からdockerサポート追加 Docker - Provisioning - Vagrant Documentation
- imageをpullしたい
# centosのimageをpull
config.vm.provision "docker" do |d|
d.pull_images "centos"
end
- vagrant up時にdocker runしたい
# rabbitmqのimageを使用してコンテナを作成したい
config.vm.provision "docker" do |d|
d.run "rabbitmq"
end
# ubuntuのimageを使用してコンテナを作成し、コマンドを実行したい
config.vm.provision "docker" do |d|
d.run "ubuntu",
cmd: "bash -l",
args: "-v '/vagrant:/var/www'" # vagrantの共有ディレクトリ(=ローカルマシンでvagrant upを実行したディレクトリ) をコンテナの/var/wwwにマウント =
end
# 同じイメージを使用して複数コンテナを作成したい
config.vm.provision "docker" do |d|
d.run "db-1", image: "user/mysql"
d.run "db-2", image: "user/mysql"
end
% vagrant up
% vagrant ssh
$ which docker
/usr/bin/docker
$ sudo service docker status
docker (pid 3244) is running...
$ docker -v
Docker version 0.8.0, build cc3a8c8/0.8.0
$ docker info
Containers: 1
Images: 1
Driver: devicemapper
Pool Name: docker-8:1-131916-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 631.6 Mb
Data Space Total: 102400.0 Mb
Metadata Space Used: 0.9 Mb
Metadata Space Total: 2048.0 Mb
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos 6.4 539c0211cd76 11 months ago 300.6 MB
centos latest 539c0211cd76 11 months ago 300.6 MB
- rootで実行
- hostnameはハッシュ
- IPアドレスは172...
$ sudo docker run -t centos /bin/bash -c "hostname && ps aux && ifconfig"
da65688cbf66
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.0 0.1 11296 1304 ? S 00:03 0:00 /bin/bash -c hostname && ps aux && ifconfig
root 7 0.0 0.1 13360 1048 ? R 00:03 0:00 ps aux
eth0 Link encap:Ethernet HWaddr 86:73:E6:8A:84:51
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::8473:e6ff:fe8a:8451/64 Scope:Link
UP BROADCAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:90 (90.0 b) TX bytes:90 (90.0 b)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
-i
オプション
$ sudo docker run -i -t centos /bin/bash
bash-4.1#
ホストVMとdockerコンテナ双方にnetcatがインストールされていること
$ PORT=10080
$ CONTAINER=$(sudo docker run -d -p ${PORT} centos /usr/bin/nc -l -p ${PORT}) # デタッチ(バックグラウンド)実行
$ PUBLIC_PORT=$(docker port ${CONTAINER} ${PORT} | awk -F":" '{print $2}') # publicポート確認
$ echo "Hello World!" | nc 127.0.0.1 ${PUBLIC_PORT}
vagrant halt
で停止後、同内容のVagrantfileで再度vagrant up
した際には、実行したdockerコンテナ/作成したdockerイメージは(当然)消える
Dockerfile Reference - Docker Documentation, Dockerfile Best Practices
-
真っさらではなく必要なミドル/ソフトがインストールされたコンテナを作成したい
- run -i して自らインストールや設定を行い、それらが済んだ状態のコンテナをcommitして使用する
- Dockerfileを使う
-
基本的な使い方
- Dockerfileにコンテナ起動時の処理等を記述、その出力先ディレクトリ上で
docker build
を実行すると結果が新規イメージへcommitされる - 作成されたイメージでコンテナを実行する
- Dockerfileにコンテナ起動時の処理等を記述、その出力先ディレクトリ上で
-
書式
- 基本は
INSTRUCTION(命令) arguments(引数)
の形。命令は大文字で書きましょう、強制ではないが引数との区別をしやすくする為 - Dockerfileは上から順番に評価/処理される
- 最初の命令は
FROM
でないと駄目 - コメントは
# Comment
シャープを使う - 1つのDockerfileのビルドで複数イメージを作成可能
- FROM で始まるコンテナ定義を複数書けば良い
- 基本は
-
命令
FROM image
- ベースとなるイメージファイルを指定MAINTAINER name
- メンテナ名EXPOSE port
- 公開するポートを指定ENV key value
- 環境変数のkey, valueを指定docker run -e KEY=VALUE
でコンテナ実行時にも指定可能。 ENVで定義済のKEYを指定した場合は上書きされる = 実行時引数 的な役割
ADD src dest
- srcかdestへのファイルコピー。srcはホストマシンかリモートURL、destはコンテナRUN command
RUN ["executable", "param1", "param2"]
- 現在指定中(ビルド中)のイメージでコマンドを実行し、結果をコミットする。Dockerfile内 の後続処理でそのイメージを使用する
RUN /usr/bin/wc -l RUN ["/usr/bin/wc","-l"]
-
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
- コンテナ実行時に実行するコマンドを指定する。 RUNと違って結果をコミットしたりはしない- 複数書いても、実際に動くのは最後のCMDのみ
- CMDの目的は、コンテナ実行時のデフォルトの状態(や挙動)を与える こと。コンテナ実行直後にsshdを立ち上げておきたい とか
- 挙動的には
docker commit -run '{"Cmd": command}'
と同じ
-
ENTRYPOINT ["executable", "param1", "param2"]
,ENTRYPOINT command param1 param2
- コンテナ実行時に実行するコマンドを指定する。 CMDと同様結果をコミットしたりはしない- 複数書いても、有効になるのは最後のENTRYPOINTのみ
-
CMDとENTRYPOINTの違いと、使用例
-
CMD, ENTRYPOINTのコマンド指定に引数が存在する場合、docker run 時を引数付きで実行したら。。。
- CMD で指定した引数は 上書きされる
- ENTRYPOINT で指定した引数は 上書きされない ※イメージとしては docker runの引数が "渡される" イメージ
-
CMDの
CMD ["param1","param2"]
形式について、 この形式の引数はENTRYPOINTで指定したコマンドに渡される- この引数群は、docker run時に引数を与えた場合、その内容で上書きされる
- つまり この形式で与えた引数は docker run で何も引数指定しなかった場合のENTRYPOINT用デフォルト引数 となる
- CMDとENTRYPOINTの併用はちょくちょく見かけるテクニック
CMD ["/usr/bin/wc","-l"] # CMD ["executable","param1","param2"] 形式 CMD /usr/bin/wc -l # CMD command param1 param2 形式。
% docker run <image> -d # <= この <image> にENTRYPOINTの指定がある場合、-dオプションはその指定コマンドに渡される # コマンド文字列を直接指定する場合 ENTRYPOINT wc -l - # ENTRYPOINT command param1 param2 形式 # CMDとENTRYPOINTを併用する場合 ENTRYPOINT ["/usr/bin/wc"] # ENTRYPOINT ["executable", "param1", "param2"] 形式 CMD ["-l", "-"] # # CMD ["param1","param2"] 形式の記述はで指定した引数は、"ENTRYPOINT command" で指定したコマンドに渡される
# docker runで # 引数を指定した場合はそれをENTRYPOINTに渡して実行し(CMDで指定した引数の上書き) # 引数を指定しなかった場合はCMDで指定した(デフォルト)引数をENTRYPOINTに渡して実行する ENTRYPOINT ["/usr/bin/rethinkdb"] CMD ["--help"]
-
-
VOLUME ["/data"]
- マウントポイント作成。ホストマシンや他コンテナのボリュームを指定 -
USER user
- イメージ実行ユーザーを指定 -
WORKDIR /path/to/workdir
- RUN, CMD, ENTRYPOINTのコマンド実行時の作業ディレクトリを指定- 1つのDockerfile内に複数指定可能
-
ONBUILD [INSTRUCTION]
- TODO
-
イメージ作成、コンテナ実行の単純例
# Dockerfileを作成する
$ vi Dockerfile
FROM centos
MAINTAINER Niku Dorei
RUN yum -y update
RUN yum -y upgrade
CMD echo "This is a test container OK."
# ビルドする
$ docker build -t test .
Uploading context 2.56 kB
Uploading context
Step 0 : FROM centos
Pulling repository centos
539c0211cd76: Download complete
---> 539c0211cd76
Step 1 : MAINTAINER Niku Dorei
---> Running in dce9c9073ad9
---> c7a5250cf4b7
Step 2 : RUN yum -y update
---> Running in 1825a69c324d
Loaded plugins: fastestmirror
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package bash.x86_64 0:4.1.2-14.el6 will be updated
:
:
Complete!
---> a19599e4ae5b
Step 3 : RUN yum -y upgrade
---> Running in efcc671d114a
Loaded plugins: fastestmirror
Determining fastest mirrors
* base: mirror.fairway.ne.jp
* extras: mirror.fairway.ne.jp
* updates: mirror.fairway.ne.jp
Setting up Upgrade Process
No Packages marked for Update
---> 293ec7165279
Step 4 : CMD echo "This is a test container OK."
---> Running in 0e08f17723b8
---> d93a7cf85eb1
Successfully built d93a7cf85eb1
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test latest d93a7cf85eb1 About a minute ago 602.6 MB
# ビルドしたイメージを使ってコンテナを実行する
$ docker run d93a7cf85eb1
This is a test container OK.
Command Line Interface - Docker Documentation
-H
- デフォルト以外のIP/ポートをLISTENしてdockerデーモンを実行する ※tcp://host:port to bind/connect to or unix://path/to/socket to use- docker groupに属するユーザーにroot同様の権限を与えることになるのでセキュリティ注意
tcp://host:4243
- tcp connection on host:4243unix://path/to/socket
- unix socket located at path/to/socket
-
docker pull NAME
- イメージのダウンロード-t
- タグを指定
-
docker images
- インストール済のイメージ一覧-t
- ツリー形式で表示-a
- 全てのイメージを表示-q
- イメージのIDだけを表示
-
docker info
- dockerの情報表示 -
docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]
- イメージ/コンテナの情報を デフォルトではJSON形式で 表示-f
- フォーマット指定
-
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- コンテナ作成/コマンド実行。 コマンドの戻り値がCONTAINER ID(ハッシュ)- Docker Run Reference - Docker Documentation
-i
- シェルにログイン-d
- デタッチモード(バックグラウンドモード)で実行。デーモンのような挙動イメージ-t
- pseudo-ttyを割り当て ssh経由でリモートホストで実行してるプロセスにSIGINT送りたい時 - As a Futurist...--name=""
- コンテナに名前を付ける-c
- CPU共有-m [<number><optional unit>]
- メモリの上限を指定。unit = b, k, m or g-h [hostname]
- ホスト名設定-p [port]
- ポートバインディング指定 (ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort)--expose [port]
- コンテナ間通信で開放するポートを指定。 ポートバインディングと違ってホストマシンに公開はしない-P
- 使用する全てのポートをホストマシン(のインタフェース)にバインディングする-v [host-path]:[container-path]:[rw|ro]
- ディレクトリをマウントする。ホストマシン=>コンテナ, コンテナ=>コンテナ, 共に可能 (from the host: -v /host:/container, from docker: -v /container)。最後のスイッチはrw=読み書き, ro=読み取り専用--volumes-from=[CONTAINERS|NAMES]
- コンテナを指定して、そのコンテナの共有ディレクトリをマウントする-w
- コンテナでの作業ディレクトリを指定する-e
- 環境変数を設定する--rm
- コンテナ終了時にそのコンテナを削除する- IMAGE はID指定でもいいし
REPOSITORY[:TAG]
形式でも指定可能
-
docker ps [OPTIONS]
- 実行中のコンテナの表示-a
- 過去に実行したコンテナも表示-l
- 直近に実行したコンテナを表示-q
- コンテナIDだけを表示--no-trunc
- 情報を省略せずに表示
-
docker diff CONTAINER_ID
- コンテナ内のファイルシステムのdiffを表示 -
docker kill [OPTIONS] CONTAINER_ID [CONTAINER...]
- 実行中のコンテナ(のプロセス)をkillする -
docker logs CONTAINER_ID
- コンテナで実行した操作履歴を表示する(≒historyコマンド)。 -
docker start CONTAINER [CONTAINER...]
- 停止しているコンテナを起動する-i
- シェルにログイン
-
docker stop [OPTIONS] CONTAINER [CONTAINER...]
- コンテナを停止する-t
- 停止までのwait秒数。デフォルトは10秒
-
docker attach [OPTIONS] CONTAINER
- 起動中のコンテナにアタッチ(再接続)する。 ctrl-p, ctrl-qでデタッチ可能--sig-proxy=true
- non-ttyモード。デフォルトtrueなので、ctrl-cとかで切断したいときは明示的にfalseを指定する
-
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- 実行中のコンテナ(の状態)から新規イメージを作成する。後述するイメージ公開時の作法に則りアカウント名/イメージ名
という名前(TAG)を使うとよさげ-
-a [author]
- author -
-m [log]
- コミットログ -
--run=[command json]
- このイメージを使用してコンテナを起動した際の設定(実行するコマンドとか)を指定する- JSONで指定
- 「Dockerfile の設定をJSONで定義する」とほぼ同義と考えてよさげ
$ docker commit --run='{"Cmd": ["ls","/etc"]}' test test2
-
-
docker search NAME
- 指定した名前(主にディストリビューション名)のイメージを検索する -
docker build [OPTIONS] PATH | URL | -
- ソースコードやパス =Dockerfile を指定して新規コンテナイメージを構築・保存する-t
- リポジトリ名(とタグ)を付加するdocker build [Dockerfileのあるディレクトリ]
docker build -
- Dockerfile形式の入力を受け付ける。<
でリダイレクトも可能
-
docker rm [OPTIONS] CONTAINER [CONTAINER...]
- コンテナを削除-l
- ベースのコンテナではなく指定されたリンクを削除-v
- コンテナに関連付けられているボリュームを削除
-
docker rmi
- イメージを削除 -
docker export CONTAINER
- コンテナをtarにエクスポート -
docker import URL|- [REPOSITORY[:TAG]]
- 空のファイルシステムイメージを作成し、そこにtar等から(コンテナを?)インポート -
docker save IMAGE
- イメージをtarに保存docker save centos > centos.tar
-
docker load
- tar形式のイメージを読み込みdocker load < centos.tar
-
docker push NAME
- イメージの登録 -
docker tag [OPTIONS] IMAGE REPOSITORY[:TAG]
- イメージにタグを登録
% cd ~/bin
% curl https://raw.github.com/boot2docker/boot2docker/master/boot2docker > boot2docker
% chmod +x boot2docker
% curl -o docker https://get.docker.io/builds/Darwin/x86_64/docker-latest
% chmod +x docker
% export DOCKER_HOST=tcp://127.0.0.1:4243
% sudo mv docker /usr/local/bin/
- boot2dockerについてはこちら boot2docker/boot2docker
- Docker上で稼働する軽量ディストリビューション。Tiny Core Linuxベース
$HOME/.boot2docker/profile
の設定でvmのカスタマイズが可能
% boot2docker
Usage xxxxx {init|start|up|save|pause|stop|restart|status|info|delete|ssh|download}
% boot2docker init # virtualboxのvbox作成
[2014-02-20 18:03:31] Creating VM boot2docker-vm
Virtual machine 'boot2docker-vm' is created and registered.
UUID: 8c856d9f-0137-4e2e-917d-xxxxxxxxxxxx
Settings file: '/home/hoge/VirtualBox VMs/boot2docker-vm/boot2docker-vm.vbox'
[2014-02-20 18:03:31] Setting VM settings
[2014-02-20 18:03:31] Setting VM networking
[2014-02-20 18:03:31] boot2docker.iso not found.
[2014-02-20 18:03:32] Latest version is v0.5.4, downloading...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 342 100 342 0 0 508 0 --:--:-- --:--:-- --:--:-- 662
100 27.0M 100 27.0M 0 0 788k 0 0:00:35 0:00:35 --:--:-- 1016k
[2014-02-20 18:04:07] Done
[2014-02-20 18:04:07] Setting VM disks
[2014-02-20 18:04:08] Creating 40000 Meg hard drive...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Disk image created. UUID: 8b28e8fa-5916-442c-9093-xxxxxxxxxxxx
Converting from raw image file="format-flag.txt" to file="format-flag.vmdk"...
Creating dynamic image with size 5242880 bytes (5MB)...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'VMDK'. UUID: 8b28e8fa-5916-442c-9093-xxxxxxxxxxxx
[2014-02-20 18:04:08] Done.
[2014-02-20 18:04:08] You can now type boot2docker up and wait for the VM to start.
% boot2docker up
[2014-02-20 18:22:47] Starting boot2docker-vm...
[2014-02-20 18:23:19] Started.
To connect the docker client to the Docker daemon, please set:
export DOCKER_HOST=tcp://localhost:4243
% boot2docker ssh
user: docker
pass: tcuser
$ docker version
Client version: 0.8.0
Go version (client): go1.2
Git commit (client): cc3a8c8
Server version: 0.8.0
Git commit (server): cc3a8c8
Go version (server): go1.2
Last stable version: 0.8.1, please update docker
- execution driver API
- コンテナの実行環境をカスタマイズすることが出来るAPI
- ドライバ開発のコミュニティ(プロジェクト)も立ち上がっている
- libcontainerドライバを独自に開発し同梱。LXCがなくても稼働するように
- 次期バージョンは0.10
- ホストVM(virtualbox)を再作成してやり直したら解決したが...下記がそこに至るまでの調査ログ
[vagrant@vmdocker1 centos65]$ sudo mkdir /container
[vagrant@vmdocker1 centos65]$ docker run -v /container:/container -t -i centos /bin/bash
bash-4.1# ulimit -a
core file size (blocks, -c) 0
bash-4.1# ulimit -c unlimited
bash-4.1# ulimit -a
core file size (blocks, -c) unlimited
bash-4.1# yum
Segmentation fault (core dumped)
bash-4.1# find / -name "core*"
/core.6
bash-4.1# cp /core.6 /container/
bash-4.1# exit
[vagrant@vmdocker1 ~]$ ls -lrt /container/
total 15184
-rw------- 1 root root 15613952 Mar 24 06:38 core.6
[vagrant@vmdocker1 ~]$ sudo gdb /usr/bin/yum -c /container/core.6
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
"/usr/bin/yum": not in executable format: File format not recognized
Missing separate debuginfo for the main executable file
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/36/c8d16cd49b865a243b27a0c035f45a7ef2f1fa
[New Thread 6]
Core was generated by `/usr/bin/python /usr/bin/yum'.
Program terminated with signal 11, Segmentation fault.
#0 0x00007f61b04c6004 in ?? ()
(gdb)