Linux

WSL2のUbuntu 22.04でSystemdでDockerを起動させる

はじめに

これまでWSL2ではDocker を立ち上げるにはSystemdではなくserviceで立ち上げるのが定番でした。これはUbuntu 22.04以前ではSystemdがPID=1で立ち上がらいのが原因でDockerが立ち上がりませんでした。Ubuntu 22.04からはSystemdをPID=1で立ち上げる方法が確立したのでSystemdでDockerを利用できます。

そこでUbuntu 22.04を利用してSystemdでDockerを起動させる方法を紹介していきます。

 

--2022/09/30 追記--

Windows のビルドのバージョンは22000.0以上の場合、Windows 11 やWindows 10 Insider ProgramなどではWSLがSystemdに対応したのでこちらをお試しください。

WSLでsystemdのPID=1に対応したらしいので試してみた - 技術的な何か。
WSLでsystemdのPID=1に対応したらしいので試してみた - 技術的な何か。

はじめに WSLでsystemdをPID=1に対応しました。非常にうれしいニュースです。 現状はWindows 11かWindows 10 Insider Programのみです。ビルドのバージョンは

level69.net

 

Dokcer のインストール

最初にDokcerをインストールします。これはドキュメントに沿った形で行います。

Ubuntu | Docker Docs
Ubuntu | Docker Docs

Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prer ...

docs.docker.com

apt-get update

apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

mkdir -p /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update

apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

インストール完了後に下記のようにエラーが表示されます。

Failed to retrieve available kernel versions.

Failed to check for processor microcode upgrades.
[Tips] Ubuntu 22.04 LTS on WSLで出るエラー対処 : Failed to retrieve available kernel versions. Failed to check for processor microcode upgrades. - 技術的な何か。
[Tips] Ubuntu 22.04 LTS on WSLで出るエラー対処 : Failed to retrieve available kernel versions. Failed to check for processor microcode upgrades. - 技術的な何か。

Tips WSLでUbuntu 22.04 LTS実行し、インストールやアップグレードを行うと下記のようなエラーが出ることがあります。 Scanning linux images... Failed

level69.net

これは以下のコマンドで解消します。

apt purge needrestart

これでエラーは解消さます。

Systemd をPID=1で起動

Ubuntu 22.04では下記のコマンドで実行できます。

# /usr/libexec/wsl-systemd
# /usr/libexec/nslogin

SystemdがPID=1で起動されていることを確認します。

# ps ax | grep systemd
1 ?        Ss     0:01 /lib/systemd/systemd --unit=multi-user.target

Systemd でDokcer を起動

# systemctl start 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.

エラー抜粋

Aug 03 14:40:02 kudo4 systemd[1]: docker.service: Failed with result 'exit-code'.
Aug 03 14:40:02 kudo4 systemd[1]: Failed to start Docker Application Container Engine.
Aug 03 14:40:04 kudo4 systemd[1]: docker.service: Scheduled restart job, restart counter is at 3.
Aug 03 14:40:04 kudo4 systemd[1]: Stopped Docker Application Container Engine.
Aug 03 14:40:04 kudo4 systemd[1]: docker.service: Start request repeated too quickly.
Aug 03 14:40:04 kudo4 systemd[1]: docker.service: Failed with result 'exit-code'.
Aug 03 14:40:04 kudo4 systemd[1]: Failed to start Docker Application Container Engine.

このエラーからは原因は特定できません。
これはUbuntu 22.04とDockerの特有の問題でiptableの設定が必要となります。またこのエラーはSystemd特有の問題ではなくserviceで起動する場合も同様です。

iptableをレガシーに設定します。

# update-alternatives --set iptables /usr/sbin/iptables-legacy
# update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
# update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

  Selection    Path                       Priority   Status
------------------------------------------------------------
  0            /usr/sbin/iptables-nft      20        auto mode
* 1            /usr/sbin/iptables-legacy   10        manual mode
  2            /usr/sbin/iptables-nft      20        manual mode

Press  to keep the current choice[*], or type selection number:1

あとはDokcer 起動するだけです。

# systemctl start docker
# systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-08-03 14:42:04 JST; 10s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 1306 (dockerd)
      Tasks: 13
     Memory: 37.2M
     CGroup: /system.slice/docker.service
             └─1306 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.238747400+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.write_bps_device"
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.238752600+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.read_iops_device"
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.238757300+09:00" level=warning msg="Your kernel does not support cgroup blkio throttle.write_iops_device"
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.238938600+09:00" level=info msg="Loading containers: start."
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.316465000+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set>
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.367323600+09:00" level=info msg="Loading containers: done."
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.542773400+09:00" level=info msg="Docker daemon" commit=a89b842 graphdriver(s)=overlay2 version=20.10.17
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.543010900+09:00" level=info msg="Daemon has completed initialization"
Aug 03 14:42:04 kudo4 systemd[1]: Started Docker Application Container Engine.
Aug 03 14:42:04 kudo4 dockerd[1306]: time="2022-08-03T14:42:04.581745100+09:00" level=info msg="API listen on /run/docker.sock"

接続できることも確認します。

~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

 

2回目以降にDocker を起動させる

この設定ではWSLを立ち上げにいちいち下記のコマンドが必要となります。

# /usr/libexec/wsl-systemd
# /usr/libexec/nslogin
# systemctl start docker

Dcokerを停止する

素直にDokcerを停止するとエラーがでます。

# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket

以下で停止します。

# systemctl stop docker.socket

 

まとめ

Docker をSystemdで起動する方法のひとつを紹介しました。WSL上のSystemdでDockerを利用したいひとは、これが一番楽だと思います。

下記の方法よりも簡単に行えるので気軽に利用できるのではないかと思います。

WSLではaz acr loginが使えないけど無理やり使う方法はDockerをsystemdで起動します。 - 技術的な何か。
WSLではaz acr loginが使えないけど無理やり使う方法はDockerをsystemdで起動します。 - 技術的な何か。

はじめに Azure Container Registryにアクセスしたい場合には、az login → az acr login --name <レジストリ名> という流れを踏みます。

level69.net

 

参考

WSL2とsystemdとnslogin
WSL2とsystemdとnslogin

zenn.dev

-Linux
-,