Ubuntu(16.04/18.04) 默認會天天自動安裝系統的安全更新,可是不會自動安裝包的更新。本文梳理 Ubuntu 16.04/18.04 系統的自動更新機制,並介紹如何配置系統自動更新全部的包。說明:簡單起見,本文中使用 Ubuntu 指代 Ubuntu 16.04/18.04。html
當咱們遠程登陸系統時,會收到以下圖所示的更新相關的消息:git
紅框中的第一行文字說明系統中有 149 個包須要更新。第二行說明沒有安全相關的包須要更新。之因此會這樣,是由於 Ubuntu 默認的配置會天天自動安裝安全更新而忽略其它包的更新。接下來咱們就介紹 Ubuntu 中的自動更新機制。github
Ubuntu 默認定義了 4 個 systemd unit 執行更新任務,它們分別是:shell
/lib/systemd/system/apt-daily-upgrade.service /lib/systemd/system/apt-daily-upgrade.timer /lib/systemd/system/apt-daily.service /lib/systemd/system/apt-daily.timer
其中的 apt-daily.timer 和 apt-daily-upgrade.timer 是兩個觸發器,分別在天天指定的時間觸發 apt-daily.service 和 apt-daily-upgrade.service。這兩個 service 的類型都是 oneshot,意思是當任務完成後 service 進程退出。這兩個 service 其實調用的是同一個腳本: /usr/lib/apt/apt.systemd.daily。 apt-daily.service 爲腳本傳入參數 "update",其功能爲檢查系統的更新並下載對應的更新包。apt-daily-upgrade.service 爲腳本傳入參數 "install",其功能爲安裝更新並刪除緩存在本地的更新包。ubuntu
apt-daily.timer 默認天天觸發兩次,分別爲 6 點和 18 點,主要是爲了緩解服務器端的下載壓力。咱們能夠根據自身業務的特色設置合適的觸發時間。
apt-daily-upgrade.service 默認天天在 6 點觸發一次,咱們也能夠設置爲其它時間,好比午夜。vim
/usr/lib/apt/apt.systemd.daily 腳本負責完成與更新相關的一系列工做,這些工做主要分爲兩大塊:緩存
apt.systemd.daily 腳本中調用 apt-config 命令從 /etc/apt/apt.conf.d/10periodic 文件和 /etc/apt/apt.conf.d/20auto-upgrades 讀中取配變量,並根據這些變量的值來控制系統的更新策略。下面咱們介紹幾個比較重要的配置項。安全
隔多少天執行一次 apt-get update,默認是 1 天,0 表示不執行該操做:bash
APT::Periodic::Update-Package-Lists "1";
隔多少天執行一次 apt-get upgrade --download-only 下載更新包,0 表示不執行該操做:服務器
APT::Periodic::Download-Upgradeable-Packages "0";
下載的更新版被緩存在目錄 /var/cache/apt/archives/ 中,執行升級操做時直接從緩存目錄中讀取包文件而不是從網絡上下載。
隔多少天執行一次 apt-get autoclean 清除無用的更新包,0 表示不執行該操做:
APT::Periodic::AutocleanInterval "0";
隔多少天執行一次 Unattended-Upgrade 執行系統安全更新(或者因此包的更新),0 表示不執行該操做:
APT::Periodic::Unattended-Upgrade "1";
經過這些配置,咱們能夠控制自動更新的頻率和行爲。注意,到目前爲止的配置還只能安裝系統的安全更新,若是要想安裝全部包的更新還須要其它的配置,相關內容咱們在後面的小節中介紹。
在繼續介紹後面的內容前,讓咱們先來了解一下 apt.systemd.daily 腳本中用到的 apt-config 命令和 apt.systemd.daily 腳本依賴的配置文件。
apt-config 命令
apt-config 是一個被 APT 套件使用的內部命令,使用它能夠在腳本中提取 /etc/apt/apt.conf 目錄下配置文件中的信息。
好比,若是要在腳本中獲取 APT::Periodic::Update-Package-Lists 的設置,可使用下面的代碼:
#!/bin/bash ABC=0 eval $(apt-config shell ABC APT::Periodic::Update-Package-Lists) echo ${ABC}
此時腳本變量 ABC 中保存的就是 APT::Periodic::Update-Package-Lists 的值。
10periodic 和 20auto-upgrades
/etc/apt/apt.conf.d/10periodic 是 update-notifier-common 的配置文件:
$ dpkg-query -S /etc/apt/apt.conf.d/10periodic
update-notifier-common: /etc/apt/apt.conf.d/10periodic
在 ubuntu 16.04 和 18.04 中,這兩個文件的默認內容是同樣的。apt.systemd.daily 腳本在註釋中說咱們能夠經過 /etc/apt/apt.conf.d/10periodic 文件自定義相關的變量值,它經過 get-config 命令來得到這些變量的值。可是測試的結果是 /etc/apt/apt.conf.d/20auto-upgrades 文件中的變量會覆蓋 /etc/apt/apt.conf.d/10periodic 文件中的變量。看來是 get-config 命令根據文件名稱的順序,排在後面的文件中的變量會覆蓋前面文件中的變量。
在 desktop 版本中,經過 GUI 程序修改相關的變量,這兩個文件都會被修改並保持一致,因此在 server 版中咱們最好也同時修改這兩個文件並保持其內容一致。
Ubuntu 其實是經過 unattended-upgrades 命令來自動安裝更新的。Ubuntu 16.04/18.04 默認安裝了這個包,若是碰到沒有安裝的狀況你還能夠經過下面的命令自行安裝:
$ sudo apt install unattended-upgrades
unattended-upgrades 的配置文件爲 /etc/apt/apt.conf.d/50unattended-upgrades。
注意,unattended-upgrades 不只可以安裝系統的安全更新,還能夠安裝全部包的更新。可是默認的配置只安裝安全更新,咱們能夠經過配置項讓 unattended-upgrades 安裝全部的包更新或者只安裝安全更新。
unattended-upgrades 命令被設計爲經過 cron 定時執行系統更新,但在 Ubuntu 16.04/18.04 中是經過 systemd 的 timer unit 定時觸發 service unit 執行的。
unattended-upgrades 命令的日誌文件存放在 /var/log/unattended-upgrades 目錄下。
unattended-upgrade 命令常見的用法之一是檢查系統是否有更新:
$ sudo unattended-upgrade --dry-run
另外一種用法是安裝更新:
$ sudo unattended-upgrade
在 apt.systemd.daily 腳本中執行 unattended-upgrade 命令時,因爲更新包已經提早下載到緩存目錄了(/var/cache/apt/archives),因此直接它直接使用緩存中的更新包。
配置文件 50unattended-upgrades
50unattended-upgrades 文件中的默認配置只是安裝安全更新:
Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}"; "${distro_id}:${distro_codename}-security"; "${distro_id}ESM:${distro_codename}"; // "${distro_id}:${distro_codename}-updates"; // "${distro_id}:${distro_codename}-proposed"; // "${distro_id}:${distro_codename}-backports"; };
若是要自動安裝全部包的更新,只要取消下面行的註釋就好了:
"${distro_id}:${distro_codename}-updates";
咱們還能夠經過黑名單的方式指定不更新哪些包:
Unattended-Upgrade::Package-Blacklist { "vim"; "libc6"; "libc6-dev"; "libc6-i686"; };
下面的配置項指定在更新後移除無用的包:
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true";
有些更新須要重啓系統,而默認的配置是不重啓系統的。下面的配置容許重啓系統(更新完成後,若是須要重啓,當即重啓系統):
Unattended-Upgrade::Automatic-Reboot "true";
可是多數狀況下咱們更指望指定一個時間讓系統重啓(若是須要重啓,在下面配置中指定的時間重啓系統):
Unattended-Upgrade::Automatic-Reboot-Time "02:38";
在系統更新的過程當中發生了錯誤怎麼辦?固然是通知管理員啦!下面的配置在發生錯誤時給管理員發送郵件:
Unattended-Upgrade::Mail "user@example.com"; Unattended-Upgrade::MailOnlyOnError "true";
注意:若是要向外網發送郵件,須要安裝 mailx 等工具。
若是你的主機運行在封閉的環境中,而且沒法鏈接到有效的更新源,此時能夠選擇關閉自動更新功能。首選的方法是中止相關的服務:
$ sudo systemctl stop apt-daily.service $ sudo systemctl stop apt-daily.timer $ sudo systemctl stop apt-daily-upgrade.service $ sudo systemctl stop apt-daily-upgrade.timer $ sudo systemctl disable apt-daily.service $ sudo systemctl disable apt-daily.timer $ sudo systemctl disable apt-daily-upgrade.service $ sudo systemctl disable apt-daily-upgrade.timer
或者修改自動更新程序的配置文件也能夠,同時更新 /etc/apt/apt.conf.d/10periodic 和 /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1";
改成
APT::Periodic::Update-Package-Lists "0"; APT::Periodic::Unattended-Upgrade "0";
由於 apt.systemd.daily 腳本同時調用了 apt-get 和 unattended-upgrade 等命令,因此相關的日誌也分散在不一樣的地方。apt-get 相關的日誌在 /var/log/apt 目錄下,unattended-upgrade 命令的日誌在 /var/log/unattended-upgrades 目錄下。
參考:
unattended-upgrade man page
Automatic Updates
AutomaticSecurityUpdates
apt-config man page
如何在Ubuntu 16.04上安裝自動安全更新
How to set up automatic updates on Ubuntu Server 18.04
Ubuntu Enable Automatic Updates Unattended Upgrades
Ubuntu 16.04: Auto apt update and apt upgrade
mvo5/unattended-upgrades