Wie deaktiviere ich "apt-daily.service" auf einem Ubuntu-Cloud-VM-Image?


59

Das VM-Image des Ubuntu 16.04-Servers startet anscheinend alle 12 Stunden den "apt-daily.service". Dieser Dienst führt verschiedene APT-bezogene Aufgaben aus, z. B. das Aktualisieren der Liste der verfügbaren Pakete, das Ausführen unbeaufsichtigter Upgrades bei Bedarf usw.

Beim Starten von einem VM "Snapshot" wird der Dienst sofort ausgelöst , da (nehme ich an) systemd schnell erkennt, dass der Timer längst abgelaufen sein sollte.

Ein laufender APT verhindert jedoch, dass andere aptProzesse ausgeführt werden, da er gesperrt ist /var/lib/dpkg. Die Fehlermeldung, die dies anzeigt, sieht folgendermaßen aus:

E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

Ich muss diese automatisierte APT-Aufgabe deaktivieren, bis Ansible die Einrichtung des Computers abgeschlossen hat (was normalerweise die Installation von Paketen umfasst). Weitere Informationen und den Kontext finden Sie unter https://github.com/gc3-uzh-ch/elasticluster/issues/304 .

Ich habe verschiedene Optionen ausprobiert, um die Funktion "Unbeaufsichtigte Upgrades" über ein Skript für "Benutzerdaten" zu deaktivieren cloud-init, aber alle sind bisher fehlgeschlagen.

1. Deaktivieren Sie die Task systemd

systemd task apt-daily.servicewird ausgelöst durch apt-daily.timer. Ich habe versucht, den einen oder den anderen oder beide mit verschiedenen Kombinationen der folgenden Befehle zu deaktivieren. apt-daily.serviceNach wie vor wird das gestartet, sobald die VM bereit ist, SSH-Verbindungen zu akzeptieren:

    #!/bin/bash

    systemctl stop apt-daily.timer
    systemctl disable apt-daily.timer
    systemctl mask apt-daily.service
    systemctl daemon-reload

2. Deaktivieren Sie die Konfigurationsoption APT::Periodic::Enable

Das Skript /usr/lib/apt/apt.systemd.dailyliest einige APT-Konfigurationsvariablen. Die Einstellung APT::Periodic::Enabledeaktiviert die Funktionalität vollständig (Zeilen 331 - 337). Ich habe versucht, es mit dem folgenden Skript zu deaktivieren:

    #!/bin/bash

    # cannot use /etc/apt/apt.conf.d/10periodic as suggested in
    # /usr/lib/apt/apt.systemd.daily, as Ubuntu distributes the
    # unattended upgrades stuff with priority 20 and 50 ...
    # so override everything with a 99xxx file
    cat > /etc/apt/apt.conf.d/99elasticluster <<__EOF
    APT::Periodic::Enable "0";
    // undo what's in 20auto-upgrade
    APT::Periodic::Update-Package-Lists "0";
    APT::Periodic::Unattended-Upgrade "0";
    __EOF

Obwohl das Programm über die Befehlszeile APT::Periodic::Enableeinen Wert hat 0(siehe unten), unattended-upgradeswird es dennoch ausgeführt ...

    ubuntu@test:~$ apt-config shell AutoAptEnable APT::Periodic::Enable
    AutoAptEnable='0'

3. Entfernen Sie /usr/lib/apt/apt.systemd.dailyinsgesamt

Das folgende cloud-initSkript entfernt das Skript für unbeaufsichtigte Upgrades insgesamt:

    #!/bin/bash

    mv /usr/lib/apt/apt.systemd.daily /usr/lib/apt/apt.systemd.daily.DISABLED

Trotzdem läuft die Aufgabe und ich kann sie in der Prozesstabelle sehen! Obwohl die Datei nicht existiert, wenn sie über die Befehlszeile abgefragt wird:

ubuntu@test:~$ ls /usr/lib/apt/apt.systemd.daily
ls: cannot access '/usr/lib/apt/apt.systemd.daily': No such file or directory

Es sieht so aus, als ob das cloud-initSkript (zusammen mit der SSH-Befehlszeile) und der Root-systemd-Prozess in separaten Dateisystemen und Prozessbereichen ausgeführt werden ...

Fragen

Gibt es etwas offensichtliches, was ich vermisse? Oder gibt es eine Namespace-Magie, von der ich nichts weiß?

Am wichtigsten: Wie kann ich das apt-daily.serviceüber ein cloud-initSkript deaktivieren ?


2
Dies wird Ihnen nicht weiterhelfen, bis es in ein offizielles Paketupdate gerollt wird, aber lesen Sie bitte den Patch, den ich gerade in Debian-Fehler 844453 gepostet habe .
— zwol

