Ubuntu bulut VM görüntüsünde 'apt-daily.service` nasıl devre dışı bırakılır?


59

Ubuntu 16.04 sunucu VM görüntüsü görünüşte her 12 saatte bir "apt-daily.service" başlatır; Bu servis mevcut paketlerin listesini yenilemek, gerektiğinde katılımsız yükseltme yapmak, vb. gibi APT ile ilgili çeşitli görevleri yerine getirir.

Bir VM "enstantanesi" nden başlarken, (sanırım) systemd, zamanlayıcının uzun zaman önce bitmiş olması gerektiğini hızla anladığı için servis hemen tetiklenir .

Bununla birlikte, çalışan bir APT diğer aptişlemlerin kilitlendiği sırada çalışmasını önler /var/lib/dpkg. Bunu gösteren hata mesajı şöyle görünür:

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?

Ansible'ın makine kurulumunu tamamlayana kadar (genellikle paketlerin yüklenmesini içeren) bu otomatik APT görevini devre dışı bırakmam gerekiyor; Daha fazla bilgi ve içerik için https://github.com/gc3-uzh-ch/elasticluster/issues/304 adresine bakınız .

"Katılımsız yükseltme" özelliğini "kullanıcı verileri" komut dosyasıyla devre dışı bırakmak için çeşitli seçenekler denedim cloud-init, ancak hepsi şu ana kadar başarısız oldu.

1. systemd görevini devre dışı bırakın

systemd görevi apt-daily.servicetarafından tetiklenir apt-daily.timer. Aşağıdaki komutların çeşitli kombinasyonları ile birini veya diğerini veya her ikisini de devre dışı bırakmaya çalıştım; yine de, apt-daily.serviceVM, SSH bağlantılarını kabul etmeye hazır hale geldikten sonra başlar.

    #!/bin/bash

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

2. config seçeneğini devre dışı bırak APT::Periodic::Enable

Script /usr/lib/apt/apt.systemd.dailybirkaç APT yapılandırma değişkenini okuyor; ayar APT::Periodic::Enableişlevselliği tamamen devre dışı bırakır (satır 331-337). Aşağıdaki komut dosyasıyla devre dışı bırakmayı denedim:

    #!/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

Ancak, komut satırından APT::Periodic::Enabledeğer almasına rağmen 0(aşağıya bakınız), unattended-upgradesprogram hala çalışıyor ...

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

3. /usr/lib/apt/apt.systemd.dailyTamamen çıkarın

Aşağıdaki cloud-initkomut, katılımsız yükseltme komut dosyasını tamamen kaldırır:

    #!/bin/bash

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

Yine de, görev devam ediyor ve bunu işlem tablosunda görebiliyorum! Her ne kadar dosya komut satırından araştırılmışsa olmasa da ::

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

Gibi gösteriyor cloud-init(birlikte SSH komut satırı ile) komut dosyası ve kök systemd süreci ayrı dosya sistemleri ve süreç mekanlarda yürütmek ...

Sorular

Kaybettiğim aşikar bir şey var mı? Yoksa bilmediğim bir sihir alanı var mı?

En önemlisi: apt-daily.servicebir cloud-initbetiği nasıl devre dışı bırakabilirim ?


2
Resmi bir paket güncellemesine alınana kadar bu size yardımcı olmayacak, ancak lütfen Debian # 844453 numaralı hataya gönderdiğim düzeltme ekini görün .
zwol

Belki de değişikliği hemen yürürlüğe koyabilmek için --nowkomuttaki bayrağı kaçırıyordunuz systemctl disable. Bu benim sorunumdu.
Daniel F,

@DanielF hayır, çünkü disable --noweşdeğerdir stopizledi disable.
kaynakjedi,

1
Görünüşe göre bu olmuştur NİHAYET 2019 Şubat içinde systemd sabit: github.com/systemd/systemd/issues/5659 . Öyleyse, 20.04 Ubuntu'da olacak.
ek bileşeni

Yanıtlar:


37

Evet, eksik olduğum belli bir şey vardı.

Systemd tüm hizmetlerin eşzamanlı başlaması konusunda, bu nedenle cloud-initkomut çalıştırılır aynı andaapt-daily.service tetiklenir. Zaman zaman cloud-initkullanıcı tarafından belirlenen yükü çalıştırmak için alır apt-get update, zaten çalışıyor. Bu yüzden 2. ve 3. denemeler bazı isim alanı büyüleri yüzünden başarısız olmadılar, ancak sistemi apt.systemd.dailyalmak için sistemi çok geç değiştirdiler .

Bu, aynı zamanda , çalışmasını engellemenin temelde bir yolu olmadığı anlamına gelir apt.systemd.daily- bir kişi ancak başladıktan sonra onu öldürebilir.

Bu "kullanıcı verileri" betiği bu rotayı izler:

#!/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

Hala SSH girişlerinin mümkün olduğu ancak apt-get çalışmayacağı bir zaman penceresi var , fakat Ubuntu 16.04 bulut görüntüsünün üzerinde çalışabilecek başka bir çözüm düşünemiyorum.


bu benim için çalıştı aws ubuntu 16.04, çözüm için teşekkürler
krisdigitx

Evet, özel bir AMI oluşturma yoluna gidiyorum. Bu aynı zamanda ortak servislerin kurulumunu da hızlandırır.
Giorgiosironi,

Bu yeterli gözükmüyor, hala zorlayıcı örnekler olduğunu görüyorumapt-get -o Acquire::http::AllowRedirect=false update
Edward Z. Yang

11

