1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

yum update するとdocker.serviceがデフォルトに戻る問題への対処

Last updated at Posted at 2020-11-02

結論

書き換わってほしくない設定は、docker.service ではなく /etc/docker/daemon.json に書きましょう。

前提

  • CentOS Linux release 7.8.2003 (Core)
  • Docker version 19.03

概要

yum updateをcronで走らせていたところ、ある日のアップデート後にDockerイメージがすっからかんになっていました。
原因はDockerデーモンの実行時のルートをサービスファイル内で書き替えていたためでした。
yum updateのタイミングでdocker.serviceが新しいバージョンのデフォルト設定に置き換わり、実行時のルートが既定値(/var/lib/docker)に戻ってしまっていたわけですね。

再現手順

もともとdocker-ceが入っていたマシンでyum remove docker-ce した後を想定しています。

ちょっと前のバージョンのDockerをインストールする

ちょっと前のバージョンは以下のコマンドで確認できます。

# yum list --showduplicates | grep docker-ce.x86_64
docker-ce.x86_64                       17.03.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64                       17.03.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64                       17.03.2.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64                       17.03.3.ce-1.el7        docker-ce-stable
docker-ce.x86_64                       17.06.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64                       17.06.1.ce-1.el7.centos docker-ce-stable
(以下略)

アーキテクチャがx86_64でない場合は適宜読み替えてください。適当に 19.03.10でもインストールします。(最新でなければ何でもいいです。)

# yum install -y docker-ce-19.03.10-3.el7

docker.serviceを書き替える

もとのファイルは以下の通りです。長いので書き替える予定の[Service]の部分だけ抜粋します。

[Service]
Type=notify
# 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 -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

これを以下のように変更します。/opt/docker はあらかじめ作っておきます。

[Service]
Type=notify
# 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 -H fd:// --graph /opt/docker --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

hello-worldを実行し、イメージが/opt/docker配下に行ったことを確認します。

# systemctl start docker
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
(省略)

# ll /opt/docker
total 0
drwx------. 2 root root  24 Nov  2 04:46 builder
drwx--x--x. 4 root root  92 Nov  2 04:46 buildkit
drwx------. 3 root root  78 Nov  2 04:46 containers
drwx------. 3 root root  22 Nov  2 04:46 image
drwxr-x---. 3 root root  19 Nov  2 04:46 network
drwx------. 6 root root 261 Nov  2 04:46 overlay2
drwx------. 4 root root  32 Nov  2 04:46 plugins
drwx------. 2 root root   6 Nov  2 04:46 runtimes
drwx------. 2 root root   6 Nov  2 04:46 swarm
drwx------. 2 root root   6 Nov  2 04:46 tmp
drwx------. 2 root root   6 Nov  2 04:46 trust
drwx------. 2 root root  25 Nov  2 04:46 volumes

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB

良いですね。

yum update する

2020/11/02時点で最新の 19.03.13に更新します。

# yum update -y docker-ce
# docker --version
Docker version 19.03.13, build 4484c46d9d

サービスファイルを確認します。([Service]のみ抜粋)

# cat /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# 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 -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

先ほど設定したはずの --graph=/opt/dockerが消えていますね。
以下のように /opt/dockerには元のファイルが残っているにもかかわらず、イメージ一覧はからっぽになりました。

# ll /opt/docker/
total 0
drwx------. 2 root root  24 Nov  2 04:46 builder
drwx--x--x. 4 root root  92 Nov  2 04:46 buildkit
drwx------. 3 root root  78 Nov  2 04:46 containers
drwx------. 3 root root  22 Nov  2 04:46 image
drwxr-x---. 3 root root  19 Nov  2 04:46 network
drwx------. 6 root root 261 Nov  2 04:46 overlay2
drwx------. 4 root root  32 Nov  2 04:46 plugins
drwx------. 2 root root   6 Nov  2 04:46 runtimes
drwx------. 2 root root   6 Nov  2 04:46 swarm
drwx------. 2 root root   6 Nov  2 04:46 tmp
drwx------. 2 root root   6 Nov  2 04:46 trust
drwx------. 2 root root  25 Nov  2 04:46 volumes

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

解決方法

/etc/docker/daemon.jsonを利用します。

デフォルトで入るdocker.serviceexecStartの内容は以下の通り

/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

ここに設定されているオプション以外はすべてデフォルト値が利用されます。公式ガイドをもとに、関係ありそうなオプションをチェックしましょう。

オプション 既定値 説明
-g, --graph /var/lib/docker Docker 実行時の Docker ルート
--config-file /etc/docker/daemon.json デーモン設定ファイル

--graph は更新時に入るサービスファイルでは未指定のため、どうあがいても/var/lib/dockerに戻ってしまいます。なのでデフォルトで --config-file として指定されている /etc/docker/daemon.json を編集すれば良いです。
Dockerインストール時には存在しないファイルなので、新しく作成します。
以下の内容になるようファイルを編集しましょう。

# cat /etc/docker/daemon.json
{
    "graph": "/opt/docker"
}

確認

一度docker-ceをアンインストールし、もう一度アップデートを試します。確認のためDocker実行時のルートの中身も消しておきます。

# yum remove docker-ce
# rm -rf /var/lib/docker/*
# rm -rf /opt/docker/*

・過去バージョンのインストール

# yum -y yum install -y docker-ce-19.03.10-3.el7
# systemctl stard docker

・設定ファイルの確認

# cat /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# 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 -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# cat /etc/docker/daemon.json
{
        "graph": "/opt/docker"
}

・hello-world実行

# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
(以下省略)

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB

# ll /opt/docker/
total 0
drwx------. 2 root root  24 Nov  2 05:14 builder
drwx--x--x. 4 root root  92 Nov  2 05:14 buildkit
drwx------. 3 root root  78 Nov  2 05:14 containers
drwx------. 3 root root  22 Nov  2 05:14 image
drwxr-x---. 3 root root  19 Nov  2 05:14 network
drwx------. 6 root root 261 Nov  2 05:14 overlay2
drwx------. 4 root root  32 Nov  2 05:14 plugins
drwx------. 2 root root   6 Nov  2 05:14 runtimes
drwx------. 2 root root   6 Nov  2 05:14 swarm
drwx------. 2 root root   6 Nov  2 05:14 tmp
drwx------. 2 root root   6 Nov  2 05:14 trust
drwx------. 2 root root  25 Nov  2 05:14 volumes

・yum update 実行

# yum -y update docker-ce
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB

これでcronでDockerを更新しても大丈夫ですね!

終わりに

daemon.json はサービスファイルの execStartで設定できる部分はおそらく全てカバーできるはずです。docker.service はノータッチで、daemon.jsonを更新しましょう。
ちなみに僕はこれにしばらく気づかずcronのyum updateの後処理でsedかけてました。そんなゴリ押しはやめましょう。(自戒)

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?