Möglicherweise haben Sie die --nowMarkierung im systemctl disableBefehl übersehen, damit die Änderung sofort wirksam wird. Das war mein Problem.
— Daniel F

@DanielF nein, weil disable --nowgleichbedeutend mit stopgefolgt von disable.
— Sourcejedi

1
Anscheinend wurde dies in systemd im Februar 2019 ENDLICH behoben: github.com/systemd/systemd/issues/5659 . So wird es hoffentlich in Ubuntu 20.04 sein.
— Snap

Antworten:


37

Ja, da war etwas offensichtlich, was mir fehlte.

Bei Systemd dreht sich alles um den gleichzeitigen Start von Diensten, sodass das cloud-initSkript zur gleichen Zeit ausgeführt wird, zu der apt-daily.servicees ausgelöst wird. Bis die Zeit cloud-initzur Ausführung der benutzerdefinierten Nutzlast kommt, apt-get updateläuft bereits. Die Versuche 2. und 3. scheiterten also nicht an irgendeiner Namespace-Magie, sondern daran, dass sie das System zu spät änderten apt.systemd.daily, um die Änderungen zu übernehmen.

Dies bedeutet auch, dass es im Grunde keine Möglichkeit gibt , das apt.systemd.daily Laufen zu verhindern - man kann es nur töten, nachdem es gestartet wurde.

Dieses "Benutzerdaten" -Skript nimmt diesen Weg:

#!/bin/bash

systemctl stop apt-daily.service
systemctl kill --kill-who=all apt-daily.service

# wait until `apt-get updated` has been killed
while ! (systemctl list-units --all apt-daily.service | egrep -q '(dead|failed)')
do
  sleep 1;
done

# now proceed with own APT tasks
apt install -y python

Es gibt immer noch ein Zeitfenster, in dem SSH-Anmeldungen möglich sind, die apt-get jedoch nicht ausgeführt werden, aber ich kann mir keine andere Lösung vorstellen, die auf dem Standard-Ubuntu 16.04-Cloud-Image funktioniert.


das hat bei mir auf aws ubuntu 16.04
— geklappt

Ja, ich bin dabei, ein benutzerdefiniertes AMI zu erstellen. Dies beschleunigt auch die Installation von gemeinsamen Diensten.
— Giorgiosironi

Dies scheint nicht genug zu sein, ich finde, es gibt immer noch stragulierende Fälle vonapt-get -o Acquire::http::AllowRedirect=false update
— Edward Z. Yang

11

Hinweis: Leider funktioniert ein Teil der unten aufgeführten Lösung nicht auf Ubuntu 16.04-Systemen (wie dem des Fragestellers), da der vorgeschlagene systemd-runAufruf nur auf Ubuntu 18.04 und höher funktioniert ( Details finden Sie in den Kommentaren ). Ich werde die Antwort hier lassen, da diese Frage immer noch ein beliebter Hit ist, unabhängig davon, welche Ubuntu-Version Sie verwenden ...

Unter Ubuntu 18.04 (und höher) sind möglicherweise bis zu zwei Dienste an der Aktualisierung / Aktualisierung der Boot-Zeit beteiligt. Der erste apt-daily.serviceaktualisiert die Liste der Pakete. Es kann jedoch eine Sekunde geben, in apt-daily-upgrade.serviceder tatsächlich sicherheitskritische Pakete installiert werden. Die Antwort auf die Frage "Unbeaufsichtigtes Upgrade beenden und deaktivieren / entfernen, bevor der Befehl zurückgegeben wird" gibt ein hervorragendes Beispiel dafür, wie Sie darauf warten können, dass beide beendet werden (hier aus Gründen der Benutzerfreundlichkeit kopiert):

systemd-run --property="After=apt-daily.service apt-daily-upgrade.service" --wait /bin/true

(Beachten Sie, dass dies als root ausgeführt werden muss). Wenn Sie versuchen, diese Dienste bei zukünftigen Starts zu deaktivieren, müssen Sie BEIDE Dienste maskieren:

systemctl mask apt-daily.service apt-daily-upgrade.service

Alternativ können Sie systemctl disablesowohl Dienste als auch die zugehörigen Timer (dh apt-daily.timerund apt-daily-upgrade.timer) verwenden.

Beachten Sie, dass die Maskierungs- / Deaktivierungstechniken in dieser Antwort nur das Aktualisieren / Aktualisieren zukünftiger Starts verhindern. Sie werden nicht gestoppt, wenn sie bereits im aktuellen Start ausgeführt werden.


2
Ausgezeichnete Antwort, danke! Beachten Sie jedoch, dass systemd-runUbuntu 16.04 zu alt ist, um die --waitOption zu unterstützen , dies sollte jedoch für den vorliegenden Zweck nicht unbedingt erforderlich sein. (Laut Manpage --waitwartet man auf die Beendigung einer Einheit, aber es reicht, auf den Start zu warten, was das Standardverhalten von ist systemd-run.)
— Riccardo Murri

