Journey

技術に関することと覚書と

Arch linuxでdockerをrootlessモードで動かす

どこかでdockerがrootlessモードを追加するみたいなことは聞いてましたが、いつの間にか追加されていたようです。 なのでrootlessモードで動かしてみようと思います

docs.docker.com

※実験的な機能なので本番環境などで使用する場合は注意してください

環境

❯ lsb_release -a
LSB Version:    1.4
Distributor ID: Arch
Description:    Arch Linux
Release:    rolling
Codename:   n/a

❯ docker -v
Docker version 19.03.5-ce, build 633a0ea838

前提条件

  • newuidmapnewgidmap が必要なみたいです。筆者は入ってました。入ってない人はAURにあると思うので入れましょう。
  • /etc/subuid and /etc/subgid should contain at least 65,536 subordinate UIDs/GIDs for the user. In the following example, the user testuser has 65,536 subordinate UIDs/GIDs (231072-296607).

とありますが、よくわかりません。とりあえずリンク先を参考に以下のようにしました。今度調べます。

sudo touch /etc/subuid /etc/subgid
sudo usermod -v 100000-165535 -w 100000-165535 vagrant

第14回 LXCの構築・活用 [2] ― コンテナを作成・構築する:LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術|gihyo.jp … 技術評論社

  • archlinux固有の前提条件として
Add kernel.unprivileged_userns_clone=1 to /etc/sysctl.conf (or /etc/sysctl.d) and run sudo sysctl --system

が必要みたいなので言われたとおりにやります

❯ sudo touch /etc/sysctl.d/sysctl.conf
❯ sudo echo kernel.unprivileged_userns_clone=1 >> /etc/sysctl.d/sysctl.conf
❯ sudo sysctl --system
* Applying /usr/lib/sysctl.d/10-arch.conf ...
fs.inotify.max_user_instances = 1024
fs.inotify.max_user_watches = 524288
* Applying /usr/lib/sysctl.d/50-coredump.conf ...
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.promote_secondaries = 1
net.core.default_qdisc = fq_codel
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_regular = 1
fs.protected_fifos = 1
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
kernel.pid_max = 4194304
* Applying /etc/sysctl.d/sysctl.conf ...
kernel.unprivileged_userns_clone = 1

最後の行を見てると成功してるっぽいですね

インストール

前提条件ができたので早速インストールしてみます

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

# Docker binaries are installed in /home/vagrant/bin
# WARN: dockerd is not in your current PATH or pointing to /home/vagrant/bin/dockerd
# Make sure the following environment variables are set (or add them to ~/.bashrc):\n
export PATH=/home/vagrant/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock

#
# To control docker service run:
# systemctl --user (start|stop|restart) docker
#

お、なにかでましたね。 書かれているとおりにやりましょう。

sudo echo export PATH=/home/vagrant/bin:$PATH >> ~/.zshrc
sudo echo export DOCKER_HOST=unix:///run/user/1000/docker.sock >> ~/.zshrc
source ~/.zshrc
systemctl --user start docker

これで終わりっぽいですね 早速試してみましょう

❯ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

お、動いた imagesを確認してみます

❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

あれ、なにもない。sudo docker images の方はどうなってるでしょうか

❯ sudo docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
<none>                                    <none>              5c617ac3beaf        2 days ago          496MB
composer                                  latest              d103d14ad00a        2 days ago          165MB
<none>                                    <none>              cab68bb4c619        4 days ago          495MB
<none>                                    <none>              087354b9e59b        4 days ago          486MB
<none>                                    <none>              b8ddc88295c1        6 days ago          496MB
<none>                                    <none>              237c179d71c0        7 days ago          496MB
<none>                                    <none>              52a40879c553        12 days ago         495MB
<none>                                    <none>              0c6d0038c226        2 weeks ago         353MB
postgres                                  latest              4a82a16ee75c        2 weeks ago         394MB
ruby                                      2.6.5-alpine        3304101ccbe9        2 months ago        50.9MB
cfcommunity/slack-notification-resource   latest              a43829b960aa        6 months ago        20.7MB
node                                      11.15.0-alpine      f18da2f58c3d        6 months ago        75.5MB

sudo docker だと色々ありますね。どうやらリソース自体が独立したものになっているようです。

次にhello worldしてみましょう

❯ time docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/


real    0m7.560s
user    0m0.033s
sys 0m0.012s

sudoなしで動きました。どうやら成功してるみたいです sudo docker run hello-world で試してみましょう。

❯ time sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/


real    0m8.331s
user    0m0.019s
sys 0m0.031s

同じような感じで成功しました。 では実際に使用しているdocker-compose.ymlファイルで試してみます。

まずはrootless dockerから

❯ time docker-compose build --parallel
real    3m13.673s
user    0m0.946s
sys 0m0.278s

次にいつものdockerです

❯ time sudo docker-compose build --parallel
real    2m40.807s
user    0m0.908s
sys 0m0.149s

ある程度差が有るみたいですが、十分実用できそうです

まとめ

sudoなし、かつdockerグループにユーザーを追加することなくdockerコマンドを使用することに成功しました。一旦rootless dockerをメインに使ってみたいと思います。 もし使用する場合は、いろいろな制限がまだ有るみたいなので、そのへんにも注意して使用しましょう。

※追記 実際に使ってみるとパーミッションエラーなど、いろいろ詰まりそうだったので、やっぱりメインで使うのはやめとこうと思います