Rootless Docker 入門 — root なしでコンテナを安全に動かす

Rootless Docker を使うと、root 権限なしで Docker デーモンとコンテナを実行できます。この記事では仕組みから導入手順、業務での使いどころまで解説します。

Rootless Docker とは

通常の Docker は dockerd デーモンを root ユーザーで起動します。そのため、Docker グループに属するユーザーは実質的に root 相当の権限を持つことになります。

Rootless Docker は Docker 20.10 から正式サポートされた機能で、デーモンもコンテナも非 root ユーザーのプロセスとして動作します。Linux の user namespacerootlesskit を活用して、コンテナ内では 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

または socatiptables でポートフォワードする方法もあります。

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 との比較

項目通常の DockerRootless 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 以降の環境であれば多くの制約はデフォルトで解消されています。