Ich stehe korrigiert da: Die gegebene systemd-runBeschwörung funktioniert überhaupt nicht auf Ubuntu 16.04; es stirbt mit Fehlermeldung Unbekannte Zuordnung After = apt-daily.service apt-daily-upgrade.service . Es sieht so aus, als wären einige Einheiten in nicht verfügbar systemd-run, siehe zum Beispiel hier
— Riccardo Murri

@riccardo-murri du hast mich erwischt :-)! Eigentlich habe ich mich über 16.04 / 18.04 Unterschiede gewundert (daher das Wiesel "bis zu zwei") und dann vergessen, die Einschränkung einzulegen. Welche Änderung würden Sie vorschlagen?
— Anon

@ Riccardo-Murri Ah, das ist schade, ich werde eine große Warnung an den Anfang der Antwort setzen, die besagt, dass es nicht auf Ubuntu 16.04
— Anon

Deaktiviert die Dienste und neu gestartet und es funktioniert!
— Digz6666

3

Sie können dies über das Cloud-Init-Modul "bootcmd" deaktivieren. Dieser Vorgang wird ausgeführt, bevor das Netzwerk gestartet wird. Dies ist erforderlich, bevor ein passendes Update ausgeführt werden kann.

#cloud-config
bootcmd:
    - echo 'APT::Periodic::Enable "0";' > /etc/apt/apt.conf.d/10cloudinit-disable
    - apt-get -y purge update-notifier-common ubuntu-release-upgrader-core landscape-common unattended-upgrades
    - echo "Removed APT and Ubuntu 18.04 garbage early" | systemd-cat

Sobald Sie sich in der Instanz befinden, sollten Sie auch warten, bis die letzten Phasen von cloud-init abgeschlossen sind, da hierdurch geeignete Quellen / Listen verschoben werden.

# Wait for cloud-init to finish moving apt sources.list around... 
# a good source of random failures
# Note this is NOT a replacement for also disabling apt updates via bootcmd
while [ ! -f /var/lib/cloud/instance/boot-finished ]; do
    echo 'Waiting for cloud-init to finish...'
    sleep 3
done

Dies ist auch hilfreich, um zu sehen, wie früh die bootcmd ausgeführt wird:

# Show microseconds in systemd journal
journalctl -r -o short-precise

Sie können überprüfen, ob dies folgendermaßen funktioniert hat:

apt-config dump | grep Periodic

# Verify nothing was updated until we run apt update ourselves.
cd /var/lib/apt/lists
sudo du -sh .   # small size
ls -ltr         # old timestamps

1

Es wird nicht einfacher sein, das Gerät zu maskieren

systemctl mask apt-daily.service

?


Funktioniert nicht - siehe Abschnitt 1. Deaktivieren Sie die Task systemd im Fragentext . Aber trotzdem danke für den Vorschlag! :-)
— Riccardo Murri

2
Deaktivieren und Maskieren eines Dienstes ist nicht dasselbe. Maske erstellen Sie einen Link zu / dev / null. ls -al /etc/systemd/system/ | grep alsa lrwxrwxrwx 1 root root 9 Sep 1 13:17 alsa-init.service -> /dev/nullDie Daten sind leer.

2
Ich werde unbeaufsichtigt Upgrade los sudo dpkg-reconfigure -plow unattended-upgradesund verbiete es. Der Status der Einheit apt-daily.service ist also gestorben.

Hi @ Bahamut, danke für deine Bemühungen! Die Frage ist jedoch, wie apt-daily.serviceein cloud-initSkript deaktiviert werden kann und bevor es nach dem Neustart der VM gestartet wird: Dies bedeutet: (1) es muss nicht interaktiv erfolgen, (2) es muss vor apt-daily.servicedem ersten Auslösen erfolgen. (Wenn mein Verständnis von systemd korrekt ist, (2) kann nicht wirklich als erreicht werden cloud-initund apt-dailygleichzeitig laufen -. Meine eigene Antwort für mehr sehen)
— Riccardo Murri

1
Ich habe dies auf einer normalen physischen Maschine (dh keiner VM) versucht und kann bestätigen, dass es nicht funktioniert. Sie müssen auch den Timer stoppen: systemctl stop apt-daily.timer; systemctl deaktiviere apt-daily.timer
— happyskeptic

0

Dieser wartet in einer Schleife 1 Sekunde und prüft, ob die Sperre aufgehoben ist.

while : ; do
                sleep 1
                echo $( ps aux | grep -c lock_is_held ) processes are using apt.
                ps aux | grep -i apt
                [[ $( ps aux | grep -c lock_is_held ) > 2 ]] || break
        done
        echo Apt released
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.