Ubuntu 18.04 で OS 起動時の apt update と unattended-upgrade を抑制する方法
時間のない人向けのまとめ
sudo systemctl edit apt-daily.timer sudo systemctl edit apt-daily-upgrade.timer
どちらも次の内容で保存します。
[Timer] Persistent=false
もしくは、直接ファイルを編集して反映してもよいです。
sudo install -d -o root -g root -m 755 /etc/systemd/system/apt-daily.timer.d cat <<EOF | sudo tee /etc/systemd/system/apt-daily.timer.d/override.conf [Timer] Persistent=false EOF cp -pR /etc/systemd/system/apt-daily.timer.d/ /etc/systemd/system/apt-daily-upgrade.timer.d/ sudo systemctl daemon-reload
何が問題なのか?
Ubuntu 18.04、少なくとも EC2 用の Ubuntu cloud image の 20200131 版 (18.04.4) では、毎日 6:00 頃に apt update
と unattended-upgrade
(セキュリティ関連の更新パッケージのインストール) が行われる (詳しくは後述) のですが、その時間帯に電源がオフで稼働していなかった場合は、次の OS 起動時に実行される設定になっています。
「その時間帯に電源がオフで稼働していなかった」は、AMI からインスタンスを起動したときも同じ状況になるので、AMI が古ければ古いほど更新パッケージが多くなり、起動直後に負荷が高まったり、しばらく apt install
できない (unattended-upgrade
がロックを獲得しているので) 時間が続いたりします。
その結果、次のような問題が発生します。
- インスタンス起動後に自動的にプロビジョニングを行うようにしている運用の場合、プロビジョニング (の過程のパッケージのインストール) が完遂するまでの時間が安定しなかったり、場合によってはタイムアウトしてエラー終了してしまう
特にオートスケーリングの場合は、一刻も早くインスタンスを投入したいので深刻な問題になります。
またもし、AMI 採取用のインスタンスから日次で AMI を作る運用の場合は、パッケージはほぼ最新であることが期待できます。
というわけで、 OS 起動時の更新処理を実行されないようにした、というお話でした。
時間のある人向けの詳細
まず定期的に更新処理が実施される仕組みの説明から。
次の 2 つの systemd の timer ユニットがトリガーとなります。
apt-daily.timer
apt-daily-upgrade.timer
内容を確認すると、
$ systemctl cat apt-daily.timer # /lib/systemd/system/apt-daily.timer [Unit] Description=Daily apt download activities [Timer] OnCalendar=*-*-* 6,18:00 RandomizedDelaySec=12h Persistent=true [Install] WantedBy=timers.target $ systemctl cat apt-daily-upgrade.timer # /lib/systemd/system/apt-daily-upgrade.timer [Unit] Description=Daily apt upgrade and clean activities After=apt-daily.timer [Timer] OnCalendar=*-*-* 6:00 RandomizedDelaySec=60m Persistent=true [Install] WantedBy=timers.target
となっており、 apt-daily.timer
は毎日 6:00 と 18:00 頃、 apt-daily-upgrade.timer
は毎日 6:00 頃に発火するのがわかります。
発火すると、対応する systemd の service ユニットが実行されます。
systemctl cat
で確認すると、実行されるコマンドライン (ExecStart
) が確認できます。
apt-daily.service
ExecStart=/usr/lib/apt/apt.systemd.daily update
apt-daily-upgrade.service
ExecStart=/usr/lib/apt/apt.systemd.daily install
ざっくり言うと、
/usr/lib/apt/apt.systemd.daily update
は
- apt-get update
- apt-get --download-only dist-upgrade
- unattended-upgrade --download-only
/usr/lib/apt/apt.systemd.daily install
は
- unattended-upgrade
を行うためのもので、APT の設定で個別に実施する/しないを制御することができます。
デフォルトでの次のような設定になっていて、
$ apt-config dump | grep Periodic APT::Periodic ""; APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "0"; APT::Periodic::AutocleanInterval "0"; APT::Periodic::Unattended-Upgrade "1";
apt-get update
実施する--download-only
系は実施しないunattended-upgrade
実施する
という挙動になります。
ここまでが定期的に実行される仕組みの説明で、次からは主題の OS 起動時の更新処理の仕組みについてです。
timer ユニットの定義をみると Persistent=true
というのがあり、これがキモです。
systemd.timer(5) から引用すると
Persistent=
Takes a boolean argument. If true, the time when the service unit was last triggered is stored on disk. When the timer is activated, the service unit is triggered immediately if it would have been triggered at least once during the time when the timer was inactive. This is useful to catch up on missed runs of the service when the system was powered down. Note that this setting only has an effect on timers configured with OnCalendar=. Defaults to false.
とのことなので、冒頭の方法で Persistent=false
と上書き設定したわけです。
ちなみに
定期的なのも含め一切の自動的な更新処理をオフにしたい場合は、 /usr/lib/apt/apt.systemd.daily
に
# check if the user really wants to do something AutoAptEnable=1 # default is yes eval $(apt-config shell AutoAptEnable APT::Periodic::Enable) if [ $AutoAptEnable -eq 0 ]; then exit 0 fi
という処理があるので
echo 'APT::Periodic::Enable "0";' | sudo tee /etc/apt/apt.conf.d/99disable-periodic
とかするといいんじゃないかと思います。
あと /etc/cron.daily/apt-compat
という crontab があるんですが、
if [ -d /run/systemd/system ]; then exit 0 fi
となってるので systemd な環境では無いのと同じです。