「Docker」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(Pkg/AUR テンプレートの更新)
(→‎Rootless Docker デーモン: 誤字脱字修正)
 
(3人の利用者による、間の56版が非表示)
3行目: 3行目:
 
[[en:Docker]]
 
[[en:Docker]]
 
[[ru:Docker]]
 
[[ru:Docker]]
[[zh-hant:Docker]]
 
 
[[zh-hans:Docker]]
 
[[zh-hans:Docker]]
 
{{Related articles start}}
 
{{Related articles start}}
9行目: 8行目:
 
{{Related|Linux Containers}}
 
{{Related|Linux Containers}}
 
{{Related|Vagrant}}
 
{{Related|Vagrant}}
  +
{{Related|Podman}}
 
{{Related articles end}}
 
{{Related articles end}}
  +
[[Wikipedia:ja:Docker|Docker]] は軽量コンテナとしてあらゆるアプリケーションを詰めて運んで実行できるユーティリティです。
 
[https://www.docker.com Docker] は軽量コンテナとしてあらゆるアプリケーションを詰めて運んで実行できるユーティリティです。
 
   
 
== インストール ==
 
== インストール ==
   
{{Pkg|docker}} パッケージ (または開発版を使いたい場合は {{Aur|docker-git}} パッケージ) を[[インストール]]してください。それから {{ic|docker.service}} を[[起動]]して有効化してください。動作検証をするには、以下のコマンド実行:
+
Docker イメージを pull し Docker コンテナを実行するには、Docker Engine が必要です。Docker Engine には、コンテナを管理するデーモンや {{ic|docker}} CLI フロントエンドが含まれています。{{Pkg|docker}} パッケージを[[インストール]]してください。開発版は {{Aur|docker-git}} パッケージを[[インストール]]してください。次に、{{ic|docker.service}} を[[起動/有効化]]して動作すること確認してください:
   
 
# docker info
 
# docker info
   
有効な vpn 接続がある場合 docker サービスの起動に失敗することがあることに注意してください。このような場合、docker サービスの起動前に vpn を切断してみてさい。その後すぐに vpn に再接続できます。[https://stackoverflow.com/questions/45692255/how-make-openvpn-work-with-docker ネットワークの衝突開始を試してみることも可能です]。
+
アクティブな vpn 接続がある場合docker サービスの起動に失敗することがあることに注意してください。VPN と Docker のブリッジネットワークやオーバーレイネットワークの間で IP が競合するからです。このような場合、docker サービスの起動前に vpn を切断してみてください。その後すぐに vpn に再接続できます。ネットワークの衝突解除を試してみることも可能です (解決策については、 [https://stackoverflow.com/questions/45692255/how-make-openvpn-work-with-docker] や [https://github.com/docker/compose/issues/4336#issuecomment-457326123] をご覧ください)
   
  +
次に、コンテナが動作することを検証します。次のコマンドは、最新の [[#Arch Linux|Arch Linux イメージ]]をダウンロードし、そのイメージを使ってコンテナの中で Hello World プログラムを実行します:
docker を通常ユーザーで実行できるようにしたい場合は、ユーザーを {{ic|docker}} [[グループ]]に追加してください。
 
   
  +
# docker run -it --rm archlinux bash -c "echo hello world"
{{Warning|ユーザーを {{ic|docker}} グループに追加することは root にするのと同義です。詳しくは [https://github.com/docker/docker/issues/9976 こちら] や [https://docs.docker.com/engine/security/security/ こちら] を参照。}}
 
   
  +
{{ic|docker}} CLI コマンドを非 root ユーザとして実行できるようにしたい場合は、ユーザーを {{ic|docker}} [[グループ]]に追加して、ログインし直し、{{ic|docker.service}} を再起動してください。
=== Rootless モード ===
 
Docker の rootless モードを使うと root 権限より低い権限にて Docker を動かせます。
 
   
  +
{{Warning|ユーザーを {{ic|docker}} グループに追加することは、そのユーザーを root にするのと等価です。なぜなら、そのグループに属するユーザーは {{ic|docker run --privileged}} コマンドを実行して、コンテナを root 権限で開始することができるからです。詳しくは [https://github.com/docker/docker/issues/9976 こちら] や [https://docs.docker.com/engine/security/security/ こちら] ([https://docs.docker.jp/engine/security/security.html 日本語訳ページ]) を参照してください。}}
{{Aur|docker-rootless}}{{Broken package link|パッケージが存在しません}} を追加でインストールし、AUR パッケージ作者によるコメント [https://aur.archlinux.org/packages/docker-rootless/#pinned-724406] に記された設定を行ってください。
 
   
  +
=== Docker Compose ===
一部の機能が動作しないなどの制限もあります。詳細は Docker 公式ドキュメント
 
  +
[https://docs.docker.com/engine/security/rootless/ Run the Docker daemon as a non-root user (Rootless mode)] を参照してください。
 
  +
[https://docs.docker.com/compose/ Docker Compose] ([https://docs.docker.jp/compose/ 日本語訳ページ]) は Docker Engine の代替 CLI フロントエンドです。(例として) {{ic|docker run}} のオプションを使うスクリプトではなく、{{ic|docker-compose.yml}} [[Wikipedia:ja:YAML|YAML]] ファイルを使ってコンテナのプロパティを指定します。これは、しばしば使用されたり複雑な設定を持っていたりするサービスを何度も設定する際に便利です。Docker Compose を使うには、{{Pkg|docker-compose}} を[[インストール]]してください。
  +
  +
=== Docker Desktop ===
  +
  +
[https://www.docker.com/products/docker-desktop/ Docker Desktop] は、Linux 仮想マシン内で Docker Engine を実行するプロプライエタリなデスクトップアプリケーションです。Kubernetes クラスタや脆弱性スキャナなどの追加の機能が含まれています。このアプリケーションは、macOS や Windows を使って Docker コンテナを開発するソフトウェア開発チームにとって便利です。このアプリケーションの Linux 移植は比較的新しく、Docker の CLI フロントエンドを補完します [https://www.docker.com/blog/the-magic-of-docker-desktop-is-now-available-on-linux/]。Arch 向けの実験的なパッケージは Docker によって直接提供されています; 詳細は [https://docs.docker.com/desktop/linux/install/archlinux/ マニュアル] ([https://docs.docker.jp/desktop/install/archlinux.html 日本語訳ページ]) を見てください。残念ながら、そのパッケージには {{Pkg|docker-compose}} パッケージと衝突するファイルが含まれているため、{{Pkg|docker-compose}} がインストールされている場合はまずそれを削除する必要があります。
  +
  +
また、[https://www.docker.com/products/docker-desktop/ Docker Desktop] を実行するには、[https://docs.docker.com/desktop/install/linux-install/ Linux システム要件] ([https://docs.docker.jp/desktop/install/linux-install.html 日本語訳ページ]) を満たしている必要があります (要件には [[KVM]] による仮想化サポートが含まれています)。Gnome でのトレイアイコンを有効化するには、{{Pkg|gnome-shell-extension-appindicator}} が必要です。
  +
  +
最後に、ファイル共有サポートは、ユーザとグループの id を {{ic|/etc/subuid}} と {{ic|/etc/subgid}} を通してマッピングする必要があります。詳細は [https://docs.docker.com/desktop/faqs/linuxfaqs/#how-do-i-enable-file-sharing Docker Desktop For Linux のファイル共有に関する指示書] ([https://docs.docker.jp/desktop/install/linux-install.html#linux-install-file-sharing 日本語訳ページ]) を見てください。
  +
  +
== 使用法 ==
  +
  +
Docker は複数のパーツから成ります:
  +
  +
* Docker デーモン (Docker Engine とも呼ばれています)。{{ic|docker.service}} として実行されるプロセスです。Docker API を提供し、Docker コンテナを管理します。
  +
* {{ic|docker}} CLI コマンド。ユーザがコマンドラインを通して Docker API と対話し、Docker デーモンを管理できるようにします。
  +
* Docker コンテナ。Docker API を通して要求された通りに Docker デーモンが起動・管理する、名前空間で隔離されたプロセスです。
  +
  +
通常、ユーザは {{ic|docker}} CLI コマンドを実行することで Docker を使用します。コマンドは Docker デーモンにアクションの実行を要求し、Docker コンテナを管理します。クライアント ({{ic|docker}})、サーバ ({{ic|docker.service}})、コンテナ間の関係を理解することは、Docker を正しく管理するために重要です。
  +
  +
Docker デーモンが停止/再起動した場合、現在実行中の Docker コンテナもすべて停止/再起動されることに注意してください。
  +
  +
Docker API にリクエストを送信して、{{ic|docker}} CLI コマンドを使わずに Docker デーモンを制御することも可能です。詳細は [https://docs.docker.com/engine/api/ Docker API 開発ドキュメント]を見てください。
  +
  +
使用法に関するドキュメントは [https://docs.docker.com/get-started/ the Docker Getting Started guide] ([https://docs.docker.jp/get-started/index.html 日本語訳ページ]) を見てください。
   
 
== 設定 ==
 
== 設定 ==
  +
  +
設定ファイル {{ic|/etc/docker/daemon.json}} を使うか、{{ic|docker.service}} systemd ユニットにコマンドラインフラグを追加することで、Docker デーモンを設定することができます。[https://docs.docker.com/config/daemon/#configure-the-docker-daemon Docker 公式ドキュメント] ([https://docs.docker.jp/config/daemon/daemon.html#configure-the-docker-daemon 日本語訳ページ]) によると、設定ファイルによる方法が推奨されています。コマンドラインフラグの方を使いたい場合は、[[ドロップインファイル|systemd のドロップインファイル]] を使って、{{ic|docker.service}} の {{ic|ExecStart}} ディレクティブを上書きしてください。
  +
  +
{{ic|daemon.json}} のオプションに関する詳細は、[https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file dockerd のドキュメント] ([https://docs.docker.jp/engine/reference/commandline/dockerd.html#daemon-configuration-file 日本語訳ページ]) を見てください。
   
 
=== ストレージドライバー ===
 
=== ストレージドライバー ===
   
docker ストレージドライバー (グラフドライバー) は性能に大きな影響を与えます。ストージドライバーはコンテナのイメージレイヤーを効率的保存、複数のイメージでレイヤー共有ている場合、ディスク容量を使用するレイヤーはひとつだけになります。デフォルトのストレージドライバーである {{ic|devicemapper}} は次善的性能しか発揮できず、ハードディスクでは問題外で。したってプロダクション環境で {{ic|devicemapper}} を使用すること推奨されません。
+
[https://docs.docker.com/storage/storagedriver/select-storage-driver/ ストレージドライバー] ([https://docs.docker.jp/storage/storagedriver/select-storage-driver.html 日本語訳ペジ]) は、Docker ホスト上でイメージコンテナをどよう格納管理するか制御します。デフォルトの {{ic|overlay2}} ドライバはパフォマンスが良く、最近の Linux カーネルとファイルシステムすべて良い選択肢です。古い Linux カーネルとの互換性のために {{ic|devicemapper}} や {{ic|aufs}} どのレガシライバがありますが、Arch Linux の {{ic|overlay2}} ではなくこれらを使う利点ありません。
   
  +
[[btrfs]] や [[ZFS]] のユーザは {{ic|btrfs}} や {{ic|zfs}} のドライバを使用できます。それぞれのドライバは、これらのファイルシステムのユニークな機能を活用します。詳細とステップ・バイ・ステップの説明は [https://docs.docker.com/storage/storagedriver/btrfs-driver/ btrfs ドライバ] ([https://docs.docker.jp/storage/storagedriver/btrfs-driver.html 日本語訳ページ]) と [https://docs.docker.com/storage/storagedriver/zfs-driver/ zfs ドライバ] ([https://docs.docker.jp/storage/storagedriver/zfs-driver.html 日本語訳ページ]) のドキュメントを見てください。
Arch Linux のカーネルは新しいため、古いドライバーを使用する意味はありません。{{ic|overlay2}} が新しいドライバーです。
 
   
  +
=== デーモンのソケット ===
現在のストレージドライバーを確認するには {{ic|# docker info {{!}} grep "Storage Driver"}} を実行してください。最近の docker 環境では {{ic|overlay2}} がデフォルトで使われます。
 
  +
  +
デフォルトで、Docker デーモンは [[Wikipedia:ja:UNIXドメインソケット|Unix ソケット]] {{ic|/var/run/docker.sock}} を用いて Docker API を提供します。ほとんどの場合、この方法は適切です。
  +
  +
さらに TCP ソケットをリッスンするようにデーモンを設定できます。これにより、他のコンピュータからリモートで Docker API にアクセスできるようになります [https://docs.docker.com/engine/install/linux-postinstall/#allow-access-to-the-remote-api-through-a-firewall]。そうすることで、ホストマシン上の {{ic|docker}} コマンドから Linux 仮想マシン (Windows や macOS システム上の Arch 仮想マシン) 上の Docker デーモンにアクセスできるようになり、便利です。
  +
  +
{{Warning|デフォルトで Docker API は暗号化も認証もされません。TLS 暗号化や認証が有効化されていなかったり、認証 HTTP リバースプロキシや適切な[https://docs.docker.com/engine/security/https/ Docker の追加設定] ([https://docs.docker.jp/engine/security/https.html 日本語訳ページ]) がなされていなかったりした場合、Docker デーモンへのリモート TCP アクセスは安全でない root アクセスと等価です。一般に、Docker API の TCP ソケットを有効化することは、セキュリティ上、高リスクであるとみなすべきです。}}
  +
  +
デフォルトの {{ic|docker.service}} ファイルは {{ic|-H}} フラグをデフォルトでセットします。そして、フラグと {{ic|/etc/docker/daemon.json}} ファイルの両方にオプションが存在する場合、Docker は起動しません。なので、ソケットの設定を変更する最も単純な方法は、[[ドロップインファイル]]を使うことです。以下は、ポート 2376 上に TCP ソケットを追加します:
  +
  +
{{hc|/etc/systemd/system/docker.service.d/docker.conf|2=
  +
[Service]
  +
ExecStart=
  +
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376
  +
}}
  +
  +
systemd デーモンを[[リロード]]し、{{ic|docker.service}} を[[再起動]]して変更を適用してください。
  +
  +
=== HTTP プロキシ ===
  +
  +
HTTP プロキシを使うために設定すべきなのは、Docker デーモンと Docker コンテナです。
  +
  +
==== Docker デーモンのプロキシ設定 ====
  +
  +
[https://docs.docker.com/config/daemon/systemd/#httphttps-proxy HTTP プロキシを設定するための systemd ドロップインユニットの設定に関する Docker ドキュメント] ([https://docs.docker.jp/config/daemon/systemd.html#http-https 日本語訳ページ]) を見てください。
  +
  +
==== Docker コンテナのプロキシ設定 ====
  +
  +
{{ic|docker}} CLI を使用して作成されたすべてのコンテナに対してプロキシを自動で設定する方法は [https://docs.docker.com/network/proxy/#configure-the-docker-client プロキシ設定に関する Docker ドキュメント] ([https://docs.docker.jp/network/proxy.html#id2 日本語訳ページ]) を見てください。
  +
  +
=== DNS の設定 ===
  +
  +
Docker コンテナ内での DNS の動作に関するドキュメントや、DNS の設定のカスタマイズに関する情報は [https://docs.docker.com/config/containers/container-networking/#dns-services Docker の DNS に関するドキュメント] ([https://docs.docker.jp/config/containers/container-networking.html#dns 日本語訳ページ]) を見てください。ほとんどの場合、ホストで設定されているリゾルバは、コンテナ内でも設定されています。
  +
  +
{{ic|127.0.0.0/8}} でホストされている DNS リゾルバのほとんどは、コンテナとホストのネットワーク名前空間の衝突により、[https://github.com/moby/moby/issues/6388#issuecomment-76124221 サポートされていません]。そのようなリゾルバは、[https://github.com/moby/libnetwork/blob/master/resolvconf/resolvconf.go コンテナの /etc/resolv.conf から削除されます]。このせいで {{ic|/etc/resolv.conf}} が空になる場合は、Google DNS が代わりに使用されます。
  +
  +
さらに、{{ic|127.0.0.53}} が、設定されている唯一のネームサーバである場合は、特殊なケースとして処理されます。この場合、Docker はリゾルバが [[systemd-resolved]] であると仮定し、{{ic|/run/systemd/resolve/resolv.conf}} にある 上流の DNS リゾルバを使用します。
  +
  +
If you are using a service such as [[dnsmasq]] to provide a local resolver, consider adding a virtual interface with a link local IP address in the {{ic|169.254.0.0/16}} block for dnsmasq to bind to instead of {{ic|127.0.0.1}} to avoid the network namespace conflict.
  +
  +
=== イメージの置き場所 ===
  +
  +
デフォルトでは、docker のイメージは {{ic|/var/lib/docker}} に保存されます。置き場所は別のパーティションに移動することが可能です (例えば、イメージ用の専用のパーティションかディスクを使いたい場合)。ここでは、例として {{ic|/mnt/docker}} にイメージを移動することにします。
  +
  +
まず、{{ic|docker.service}} を[[停止]]してください。すると、現在実行中のコンテナがすべて停止され、実行中のイメージはすべてアンマウントされます。これで、イメージを {{ic|/var/lib/docker}} から目的の場所へ移動できるようになります (例: {{ic|cp -r /var/lib/docker /mnt/docker}})。
  +
  +
{{ic|/etc/docker/daemon.json}} 内の {{ic|data-root}} を設定してください:
   
ストレージドライバーを自分で選択して設定するには、{{ic|/etc/docker/daemon.json}} を編集してください (ファイルが存在しない場合は作成してください):
 
 
{{hc|/etc/docker/daemon.json|2=
 
{{hc|/etc/docker/daemon.json|2=
 
{
 
{
"storage-driver": "overlay2"
+
"data-root": "/mnt/docker"
 
}
 
}
  +
}}
   
  +
変更を適用するために、{{ic|docker.service}} を再起動してください。
  +
  +
=== 安全ではないレジストリ ===
  +
  +
プライベートレジストリに自己署名証明書を使うことにした場合、あなたが信頼すると宣言するまで Docker はその使用を拒否します。例えば、{{ic|myregistry.example.com:8443}} でホストされているレジストリのイメージを許可するには、{{ic|/etc/docker/daemon.json}} ファイル内の {{ic|insecure-registries}} を設定してください:
  +
  +
{{hc|/etc/docker/daemon.json|2=
  +
{
  +
"insecure-registries": [
  +
"my.registry.example.com:8443"
  +
]
  +
}
 
}}
 
}}
   
その後、docker を[[再起動]]してください。
+
変更を適用するために {{ic|docker.service}} を再起動してください。
   
  +
=== IPv6 ===
オプションに関する詳細は [https://docs.docker.com/engine/userguide/storagedriver/selectadriver/ ユーザーガイド] を見てください。{{ic|daemon.json}} の中のオプションの詳細は [https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file dockerd のドキュメント] を見てください。
 
   
  +
Docker で IPv6 のサポートを有効化するには、いくつかやるべきことがあります。詳細は [https://github.com/docker/docker.github.io/blob/c0eb65aabe4de94d56bbc20249179f626df5e8c3/engine/userguide/networking/default_network/ipv6.md] と [https://github.com/moby/moby/issues/36954] を見てください。
=== Remote API ===
 
   
  +
まず、{{ic|/etc/docker/daemon.json}} で {{ic|ipv6}} の設定を有効化し、特定の IPv6 サブネットを設定してください。ここでは、プライベート {{ic|fd00::/80}} サブネットを使用します。少なくとも 80 ビット以上のサブネットを使用してください。そうすることで、コンテナの IPv6 がコンテナの MAC アドレスで終わり、NDP ネイバーキャッシュの無効化問題を軽減できます。
ポート {{ic|4243}} で Remote API を手動で開くには:
 
   
  +
{{hc|/etc/docker/daemon.json|
# /usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
 
  +
{
  +
"ipv6": true,
  +
"fixed-cidr-v6": "fd00::/80"
  +
}
  +
}}
   
  +
変更を適用するために {{ic|docker.service}} を[[再起動]]してください。
{{ic|-H tcp://0.0.0.0:4243}} で Remote API が開かれます。
 
   
  +
最後に、コンテナがホストネットワークにアクセスできるようにするために、プライベート IPv6 サブネットの使用に起因するルーティングの問題を解決する必要があります。実際にトラフィックを取得するために、IPv6 NAT を追加してください:
{{ic|-H unix:///var/run/docker.sock}} はターミナルからホストマシンにアクセスできるようにします。
 
   
  +
# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE
==== Remote API と systemd ====
 
   
docker デーモンRemote API を起動するには、以下の内容で[[ドロップインスニペット]]作成してください:
+
これで、DockerIPv6 が適切に有効化されているはずです。テストするには、以下を実行してください:
   
  +
# docker run curlimages/curl curl -v -6 archlinux.org
{{hc|/etc/systemd/system/docker.service.d/override.conf|2=
 
[Service]
 
ExecStart=
 
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
 
}}
 
   
  +
以下のようなルールを追加することで、[[firewalld]] を使用できます:
=== デーモンのソケットの設定 ===
 
   
  +
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv6" destination not address="fd00::1/80" source address="fd00::/80" masquerade'
''docker'' デーモンはデフォルトで [[Wikipedia:ja:UNIXドメインソケット|Unix ソケット]]を使います。特定のポートを listen させるには、以下の内容の[[ドロップインスニペット]]を作成してください:
 
   
  +
[[ufw]] を使用する場合、まず [[Uncomplicated Firewall#Forward ポリシー]] に従って ipv6 フォワーディングを有効化する必要があります。次に、{{ic|/etc/default/ufw}} を編集して、以下の行をアンコメントする必要があります:
{{hc|/etc/systemd/system/docker.socket.d/socket.conf|2=
 
  +
[Socket]
 
  +
{{hc|head=/etc/ufw/sysctl.conf|output=
ListenStream=0.0.0.0:2375
 
  +
net/ipv6/conf/default/forwarding=1
  +
net/ipv6/conf/all/forwarding=1
 
}}
 
}}
   
  +
そして、iptables のルールを追加できます:
=== プロキシ ===
 
   
  +
# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE
プロキシの設定は2つに分けられます。ひとつは Docker デーモンのホストの設定で、もうひとつはコンテナからプロキシにアクセスできるようにするための設定です。
 
   
  +
''docker-compose'' を使用して作成された Docker コンテナには、対応するネットワークに対して {{ic|networks}} 部で {{ic|enable_ipv6: true}} を設定する必要がある場合があります。さらに、IPv6 サブネットの設定も必要になる場合があります。詳細は [https://docs.docker.com/compose/compose-file/compose-file-v2/#ipv4_address-ipv6_address] ([https://docs.docker.jp/compose/compose-file/compose-file-v2.html#ipv4-address-ipv6-address 日本語訳ページ]) を見てください。
==== プロキシの設定 ====
 
   
  +
=== ユーザ名前空間の隔離 ===
以下の内容で[[ドロップインスニペット]]を作成:
 
{{hc|/etc/systemd/system/docker.service.d/proxy.conf|2=
 
[Service]
 
Environment="HTTP_PROXY=192.168.1.1:8080"
 
Environment="HTTPS_PROXY=192.168.1.1:8080"
 
}}
 
   
  +
デフォルトでは、Docker コンテナ内のプロセスはメインの {{ic|dockerd}} デーモンと同じユーザ名前空間内で実行されます。つまり、コンテナは {{man|7|user_namespaces}} の機能によって隔離されていません。これにより、[[ユーザーとグループ#パーミッションと所有権]] に従って、コンテナ内のプロセスはホスト上に構成されたリソースにアクセスできます。これは互換性を最大化しますが、ホスト上のリソースに意図せずアクセスできてしまう特権昇格や情報漏えいの脆弱性が発見された場合は、セキュリティリスクが発生してしまいます (そのような脆弱性が[https://seclists.org/oss-sec/2019/q1/119 2019年2月に公開され、パッチが適用されました])。
{{Note|これはあなたのプロクシサーバが {{ic|192.168.1.1}} だと仮定しています、{{ic|127.0.0.1}} は使わないでください。}}
 
   
  +
そのような脆弱性による影響は、[https://docs.docker.com/engine/security/userns-remap/ ユーザ名前空間の隔離] ([https://docs.docker.jp/engine/security/userns-remap.html 日本語訳ページ]) を有効化することで軽減できます。これは、それぞれのコンテナを別のユーザ名前空間内で実行し、ユーザ名前空間内の UID と GID をホスト上の (通常は非特権の) 異なる UID/GID 範囲に割り当てます。
設定がロードされたことを確認:
 
   
  +
{{Note|
{{hc|# systemctl show docker --property Environment|2=
 
  +
* メインの {{ic|dockerd}} デーモンは依然としてホスト上で {{ic|root}} として実行されます。Docker を [https://docs.docker.com/engine/security/rootless/ rootless モード] ([https://docs.docker.jp/engine/security/rootless.html 日本語訳ページ]) で実行するのは、これとは別の機能です。
Environment=HTTP_PROXY=192.168.1.1:8080 HTTPS_PROXY=192.168.1.1:8080
 
  +
* コンテナ内のプロセスは、コンテナのイメージをビルドするために使用された Dockerfile 内の [https://docs.docker.com/engine/reference/builder/#user USER] ([https://docs.docker.jp/engine/reference/builder.html#user 日本語訳ページ]) ディレクティブで定義されているユーザとして起動されます。
  +
* すべてのコンテナは、同じ UID/GID 範囲に割り当てられます。これにより、コンテナ間でボリュームを共有できることが保証されます。
  +
* ユーザ名前空間の隔離の有効化には、[https://docs.docker.com/engine/security/userns-remap/#user-namespace-known-limitations いくつかの制限] ([https://docs.docker.jp/engine/security/userns-remap.html#user-namespace-known-limitations 日本語訳ページ]) があります。
  +
* ユーザ名前空間の隔離を有効化すると、{{ic|/var/lib/docker/}} にある他の Docker オブジェクトだけでなく、既存のイメージやコンテナのレイヤーも効果的にマスクします。Docker はこれらのリソースの所有権を調整する必要があるからです。上流のドキュメントでは、既存の Docker 環境ではなく、新しい Docker 環境でこの機能を有効化することが推奨されています。
 
}}
 
}}
   
  +
{{ic|/etc/docker/daemon.json}} 内の {{ic|userns-remap}} を設定してください。{{ic|default}} は特殊な値で、再割当てによって {{ic|dockremap}} という名前のユーザとグループを自動的に作成します。
==== コンテナの設定 ====
 
   
  +
{{hc|/etc/docker/daemon.json|2=
{{ic|docker.service}} ファイルの設定はコンテナには適用されません。{{ic|Dockerfile}} で {{ic|ENV}} 変数を設定する必要があります:
 
  +
{
  +
"userns-remap": "default"
  +
}
  +
}}
   
  +
{{ic|/etc/subuid}} と {{ic|/etc/subgid}} で、ユーザ名/グループ名、再割当てユーザとグループに割り当てる開始 UID/GID と UID/GID 範囲サイズを設定してください。以下の例では、165536 から始まる、範囲 65536 の UID と GID を {{ic|dockremap}} ユーザ・グループに割り当てます。
FROM base/archlinux
 
ENV http_proxy="<nowiki>http://192.168.1.1:3128</nowiki>"
 
ENV https_proxy="<nowiki>https://192.168.1.1:3128</nowiki>"
 
   
  +
{{hc|/etc/subuid|dockremap:165536:65536}}
[https://docs.docker.com/engine/reference/builder/#env Docker] は Dockerfile で {{ic|ENV}} を使って設定する方法について詳しい情報を提供しています。
 
   
  +
{{hc|/etc/subgid|dockremap:165536:65536}}
=== DNS の設定 ===
 
   
  +
設定を適用するために {{ic|docker.service}} を[[再起動]]してください。
デフォルトでは、docker はホストマシンにある {{ic|resolv.conf}} と同じ中身の {{ic|resolv.conf}} をコンテナに作成します。その際、ローカルアドレス (例: {{ic|127.0.0.1}}) は消されます。それによって {{ic|resolv.conf}} が空ファイルになった場合、[https://developers.google.com/speed/public-dns/ Google の DNS サーバー] が記述されます。[[dnsmasq]] などのサービスを利用して名前を解決するようにしたい場合、設定が消されないように docker のネットワークインターフェイス用にエントリを {{ic|/etc/resolv.conf}} に追加する必要があります。
 
   
  +
この変更を適用したあと、デフォルトですべてのコンテナは隔離されたユーザ名前空間内で実行されます。{{ic|docker}} コマンドに {{ic|1=--userns=host}} フラグを渡すことで、特定のコンテナ上で再割当てを部分的に無効化できます。詳細は [https://docs.docker.com/engine/security/userns-remap/#disable-namespace-remapping-for-a-container] ([https://docs.docker.jp/engine/security/userns-remap.html#disable-namespace-remapping-for-a-container 日本語訳ページ]) を見てください。
=== systemd-networkd 上に手動で定義したネットワークで Docker を実行 ===
 
   
  +
=== Rootless Docker デーモン ===
バージョン ''220'' 以上の [[systemd-networkd]] を使ってネットワークを手動設定している場合、Docker で起動したコンテナがネットワークにアクセスできない場合があります。バージョン 220 から、ネットワークの転送設定 ({{ic|net.ipv4.conf.<interface>.forwarding}}) はデフォルトで {{ic|off}} です。この設定で IP フォワーディングが使えません。また、コンテナの中で Docker によって有効になる {{ic|net.ipv4.conf.all.forwarding}} の設定と衝突します。
 
   
  +
{{Note|Docker rootless は、非特権ユーザの名前空間 ({{ic|CONFIG_USER_NS_UNPRIVILEGED}}) に依存しています。これは、{{Pkg|linux}}、{{Pkg|linux-lts}}、そして {{Pkg|linux-zen}} でデフォルトで有効化されています。他のカーネルのユーザはこれを有効化する必要があるかもしれません。これはセキュリティ上、重要な意味を持ちます。詳細については、[[セキュリティ#アプリケーションのサンドボックス化]] をご覧ください。}}
インターネットにアクセスするには、Docker のホスト側で {{ic|/etc/systemd/network/}} にある {{ic|<interface>.network}} ファイルを編集して {{ic|1=IPForward=kernel}} を追加してください:
 
   
  +
Docker デーモン自体を通常ユーザとして実行するには、{{aur|docker-rootless-extras}} パッケージをインストールしてください。
{{hc|/etc/systemd/network/<interface>.network|2=
 
[Network]
 
...
 
IPForward=kernel
 
...}}
 
   
  +
{{ic|/etc/subuid}} と {{ic|/etc/subgid}} に ユーザ名/グループ名、開始 UID/GID、そして UID/GID 範囲を設定し、再割り当てユーザ/グループに割り当てます:
上記の設定でコンテナから IP フォワーディングが使えるようになります。
 
   
  +
{{hc|/etc/subuid|your_username:165536:65536}}
=== イメージの置き場所 ===
 
   
  +
{{hc|/etc/subgid|your_username:165536:65536}}
デフォルトでは、docker のイメージは {{ic|/var/lib/docker}} に保存されます。置き場所は別のパーティションに移動することが可能です。
 
まず、{{ic|docker.service}} を[[停止]]してください。
 
   
  +
{{ic|docker.socket}} [[Systemd/ユーザー|ユーザユニット]] を [[有効化]]します。これにより、docker は systemd の socket activation を利用して開始されます。
docker イメージを起動したことがある場合、イメージが完全にアンマウントされていることを確認します。そうしたら、イメージを {{ic|/var/lib/docker}} から好きな場所に移動してください。
 
   
  +
最後に docker ソケットの[[環境変数]]を設定します:
その後、{{ic|docker.service}} の[[ドロップインスニペット]]を作成して、{{ic|ExecStart}} に {{ic|-g}} パラメータを追加してください:
 
   
  +
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
{{hc|/etc/systemd/system/docker.service.d/docker-storage.conf|2=
 
[Service]
 
ExecStart=
 
ExecStart=/usr/bin/dockerd -g ''/path/to/new/location/docker'' -H fd://}}
 
   
  +
=== ネイティブ overlay diff エンジンを有効化する ===
=== 安全ではないレジストリ ===
 
   
  +
{{Accuracy|これはあなたのシステムでは必要ないかもしれません。{{ic|1=metacopy=on redirect_dir=on}} は Arch Linux カーネルでデフォルトとなっていますが、これらの設定は実行時に無効化されると一部のユーザが報告しています。}}
もしプライベートレジストリに自己署名証明書を使うことに決めた場合、あなたが信頼すると宣言するまで Docker はその使用を拒否します。{{ic|docker.service}} の[[ドロップインスニペット]]を追加して、{{ic|--insecure-registry}} パラメータを {{ic|dockerd}} に追加してください:
 
  +
{{hc|/etc/systemd/system/docker.service.d/override.conf|2=
 
  +
デフォルトでは、Docker は Arch Linux 上でネイティブの overlay diff エンジンを使用できません。これにより、Docker イメージのビルドが遅くなります。頻繁にイメージをビルドする場合は、[https://mikeshade.com/posts/docker-native-overlay-diff/] で説明されているようにネイティブの diff エンジンを設定してください:
[Service]
 
  +
ExecStart=
 
  +
{{hc|/etc/modprobe.d/disable-overlay-redirect-dir.conf|2=
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry my.registry.name:5000
 
  +
options overlay metacopy=off redirect_dir=off
 
}}
 
}}
  +
  +
その後、{{ic|docker.service}} を[[停止]]し、以下のように {{ic|overlay}} モジュールを再読込してください:
  +
  +
# modprobe -r overlay
  +
# modprobe overlay
  +
  +
そして、{{ic|docker.service}} を再[[起動]]してください。
  +
  +
確認するには、{{ic|docker info}} を実行して、{{ic|Native Overlay Diff}} が {{ic|true}} になっているかどうか見てください。
   
 
== イメージ ==
 
== イメージ ==
  +
 
=== Arch Linux ===
 
=== Arch Linux ===
次のコマンドは [https://hub.docker.com/r/archlinux/archlinux archlinux/archlinux] x86_64 イメージを取得します。これはネットワークなどを削減した Arch コア環境です:
 
# docker pull archlinux/archlinux
 
詳しくは [https://gitlab.archlinux.org/archlinux/archlinux-docker/-/blob/master/README.md README.md] を参照してください。
 
   
リポジトリを clone して自分でイメージを作成することもできます。{{ic|archlinux/archlinux:base}} イメージを作成るに次のようにす:
+
以下のコマンドは [https://hub.docker.com/_/archlinux/ archlinux] x86_64 イメージを pull しま。これネットワークなどを落とた Arch コア環境です:
  +
  +
# docker pull archlinux
  +
  +
[https://gitlab.archlinux.org/archlinux/archlinux-docker/blob/master/README.md README.md] も見てください。
  +
  +
完全な Arch ベースは、上記からリポジトリを clone し、独自のイメージをビルドしてください。
   
 
$ git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git
 
$ git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git
$ make docker-image-base
 
   
  +
パッケージ {{Pkg|devtools}}、{{Pkg|fakechroot}}、{{Pkg|fakeroot}} はインストールされていることに注意してください。
{{Note|以前使われていた [https://hub.docker.com/r/archlinux/base/ archlinux/base] イメージは更新が終了しています。[https://lists.archlinux.org/pipermail/arch-dev-public/2020-November/030181.html]}}
 
  +
  +
ベースイメージをビルドするには:
  +
  +
$ make image-base
  +
  +
=== Alpine Linux ===
  +
  +
[https://www.alpinelinux.org/ Alpine Linux] は、(特に静的バイナリとしてコンパイルされたソフトウェアための) 小さなコンテナイメージとして人気の選択肢です。以下のコマンドは最新の Alpine Linux イメージを pull します:
  +
  +
# docker pull alpine
  +
  +
Alpine Linux は、ほとんどの Linux ディストリビューションで使用されている [https://www.gnu.org/software/libc/ glibc] libc 実装ではなく、[https://musl.libc.org/ musl] libc 実装を使用します。Arch Linux は glibc を使用するので、Arch Linux ホストと Alpine Linux コンテナの間には機能的な違いが一定数存在し、ソフトウェアのパフォーマンスと正確性に影響を与えます。これらの違いのリストは、[https://wiki.musl-libc.org/functional-differences-from-glibc.html ここ]でドキュメント化されています。
  +
  +
Arch Linux (または glibc を使用する他のシステム) でビルドされた動的リンクのソフトウェアは、Alpine Linux (または異なる libc を使用する他のシステム) 上で実行すると、バグとパフォーマンス上の問題を生じる場合があります。例は、[https://bugs.python.org/issue32307]、[https://superuser.com/questions/1219609/why-is-the-alpine-docker-image-over-50-slower-than-the-ubuntu-image]、[https://pythonspeed.com/articles/alpine-docker-python] を見てください。
   
 
=== Debian ===
 
=== Debian ===
  +
以下のコマンドで [https://hub.docker.com/r/_/debian/ debian] x86_64 イメージが取得されます:
 
  +
次のコマンドは最新の [https://hub.docker.com/_/debian debian] イメージを pull します:
  +
 
# docker pull debian
 
# docker pull debian
   
  +
(各 Debian リリースの標準バージョンとスリムバージョンの療法を含む) 利用可能なタグの完全なリストは Docker Hub ページを見てください。
==== 手動 ====
 
  +
  +
=== Distroless ===
  +
  +
Google は、パッケージマネージャやシェルなどの OS コンポーネントの無い最小イメージである [https://github.com/GoogleContainerTools/distroless distroless イメージ]をメンテナンスしています。これにより、ソフトウェアをパッケージングするためにイメージのサイズを非常に小さくできます。
  +
  +
イメージのリストと様々なプログラミング言語での使用法に関する指示は GitHub README を見てください。
  +
  +
== ヒントとテクニック ==
  +
  +
=== 実行中のコンテナの IP アドレスを取得する ===
  +
  +
実行中のコンテナの IP アドレスを取得するには:
  +
  +
{{hc|<nowiki>$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-name OR id> </nowiki>|
  +
172.17.0.37}}
  +
  +
それぞれの実行中のコンテナについて、{{ic|/etc/hosts}} で使用するために、名前とそれに対応する IP アドレスを出力:
  +
  +
{{bc|#!/usr/bin/env sh
  +
<nowiki>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</nowiki>}}
  +
  +
=== コンテナ内でグラフィカルなプログラムを実行する ===
  +
  +
このセクションでは、グラフィカルなプログラム (OpenGL や Vulkan に依存しているものを含む) をホストの X サーバ上で実行できるようにする手順を説明します。
  +
  +
まず、('''ホストの'''グラフィックハードウェアと互換性のある) 適切なドライバがコンテナ内にインストールされている必要があります。インストール手順はコンテナの種類に依存しますが、Arch Linux イメージベースのコンテナでは、[[OpenGL#インストール]] と [[Vulkan#インストール]] を参照してあなたのハードウェア固有のパッケージを調べてください。
  +
  +
次に、コンテナがホストの X サーバにアクセスできるようにしなくてはなりません。シングルユーザな環境では、ホスト上で [[Xhost]] を実行すれば簡単に行なえます。Xhost は、非ネットワークなローカル接続をアクセス制御リストに追加します:
  +
  +
$ xhost +local:
  +
  +
最後に、以下のパラメータを {{ic|docker run}} に渡す必要があります:
  +
  +
* {{ic|1=-e "DISPLAY=$DISPLAY"}}: ホストのディスプレイを示す環境変数 {{ic|DISPLAY}} をコンテナ内で設定します。
  +
* {{ic|1=--mount type=bind,src=/tmp/.X11-unix,dst=/tmp/.X11-unix}}: ホストの X サーバソケットをコンテナ内部に同じパスでマウントします。
  +
* {{ic|1=--device=/dev/dri:/dev/dri}}: コンテナにホストの [[wikipedia:Direct Rendering Infrastructure|Direct Rendering Infrastructure]] デバイスへのアクセス権を与えます。
  +
  +
すべて正しくセットアップできたことを確認するには、コンテナ内で {{Pkg|mesa-utils}} パッケージの {{ic|glxgears}} や、{{Pkg|vulkan-tools}} パッケージの {{ic|vkcube}} を実行してみてください。
  +
  +
=== ブート時に Docker Compose プロジェクトを開始する ===
  +
  +
{{Accuracy|これは、{{ic|compose.yml}} 内に {{ic|restart: always}} がある場合は必須ではありません。[https://docs.docker.com/compose/compose-file/compose-file-v3/#restart] [[:en:Talk:Docker#"Start Docker Compose projects on boot" Spurious?]]}}
  +
  +
まず、サービスの名前でパラメータ化された Docker Compose のテンプレート[[Systemd#ユニットファイル|ユニット]]を作成してください ({{man|5|systemd.service|SERVICE TEMPLATES}} を参照):
  +
  +
{{hc|/etc/systemd/system/docker-compose@.service|2=
  +
[Unit]
  +
Description=%i service with docker compose
  +
Requires=docker.service
  +
After=docker.service
  +
  +
[Service]
  +
WorkingDirectory=/opt/%i
  +
ExecStartPre=-/usr/bin/docker compose pull
  +
ExecStart=/usr/bin/docker compose up --remove-orphans
  +
ExecStop=/usr/bin/docker compose down
  +
ExecReload=/usr/bin/docker compose pull
  +
ExecReload=/usr/bin/docker compose up --remove-orphans
  +
  +
[Install]
  +
WantedBy=multi-user.target
  +
}}
  +
  +
そして、実行したい各サービスに対して、Compose ファイルとその他必須のファイル ({{ic|.env}} など) が入っているディレクトリを {{ic|/opt/''project_name''}} に作成してください。[https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html]
  +
  +
最後に、{{ic|docker-compose@''project_name''.service}} を[[起動/有効化]]してください。
  +
  +
=== クロスコンパイルに buildx を使う ===
  +
  +
[https://docs.docker.com/buildx/working-with-buildx/ buildx CLI プラグイン] は新しい [https://docs.docker.com/develop/develop-images/build_enhancements/ BuildKit building toolkit] ([https://docs.docker.jp/develop/develop-images/build_enhancements.html 日本語訳ページ]) を使用します。buildx インターフェイスはマルチプラットフォームなイメージのビルドをサポートしています (ホストのアーキテクチャ以外も)。
  +
  +
イメージのクロスコンパイルには QEMU が必要です。Docker 内で QEMU の静的ビルドをセットアップする方法については、[https://github.com/multiarch/qemu-user-static multiarch/qemu-user-static] イメージの情報を見てください。あるいは、QEMU をホストのシステム上でセットアップして、Docker と一緒に使う方法については、[[QEMU#x86_64 から arm/arm64 環境への chrooting]] を見てください。どちらの場合にせよ、あなたのシステムはゲストアーキテクチャのユーザモードエミュレート用に設定されます。
  +
  +
{{hc|$ docker buildx ls|
  +
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
  +
default * docker
  +
default default running linux/amd64, linux/386, linux/arm64, linux/riscv64, linux/s390x, linux/arm/v7, linux/arm/v6
  +
}}
  +
  +
=== NVIDIA GPU で GPU アクセラレートされた Docker コンテナを動かす ===
  +
  +
==== NVIDIA Container Toolkit を使う (推奨) ====
  +
  +
Docker バージョン 19.03 より、NVIDIA GPU が Docker デバイスとしてネイティブにサポートされています。NVIDIA GPU を活用するコンテナの実行方法として [https://github.com/NVIDIA/nvidia-docker NVIDIA Container Toolkit] が推奨されています。
  +
  +
{{aur|nvidia-container-toolkit}} パッケージをインストールしてください。次に、docker を[[再起動]]してください。これで、{{ic|--gpus}} オプションを使うことで、NVIDIA GPU を使用するコンテナを実行できるようになります:
  +
  +
# docker run --gpus all nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
コンテナ内でいくつの GPU を有効化するかを指定するには:
  +
  +
# docker run --gpus 2 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
どの GPU を使用するかを指定するには:
  +
  +
# docker run --gpus '"device=1,2"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
あるいは
  +
  +
# docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
{{Accuracy|1=以下のエラーが発生する場合のより詳細な情報が必要です。これは機能するはずです。[https://aur.archlinux.org/cgit/aur.git/tree/nvidia-container-toolkit.install?h=nvidia-container-toolkit]{{Dead link|2023|04|23|status=404}} を参照してください。[[:en:Talk:Docker#GPU accelerated Docker Nvidia]]}}
  +
  +
上記のコマンドを使っていて、{{ic|Failed to initialize NVML: Unknown Error}} のようなエラーが発生する場合、GPU をより具体的に指定してみてください:
  +
  +
# docker run --gpus all --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm --device /dev/nvidia0:/dev/nvidia0 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
コンテナで使用する機能 (グラフィックス、計算、...) を指定するには (とはいえ、この方法が使用されるのは稀です):
  +
  +
# docker run --gpus all,capabilities=utility nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
  +
  +
詳細は [https://github.com/NVIDIA/nvidia-docker/blob/master/README.md README.md] と [https://github.com/NVIDIA/nvidia-docker/wiki Wiki] を見てください。
  +
  +
==== NVIDIA Container Runtime を使う ====
  +
  +
{{aur|nvidia-container-runtime}} パッケージをインストールしてください。次に、{{ic|/etc/docker/daemon.json}} を編集して NVIDIA ランタイムを登録してください:
  +
  +
{{hc|/etc/docker/daemon.json|2=
  +
{
  +
"runtimes": {
  +
"nvidia": {
  +
"path": "/usr/bin/nvidia-container-runtime",
  +
"runtimeArgs": []
  +
}
  +
}
  +
}
  +
}}
  +
  +
そして、docker を[[再起動]]してください。
  +
  +
ランタイムは、''dockerd'' にコマンドラインオプションを渡すことでも登録できます:
  +
  +
# /usr/bin/dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime
  +
  +
その後、GPU アクセラレートされたコンテナを実行するには:
  +
  +
# docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi
  +
  +
あるいは (以下の方法は Docker バージョン 19.03 およびそれ以降が必要です):
  +
  +
# docker run --gpus all nvidia/cuda:9.0-base nvidia-smi
  +
  +
[https://github.com/NVIDIA/nvidia-container-runtime/blob/master/README.md README.md] も見てください。
  +
  +
==== CUDA 付き Arch Linux イメージ ====
  +
  +
以下の {{ic|Dockerfile}} を使うことで、CUDA 付きのカスタム Arch Linux イメージをビルドできます。ホスト上で pacman パッケージをキャッシュするために [https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md Dockerfile frontend syntax 1.2] を使用します。Docker イメージをビルドする前に、クライアント上で {{ic|1=DOCKER_BUILDKIT=1}} [[環境変数]]を設定する必要があります。
  +
  +
{{hc|Dockerfile|<nowiki>
  +
# syntax = docker/dockerfile:1.2
  +
  +
FROM archlinux
   
  +
# install packages
{{Pkg|debootstrap}} で Debian イメージを作成:
 
  +
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman \
  +
pacman -Syu --noconfirm --needed base base-devel cuda
   
  +
# configure nvidia container runtime
# mkdir jessie-chroot
 
  +
# https://github.com/NVIDIA/nvidia-container-runtime#environment-variables-oci-spec
# debootstrap jessie ./jessie-chroot http://http.debian.net/debian/
 
  +
ENV NVIDIA_VISIBLE_DEVICES all
# cd jessie-chroot
 
  +
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
# tar cpf - . | docker import - debian
 
  +
</nowiki>}}
# docker run -t -i --rm debian /bin/bash
 
   
 
== Docker とイメージの削除 ==
 
== Docker とイメージの削除 ==
189行目: 457行目:
 
{{Note|コマンドを実行する前にどういう意味なのか考えてください。何も考えずにコピーアンドペーストしてはいけません。}}
 
{{Note|コマンドを実行する前にどういう意味なのか考えてください。何も考えずにコピーアンドペーストしてはいけません。}}
   
実行中のコンテナをチェック:
+
実行中のコンテナをチェックする:
   
 
# docker ps
 
# docker ps
   
削除するホストで実行中の全てのコンテナを確認:
+
削除するために、ホストで実行中のコンテナをすべて表示する:
   
 
# docker ps -a
 
# docker ps -a
   
実行中のコンテナを停止:
+
実行中のコンテナを停止する:
   
 
# docker stop <CONTAINER ID>
 
# docker stop <CONTAINER ID>
   
停止ないコンテナを終了:
+
依然とて実行中のコンテナを kill する:
   
 
# docker kill <CONTAINER ID>
 
# docker kill <CONTAINER ID>
   
ID で指定して全てのコンテナを削除:
+
ID でリストされたコンテナを削除する:
   
 
# docker rm <CONTAINER ID>
 
# docker rm <CONTAINER ID>
   
全ての Docker イメージを確認:
+
Docker イメージをすべて表示する:
   
 
# docker images
 
# docker images
   
ID で指定して全てのイメージを削除:
+
ID でイメージを削除する:
   
 
# docker rmi <IMAGE ID>
 
# docker rmi <IMAGE ID>
   
  +
コンテナに関連付けられていない (ダングリング) すべてのイメージ、コンテナ、ボリューム、ネットワークを削除する:
全ての Docker データを削除:
 
   
  +
# docker system prune
# rm -R /var/lib/docker
 
   
  +
停止中のコンテナと未使用のイメージ (ダングリングイメージでないもの) を追加で削除するには、-a フラグをコマンドに追加してください:
== 便利なヒント ==
 
   
  +
# docker system prune -a
実行中のコンテナの IP アドレスを取得するには:
 
   
  +
すべての Docker データを削除する (ディレクトリを削除する):
{{hc|<nowiki>$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-name OR id> </nowiki>|
 
172.17.0.37}}
 
   
  +
# rm -R /var/lib/docker
それぞれの実行中のコンテナについて、{{ic|/etc/hosts}} で使うために名前と対応する IP アドレスを出力:
 
 
{{bc|#!/usr/bin/env sh
 
<nowiki>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</nowiki>}}
 
   
 
== トラブルシューティング ==
 
== トラブルシューティング ==
   
=== systemd 232 でコンテナが起動できない ===
+
=== systemd-networkd を使用していると、docker0 ブリッジが IP を取得きない / コンテナからインターネットにアクセスできない ===
[[カーネルパラメータ]]として {{ic|1=systemd.legacy_systemd_cgroup_controller=yes}} を追加してください。詳しくは [https://github.com/opencontainers/runc/issues/1175 バグレポート] を参照。
 
 
=== Btrfs ファイルシステムで Docker イメージを消去 ===
 
 
[[btrfs]] ファイルシステムで docker イメージを削除すると {{ic|/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
 
   
  +
Docker はグローバルに IP フォワーディングを有効化しようと試みますが、デフォルトでは、定義されているネットワークプロファイルのグローバルな sysctl 設定を [[systemd-networkd]] が上書きしてしまいます。ネットワークプロファイルに {{ic|1=IPForward=yes}} を設定してください。詳しくは [[インターネット共有#パケット転送の有効化]] を参照してください。
このエラーは btrfs が docker イメージのためにサブボリュームを作成したのが原因です。したがって削除するときの正しいコマンドは次のようになります:
 
# btrfs subvolume delete /var/lib/docker/btrfs/subvolumes/85122f1472a76b7519ed0095637d8501f1d456787be1a87f2e9e02792c4200ab
 
   
  +
[[systemd-networkd]] が Docker によって作成されたネットワークインターフェイスを管理しようとする場合 (例えば、Match セクションに {{ic|1=Name=*}} を設定した場合)、接続の問題が発生する可能性があります。それらのインターフェイスの管理を無効化してみてください。例えば、{{ic|networkctl list}} を実行すると、SETUP 列ですべての Docker によって作成されたネットワークは {{ic|unmanaged}} と表示される必要があります。
=== docker0 ブリッジが IP を取得できない / コンテナからインターネットにアクセスできない ===
 
   
Docker は自分で IP フォワーディングを有効にしますが、デフォルトでは [[systemd-networkd]] によって sysctl の設定が上書きされてしまいます。ネットワークプロファイルに {{ic|1=IPForward=yes}} を設定してください。詳しくは[[インターネット共有#パケット転送の有効化]]を参照してください。
 
 
 
{{Note|
 
{{Note|
 
* {{ic|systemd-networkd.service}} や {{ic|iptables.service}} を[[再起動]]したときは {{ic|docker.service}} を[[再起動]]する必要があります。
 
* {{ic|systemd-networkd.service}} や {{ic|iptables.service}} を[[再起動]]したときは {{ic|docker.service}} を[[再起動]]する必要があります。
* [[nftables]] によって docker の接続がデフォルトでブロックされる可能性があります。{{ic|nft list ruleset}} を使ってブロックしているルールを確認してください。{{ic|nft flush chain inet filter forward}} で一時的に全ての転送ルールを削除できます。変更を永続化するには {{ic|/etc/nftables.conf}} を編集してください。設定ファイルからルールをリロードするに {{ic|nftables.service}} を[[再起動]]てください。
+
* また、デフォルトで [[nftables]] docker の接続ブロックる可能性も考慮してください。{{ic|nft list ruleset}} を使ってブロックしているルールを確認してください。{{ic|nft flush chain inet filter forward}} で一時的に全ての転送ルールを削除できます。変更を永続化するには {{ic|/etc/nftables.conf}} を編集してください。設定ファイルからルールをリロードするために {{ic|nftables.service}} を[[再起動]]することを忘れないでください。Docker での nftables サポートに関する詳細は [https://github.com/moby/moby/issues/26824] を見てください。
 
}}
 
}}
   
265行目: 514行目:
 
以下のようなエラーメッセージが表示される場合:
 
以下のようなエラーメッセージが表示される場合:
   
# e.g. Java
+
# Java の場合
 
java.lang.OutOfMemoryError: unable to create new native thread
 
java.lang.OutOfMemoryError: unable to create new native thread
# e.g. C, bash, ...
+
# Cbash などの場合
 
fork failed: Resource temporarily unavailable
 
fork failed: Resource temporarily unavailable
   
systemd によって許可されるプロセスの数を調整する必要があります。デフォルトは 500 ですが ({{ic|system.conf}} を参照)、複数の docker コンテナを動作させるには少なすぎます。以下のスニペットで {{ic|docker.service}} を[[編集]]してください:
+
systemd によって許可されるプロセスの数を調整する必要があります。以下のように {{ic|docker.service}} を[[編集]]してください:
   
  +
[Service]
{{hc|# systemctl edit docker.service|2=
 
  +
TasksMax=infinity
[Service]
 
  +
TasksMax=infinity
 
  +
より詳細な背景情報は、{{man|5|systemd-system.conf|OPTIONS}} の {{ic|DefaultLimitNPROC}} を見てください。また、{{man|5|systemd.resource-control|OPTIONS}} の {{ic|TasksMax}} も見てください。
}}
 
   
 
=== Error initializing graphdriver: devmapper ===
 
=== Error initializing graphdriver: devmapper ===
293行目: 542行目:
 
Docker イメージの作成・実行時、ディスク容量が十分に存在するにもかかわらず、上記のメッセージが表示されるときは以下を確認してください:
 
Docker イメージの作成・実行時、ディスク容量が十分に存在するにもかかわらず、上記のメッセージが表示されるときは以下を確認してください:
   
* [[Tmpfs]] が無効になっている、あるいは十分なメモリが割り当てられている。Docker が {{ic|/tmp}} にファイルを書き出そうとしていて、ディスク容量ではなくメモリ使用量が制限となっている可能性があります。
+
* [[Tmpfs]] が無効になっているか。十分なメモリが割り当てられている。Docker が {{ic|/tmp}} にファイルを書き出そうとしていて、ディスク容量ではなくメモリ使用量が制限となっている可能性があります。
* [[XFS]] を使っている場合、{{ic|/etc/fstab}} の ({{ic|/tmp}} や {{ic|/var/lib/docker}} がある) エントリから {{ic|noquota}} マウントオプションを削除すると良いかもしれません。詳しくは[[ディスククォータ]]を参照してください。Docker ストレージドライバーの {{ic|overlay2}} を使用するときは特に注意してください。
+
* [[XFS]] を使っている場合、{{ic|/etc/fstab}} の ({{ic|/tmp}} や {{ic|/var/lib/docker}} がある) エントリから {{ic|noquota}} マウントオプションを削除するべきかもしれません。詳しくは[[ディスククォータ]]を参照してください。Docker ストレージドライバーの {{ic|overlay2}} を使用するときは特に注意してください。
 
* XFS クォータのマウントオプション ({{ic|uquota}}, {{ic|gquota}}, {{ic|prjquota}} など) がファイルシステムの再マウント時に失敗している。ルートファイルシステムでクォータを使うには、マウントオプションを {{ic|1=rootflags=}} [[カーネルパラメータ]]で initramfs に渡す必要があります。その場合、root ({{ic|/}}) ファイルシステムのマウントオプションとして {{ic|/etc/fstab}} に指定してはいけません。
 
* XFS クォータのマウントオプション ({{ic|uquota}}, {{ic|gquota}}, {{ic|prjquota}} など) がファイルシステムの再マウント時に失敗している。ルートファイルシステムでクォータを使うには、マウントオプションを {{ic|1=rootflags=}} [[カーネルパラメータ]]で initramfs に渡す必要があります。その場合、root ({{ic|/}}) ファイルシステムのマウントオプションとして {{ic|/etc/fstab}} に指定してはいけません。
   
{{Note|XFS のクォータと Linux 標準の[[ディスククォータ]]には違いが存在します。詳しくは [http://inai.de/linux/adm_quota] を参照てください。}}
+
{{Note|XFS のクォータと Linux 標準の[[ディスククォータ]]には違いが存在します。[https://inai.de/linux/adm_quota] は読む価値があるかもれません。}}
 
=== カーネル 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
 
 
その場合 {{ic|1=overlay.metacopy=N}} [[カーネルパラメータ]]を追加するか、[https://github.com/docker/for-linux/issues/480 この問題] が解決するまで 4.18.x にダウングレードしてください。詳しくは [https://bbs.archlinux.org/viewtopic.php?id=241866 Arch フォーラム] を参照。
 
   
 
=== virtualbox ドライバーを使用したときに Docker-machine が仮想マシンの作成に失敗する ===
 
=== virtualbox ドライバーを使用したときに Docker-machine が仮想マシンの作成に失敗する ===
317行目: 558行目:
 
=== Docker を起動すると KVM のブリッジネットワークが壊れる ===
 
=== Docker を起動すると KVM のブリッジネットワークが壊れる ===
   
  +
この問題は、Docker のスクリプトがいくつかの iptables ルールを追加し、それ自体のインターフェイス以外のインターフェイスのフォワーディングをブロックしてしまうというものです。これは[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865975 既知の問題]です。
[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865975 既知のバグ] が原因です。以下の方法で回避できます:
 
  +
  +
以下の解決策では、br0 をあなたのブリッジ名に置き換えてください。
  +
  +
最も速い解決策は (しかし、これは Docker の iptabkes 自己追加調整機能をすべて無効化してしまいます。これは望ましくない場合があります。):
   
 
{{hc|/etc/docker/daemon.json|2=
 
{{hc|/etc/docker/daemon.json|2=
 
{
 
{
 
"iptables": false
 
"iptables": false
  +
}
  +
}}
  +
  +
KVM 用に設定されたネットワークブリッジがすでに存在する場合、Docker にそのことを伝えることで解決できる場合があります。[https://muthii.com/blog/?p=540] を見て、以下のように docker の設定を変更してください:
  +
  +
{{hc|/etc/docker/daemon.json|2=
  +
{
  +
"bridge": "br0"
  +
}
  +
}}
  +
  +
上記の設定がうまく行かない場合や、UFW のようなマネージャ、あるいは iptables を通して直接この問題を解決したい場合、以下を追加してください:
  +
  +
{{bc|iptables -I FORWARD -i br0 -o br0 -j ACCEPT}}
  +
  +
更に詳しい解決策は [https://serverfault.com/questions/963759/docker-breaks-libvirt-bridge-network ここ] にあります。
  +
  +
=== Docker Hub からのイメージ取得に速度制限が掛かる ===
  +
  +
2020年11月1日より、無名アカウントや無料アカウントによる Docker Hub からのダウンロードには速度制限がかかるようになりました。詳細は [https://docs.docker.com/docker-hub/download-rate-limit/ 速度制限に関するドキュメント] を見てください。
  +
  +
認証されていない速度制限はソースの IP によって追跡され、認証済みの速度制限はアカウントによって追跡されます。
  +
  +
速度制限を超過する必要がある場合、[https://www.docker.com/pricing 有料プランに登録]するか、必要なイメージを別のイメージレジストリでミラーすることで可能です。[https://docs.docker.com/registry/ 自分自身のレジストリをホストする] ([https://docs.docker.jp/registry/ 日本語訳ページ]) こともできますし、[https://aws.amazon.com/ecr/ Amazon ECR]、[https://cloud.google.com/container-registry/ Google Container Registry]、[https://azure.microsoft.com/en-us/services/container-registry/ Azure Container Registry]、[https://quay.io/ Quay Container Registry] などのクラウドでホストされているレジストリを使うこともできます。
  +
  +
イメージをミラーするには、Docker CLI のサブコマンド {{ic|pull}}、{{ic|tag}}、{{ic|push}} を使ってください。例えば、[[Nginx]] イメージの {{ic|1.19.3}} タグを、{{ic|cr.example.com}} でホストされているレジストリでミラーするには:
  +
  +
$ docker pull nginx:1.19.3
  +
$ docker tag nginx:1.19.3 cr.example.com/nginx:1.19.3
  +
$ docker push cr.example.com/nginx:1.19.3
  +
  +
その後に、そのミラーからイメージを pull または実行することができます:
  +
  +
$ docker pull cr.example.com/nginx:1.19.3
  +
$ docker run cr.example.com/nginx:1.19.3
  +
  +
=== iptables (legacy): unknown option "--dport" ===
  +
  +
{{Accuracy|[[Nftables#Docker と共に使う]] では、{{Pkg|iptables-nft}} を使用しないことが推奨されています。}}
  +
  +
コンテナの実行中にこのエラーが発生する場合は、{{Pkg|iptables}} (legacy) の代わりに {{Pkg|iptables-nft}} をインストールして、再起動してください [https://bbs.archlinux.org/viewtopic.php?id=256709]。
  +
  +
=== docker ログイン時に "Your password will be stored unencrypted" ===
  +
  +
[https://docs.docker.com/engine/reference/commandline/login/#credentials-store デフォルトでは]、Docker はレジストリパスワードを保存するために {{ic|pass}} や {{ic|secretservice}} バイナリの使用を試みます。これらのバイナリが見つからない場合、Docker はパスワードを平文 (base64 エンコード) で {{ic|$HOME/.docker/config.json}} に保存し、ログイン成功後に以下のメッセージを出力します:
  +
  +
$ WARNING! Your password will be stored unencrypted in /home/''username''/.docker/config.json.
  +
  +
[https://specifications.freedesktop.org/secret-service/latest/ Secret Service Freedesktop DBUS API] を実装しているパスワードマネージャ (KDE の {{Pkg|KWallet}} や GNOME の {{Pkg|gnome-keyring}} など) を使用している場合、パスワードをパスワードマネージャに保存するための {{Aur|docker-credentials-secretservice}} パッケージをインストールすることができます。
  +
  +
=== "Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network" ===
  +
  +
Sometimes if you use a lot of Docker projects (ex. using docker-compose) it can happens that you run out of available IPs for Docker containers triggering the error:
  +
  +
Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
  +
  +
As found on [https://github.com/docker/docs/issues/8663 this Docker issue], the defaults are:
  +
  +
{| class="wikitable"
  +
! Type !! Default Size !! Default Pool
  +
|-
  +
| local || /16 || 172.17.0.0/12
  +
|-
  +
| local* || /20 || 192.168.0.0/16
  +
|}
  +
  +
This can be easily fixed increasing the Docker IP space by configuring {{ic|default-address-pools}} in {{ic|/etc/docker/daemon.json}} increasing the size value from 16 to 24 on the first IP range, keeping the second one unaltered to avoid ip collision on the local network:
  +
  +
{{hc|/etc/docker/daemon.json|2=
  +
{
  +
...
  +
"default-address-pools" : [
  +
{
  +
"base" : "172.17.0.0/12",
  +
"size" : 24
  +
},
  +
{
  +
"base" : "192.168.0.0/16",
  +
"size" : 24
  +
}
  +
]
  +
}
  +
}}
  +
  +
Restart {{ic|docker.service}} to apply changes.
  +
  +
More details and technical explanations can be found on the following excellent article: [https://straz.to/2021-09-08-docker-address-pools/ The definitive guide to docker's default-address-pools option].
  +
  +
=== Slow golang compilation ===
  +
  +
Due to a ulimit configuration, building a docker image and its dependances with makepkg is very slow (stuck at "Entering fakeroot environment..." step).
  +
  +
It is related to [https://github.com/moby/moby/issues/45436] and [https://github.com/containerd/containerd/pull/7566].
  +
  +
You can add {{ic|1=--ulimit "nofile=1024:524288"}} to your docker build option or create/edit:
  +
  +
{{hc|/etc/docker/daemon.json|
  +
{
  +
"default-ulimits": {
  +
"nofile": {
  +
"Name": "nofile",
  +
"Soft": 1024,
  +
"Hard": 524288
  +
}
  +
}
 
}
 
}
 
}}
 
}}
328行目: 678行目:
   
 
* [https://www.docker.com 公式ウェブサイト]
 
* [https://www.docker.com 公式ウェブサイト]
* [https://docs.docker.com/engine/installation/linux/archlinux/ Arch Linux on docs.docker.com]
+
* [https://docs.docker.com/engine/installation/linux/archlinux/ docs.docker.com の Arch Linux] ([https://docs.docker.jp/engine/installation/linux/archlinux.html 日本語訳])
* [http://opensource.com/business/14/7/docker-security-selinux Are Docker containers really secure?] — opensource.com
+
* [https://opensource.com/business/14/7/docker-security-selinux Are Docker containers really secure?] — opensource.com
  +
* [https://awesome-docker.netlify.com/ Awesome Docker]
  +
* [https://www.trendmicro.com/en_us/research/19/l/why-running-a-privileged-container-in-docker-is-a-bad-idea.html Why A Privileged Container in Docker Is a Bad Idea]
  +
  +
{{TranslationStatus|Docker|2023-05-12|777552}}

2024年8月20日 (火) 19:43時点における最新版

関連記事

Docker は軽量コンテナとしてあらゆるアプリケーションを詰めて運んで実行できるユーティリティです。

目次

インストール

Docker イメージを pull し Docker コンテナを実行するには、Docker Engine が必要です。Docker Engine には、コンテナを管理するデーモンや docker CLI フロントエンドが含まれています。docker パッケージをインストールしてください。開発版は docker-gitAUR パッケージをインストールしてください。次に、docker.service起動/有効化して、動作することを確認してください:

# docker info

アクティブな vpn 接続がある場合、docker サービスの起動に失敗することがあることに注意してください。VPN と Docker のブリッジネットワークやオーバーレイネットワークの間で IP が競合するからです。このような場合、docker サービスの起動前に vpn を切断してみてください。その後すぐに vpn に再接続できます。ネットワークの衝突解除を試してみることも可能です (解決策については、 [1][2] をご覧ください)。

次に、コンテナが動作することを検証します。次のコマンドは、最新の Arch Linux イメージをダウンロードし、そのイメージを使ってコンテナの中で Hello World プログラムを実行します:

# docker run -it --rm archlinux bash -c "echo hello world"

docker CLI コマンドを非 root ユーザとして実行できるようにしたい場合は、ユーザーを docker グループに追加して、ログインし直し、docker.service を再起動してください。

警告: ユーザーを docker グループに追加することは、そのユーザーを root にするのと等価です。なぜなら、そのグループに属するユーザーは docker run --privileged コマンドを実行して、コンテナを root 権限で開始することができるからです。詳しくは こちらこちら (日本語訳ページ) を参照してください。

Docker Compose

Docker Compose (日本語訳ページ) は Docker Engine の代替 CLI フロントエンドです。(例として) docker run のオプションを使うスクリプトではなく、docker-compose.yml YAML ファイルを使ってコンテナのプロパティを指定します。これは、しばしば使用されたり複雑な設定を持っていたりするサービスを何度も設定する際に便利です。Docker Compose を使うには、docker-composeインストールしてください。

Docker Desktop

Docker Desktop は、Linux 仮想マシン内で Docker Engine を実行するプロプライエタリなデスクトップアプリケーションです。Kubernetes クラスタや脆弱性スキャナなどの追加の機能が含まれています。このアプリケーションは、macOS や Windows を使って Docker コンテナを開発するソフトウェア開発チームにとって便利です。このアプリケーションの Linux 移植は比較的新しく、Docker の CLI フロントエンドを補完します [3]。Arch 向けの実験的なパッケージは Docker によって直接提供されています; 詳細は マニュアル (日本語訳ページ) を見てください。残念ながら、そのパッケージには docker-compose パッケージと衝突するファイルが含まれているため、docker-compose がインストールされている場合はまずそれを削除する必要があります。

また、Docker Desktop を実行するには、Linux システム要件 (日本語訳ページ) を満たしている必要があります (要件には KVM による仮想化サポートが含まれています)。Gnome でのトレイアイコンを有効化するには、gnome-shell-extension-appindicator が必要です。

最後に、ファイル共有サポートは、ユーザとグループの id を /etc/subuid/etc/subgid を通してマッピングする必要があります。詳細は Docker Desktop For Linux のファイル共有に関する指示書 (日本語訳ページ) を見てください。

使用法

Docker は複数のパーツから成ります:

  • Docker デーモン (Docker Engine とも呼ばれています)。docker.service として実行されるプロセスです。Docker API を提供し、Docker コンテナを管理します。
  • docker CLI コマンド。ユーザがコマンドラインを通して Docker API と対話し、Docker デーモンを管理できるようにします。
  • Docker コンテナ。Docker API を通して要求された通りに Docker デーモンが起動・管理する、名前空間で隔離されたプロセスです。

通常、ユーザは docker CLI コマンドを実行することで Docker を使用します。コマンドは Docker デーモンにアクションの実行を要求し、Docker コンテナを管理します。クライアント (docker)、サーバ (docker.service)、コンテナ間の関係を理解することは、Docker を正しく管理するために重要です。

Docker デーモンが停止/再起動した場合、現在実行中の Docker コンテナもすべて停止/再起動されることに注意してください。

Docker API にリクエストを送信して、docker CLI コマンドを使わずに Docker デーモンを制御することも可能です。詳細は Docker API 開発ドキュメントを見てください。

使用法に関するドキュメントは the Docker Getting Started guide (日本語訳ページ) を見てください。

設定

設定ファイル /etc/docker/daemon.json を使うか、docker.service systemd ユニットにコマンドラインフラグを追加することで、Docker デーモンを設定することができます。Docker 公式ドキュメント (日本語訳ページ) によると、設定ファイルによる方法が推奨されています。コマンドラインフラグの方を使いたい場合は、systemd のドロップインファイル を使って、docker.serviceExecStart ディレクティブを上書きしてください。

daemon.json のオプションに関する詳細は、dockerd のドキュメント (日本語訳ページ) を見てください。

ストレージドライバー

ストレージドライバー (日本語訳ページ) は、Docker ホスト上でイメージとコンテナをどのように格納し管理するかを制御します。デフォルトの overlay2 ドライバはパフォーマンスが良く、最近の Linux カーネルとファイルシステムすべてで良い選択肢です。古い Linux カーネルとの互換性のために devicemapperaufs などのレガシーなドライバがありますが、Arch Linux の overlay2 ではなくこれらを使う利点はありません。

btrfsZFS のユーザは btrfszfs のドライバを使用できます。それぞれのドライバは、これらのファイルシステムのユニークな機能を活用します。詳細とステップ・バイ・ステップの説明は btrfs ドライバ (日本語訳ページ) と zfs ドライバ (日本語訳ページ) のドキュメントを見てください。

デーモンのソケット

デフォルトで、Docker デーモンは Unix ソケット /var/run/docker.sock を用いて Docker API を提供します。ほとんどの場合、この方法は適切です。

さらに TCP ソケットをリッスンするようにデーモンを設定できます。これにより、他のコンピュータからリモートで Docker API にアクセスできるようになります [4]。そうすることで、ホストマシン上の docker コマンドから Linux 仮想マシン (Windows や macOS システム上の Arch 仮想マシン) 上の Docker デーモンにアクセスできるようになり、便利です。

警告: デフォルトで Docker API は暗号化も認証もされません。TLS 暗号化や認証が有効化されていなかったり、認証 HTTP リバースプロキシや適切なDocker の追加設定 (日本語訳ページ) がなされていなかったりした場合、Docker デーモンへのリモート TCP アクセスは安全でない root アクセスと等価です。一般に、Docker API の TCP ソケットを有効化することは、セキュリティ上、高リスクであるとみなすべきです。

デフォルトの docker.service ファイルは -H フラグをデフォルトでセットします。そして、フラグと /etc/docker/daemon.json ファイルの両方にオプションが存在する場合、Docker は起動しません。なので、ソケットの設定を変更する最も単純な方法は、ドロップインファイルを使うことです。以下は、ポート 2376 上に TCP ソケットを追加します:

/etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376

systemd デーモンをリロードし、docker.service再起動して変更を適用してください。

HTTP プロキシ

HTTP プロキシを使うために設定すべきなのは、Docker デーモンと Docker コンテナです。

Docker デーモンのプロキシ設定

HTTP プロキシを設定するための systemd ドロップインユニットの設定に関する Docker ドキュメント (日本語訳ページ) を見てください。

Docker コンテナのプロキシ設定

docker CLI を使用して作成されたすべてのコンテナに対してプロキシを自動で設定する方法は プロキシ設定に関する Docker ドキュメント (日本語訳ページ) を見てください。

DNS の設定

Docker コンテナ内での DNS の動作に関するドキュメントや、DNS の設定のカスタマイズに関する情報は Docker の DNS に関するドキュメント (日本語訳ページ) を見てください。ほとんどの場合、ホストで設定されているリゾルバは、コンテナ内でも設定されています。

127.0.0.0/8 でホストされている DNS リゾルバのほとんどは、コンテナとホストのネットワーク名前空間の衝突により、サポートされていません。そのようなリゾルバは、コンテナの /etc/resolv.conf から削除されます。このせいで /etc/resolv.conf が空になる場合は、Google DNS が代わりに使用されます。

さらに、127.0.0.53 が、設定されている唯一のネームサーバである場合は、特殊なケースとして処理されます。この場合、Docker はリゾルバが systemd-resolved であると仮定し、/run/systemd/resolve/resolv.conf にある 上流の DNS リゾルバを使用します。

If you are using a service such as dnsmasq to provide a local resolver, consider adding a virtual interface with a link local IP address in the 169.254.0.0/16 block for dnsmasq to bind to instead of 127.0.0.1 to avoid the network namespace conflict.

イメージの置き場所

デフォルトでは、docker のイメージは /var/lib/docker に保存されます。置き場所は別のパーティションに移動することが可能です (例えば、イメージ用の専用のパーティションかディスクを使いたい場合)。ここでは、例として /mnt/docker にイメージを移動することにします。

まず、docker.service停止してください。すると、現在実行中のコンテナがすべて停止され、実行中のイメージはすべてアンマウントされます。これで、イメージを /var/lib/docker から目的の場所へ移動できるようになります (例: cp -r /var/lib/docker /mnt/docker)。

/etc/docker/daemon.json 内の data-root を設定してください:

/etc/docker/daemon.json
{
  "data-root": "/mnt/docker"
}

変更を適用するために、docker.service を再起動してください。

安全ではないレジストリ

プライベートレジストリに自己署名証明書を使うことにした場合、あなたが信頼すると宣言するまで Docker はその使用を拒否します。例えば、myregistry.example.com:8443 でホストされているレジストリのイメージを許可するには、/etc/docker/daemon.json ファイル内の insecure-registries を設定してください:

/etc/docker/daemon.json
{
  "insecure-registries": [
    "my.registry.example.com:8443"
  ]
}

変更を適用するために docker.service を再起動してください。

IPv6

Docker で IPv6 のサポートを有効化するには、いくつかやるべきことがあります。詳細は [5][6] を見てください。

まず、/etc/docker/daemon.jsonipv6 の設定を有効化し、特定の IPv6 サブネットを設定してください。ここでは、プライベート fd00::/80 サブネットを使用します。少なくとも 80 ビット以上のサブネットを使用してください。そうすることで、コンテナの IPv6 がコンテナの MAC アドレスで終わり、NDP ネイバーキャッシュの無効化問題を軽減できます。

/etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80"
}

変更を適用するために docker.service再起動してください。

最後に、コンテナがホストネットワークにアクセスできるようにするために、プライベート IPv6 サブネットの使用に起因するルーティングの問題を解決する必要があります。実際にトラフィックを取得するために、IPv6 NAT を追加してください:

# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE

これで、Docker で IPv6 が適切に有効化されているはずです。テストするには、以下を実行してください:

# docker run curlimages/curl curl -v -6 archlinux.org

以下のようなルールを追加することで、firewalld を使用できます:

# firewall-cmd --zone=public --add-rich-rule='rule family="ipv6" destination not address="fd00::1/80" source address="fd00::/80" masquerade'

ufw を使用する場合、まず Uncomplicated Firewall#Forward ポリシー に従って ipv6 フォワーディングを有効化する必要があります。次に、/etc/default/ufw を編集して、以下の行をアンコメントする必要があります:

/etc/ufw/sysctl.conf
net/ipv6/conf/default/forwarding=1
net/ipv6/conf/all/forwarding=1

そして、iptables のルールを追加できます:

# ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE

docker-compose を使用して作成された Docker コンテナには、対応するネットワークに対して networks 部で enable_ipv6: true を設定する必要がある場合があります。さらに、IPv6 サブネットの設定も必要になる場合があります。詳細は [7] (日本語訳ページ) を見てください。

ユーザ名前空間の隔離

デフォルトでは、Docker コンテナ内のプロセスはメインの dockerd デーモンと同じユーザ名前空間内で実行されます。つまり、コンテナは user_namespaces(7) の機能によって隔離されていません。これにより、ユーザーとグループ#パーミッションと所有権 に従って、コンテナ内のプロセスはホスト上に構成されたリソースにアクセスできます。これは互換性を最大化しますが、ホスト上のリソースに意図せずアクセスできてしまう特権昇格や情報漏えいの脆弱性が発見された場合は、セキュリティリスクが発生してしまいます (そのような脆弱性が2019年2月に公開され、パッチが適用されました)。

そのような脆弱性による影響は、ユーザ名前空間の隔離 (日本語訳ページ) を有効化することで軽減できます。これは、それぞれのコンテナを別のユーザ名前空間内で実行し、ユーザ名前空間内の UID と GID をホスト上の (通常は非特権の) 異なる UID/GID 範囲に割り当てます。

ノート:
  • メインの dockerd デーモンは依然としてホスト上で root として実行されます。Docker を rootless モード (日本語訳ページ) で実行するのは、これとは別の機能です。
  • コンテナ内のプロセスは、コンテナのイメージをビルドするために使用された Dockerfile 内の USER (日本語訳ページ) ディレクティブで定義されているユーザとして起動されます。
  • すべてのコンテナは、同じ UID/GID 範囲に割り当てられます。これにより、コンテナ間でボリュームを共有できることが保証されます。
  • ユーザ名前空間の隔離の有効化には、いくつかの制限 (日本語訳ページ) があります。
  • ユーザ名前空間の隔離を有効化すると、/var/lib/docker/ にある他の Docker オブジェクトだけでなく、既存のイメージやコンテナのレイヤーも効果的にマスクします。Docker はこれらのリソースの所有権を調整する必要があるからです。上流のドキュメントでは、既存の Docker 環境ではなく、新しい Docker 環境でこの機能を有効化することが推奨されています。

/etc/docker/daemon.json 内の userns-remap を設定してください。default は特殊な値で、再割当てによって dockremap という名前のユーザとグループを自動的に作成します。

/etc/docker/daemon.json
{
  "userns-remap": "default"
}

/etc/subuid/etc/subgid で、ユーザ名/グループ名、再割当てユーザとグループに割り当てる開始 UID/GID と UID/GID 範囲サイズを設定してください。以下の例では、165536 から始まる、範囲 65536 の UID と GID を dockremap ユーザ・グループに割り当てます。

/etc/subuid
dockremap:165536:65536
/etc/subgid
dockremap:165536:65536

設定を適用するために docker.service再起動してください。

この変更を適用したあと、デフォルトですべてのコンテナは隔離されたユーザ名前空間内で実行されます。docker コマンドに --userns=host フラグを渡すことで、特定のコンテナ上で再割当てを部分的に無効化できます。詳細は [8] (日本語訳ページ) を見てください。

Rootless Docker デーモン

ノート: Docker rootless は、非特権ユーザの名前空間 (CONFIG_USER_NS_UNPRIVILEGED) に依存しています。これは、linuxlinux-lts、そして linux-zen でデフォルトで有効化されています。他のカーネルのユーザはこれを有効化する必要があるかもしれません。これはセキュリティ上、重要な意味を持ちます。詳細については、セキュリティ#アプリケーションのサンドボックス化 をご覧ください。

Docker デーモン自体を通常ユーザとして実行するには、docker-rootless-extrasAUR パッケージをインストールしてください。

/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

ネイティブ overlay diff エンジンを有効化する

この記事またはセクションの正確性には問題があります。
理由: これはあなたのシステムでは必要ないかもしれません。metacopy=on redirect_dir=on は Arch Linux カーネルでデフォルトとなっていますが、これらの設定は実行時に無効化されると一部のユーザが報告しています。 (議論: トーク:Docker#)

デフォルトでは、Docker は Arch Linux 上でネイティブの overlay diff エンジンを使用できません。これにより、Docker イメージのビルドが遅くなります。頻繁にイメージをビルドする場合は、[9] で説明されているようにネイティブの diff エンジンを設定してください:

/etc/modprobe.d/disable-overlay-redirect-dir.conf
options overlay metacopy=off redirect_dir=off

その後、docker.service停止し、以下のように overlay モジュールを再読込してください:

# modprobe -r overlay
# modprobe overlay

そして、docker.service を再起動してください。

確認するには、docker info を実行して、Native Overlay Difftrue になっているかどうか見てください。

イメージ

Arch Linux

以下のコマンドは archlinux x86_64 イメージを pull します。これはネットワークなどを落とした Arch コア環境です:

# docker pull archlinux

README.md も見てください。

完全な Arch ベースは、上記からリポジトリを clone し、独自のイメージをビルドしてください。

$ git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git

パッケージ devtoolsfakechrootfakeroot はインストールされていることに注意してください。

ベースイメージをビルドするには:

$ make image-base

Alpine Linux

Alpine Linux は、(特に静的バイナリとしてコンパイルされたソフトウェアための) 小さなコンテナイメージとして人気の選択肢です。以下のコマンドは最新の Alpine Linux イメージを pull します:

# docker pull alpine

Alpine Linux は、ほとんどの Linux ディストリビューションで使用されている glibc libc 実装ではなく、musl libc 実装を使用します。Arch Linux は glibc を使用するので、Arch Linux ホストと Alpine Linux コンテナの間には機能的な違いが一定数存在し、ソフトウェアのパフォーマンスと正確性に影響を与えます。これらの違いのリストは、ここでドキュメント化されています。

Arch Linux (または glibc を使用する他のシステム) でビルドされた動的リンクのソフトウェアは、Alpine Linux (または異なる libc を使用する他のシステム) 上で実行すると、バグとパフォーマンス上の問題を生じる場合があります。例は、[10][11][12] を見てください。

Debian

次のコマンドは最新の debian イメージを pull します:

# docker pull debian

(各 Debian リリースの標準バージョンとスリムバージョンの療法を含む) 利用可能なタグの完全なリストは Docker Hub ページを見てください。

Distroless

Google は、パッケージマネージャやシェルなどの OS コンポーネントの無い最小イメージである distroless イメージをメンテナンスしています。これにより、ソフトウェアをパッケージングするためにイメージのサイズを非常に小さくできます。

イメージのリストと様々なプログラミング言語での使用法に関する指示は GitHub README を見てください。

ヒントとテクニック

実行中のコンテナの IP アドレスを取得する

実行中のコンテナの 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

コンテナ内でグラフィカルなプログラムを実行する

このセクションでは、グラフィカルなプログラム (OpenGL や Vulkan に依存しているものを含む) をホストの X サーバ上で実行できるようにする手順を説明します。

まず、(ホストのグラフィックハードウェアと互換性のある) 適切なドライバがコンテナ内にインストールされている必要があります。インストール手順はコンテナの種類に依存しますが、Arch Linux イメージベースのコンテナでは、OpenGL#インストールVulkan#インストール を参照してあなたのハードウェア固有のパッケージを調べてください。

次に、コンテナがホストの X サーバにアクセスできるようにしなくてはなりません。シングルユーザな環境では、ホスト上で Xhost を実行すれば簡単に行なえます。Xhost は、非ネットワークなローカル接続をアクセス制御リストに追加します:

$ xhost +local:

最後に、以下のパラメータを docker run に渡す必要があります:

  • -e "DISPLAY=$DISPLAY": ホストのディスプレイを示す環境変数 DISPLAY をコンテナ内で設定します。
  • --mount type=bind,src=/tmp/.X11-unix,dst=/tmp/.X11-unix: ホストの X サーバソケットをコンテナ内部に同じパスでマウントします。
  • --device=/dev/dri:/dev/dri: コンテナにホストの Direct Rendering Infrastructure デバイスへのアクセス権を与えます。

すべて正しくセットアップできたことを確認するには、コンテナ内で mesa-utils パッケージの glxgears や、vulkan-tools パッケージの vkcube を実行してみてください。

ブート時に Docker Compose プロジェクトを開始する

この記事またはセクションの正確性には問題があります。
理由: これは、compose.yml 内に restart: always がある場合は必須ではありません。[13] en:Talk:Docker#"Start Docker Compose projects on boot" Spurious? (議論: トーク:Docker#)

まず、サービスの名前でパラメータ化された Docker Compose のテンプレートユニットを作成してください (systemd.service(5) § SERVICE TEMPLATES を参照):

/etc/systemd/system/docker-compose@.service
[Unit]
Description=%i service with docker compose
Requires=docker.service
After=docker.service

[Service]
WorkingDirectory=/opt/%i
ExecStartPre=-/usr/bin/docker compose pull
ExecStart=/usr/bin/docker compose up --remove-orphans
ExecStop=/usr/bin/docker compose down
ExecReload=/usr/bin/docker compose pull
ExecReload=/usr/bin/docker compose up --remove-orphans

[Install]
WantedBy=multi-user.target

そして、実行したい各サービスに対して、Compose ファイルとその他必須のファイル (.env など) が入っているディレクトリを /opt/project_name に作成してください。[14]

最後に、docker-compose@project_name.service起動/有効化してください。

クロスコンパイルに buildx を使う

buildx CLI プラグイン は新しい BuildKit building toolkit (日本語訳ページ) を使用します。buildx インターフェイスはマルチプラットフォームなイメージのビルドをサポートしています (ホストのアーキテクチャ以外も)。

イメージのクロスコンパイルには QEMU が必要です。Docker 内で QEMU の静的ビルドをセットアップする方法については、multiarch/qemu-user-static イメージの情報を見てください。あるいは、QEMU をホストのシステム上でセットアップして、Docker と一緒に使う方法については、QEMU#x86_64 から arm/arm64 環境への chrooting を見てください。どちらの場合にせよ、あなたのシステムはゲストアーキテクチャのユーザモードエミュレート用に設定されます。

$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker                  
  default default         running linux/amd64, linux/386, linux/arm64, linux/riscv64, linux/s390x, linux/arm/v7, linux/arm/v6

NVIDIA GPU で GPU アクセラレートされた Docker コンテナを動かす

NVIDIA Container Toolkit を使う (推奨)

Docker バージョン 19.03 より、NVIDIA GPU が Docker デバイスとしてネイティブにサポートされています。NVIDIA GPU を活用するコンテナの実行方法として NVIDIA Container Toolkit が推奨されています。

nvidia-container-toolkitAUR パッケージをインストールしてください。次に、docker を再起動してください。これで、--gpus オプションを使うことで、NVIDIA GPU を使用するコンテナを実行できるようになります:

# docker run --gpus all nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi

コンテナ内でいくつの GPU を有効化するかを指定するには:

# docker run --gpus 2 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi

どの GPU を使用するかを指定するには:

# docker run --gpus '"device=1,2"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi

あるいは

# docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi
この記事またはセクションの正確性には問題があります。
理由: 以下のエラーが発生する場合のより詳細な情報が必要です。これは機能するはずです。[15][リンク切れ 2023-04-23] を参照してください。en:Talk:Docker#GPU accelerated Docker Nvidia (議論: トーク:Docker#)

上記のコマンドを使っていて、Failed to initialize NVML: Unknown Error のようなエラーが発生する場合、GPU をより具体的に指定してみてください:

# docker run --gpus all --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm --device /dev/nvidia0:/dev/nvidia0 nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi

コンテナで使用する機能 (グラフィックス、計算、...) を指定するには (とはいえ、この方法が使用されるのは稀です):

# docker run --gpus all,capabilities=utility nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi

詳細は README.mdWiki を見てください。

NVIDIA Container Runtime を使う

nvidia-container-runtimeAUR パッケージをインストールしてください。次に、/etc/docker/daemon.json を編集して NVIDIA ランタイムを登録してください:

/etc/docker/daemon.json
{
  "runtimes": {
    "nvidia": {
      "path": "/usr/bin/nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}

そして、docker を再起動してください。

ランタイムは、dockerd にコマンドラインオプションを渡すことでも登録できます:

# /usr/bin/dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime

その後、GPU アクセラレートされたコンテナを実行するには:

# docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi

あるいは (以下の方法は Docker バージョン 19.03 およびそれ以降が必要です):

# docker run --gpus all nvidia/cuda:9.0-base nvidia-smi

README.md も見てください。

CUDA 付き Arch Linux イメージ

以下の Dockerfile を使うことで、CUDA 付きのカスタム Arch Linux イメージをビルドできます。ホスト上で pacman パッケージをキャッシュするために Dockerfile frontend syntax 1.2 を使用します。Docker イメージをビルドする前に、クライアント上で DOCKER_BUILDKIT=1 環境変数を設定する必要があります。

Dockerfile
# syntax = docker/dockerfile:1.2

FROM archlinux

# install packages
RUN --mount=type=cache,sharing=locked,target=/var/cache/pacman \
    pacman -Syu --noconfirm --needed base base-devel cuda

# configure nvidia container runtime
# https://github.com/NVIDIA/nvidia-container-runtime#environment-variables-oci-spec
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility

Docker とイメージの削除

Docker を完全に削除したい場合は以下の手順に従ってください。

ノート: コマンドを実行する前にどういう意味なのか考えてください。何も考えずにコピーアンドペーストしてはいけません。

実行中のコンテナをチェックする:

# docker ps

削除するために、ホスト上で実行中のコンテナをすべて表示する:

# docker ps -a

実行中のコンテナを停止する:

# docker stop <CONTAINER ID>

依然として実行中のコンテナを kill する:

# docker kill <CONTAINER ID>

ID でリストされたコンテナを削除する:

# docker rm <CONTAINER ID>

Docker イメージをすべて表示する:

# docker images

ID でイメージを削除する:

# docker rmi <IMAGE ID>

コンテナに関連付けられていない (ダングリング) すべてのイメージ、コンテナ、ボリューム、ネットワークを削除する:

# docker system prune

停止中のコンテナと未使用のイメージ (ダングリングイメージでないもの) を追加で削除するには、-a フラグをコマンドに追加してください:

# docker system prune -a

すべての Docker データを削除する (ディレクトリを削除する):

# rm -R /var/lib/docker

トラブルシューティング

systemd-networkd を使用していると、docker0 ブリッジが IP を取得できない / コンテナからインターネットにアクセスできない

Docker はグローバルに IP フォワーディングを有効化しようと試みますが、デフォルトでは、定義されているネットワークプロファイルのグローバルな sysctl 設定を systemd-networkd が上書きしてしまいます。ネットワークプロファイルに IPForward=yes を設定してください。詳しくは インターネット共有#パケット転送の有効化 を参照してください。

systemd-networkd が Docker によって作成されたネットワークインターフェイスを管理しようとする場合 (例えば、Match セクションに Name=* を設定した場合)、接続の問題が発生する可能性があります。それらのインターフェイスの管理を無効化してみてください。例えば、networkctl list を実行すると、SETUP 列ですべての Docker によって作成されたネットワークは unmanaged と表示される必要があります。

ノート:
  • systemd-networkd.serviceiptables.service再起動したときは docker.service再起動する必要があります。
  • また、デフォルトで nftables が docker の接続をブロックする可能性も考慮してください。nft list ruleset を使ってブロックしているルールを確認してください。nft flush chain inet filter forward で一時的に全ての転送ルールを削除できます。変更を永続化するには /etc/nftables.conf を編集してください。設定ファイルからルールをリロードするために nftables.service再起動することを忘れないでください。Docker での nftables サポートに関する詳細は [16] を見てください。

デフォルトで使用できるプロセスやスレッドの数が少なすぎる

以下のようなエラーメッセージが表示される場合:

# Java の場合
java.lang.OutOfMemoryError: unable to create new native thread
# C、bash などの場合
fork failed: Resource temporarily unavailable

systemd によって許可されるプロセスの数を調整する必要があります。以下のように docker.service編集してください:

[Service]
TasksMax=infinity

より詳細な背景情報は、systemd-system.conf(5) § OPTIONSDefaultLimitNPROC を見てください。また、systemd.resource-control(5) § OPTIONSTasksMax も見てください。

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 に指定してはいけません。
ノート: XFS のクォータと Linux 標準のディスククォータには違いが存在します。[17] は読む価値があるかもしれません。

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 のブリッジネットワークが壊れる

この問題は、Docker のスクリプトがいくつかの iptables ルールを追加し、それ自体のインターフェイス以外のインターフェイスのフォワーディングをブロックしてしまうというものです。これは既知の問題です。

以下の解決策では、br0 をあなたのブリッジ名に置き換えてください。

最も速い解決策は (しかし、これは Docker の iptabkes 自己追加調整機能をすべて無効化してしまいます。これは望ましくない場合があります。):

/etc/docker/daemon.json
{
  "iptables": false
}

KVM 用に設定されたネットワークブリッジがすでに存在する場合、Docker にそのことを伝えることで解決できる場合があります。[18] を見て、以下のように docker の設定を変更してください:

/etc/docker/daemon.json
{
  "bridge": "br0"
}

上記の設定がうまく行かない場合や、UFW のようなマネージャ、あるいは iptables を通して直接この問題を解決したい場合、以下を追加してください:

iptables -I FORWARD -i br0 -o br0 -j ACCEPT

更に詳しい解決策は ここ にあります。

Docker Hub からのイメージ取得に速度制限が掛かる

2020年11月1日より、無名アカウントや無料アカウントによる Docker Hub からのダウンロードには速度制限がかかるようになりました。詳細は 速度制限に関するドキュメント を見てください。

認証されていない速度制限はソースの IP によって追跡され、認証済みの速度制限はアカウントによって追跡されます。

速度制限を超過する必要がある場合、有料プランに登録するか、必要なイメージを別のイメージレジストリでミラーすることで可能です。自分自身のレジストリをホストする (日本語訳ページ) こともできますし、Amazon ECRGoogle Container RegistryAzure Container RegistryQuay Container Registry などのクラウドでホストされているレジストリを使うこともできます。

イメージをミラーするには、Docker CLI のサブコマンド pulltagpush を使ってください。例えば、Nginx イメージの 1.19.3 タグを、cr.example.com でホストされているレジストリでミラーするには:

$ docker pull nginx:1.19.3
$ docker tag nginx:1.19.3 cr.example.com/nginx:1.19.3
$ docker push cr.example.com/nginx:1.19.3

その後に、そのミラーからイメージを pull または実行することができます:

$ docker pull cr.example.com/nginx:1.19.3
$ docker run cr.example.com/nginx:1.19.3

iptables (legacy): unknown option "--dport"

この記事またはセクションの正確性には問題があります。
理由: Nftables#Docker と共に使う では、iptables-nft を使用しないことが推奨されています。 (議論: トーク:Docker#)

コンテナの実行中にこのエラーが発生する場合は、iptables (legacy) の代わりに iptables-nft をインストールして、再起動してください [19]

docker ログイン時に "Your password will be stored unencrypted"

デフォルトでは、Docker はレジストリパスワードを保存するために passsecretservice バイナリの使用を試みます。これらのバイナリが見つからない場合、Docker はパスワードを平文 (base64 エンコード) で $HOME/.docker/config.json に保存し、ログイン成功後に以下のメッセージを出力します:

$ WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.

Secret Service Freedesktop DBUS API を実装しているパスワードマネージャ (KDE の KWallet や GNOME の gnome-keyring など) を使用している場合、パスワードをパスワードマネージャに保存するための docker-credentials-secretserviceAUR パッケージをインストールすることができます。

"Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network"

Sometimes if you use a lot of Docker projects (ex. using docker-compose) it can happens that you run out of available IPs for Docker containers triggering the error:

Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

As found on this Docker issue, the defaults are:

Type Default Size Default Pool
local /16 172.17.0.0/12
local* /20 192.168.0.0/16

This can be easily fixed increasing the Docker IP space by configuring default-address-pools in /etc/docker/daemon.json increasing the size value from 16 to 24 on the first IP range, keeping the second one unaltered to avoid ip collision on the local network:

/etc/docker/daemon.json
{
  ...
  "default-address-pools" : [
    {
      "base" : "172.17.0.0/12",
      "size" : 24
    },
    {
      "base" : "192.168.0.0/16",
      "size" : 24
    }
  ]
}

Restart docker.service to apply changes.

More details and technical explanations can be found on the following excellent article: The definitive guide to docker's default-address-pools option.

Slow golang compilation

Due to a ulimit configuration, building a docker image and its dependances with makepkg is very slow (stuck at "Entering fakeroot environment..." step).

It is related to [20] and [21].

You can add --ulimit "nofile=1024:524288" to your docker build option or create/edit:

/etc/docker/daemon.json
{
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Soft": 1024,
      "Hard": 524288
    }
  }
}

参照

翻訳ステータス: このページは en:Docker の翻訳バージョンです。最後の翻訳日は 2023-05-12 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。