Docker Rootless modeを使う (ユーザー権限でsystemctlを動かす)

DockerにはRootless modeというものがあり、デーモンとクライアントをユーザー権限で動作させることができます。これをインストールする際にユーザー権限systemctlの辺りで嵌ってしまったのでメモを残しておきます。

環境

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:        20.04
Codename:       focal
$ uname -a
Linux l1 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

上手くいくインストール方法

sudoできるユーザーでuidmapをインストール

$ sudo apt install -y uidmap

rootでユーザーを作って、ログインする

ここではaliceというユーザーを作成しました。

# adduser alice
# login -f alice

ユーザー権限でsystemctlを動かせるようにする

このままではユーザー権限でsystemctlを動かせません。

$ systemctl --user status
Failed to connect to bus: No such file or directory

そのため、以下のように準備をします。

$ loginctl enable-linger alice
$ export XDG_RUNTIME_DIR=/run/user/$(id -u alice)

これでaliceの権限でsystemctlが動きます。

$ systemctl --user status
● l1
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Wed 2021-06-09 13:27:05 UTC; 12s ago
   CGroup: /user.slice/user-1001.slice/user@1001.service
           └─init.scope 
             ├─53454 /lib/systemd/systemd --user
             └─53455 (sd-pam)

Rootless Dockerをインストールする

後は以下のドキュメントの通りに進めれば大丈夫です。

Docker デーモンをルート以外のユーザで実行(Rootless モード) — Docker-docs-ja 19.03 ドキュメント

$ curl -fsSL https://get.docker.com/rootless | sh
< 略 >
export PATH=/home/alice/bin:$PATH
export DOCKER_HOST=unix:///run/user/1001/docker.sock

最後に表示されたexport.bashrcに追記して、反映させます。

$ vim .bashrc # 上記のexportを追記
$ source .bashrc

デーモンの起動・自動起動の設定

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

Dockerが動作することを確認する

試しにalpineを動かしてみます。

$ docker run -it alpine sh
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
540db60ca938: Pull complete 
Digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f
Status: Downloaded newer image for alpine:latest
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var

インストール出来てますね!

失敗した方法

上の手順の「ユーザー権限でsystemctlを動かせるようにする」をやらずに、「Rootless Dockerをインストールする」を進めたのが原因のようです。これで進めるとsystemctl --user start dockerを実行した際に、Failed to connect to bus: No such file or directoryというエラーが出ます。

このエラーについて、以下のドキュメントには次のように書いてあります。

Docker デーモンをルート以外のユーザで実行(Rootless モード) — Docker-docs-ja 19.03 ドキュメント

sudo -iu <ユーザ名> の代わりに、 pam_systemd を使ってログインする必要があります。たとえば、

  • グラフィック・コンソールを通してログイン
  • ssh <ユーザ名>@localhost
  • machinectl shell <ユーザ名>@

と書いてありました。しかし、リモートサーバーではグラフィックコンソールは使えないですし、sshでログインできるユーザーは制限することが多いですし、このためだけにmachinectlをインストールするのも気が進みません。 ここで紹介した方法の方が幾分スマートなのではないかと思います。