Not: Ne yazık ki, aşağıdaki çözümün bir kısmı Ubuntu 16.04 sistemlerinde (örneğin, sorgulayanlar gibi) çalışmaz çünkü önerilen systemd-runçağrı yalnızca Ubuntu 18.04 ve üzeri sürümlerde çalışır (ayrıntılar için yorumlara bakın ). Cevabı burada bırakacağım çünkü bu soru, hangi Ubuntu sürümünü kullandığınıza bakmaksızın hala popüler bir hit.

Ubuntu 18.04'te (ve üstü) önyükleme zamanında apt güncelleme / yükseltme işlemleriyle ilgili en fazla iki hizmet olabilir. İlk apt-daily.servicepaket listesini yeniler. Ancak, apt-daily-upgrade.servicegüvenlik açısından kritik paketleri yükleyen bir saniye olabilir . Bir "sonlandır ve devre dışı / komut dönmeden önce gözetimsiz yükseltme kaldır" cevabı soru (kolaylık olması açısından burada kopyalanan) bitirmek için bunlardan ikisi için beklemek nasıl mükemmel bir örnek verir:

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

(Bunun root olarak çalıştırılması gerektiğine dikkat edin). Bu hizmetleri gelecekteki botlarda devre dışı bırakmaya çalışıyorsanız, BOTH hizmetlerini maskelemeniz gerekir:

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

Alternatif olarak, systemctl disablehem hizmetleri hem de ilişkili zamanlayıcılarını (yani apt-daily.timerve apt-daily-upgrade.timer) yapabilirsiniz.

Bu cevaptaki maskeleme / devre dışı bırakma tekniklerinin yalnızca gelecekteki önyüklemelerde güncelleme / yükseltme yapılmasını önlediğini unutmayın; mevcut önyüklemede zaten çalışıyorlarsa bunları durdurmazlar.


2
Mükemmel cevap, teşekkür ederim! Bununla birlikte, systemd-runUbuntu 16.04'te bu --waitseçeneği desteklemek için çok eski olduğuna dikkat edin , ancak eldeki amaç için gerçekten gerekli olmamalıdır. (Man sayfasına göre , bir birimin sonlandırılmasını--wait bekler, ancak varsayılan davranışı olan başlangıcını beklemek yeterlidir .)systemd-run
Riccardo Murri

Düzeltilmiş systemd-rundurumdayım : verilen teşvik Ubuntu 16.04 ile hiç çalışmıyor; hata mesajı ile ölür Bilinmeyen atama Sonra = apt-daily.service apt-daily-upgrade.service . Bazı birim özellikleri mevcut değildi gibi görünüyor systemd-run, örneğin bkz burada
Riccardo Murri

@ riccardo-murri beni aldın :-)! Aslında 16.04 / 18.04 arasında kendimden farklılıklar olduğunu merak ediyordum (bu yüzden cılızca "ikiye") ve sonra ihtarı koymayı unuttum. Hangi değişikliği önerirsiniz?
Anon

@ riccardo-murri ah çok kötü, cevabın tepesine Ubuntu'da kullanılamayacağını söyleyen büyük bir uyarı ekleyeceğim 16.04
Anon

Hizmetleri devre dışı bırakıp yeniden başlattı ve işe yarıyor!
digz6666

3

Bunu "bootcmd" cloud-init modülü ile devre dışı bırakabilirsiniz. Bu, ağ yükseltilmeden önce çalışır; apt güncellemesinin çalıştırma şansı elde etmeden önce yapılması gerekir.

#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

Örneğe başladığınızda, cloud-init'in son aşamalarının bitmesini beklemelisiniz, çünkü uygun kaynakları / listeleri dolaştırır.

# 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

Bu, bootcmd'nin ne kadar erken çalıştığını görmek için de yararlıdır:

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

Bunun çalıştığını doğrulayabilirsiniz:

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

Üniteyi maskelemek daha kolay olmaz

systemctl mask apt-daily.service

?


Çalışmıyor - bölüm 1'e bakın . Sorunun metninde systemd görevini devre dışı bırakın . Ancak öneri için yine de teşekkürler! :-)
Riccardo Murri

2
Bir hizmeti devre dışı bırakma ve maskeleme aynı değildir. mask / dev / null dizinine bağlantı oluştur. ls -al /etc/systemd/system/ | grep alsa lrwxrwxrwx 1 root root 9 Sep 1 13:17 alsa-init.service -> /dev/nullVeri boş.

2
katılımsız yükseltme kurtulmak sudo dpkg-reconfigure -plow unattended-upgradesve onu yasakladı. Yani apt-daily.servis biriminin durumu öldü.

Merhaba @Bahamut çabalarınız için teşekkürler! Bununla birlikte asıl soru, apt-daily.servicebir cloud-initkomut dosyasından nasıl devre dışı bırakılacağı ve VM yeniden başlatıldıktan sonra başlamadan önce: bu şu anlama gelir: (1) etkileşimli olarak yapılmalı, (2) apt-daily.serviceilk defa ateşlenmeden önce yapılması gerekir . (Systemd benim anlayış doğru ise, (2) olamaz aslında olarak gerçekleştirilebilir cloud-initve apt-dailyaynı anda çalışacak -. Daha fazlası için kendi cevap bakınız)
Riccardo Murri

1
Bunu normal bir fiziksel makinede (yani bir VM değil) denedim ve çalışmadığını onaylayabilirim. Zamanlayıcıyı da durdurmanız gerekir: systemctl stop apt-daily.timer; systemctl devre dışı bırakmak apt-daily.timer
happyskeptic

0

Bu bir süre döngüsünde 1 saniye bekler ve kilidin serbest olup olmadığını kontrol eder.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.