Docker

DockerにRootlessモードが入ったぞ!という話


概要

DockerのデーモンをLinux上で実行するためには、通常はroot権限を渡す必要がありましたが、Docker Meetup TokyoのオーガナイザーをやっているNTTの須田さんによるこちらのコミットによって、Dockerをroot権限なしに実行できるようになりました。

より詳しくは、Dockerのエンジニアリングブログを御覧ください。


試してみた


Rootless dockerのインストール


  • 試した環境


    • Ubuntu 18.04



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

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 54.0M 100 54.0M 0 0 9624k 0 0:00:05 0:00:05 --:--:-- 11.9M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13.3M 100 13.3M 0 0 5584k 0 0:00:02 0:00:02 --:--:-- 5582k
# systemd not detected, dockerd daemon needs to be started manually

/home/inductor/bin/dockerd-rootless.sh --experimental --storage-driver vfs

# Docker binaries are installed in /home/inductor/bin
# WARN: dockerd is not in your current PATH or pointing to /home/inductor/bin/dockerd
# Make sure the following environment variables are set (or add them to ~/.bashrc):

export XDG_RUNTIME_DIR=/tmp/docker-1000
export PATH=/home/inductor/bin:$PATH
export PATH=$PATH:/sbin
export DOCKER_HOST=unix:///tmp/docker-1000/docker.sock

出てきた環境変数を .bashrc などに登録しておきます。


Docker daemonの起動

Mobyのドキュメントの通りに起動してみる。

$ dockerd-rootless.sh --experimental

+ [ -w /tmp/docker-1000 ]
+ [ -w /home/inductor ]
...
...中略
...
INFO[2019-03-02T09:43:30.951521529+09:00] Daemon has completed initialization
INFO[2019-03-02T09:43:30.980047655+09:00] API listen on /tmp/docker-1000/docker.sock

ダエモンさんのInitializeが終わって、APIがListenし始めたよ!と表示されました。

Docker daemonが起動してsocketのlistenが行われているのがわかりますね!

ここからDockerを実際に動かすためには、CLIを使って起動されたDaemonとおしゃべりする必要があります。

また、何らかのシステム管理用のDaemon(systemdとか)にちゃんと設定は入れておいたほうがよさそうです(デフォだと上手く入ってくれませんでした)。

Docker CLIで以下のようにSocketを明示的に指定してあげることで、nginxのイメージをPullしてRunすることができます。

$ docker -H unix://$XDG_RUNTIME_DIR/docker.sock run -d nginx

Portをexposeするときも同様にSocketを明示的に指定したのち、socatを使ってソケット通信のプロキシを行います。

docker -H unix://$XDG_RUNTIME_DIR/docker.sock run -d -p 80:80 nginx

socat -t -- TCP-LISTEN:8080,reuseaddr,fork EXEC:"nsenter -U -n -t $(cat $XDG_RUNTIME_DIR/docker.pid) socat -t -- STDIN TCP4\:127.0.0.1\:80"

すごい。本当にユーザー領域で動いた!


どうやって動いてるのか

基本的には、RootlessKitというOSSがベースとなっています。

GitHubの概要には


made for mainly running Docker and Kubernetes as an unprivileged user


と書かれていて、要するに、KubernetesやDockerのDaemonをを特権ユーザーでなくとも動かせるようにするためのツールです。

実はこのOSSが存在するrootless-containersのOrganizationの中にはusernetesというプロジェクトもあって、こちらは、DockerではなくKuberntesをユーザー領域で動かそうというプロジェクトです。こちらも、Docker rootless modeと同じくNTTの須田さんが主に動いて開発しています。

一通り動かせるのがわかったので僕は満足したので、誰かもうちょい詳しいエントリーをお願いします(他力本願)