Docker
Docker は軽量コンテナとしてあらゆるアプリケーションを詰めて運んで実行できるユーティリティです。
目次
- 1 インストール
- 2 設定
- 3 イメージ
- 4 Docker とイメージの削除
- 5 便利なヒント
- 6 トラブルシューティング
- 6.1 systemd 232 でコンテナが起動できない
- 6.2 Btrfs ファイルシステムで Docker イメージを消去
- 6.3 docker0 ブリッジが IP を取得できない / コンテナからインターネットにアクセスできない
- 6.4 デフォルトで使用できるプロセスやスレッドの数が少なすぎる
- 6.5 Error initializing graphdriver: devmapper
- 6.6 Failed to create some/path/to/file: No space left on device
- 6.7 カーネル 4.19.1 で Invalid cross-device link
- 6.8 virtualbox ドライバーを使用したときに Docker-machine が仮想マシンの作成に失敗する
- 6.9 Docker を起動すると KVM のブリッジネットワークが壊れる
- 7 参照
インストール
docker パッケージ (または開発版を使いたい場合は docker-gitAUR パッケージ) をインストールしてください。それから docker.service
を起動して有効化してください。動作検証をするには、以下のコマンドを実行:
# docker info
有効な vpn 接続がある場合 docker サービスの起動に失敗することがあることに注意してください。このような場合、docker サービスの起動前に vpn を切断してみて下さい。その後すぐに vpn に再接続できます。ネットワークの衝突開始を試してみることも可能です。
Next, verify that you can run containers. The following command downloads the latest Arch Linux image and uses it to run a Hello World program within a container:
# docker run -it --rm archlinux bash -c "echo hello world"
docker を通常ユーザーで実行できるようにしたい場合は、ユーザーを docker
グループに追加してください。
設定
ストレージドライバー
docker のストレージドライバー (グラフドライバー) は性能に大きな影響を与えます。ストレージドライバーはコンテナのイメージレイヤーを効率的に保存し、複数のイメージでレイヤーを共有している場合、ディスク容量を使用するレイヤーはひとつだけになります。デフォルトのストレージドライバーである devicemapper
は次善的な性能しか発揮できず、ハードディスクでは問題外です。したがって、プロダクション環境で devicemapper
を使用することは推奨されません。
Arch Linux のカーネルは新しいため、古いドライバーを使用する意味はありません。overlay2
が新しいドライバーです。
現在のストレージドライバーを確認するには # docker info | grep "Storage Driver"
を実行してください。最近の docker 環境では overlay2
がデフォルトで使われます。
ストレージドライバーを自分で選択して設定するには、/etc/docker/daemon.json
を編集してください (ファイルが存在しない場合は作成してください):
/etc/docker/daemon.json
{ "storage-driver": "overlay2" }
その後、docker を再起動してください。
オプションに関する詳細は ユーザーガイド を見てください。daemon.json
の中のオプションの詳細は dockerd のドキュメント を見てください。
Remote API
ポート 4243
で Remote API を手動で開くには:
# /usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
-H tcp://0.0.0.0:4243
で Remote API が開かれます。
-H unix:///var/run/docker.sock
はターミナルからホストマシンにアクセスできるようにします。
Remote API と systemd
docker デーモンで Remote API を起動するには、以下の内容でドロップインスニペットを作成してください:
/etc/systemd/system/docker.service.d/override.conf
[Service] ExecStart= ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
デーモンのソケットの設定
docker デーモンはデフォルトで Unix ソケットを使います。特定のポートを listen させるには、以下の内容のドロップインスニペットを作成してください:
/etc/systemd/system/docker.socket.d/socket.conf
[Socket] ListenStream=0.0.0.0:2375
プロキシ
プロキシの設定は2つに分けられます。ひとつは Docker デーモンのホストの設定で、もうひとつはコンテナからプロキシにアクセスできるようにするための設定です。
プロキシの設定
以下の内容でドロップインスニペットを作成:
/etc/systemd/system/docker.service.d/proxy.conf
[Service] Environment="HTTP_PROXY=192.168.1.1:8080" Environment="HTTPS_PROXY=192.168.1.1:8080"
設定がロードされたことを確認:
# systemctl show docker --property Environment
Environment=HTTP_PROXY=192.168.1.1:8080 HTTPS_PROXY=192.168.1.1:8080
コンテナの設定
docker.service
ファイルの設定はコンテナには適用されません。Dockerfile
で ENV
変数を設定する必要があります:
FROM base/archlinux ENV http_proxy="http://192.168.1.1:3128" ENV https_proxy="https://192.168.1.1:3128"
Docker は Dockerfile で ENV
を使って設定する方法について詳しい情報を提供しています。
DNS の設定
デフォルトでは、docker はホストマシンにある resolv.conf
と同じ中身の resolv.conf
をコンテナに作成します。その際、ローカルアドレス (例: 127.0.0.1
) は消されます。それによって resolv.conf
が空ファイルになった場合、Google の DNS サーバー が記述されます。dnsmasq などのサービスを利用して名前を解決するようにしたい場合、設定が消されないように docker のネットワークインターフェイス用にエントリを /etc/resolv.conf
に追加する必要があります。
systemd-networkd 上に手動で定義したネットワークで Docker を実行
バージョン 220 以上の systemd-networkd を使ってネットワークを手動設定している場合、Docker で起動したコンテナがネットワークにアクセスできない場合があります。バージョン 220 から、ネットワークの転送設定 (net.ipv4.conf.<interface>.forwarding
) はデフォルトで off
です。この設定で IP フォワーディングが使えません。また、コンテナの中で Docker によって有効になる net.ipv4.conf.all.forwarding
の設定と衝突します。
インターネットにアクセスするには、Docker のホスト側で /etc/systemd/network/
にある <interface>.network
ファイルを編集して IPForward=kernel
を追加してください:
/etc/systemd/network/<interface>.network
[Network] ... IPForward=kernel ...
上記の設定でコンテナから IP フォワーディングが使えるようになります。
イメージの置き場所
デフォルトでは、docker のイメージは /var/lib/docker
に保存されます。置き場所は別のパーティションに移動することが可能です。
まず、docker.service
を停止してください。
docker イメージを起動したことがある場合、イメージが完全にアンマウントされていることを確認します。そうしたら、イメージを /var/lib/docker
から好きな場所に移動してください。
その後、docker.service
のドロップインスニペットを作成して、ExecStart
に -g
パラメータを追加してください:
/etc/systemd/system/docker.service.d/docker-storage.conf
[Service] ExecStart= ExecStart=/usr/bin/dockerd -g /path/to/new/location/docker -H fd://
安全ではないレジストリ
もしプライベートレジストリに自己署名証明書を使うことに決めた場合、あなたが信頼すると宣言するまで Docker はその使用を拒否します。docker.service
のドロップインスニペットを追加して、--insecure-registry
パラメータを dockerd
に追加してください:
/etc/systemd/system/docker.service.d/override.conf
[Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry my.registry.name:5000
Docker rootless
docker を rootless モードで実行するには(つまり、rootとしてではなく、通常ユーザとして)、docker-rootless-extras-binAUR パッケージをインストールします。
/etc/subuid
と /etc/subgid
に ユーザ名/グループ名、開始 UID/GID、そして UID/GID 範囲を設定し、再割り当てユーザ/グループに割り当てます:
/etc/subuid
your_username:165536:65536
/etc/subgid
your_username:165536:65536
docker.socket
ユーザユニット を 有効化します。これにより、docker は systemd の socket activation を利用して開始されます。
最後に docker ソケットの環境変数を設定します:
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
イメージ
Arch Linux
次のコマンドは archlinux/archlinux x86_64 イメージを取得します。これはネットワークなどを削減した Arch コア環境です:
# docker pull archlinux/archlinux
詳しくは README.md を参照してください。
リポジトリを clone して自分でイメージを作成することもできます。archlinux/archlinux:base
イメージを作成するには次のようにします:
$ git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git $ make docker-image-base
Debian
以下のコマンドで debian x86_64 イメージが取得されます:
# docker pull debian
手動
debootstrap で Debian イメージを作成:
# mkdir jessie-chroot # debootstrap jessie ./jessie-chroot http://http.debian.net/debian/ # cd jessie-chroot # tar cpf - . | docker import - debian # docker run -t -i --rm debian /bin/bash
Docker とイメージの削除
Docker を完全に削除したい場合は以下の手順に従ってください。
実行中のコンテナをチェック:
# docker ps
削除するホストで実行中の全てのコンテナを確認:
# docker ps -a
実行中のコンテナを停止:
# docker stop <CONTAINER ID>
停止しないコンテナを終了:
# docker kill <CONTAINER ID>
ID で指定して全てのコンテナを削除:
# docker rm <CONTAINER ID>
全ての Docker イメージを確認:
# docker images
ID で指定して全てのイメージを削除:
# docker rmi <IMAGE ID>
全ての Docker データを削除:
# rm -R /var/lib/docker
便利なヒント
実行中のコンテナの IP アドレスを取得するには:
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-name OR id>
172.17.0.37
それぞれの実行中のコンテナについて、/etc/hosts
で使うために名前と対応する IP アドレスを出力:
#!/usr/bin/env sh for ID in $(docker ps -q | awk '{print $1}'); do IP=$(docker inspect --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" "$ID") NAME=$(docker ps | grep "$ID" | awk '{print $NF}') printf "%s %s\n" "$IP" "$NAME" done
トラブルシューティング
systemd 232 でコンテナが起動できない
カーネルパラメータとして systemd.legacy_systemd_cgroup_controller=yes
を追加してください。詳しくは バグレポート を参照。
Btrfs ファイルシステムで Docker イメージを消去
btrfs ファイルシステムで docker イメージを削除すると /var/lib/docker/btrfs/subvolumes/
にサイズが0のイメージが残されてしまいます。これを削除しようとするとパーミッションエラーが表示されます:
# docker rm bab4ff309870 # rm -Rf /var/lib/docker/btrfs/subvolumes/* rm: cannot remove '/var/lib/docker/btrfs/subvolumes/85122f1472a76b7519ed0095637d8501f1d456787be1a87f2e9e02792c4200ab': Operation not permitted
このエラーは btrfs が docker イメージのためにサブボリュームを作成したのが原因です。したがって削除するときの正しいコマンドは次のようになります:
# btrfs subvolume delete /var/lib/docker/btrfs/subvolumes/85122f1472a76b7519ed0095637d8501f1d456787be1a87f2e9e02792c4200ab
docker0 ブリッジが IP を取得できない / コンテナからインターネットにアクセスできない
Docker は自分で IP フォワーディングを有効にしますが、デフォルトでは systemd-networkd によって sysctl の設定が上書きされてしまいます。ネットワークプロファイルに IPForward=yes
を設定してください。詳しくはインターネット共有#パケット転送の有効化を参照してください。
デフォルトで使用できるプロセスやスレッドの数が少なすぎる
以下のようなエラーメッセージが表示される場合:
# e.g. Java java.lang.OutOfMemoryError: unable to create new native thread # e.g. C, bash, ... fork failed: Resource temporarily unavailable
systemd によって許可されるプロセスの数を調整する必要があります。デフォルトは 500 ですが (system.conf
を参照)、複数の docker コンテナを動作させるには少なすぎます。以下のスニペットで docker.service
を編集してください:
# systemctl edit docker.service
[Service] TasksMax=infinity
Error initializing graphdriver: devmapper
systemctl で docker の起動に失敗して以下のエラーが表示される場合:
Error starting daemon: error initializing graphdriver: devmapper: Device docker-8:2-915035-pool is not a thin pool
エラーを解消するには、サービスを停止して、/var/lib/docker/
を (必要に応じて) バックアップし、/var/lib/docker/
の中身を消してから、サービスを起動してみてください。詳しくは GitHub issue を参照。
Failed to create some/path/to/file: No space left on device
以下のようにエラーメッセージが表示される場合:
ERROR: Failed to create some/path/to/file: No space left on device
Docker イメージの作成・実行時、ディスク容量が十分に存在するにもかかわらず、上記のメッセージが表示されるときは以下を確認してください:
- Tmpfs が無効になっている、あるいは十分なメモリが割り当てられている。Docker が
/tmp
にファイルを書き出そうとしていて、ディスク容量ではなくメモリ使用量が制限となっている可能性があります。 - XFS を使っている場合、
/etc/fstab
の (/tmp
や/var/lib/docker
がある) エントリからnoquota
マウントオプションを削除すると良いかもしれません。詳しくはディスククォータを参照してください。Docker ストレージドライバーのoverlay2
を使用するときは特に注意してください。 - XFS クォータのマウントオプション (
uquota
,gquota
,prjquota
など) がファイルシステムの再マウント時に失敗している。ルートファイルシステムでクォータを使うには、マウントオプションをrootflags=
カーネルパラメータで initramfs に渡す必要があります。その場合、root (/
) ファイルシステムのマウントオプションとして/etc/fstab
に指定してはいけません。
カーネル 4.19.1 で Invalid cross-device link
docker 内で 'dpkg' のようなコマンドの実行に失敗することがあります。例:
dpkg: error: error creating new backup file '/var/lib/dpkg/status-old': Invalid cross-device link
その場合 overlay.metacopy=N
カーネルパラメータを追加するか、この問題 が解決するまで 4.18.x にダウングレードしてください。詳しくは Arch フォーラム を参照。
virtualbox ドライバーを使用したときに Docker-machine が仮想マシンの作成に失敗する
以下のように virtualbox ドライバーで docker-machine が仮想マシンの作成に失敗する場合:
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
vboxreload
で CLI から virtualbox をリロードしてください。
Docker を起動すると KVM のブリッジネットワークが壊れる
既知のバグ が原因です。以下の方法で回避できます:
/etc/docker/daemon.json
{ "iptables": false }
参照
- 公式ウェブサイト
- Arch Linux on docs.docker.com
- Are Docker containers really secure? — opensource.com