ytooyamaのブログ

サーバ構築とか、仕事で発見したこととか、趣味のこととかを書いています。

Fedoraのmoby-engineパッケージでインストールするDocker EngineはデフォルトでコンテナにもSELinux機能を渡す

Fedoraのmoby-engineパッケージをインストールすると、Dockerを利用できます。多分このことを知らずに、Fedora向けのDocker Engine(旧称 Docker CE)をインストールしている人のほうが多いと思います。

ちなみにDocker Engine(旧称 Docker CE)の場合は /etc/docker/daemon.json{ "selinux-enabled": true }とか書いてサービス再起動するまで、コンテナーに対してSELinuxによる制御はされません。つまりホストでSELinuxが有効化されていても、コンテナに対してはSELinuxは働かないということです。

docs.docker.com

一方、moby-engineパッケージでインストールしたDockerでは、デフォルトでSELinuxサポートが有効になっていることがdocker infoコマンドの実行結果から確認できます。

# docker info
...
 Security Options:
  seccomp
   Profile: default
  selinux            #seccompとselinuxサポートが有効化されている
  cgroupns
...

そこで、試しに /etc/docker/daemon.json{ "selinux-enabled": false }とあえて書いてみました。すると、Dockerサービスが正常に動いてくれません。

# systemctl restart docker
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xeu docker.service" for details.

ステータスやjournalctlで内容を確認せよと言われていますが、サービスを起動できなかったことくらいしかログには出ておらず、正直有力な情報は書かれていません。

うまくいかない理由を調べるためにmoby-engineパッケージのサービスファイルと環境変数を指定しているファイルを見たら、原因がわかりました。

必要なところだけ抜き出すと、サービスを起動するときに環境変数として/etc/sysconfig/dockerが呼ばれるようです。ここにdockerdのオプション --selinux-enabledが書かれていました。ここに書かれているのに/etc/docker/daemon.jsonで設定をしようとしたのでサービスの実行に失敗したようです。

# cat /usr/lib/systemd/system/docker.service
...
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd \
          --host=fd:// \
          --exec-opt native.cgroupdriver=systemd \
          $OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
...

# cat /etc/sysconfig/docker
...
# Modify these options if you want to change the way the docker daemon runs
OPTIONS="--selinux-enabled \
  --log-driver=journald \
  --live-restore \
  --default-ulimit nofile=1024:1024 \
  --init-path /usr/libexec/docker/docker-init \
  --userland-proxy-path 

もし、/etc/docker/daemon.json側でDockerコンテナー側のSELinuxサポートを制御したい場合は、 /etc/sysconfig/dockerのOPTIONSから--selinux-enabledを取り除いた上で、つぎのように記述すれば良いようです。

# vi /etc/docker/daemon.json
{
    "selinux-enabled": true
}

ただ、DockerについてはSELinuxサポートが有効化されていても困ることはあまりないので、問題が起きない限りデフォルト設定のまま使ったほうが良いと思います。また、/etc/sysconfig/dockerの設定変更はなにかの拍子に元の設定に戻る可能性があるので、どうしてもこの設定を変更したい場合はDocker Engineの方をインストールすると良いかなと思います。

docs.docker.com

ちなみにPodmanも割と良いので、DockerからPodmanへの乗り換えもありといえば有りなのかもしれません。

# dnf install podman
# podman container run -it docker.io/redhat/ubi9  bash

このブログサイトはJavaScriptを使っていますが、読み込んでいるJavaScriptは全てはてなが提供しているものであり、筆者が設置しているものではありません。