Rootless Docker 入門 — root なしでコンテナを安全に動かす
Rootless Docker を使うと、root 権限なしで Docker デーモンとコンテナを実行できます。この記事では仕組みから導入手順、業務での使いどころまで解説します。
Rootless Docker とは
通常の Docker は dockerd デーモンを root ユーザーで起動します。そのため、Docker グループに属するユーザーは実質的に root 相当の権限を持つことになります。
Rootless Docker は Docker 20.10 から正式サポートされた機能で、デーモンもコンテナも非 root ユーザーのプロセスとして動作します。Linux の user namespace と rootlesskit を活用して、コンテナ内では root に見えても、ホスト上では一般ユーザーとして動作します。
通常の Docker:
ホスト: root → dockerd → コンテナ
Rootless Docker:
ホスト: 一般ユーザー → rootlesskit → dockerd → コンテナ
メリット
- セキュリティの向上: デーモンやコンテナが侵害されても、ホストへの影響が一般ユーザー権限に限定される
- マルチユーザー環境での隔離: 各ユーザーが独自の Docker デーモンを持つため、他ユーザーのコンテナにアクセスできない
- CI/CD 環境の安全性: root を必要としないため、最小権限の原則を守れる
- コンテナ内 root の影響を最小化: コンテナが root で動いていても、ホスト上では一般ユーザーの権限に変換される
デメリット・制限事項
- 一部のネットワーク機能が使えない: ポート 1024 未満のバインドにはデフォルトでは制限がある(
sysctlで変更可能) - overlay2 ストレージドライバーが制限される: カーネル 5.11 未満では
fuse-overlayfsを使う必要がある - cgroup v2 が必要: リソース制限(CPU・メモリ)には cgroup v2 が必要
- パフォーマンスオーバーヘッド: user namespace の変換処理が入るため、わずかなオーバーヘッドがある
- 一部の Docker 機能が使えない:
--privilegedコンテナや AppArmor のカスタムプロファイルなど
前提条件の確認
# カーネルバージョン(5.11 以上推奨)
uname -r
# newuidmap / newgidmap が存在するか
which newuidmap newgidmap
# /etc/subuid, /etc/subgid に自分のエントリがあるか
grep $USER /etc/subuid /etc/subgid
エントリがない場合は追加します。
sudo usermod --add-subuids 100000-165535 $USER
sudo usermod --add-subgids 100000-165535 $USER
インストール手順(Ubuntu 22.04 / 24.04)
1. 依存パッケージのインストール
sudo apt-get install -y uidmap dbus-user-session slirp4netns
2. Rootless インストールスクリプトの実行
# Docker がすでにインストール済みの場合
dockerd-rootless-setuptool.sh install
# Docker 未インストールの場合は公式スクリプトで一括セットアップ
curl -fsSL https://get.docker.com/rootless | sh
3. 環境変数の設定
.bashrc または .zshrc に追加します。
export PATH=/home/$USER/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
設定を反映します。
source ~/.bashrc
4. systemd ユーザーサービスとして起動
systemctl --user start docker
systemctl --user enable docker # ログイン時に自動起動
5. 動作確認
docker version
docker run --rm hello-world
ポート 1024 未満へのバインド
デフォルトでは 1024 未満のポートはバインドできません。以下で許可できます。
# 一時的に許可(再起動で元に戻る)
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
# 永続化
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/99-rootless.conf
sudo sysctl --system
または socat や iptables でポートフォワードする方法もあります。
cgroup v2 でリソース制限を使う
Ubuntu 22.04 以降はデフォルトで cgroup v2 が有効です。確認します。
cat /sys/fs/cgroup/cgroup.controllers
# cpu io memory pids が表示されれば OK
cgroup v2 が有効な場合、通常通りリソース制限が使えます。
docker run --memory=512m --cpus=1 nginx
ハマりやすいポイント
DOCKER_HOST を忘れる
Rootless Docker は /run/user/$(id -u)/docker.sock をソケットとして使います。DOCKER_HOST を設定しないと通常の /var/run/docker.sock に接続しようとしてエラーになります。
# エラー例
Cannot connect to the Docker daemon at unix:///var/run/docker.sock
# 解決策
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
ログアウト時にコンテナが停止する
デフォルトではログアウトするとユーザーサービスも停止します。loginctl enable-linger で常駐させます。
sudo loginctl enable-linger $USER
bind mount でパーミッションエラー
user namespace の UID マッピングにより、ホストのファイルがコンテナ内で別 UID に見えることがあります。
# コンテナ内のプロセスの UID に合わせてホスト側もディレクトリを作る
mkdir -p /home/$USER/data
chmod 777 /home/$USER/data
SSH セッションで DBUS_SESSION_BUS_ADDRESS がない
SSH で接続した場合、systemd ユーザーセッションが起動していないと Docker が動かないことがあります。
# systemctl --user が使えない場合
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
業務での使いどころ
共有 Linux サーバーでの開発環境分離
チームメンバーが同一サーバーを使う場合、各自が独立した Docker 環境を持てます。Aさんのコンテナが Bさんに影響を与えません。
# ユーザー A の環境
ssh userA@server
docker ps # userA のコンテナのみ表示
# ユーザー B の環境
ssh userB@server
docker ps # userB のコンテナのみ表示
CI/CD パイプラインでの安全なコンテナビルド
GitHub Actions や Jenkins などで root 不要のコンテナビルドが実現できます。DinD(Docker in Docker)より安全です。
セキュリティ要件の厳しい本番環境
PCI DSS や SOC2 などのコンプライアンス要件で最小権限の原則が求められる場合、Rootless Docker は有効な選択肢です。
通常の Docker との比較
| 項目 | 通常の Docker | Rootless Docker |
|---|---|---|
| デーモンの権限 | root | 一般ユーザー |
| セキュリティリスク | 高(root 相当) | 低(ユーザー権限) |
| ポート < 1024 | 使用可 | 要設定 |
| overlay2 ストレージ | 使用可 | カーネル 5.11+ |
| cgroup リソース制限 | 使用可 | cgroup v2 必要 |
| セットアップの手間 | 少ない | やや多い |
| マルチユーザー対応 | 要注意 | 適している |
Ubuntu 23.10 以降の注意点
Ubuntu 23.10 以降、Canonical が AppArmor とカーネルのデフォルト設定を強化し、非特権ユーザー namespace がデフォルトで制限されるようになりました。これにより Rootless Docker がそのまま動かないケースがあります。
# unprivileged user namespace が有効か確認
cat /proc/sys/kernel/unprivileged_userns_clone
# 1 なら OK、0 なら有効化が必要
# 有効化(Ubuntu 24.04+)
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
または AppArmor プロファイルを調整する方法もあります。詳しくは Docker の公式トラブルシューティング を参照してください。
まとめ
Rootless Docker はセキュリティと隔離性の面で大きなメリットをもたらします。特に共有サーバーや CI/CD 環境、セキュリティ要件の高い環境では積極的に採用を検討する価値があります。ポート制限や cgroup v2 の要件など制約もありますが、Ubuntu 22.04 以降の環境であれば多くの制約はデフォルトで解消されています。