Dockerの使い方を記載します。
Table of Contents
1 インストール方法
2 イメージとコンテナ
イメージとはDockefileという定義ファイルから生成される不変のルートファイルシステムです。イメージは実行時に使用されません。
コンテナとはイメージから作成される可変のルートファイルシステムです。コンテナは実行時に使用されます。
例えば以下のコマンドを実行すると以下の通りになります。
$ docker run hello-world <snip> Hello from Docker! <snip>
- hello-worldというイメージをリモートサーバからダウンロードします。
- ランダムな名前のコンテナが生成されます。
- DockerfileのCMDで指定されたhelloというバイナリが"Hello from Docker!"の文字列を出力します。
helloというバイナリをホストマシンで実行すると同様の出力を得ます。ただし、コンテナ内で実行していないので環境は全く異なります。
$ sudo /var/lib/docker/aufs/diff/<hash>/hello <snip> Hello from Docker! <snip>
3 イメージをダウンロードしてコンテナ上でコマンドを実行する
docker runで使う方法とdocker pull, docker create, docker startを使う方法があります。
3.1 docker run
以下のコマンドを実行すると、<image>という名前のイメージがダウンロードされ、<container>という名前のコンテナ上で<cmd>で指定したコマンドが実行されます。
$ docker run -it --name <container> <image> <cmd>
- –name <container>を省略するとランダムな名前が生成されます。
- <cmd>を省略するとDockerfileのCMDで指定したコマンドが設定されます。
- すでに存在する<container>を指定した場合はエラーとなります。
- <container>と<image>は名前でなくIDで指定することもできます。
上記のdocker runは以下のコマンド郡と同等です。なお、docker pullを省略した場合、ローカルに<image>がない場合はdocker create時にリモートサーバからダウンロードします。
$ docker pull <image> $ docker create -it --name <container> <image> <cmd> $ docker start -i <container>
3.2 docker pull
docker pullはイメージをローカルにダウンロードするコマンドです。イメージはRegistryと呼ばれるリモートサーバからダウンロードされます。デフォルトのRegistryはDocker Hubです。
docker createはローカルからイメージを探すので、あらかじめ使う予定のあるイメージはダウンロードしておくと良いでしょう。
また、ローカルでRegistryを作成する場合、デフォルトのRegistryからイメージをダウンロードしておき、ダウンロードしたイメージをローカルのRegistryへdocker pushすることができます。それ以降のそのイメージはローカルのRegistryからダウンロードすることができます。
3.3 docker create -it
docker createはイメージからコンテナを作成するコマンドです。ローカルに存在しないイメージはRegistryからダウンロードされます。
-itオプションの両方がない場合はbashは即座に終了する為、コンテナも停止します。
$ docker create --name bash-without-it ubuntu:16.04 $ docker start -i bash-without-it $ # This is host machine's shell prompt. $ docker attach bash-without-it You cannot attach to a stopped container, start it first
-iオプションがない場合は標準入力を受け付けません。
$ docker create -t --name bash-without-i ubuntu:16.04 $ docker start -i bash-without-i root@35859c489ea1:/# ls # Type ls[RET] but no response
-tオプションがない場合はpseudo-ttyが作成されません。bashの場合は環境変数TERMが空になり、プロンプト文字列が表示されません。
$ docker create -i --name bash-without-t ubuntu:16.04 $ docker start -i bash-without-t uname # Type uname[RET] Linux ls # Type ls[RET] bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
-itオプションの両方がある場合は通常の動作となります。
$ docker create -it --name bash ubuntu:16.04 $ docker start -i bash root@f5fbe8daa835:/# uname Linux root@f5fbe8daa835:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
3.4 docker start -i
docker startはコンテナを動かすコマンドです。
-iオプションをつけることで、コンテナを開始すると同時にコンテナへアタッチします。標準入力へも接続されます。
$ docker start -i <container>
上記は以下とほぼ同等ですが、以下の場合はstartとattachの間にホストマシンへ一度戻ります。
$ docker start <container> $ docker atttach <container>
-iオプションに似た-aオプションもあります。-aオプションをつけることで、コンテナを開始すると同時にコンテナへアタッチします。ただし、標準入力へは接続されません。
$ docker start -i <container>
上記は以下とほぼ同等ですが、先ほどと同様に、以下の場合はstartとattachの間にホストマシンへ一度戻ります。
$ docker start <container> $ docker atttach --no-stdin <container>
4 独自のイメージを作成する
ここではubuntu:16.04をベースとしてemacsをインストールしたイメージを作成します。
4.1 コンテナから独自のイメージを作成する
最初にイメージからコンテナを作成します。
$ docker run -it --name ubuntu-1604-emacs ubuntu:16.04
ubuntu:16.04のイメージはemacsがインストールされていません。
root@cf4e53146385:/# emacs --version bash: emacs: command not found
emacsをインストールした後、bashを終了させ、コンテナを停止します。
root@cf4e53146385:/# apt update -y && apt install -y emacs && exit
docker commitでコンテナからイメージを作成します。
$ docker commit ubuntu-1604-emacs ubuntu-1604-emacs-image
イメージが作成されました。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu-1604-emacs-image latest 41716956f654 About a minute ago 546 MB ubuntu 16.04 f49eec89601e 3 weeks ago 129 MB
作成したイメージからコンテナを作成します。
$ docker run -it ubuntu-1604-emacs-image
作成したイメージはemacsがインストールされています。
root@b91c82c0c976:/# emacs --version GNU Emacs 24.5.1 Copyright (C) 2015 Free Software Foundation, Inc. GNU Emacs comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of Emacs under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING.
4.2 Dockerfileから独自のイメージを作成する
以下のDockerfileを作成します。
$ cat Dockerfile FROM ubuntu:16.04 RUN \ apt update -y && \ apt install -y emacs CMD ["bash"]
docker buildでDockerfileからイメージを作成します。Dockerfileで作成した場合も一時的なコンテナが作成されます。
$ docker build -t ubuntu-1604-emacs-dockerfile . Sending build context to Docker daemon 2.048 kB Step 1/3 : FROM ubuntu:16.04 ---> f49eec89601e Step 2/3 : RUN apt update -y && apt install -y emacs ---> Running in d7a592031026 WARNING: apt does not have a stable CLI interface. Use with caution in scripts. Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB] Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease [102 kB] <snip> Step 3/3 : CMD bash ---> Running in 77adc54aa247 ---> bcf7de949838 Removing intermediate container 77adc54aa247 Successfully built bcf7de949838
イメージが作成されました。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu-1604-emacs-dockerfile latest bcf7de949838 36 seconds ago 546 MB ubuntu-1604-emacs-image latest 41716956f654 34 minutes ago 546 MB ubuntu 16.04 f49eec89601e 3 weeks ago 129 MB
作成したイメージからコンテナを作成します。
$ docker run -it ubuntu-1604-emacs-dockerfile
作成したイメージはemacsがインストールされています。
root@6ac693d1b24a:/# emacs --version GNU Emacs 24.5.1 Copyright (C) 2015 Free Software Foundation, Inc. GNU Emacs comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of Emacs under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING.
5 外部ネットワークからアクセスする
ここではコンテナ内で動かしたJenkinsへ外部ネットワークからアクセスします。Jenkinsが使用するポートはTCP8080です。
dockerのデフォルトで用意されているネットワークは以下の通りです。なおdocker runやdocker createで–networkオプションを省略した場合はbridgeが指定されます。
bridge | docker0というbridgeを作成して、ホストマシンのNICと |
iptablesによるIPマスカレードで接続します(L3レイヤで接続)。 | |
外部からアクセスするにはポートフォワーディングが必要です。 | |
host | 見かけ上ホストマシンのNICをそのまま使います。 |
外部からはアクセスできません。 | |
none | NICを作成しません。 |
本記事のネットワークインターフェースは以下の通りです。
eth0 | ホストマシンのNICです。IPアドレスは192.168.11.102/24です。 |
docker0 | docker起動時に作成されるbridgeです。 |
bridgeネットワークが172.17.0.1/16のIPアドレスを割り当てます。 |
5.1 bridgeネットワークでポートフォワーディングを使う
ホストマシンのTCP80をコンテナのTCP8080へマッピングします。–networkオプションを省略しているのでbridgeネットワークが使われます。
$ docker run -d -p 80:8080 jenkins
ホストマシンのTCP80にHTTP接続するとJenkinsの画面が表示されます。
http://192.168.11.102
5.2 独自ネットワークで外部ネットワークと同じネットワークアドレスを用いる
docker0のbridgeとは別に、L2レイヤで接続するbridgeを作成します。
作成したネットワークインターフェースは以下の通りです。
br0 | dockerとは無関係で作成したbridgeです。 |
eth0の代わりに192.168.11.102/24が割り当てられています。 |
docker network createでbr0を持つネットワークを作成します。
$ docker network create \ --driver=bridge \ --subnet=192.168.11.102/24 \ --gateway=192.168.11.102 \ -o "com.docker.network.bridge.enable_icc=true" \ -o "com.docker.network.bridge.enable_ip_masquerade=false" \ -o "com.docker.network.bridge.host_binding_ipv4=0.0.0.0" \ -o "com.docker.network.bridge.name=br0" \ -o "com.docker.network.driver.mtu=1500" \ br0_network
ネットワークをbr0_network、IPアドレスを192.168.11.200、DNSを192.168.11.1とするコンテナを作成します。ここで指定したDNSはdockerに組み込まれたDNSサーバ(127.0.0.11)が参照します。見かけ上は/etc/resolv.confに反映されない点に注意してください。
$ docker run -d --network=br0_network --ip=192.168.11.200 \ --dns=192.168.11.1 jenkins
コンテナのTCP8080にHTTP接続するとJenkinsの画面が表示されます。
http://192.168.11.200:8080
5.3 独自ネットワークの注意点
外部のDHCPサーバからIPアドレスをもらうIPAMドライバないようで、Dockerとは別に、コンテナのMACアドレスに対するDHCPの応答処理を追加する必要があります(あるいはDHCPサーバのdhcpd.confに直接書く)。
IPマスカレイドをfalseにしてもL3レイヤの設定が実行されます。この影響なのか、bridgeネットワークが動作しなくなります。docker buildでイメージを作成する際、コンテナにIPアドレスをわざわざ割り振りらないようにするには–network=hostを使う必要があります。
また、組み込まれたDNSサーバは複数の–dnsオプションを指定した場合、ひとつ目のDNSサーバが問い合わせをREFUSEした場合は、ふたつ目のDNSサーバに問い合わせを実行しないようです(DROPやREJECTなら問題ありません)。これを回避するにはひとつ目のDNSサーバにて、名前解決できない場合はREFUSEせずに再帰問い合わせを実行するしかないです。Windows, Linux, MacOSではふたつ目のDNSサーバに問い合わせするので、この動作が正しいのかどうかはわかりません。
6 その他のコマンド
docker <arg>はdocker image <arg>やdocker container <arg>のエイリアスであったりします。ここではdocker <arg>の方のみを扱います。
docker images | イメージの一覧を表示する |
docker rmi <image> | イメージを削除する |
docker ps [-a] | コンテナの一覧を表示する |
(-aをつけた場合は停止したコンテナも) | |
docker stop <container> | コンテナを停止する |
docker exec <container> <cmd> | 起動中のコンテナで別のコマンドを実行する |
docker ps -qを実行するとIDのみが表示されます。起動中のコンテナをすべて止めるには以下のコマンドを実行します。
$ docker stop $(docker ps -q)