Rootless Docker 完全ガイド — 仕組み・セットアップ・注意点まとめ

Rootless Docker を使うと、root 権限なしで Docker デーモンを動かせるため、ホストへの影響を最小限に抑えたセキュアなコンテナ実行が実現できます。本記事では仕組みの基礎から実際のセットアップ・よくあるハマりどころまでを実務目線でまとめます。

Rootless Docker とは

通常の Docker デーモン (dockerd) は root ユーザーとして動作します。これはコンテナを特権なしで隔離するうえで必要な権限ですが、ホストシステムへの影響範囲が広くなるというリスクがあります。

Rootless Docker は、Docker デーモンおよびコンテナを一般ユーザー権限内で動作させる仕組みです。2020 年の Docker 20.10 から正式サポートされました。

通常の Docker:
  root  → dockerd → container

Rootless Docker:
  一般ユーザー → rootlesskit → dockerd → container

仕組み

rootlesskit

rootlesskit は「Linux の名前空間を使って、あたかも root であるかのような環境」を一般ユーザーに提供するラッパーツールです。Rootless Docker の根幹をなすコンポーネントで、dockerd はこの中で動作します。

User Namespace

Linux カーネルの user namespace により、コンテナ内の UID 0(root)をホスト上の一般ユーザー UID にマッピングします。

コンテナ内:  UID 0 (root)
                 ↕  /etc/subuid マッピング
ホスト上:    UID 1000 (alice)  →  UID 100000〜165535

マッピングの設定ファイル:

# /etc/subuid
alice:100000:65536

# /etc/subgid
alice:100000:65536

cgroup v2

cgroup v2 では、一般ユーザーが自身のプロセスに対してリソース制限を設定できます(delegation 機能)。Rootless Docker はこれを利用して、root なしでもメモリ・CPU 制限が効くようになっています。

# cgroup v2 が有効かどうかの確認
ls /sys/fs/cgroup/cgroup.controllers
# cpu cpuset hugetlb io memory pids  ← 表示されれば cgroup v2

mount | grep cgroup2
# cgroup2 on /sys/fs/cgroup type cgroup2 ...

ネットワーク (slirp4netns / pasta)

root なしでは TUN/TAP デバイスを直接扱えないため、ユーザー空間のネットワークスタック実装が使われます。

  • slirp4netns: 従来の標準実装。NAT 方式でホストネットワークに接続。
  • pasta: より新しい実装で slirp4netns より高速。Docker 27 以降で推奨。

インストール・セットアップ

前提条件の確認

# カーネルバージョン (5.11+ 推奨)
uname -r

# cgroup v2 有効確認
cat /proc/1/cgroup
# 0::/ と表示されれば cgroup v2

# subuid/subgid の確認
grep $(whoami) /etc/subuid /etc/subgid

必要パッケージのインストール

sudo apt update
sudo apt install -y \
  uidmap \
  dbus-user-session \
  fuse-overlayfs \
  slirp4netns
パッケージ用途
uidmapnewuidmap / newgidmap コマンドを提供
dbus-user-sessionユーザーセッション用 D-Bus(systemd 連携に必要)
fuse-overlayfsoverlay2 ストレージドライバの代替
slirp4netnsユーザー空間ネットワーク

Rootless Docker のインストール

方法 1: 公式スクリプトを使う(推奨)

curl -fsSL https://get.docker.com/rootless | sh

スクリプト実行後、指示に従って環境変数を設定します。

# ~/.bashrc や ~/.zshrc に追記
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

方法 2: Docker CE パッケージから移行する

sudo apt install -y docker-ce-rootless-extras
dockerd-rootless-setuptool.sh install

systemd ユーザーサービスとして登録

systemctl --user enable docker
systemctl --user start docker

# ログイン不要で起動させる(サーバー用途)
sudo loginctl enable-linger $(whoami)

# 動作確認
systemctl --user status docker
docker info

メリット・デメリット

メリット説明
セキュリティ向上デーモン侵害時でもホスト root を奪取されにくい
マルチユーザー対応各ユーザーが独立した Docker 環境を持てる
CI 環境での利用特権不要のため SaaS CI などでも動作しやすい
デメリット内容
1024 以下のポートはバインドできないルーティングの工夫が必要
overlay2 が使えない環境があるfuse-overlayfs にフォールバック(速度低下)
ネットワーク性能がやや低下slirp4netns/pasta 経由のオーバーヘッド

よくあるハマりどころ

1. 1024 以下のポートがバインドできない

# エラー例
docker run -p 80:80 nginx
# Error response from daemon: driver failed programming external connectivity

# 対策: ポート番号を変える
docker run -p 8080:80 nginx

# または sysctl で解放する
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80

2. overlay2 ストレージドライバが使えない

docker info | grep "Storage Driver"
# Storage Driver: fuse-overlayfs  ← overlay2 より遅い

# Ubuntu 22.04+ で overlay2 を有効にする
echo '{ "storage-driver": "overlay2" }' > ~/.config/docker/daemon.json
systemctl --user restart docker

3. DOCKER_HOST 環境変数の設定忘れ

# 症状
docker ps
# Cannot connect to the Docker daemon at unix:///var/run/docker.sock

# 解決
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

4. ボリュームマウント時の UID/GID ズレ

# 症状: マウントしたディレクトリに書き込めない
docker run -v $HOME/data:/app/data myimage
# permission denied: /app/data/output.txt

# 解決: コンテナ実行ユーザーを明示する
docker run -u $(id -u):$(id -g) -v $HOME/data:/app/data myimage

5. systemd linger 未設定でログアウト後にコンテナが止まる

sudo loginctl enable-linger $(whoami)

loginctl show-user $(whoami) | grep Linger
# Linger=yes  ← これが表示されれば OK

業務での使いどころ

CI/CD 環境

GitHub Actions self-hosted runner や Jenkins エージェントで root なし Docker が使えます。

jobs:
  build:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        env:
          DOCKER_HOST: unix://${{ env.XDG_RUNTIME_DIR }}/docker.sock
        run: docker build -t myapp .

Podman との使い分け

ツールrootless 対応特徴
Rootless DockerDocker エコシステムとの互換性が高い
Podman rootlessデーモンレスで systemd ソケットアクティベーション対応
  • Podman が向く場合: デーモンプロセスを持ちたくない、RHEL/Fedora 環境
  • Rootless Docker が向く場合: 既存の Docker Compose ワークフローをそのまま使いたい

まとめ

Rootless Docker は「セキュリティを高めたいが Docker エコシステムを手放したくない」という場面に有効な選択肢です。

  • User Namespace + rootlesskit でユーザー権限内に Docker デーモンを閉じ込める
  • cgroup v2 delegate でリソース制限も一般ユーザーから設定可能
  • ポートや overlay2、DOCKER_HOST などのハマりどころは事前に把握しておく
  • Ubuntu 22.04+ ならほぼ追加設定なしで動作するため、まず開発環境で試してみることをおすすめします