วิธีการปิดการใช้งาน 'apt-daily.service' บน Ubuntu cloud VM image?


59

อิมเมจ VM เซิร์ฟเวอร์ Ubuntu 16.04 เห็นได้ชัดว่าเริ่ม "apt-daily.service" ทุก ๆ 12 ชั่วโมงหรือมากกว่านั้น บริการนี้ทำหน้าที่ที่เกี่ยวข้องกับ APT หลายประการเช่นการรีเฟรชรายการแพ็คเกจที่มีอยู่ดำเนินการอัปเกรดแบบไม่ต้องใส่ข้อมูลหากจำเป็น ฯลฯ

เมื่อเริ่มต้นจาก VM "snapshot" บริการจะถูกเรียกใช้ทันทีเนื่องจาก (ฉันเข้าใจ) systemd ตระหนักถึงอย่างรวดเร็วว่าตัวจับเวลาควรจะหายไปนานแล้ว

อย่างไรก็ตามการป้องกันไม่ให้ APT ทำงานอื่น ๆกระบวนการจากการทำงานในขณะที่มันถือล็อคบนapt /var/lib/dpkgข้อความแสดงข้อผิดพลาดที่ระบุว่ามีลักษณะดังนี้:

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?

ฉันต้องปิดการใช้งานงาน APT อัตโนมัตินี้จนกว่า Ansible จะเสร็จสิ้นการตั้งค่าเครื่อง (ซึ่งโดยทั่วไปเกี่ยวข้องกับการติดตั้งแพ็คเกจ) ดูhttps://github.com/gc3-uzh-ch/elasticluster/issues/304สำหรับข้อมูลเพิ่มเติมและบริบท

ฉันได้ลองตัวเลือกต่าง ๆ เพื่อปิดใช้งานคุณลักษณะ "การอัปเกรดแบบไม่ต้องใส่ข้อมูล" ผ่านสคริปต์ "ข้อมูลผู้ใช้" สำหรับcloud-initแต่พวกเขาทั้งหมดล้มเหลวไปแล้ว

1. ปิดใช้งานภารกิจ systemd

งาน systemd ถูกเรียกโดยapt-daily.service apt-daily.timerฉันได้ลองปิดการใช้งานอย่างใดอย่างหนึ่งหรืออื่น ๆ หรือทั้งสองอย่างด้วย cobinations ต่าง ๆ ของคำสั่งต่อไปนี้ ยังคงapt-daily.serviceมีการเริ่มต้นช่วงเวลาหลังจาก VM ก็พร้อมที่จะยอมรับการเชื่อมต่อ SSH ::

    #!/bin/bash

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

2. ปิดการใช้งานตัวเลือกการกำหนดค่า APT::Periodic::Enable

สคริปต์/usr/lib/apt/apt.systemd.dailyอ่านตัวแปรการกำหนดค่า APT สองสามตัว การตั้งค่าAPT::Periodic::Enableปิดการใช้งานการทำงานทั้งหมด (บรรทัด 331--337) ฉันได้ลองปิดการใช้งานด้วยสคริปต์ต่อไปนี้ ::

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

อย่างไรก็ตามแม้จะAPT::Periodic::Enableมีค่า0จากบรรทัดคำสั่ง (ดูด้านล่าง) unattended-upgradesโปรแกรมยังคงทำงาน ...

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

3. ลบ/usr/lib/apt/apt.systemd.dailyทั้งหมด

cloud-initสคริปต์ต่อไปนี้ลบสคริปต์การอัพเกรดแบบอัตโนมัติทั้งหมด ::

    #!/bin/bash

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

ยังทำงานและฉันสามารถดูได้ในตารางกระบวนการ! แม้ว่าไฟล์จะไม่มีอยู่หากตรวจสอบจากบรรทัดคำสั่ง ::

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

ดูเหมือนว่าcloud-initสคริปต์ (พร้อมกับบรรทัดคำสั่ง SSH) และกระบวนการรูท systemd ดำเนินการในระบบไฟล์แยกต่างหากและพื้นที่กระบวนการ ...

คำถาม

มีบางสิ่งที่ชัดเจนว่าฉันหายไปหรือไม่? หรือมีเนมสเปซเวทมนตร์ที่เกิดขึ้นซึ่งฉันไม่รู้

ที่สำคัญที่สุด: ฉันจะปิดการใช้งานapt-daily.serviceผ่าน cloud-initสคริปต์ได้อย่างไร


2
นี้ไม่ได้จะช่วยให้คุณจนกว่าจะได้รับรีดเป็นแพคเกจการปรับปรุงอย่างเป็นทางการ แต่โปรดดูแพทช์ฉันเพียงแค่โพสต์ไป Debian ข้อผิดพลาด #
zwol

บางทีคุณอาจพลาดการ--nowตั้งค่าสถานะในsystemctl disableคำสั่งเพื่อให้การเปลี่ยนแปลงมีผลทันที นั่นคือปัญหาของฉัน
Daniel F

@DanielF ไม่เพราะdisable --nowจะเทียบเท่ากับการตามstop disable
sourcejedi

1
เห็นได้ชัดว่านี้ได้รับในที่สุดการแก้ไขใน systemd ใน 2019 กุมภาพันธ์: github.com/systemd/systemd/issues/5659 หวังว่ามันจะอยู่ใน Ubuntu 20.04
snap

คำตอบ:


37

ใช่มีบางสิ่งที่ชัดเจนว่าฉันหายไป

Systemd คือทั้งหมดที่เกี่ยวกับการเริ่มต้นบริการพร้อมกันดังนั้นcloud-initสคริปต์จะถูกเรียกใช้ในเวลาเดียวกันที่apt-daily.serviceถูกทริกเกอร์ ตามเวลาที่ cloud-initได้รับการดำเนินการ payload ระบุผู้ใช้apt-get updateกำลังทำงานอยู่ ดังนั้นความพยายามที่ 2. และ 3. ล้มเหลวไม่ใช่เพราะเวทมนตร์เนมสเปซบางอย่าง แต่เนื่องจากพวกเขาเปลี่ยนระบบสายเกินไปที่apt.systemd.dailyจะรับการเปลี่ยนแปลง

นี่ก็หมายความว่าไม่มีทางที่จะป้องกันการ apt.systemd.dailyวิ่ง - โดยทั่วไปสามารถฆ่ามันได้หลังจากเริ่ม

สคริปต์ "ข้อมูลผู้ใช้" นี้ใช้เส้นทางนี้ ::

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

ยังคงมีหน้าต่างเวลาระหว่างการล็อกอิน SSH ที่เป็นไปได้ แต่apt-get จะไม่ทำงาน แต่ฉันไม่สามารถจินตนาการโซลูชันอื่นที่สามารถใช้งานได้ในสต็อกภาพเมฆ Ubuntu Ubuntu 16.04


นี้ทำงานสำหรับฉันใน AWS อูบุนตู 16.04 ขอบคุณสำหรับการแก้ปัญหา
krisdigitx

ใช่ฉันกำลังจะไปสู่การสร้าง AMI ที่กำหนดเอง นอกจากนี้ยังเพิ่มความเร็วในการติดตั้งบริการทั่วไป
giorgiosironi

ดูเหมือนว่าจะไม่เพียงพอฉันพบว่ายังมีกรณีที่ยังหลงเหลืออยู่ของapt-get -o Acquire::http::AllowRedirect=false update
เอ็ดเวิร์ดซีหยาง

11

หมายเหตุ: น่าเสียดายที่บางส่วนของวิธีการแก้ปัญหาด้านล่างใช้ไม่ได้กับระบบ Ubuntu 16.04 (เช่นของผู้ถาม) เนื่องจากการsystemd-runร้องขอที่แนะนำใช้งานได้กับUbuntu 18.04 ขึ้นไปเท่านั้น (ดูความคิดเห็นเพื่อดูรายละเอียด ) ฉันจะทิ้งคำตอบไว้ที่นี่เพราะคำถามนี้ยังได้รับความนิยมไม่ว่าคุณใช้ Ubuntu เวอร์ชันใด ...

ใน Ubuntu 18.04 (และสูงกว่า) อาจมีบริการไม่เกินสองรายการที่เกี่ยวข้องกับเวลาบูตที่สามารถอัปเดต / อัปเกรดได้ การapt-daily.serviceรีเฟรชรายการแพ็คเกจเป็นครั้งแรก อย่างไรก็ตามอาจมีวินาทีapt-daily-upgrade.serviceที่ติดตั้งแพ็คเกจความปลอดภัยที่สำคัญจริง ๆ คำตอบของ "ยุติและปิดการใช้งาน / ลบอัพเกรดแบบอัตโนมัติก่อนที่คำสั่งส่งกลับ"คำถามที่จะช่วยให้เป็นตัวอย่างที่ดีของวิธีการที่จะรอให้ทั้งสองคนนี้จะเสร็จสิ้น (คัดลอกมาที่นี่เพื่อความสะดวก)

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

(โปรดทราบว่าสิ่งนี้จะต้องถูกเรียกใช้ในฐานะรูท) หากคุณพยายามปิดการใช้งานบริการเหล่านี้ในบูทในอนาคตคุณจะต้องปิดบังบริการ BOTH:

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

อีกทางเลือกหนึ่งคุณสามารถsystemctl disableทั้งบริการและตัวจับเวลาที่เกี่ยวข้อง (เช่นapt-daily.timerและapt-daily-upgrade.timer)

หมายเหตุเทคนิคการปิด / ปิดการใช้งานในคำตอบนี้จะป้องกันการอัปเดต / อัปเกรดในบู๊ตในอนาคตเท่านั้น - พวกเขาจะไม่หยุดพวกเขาหากพวกเขากำลังทำงานอยู่ในการบู๊ตปัจจุบัน


2
คำตอบที่ยอดเยี่ยมขอบคุณ! แม้ว่าโปรดทราบว่าsystemd-runใน Ubuntu 16.04 นั้นเก่าเกินไปที่จะรองรับ--waitตัวเลือก แต่ไม่จำเป็นต้องมีจุดประสงค์ (ตามหน้าคนที่--waitรอสำหรับการเลิกจ้างของหน่วย แต่ก็พอที่จะรอสำหรับการเริ่มต้นซึ่งเป็นพฤติกรรมปกติของsystemd-run.)
คาร์โด้ Murri

ฉันยืนแก้ไข: systemd-runคาถาที่กำหนดไม่ทำงานบน Ubuntu 16.04 เลย; มันตายด้วยข้อผิดพลาดที่ไม่รู้จักที่ได้รับมอบหมายหลังจาก = apt-daily.service apt-ประจำวัน ดูเหมือนว่าคุณสมบัติของหน่วยบางอย่างไม่พร้อมใช้งานsystemd-runดูตัวอย่างได้ที่นี่
Riccardo Murri

@ riccardo-murri คุณได้รับฉัน :-)! จริง ๆ แล้วฉันสงสัยเกี่ยวกับความแตกต่าง 16.04 / 18.04 ตัวเอง (ดังนั้น weaselly "ถึงสอง") และจากนั้นลืมที่จะใส่ข้อแม้คุณจะเปลี่ยนแปลงอะไรแนะนำ?
Anon

@ riccardo-murri อ่าแย่เกินไปฉันจะเพิ่มคำเตือนไปด้านบนสุดของคำตอบว่าไม่สามารถใช้กับ Ubuntu 16.04
Anon

ปิดใช้งานบริการและเริ่มต้นใหม่และใช้งานได้!
digz6666

3

คุณสามารถปิดการใช้งานผ่านโมดูล "bootcmd" cloud-init สิ่งนี้จะทำงานก่อนที่จะมีเครือข่ายเกิดขึ้นซึ่งเป็นสิ่งจำเป็นก่อนที่ apt update จะได้รับโอกาสให้รัน

#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

เมื่อคุณเข้าสู่อินสแตนซ์แล้วคุณควรรอขั้นตอนสุดท้ายของ cloud-init ให้เสร็จเนื่องจากมันจะย้ายแหล่ง / รายการที่เหมาะสม

# 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

สิ่งนี้มีประโยชน์เช่นกันเพื่อดูว่า bootcmd ทำงานเร็วแค่ไหน:

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

คุณสามารถตรวจสอบการทำงานดังต่อไปนี้:

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

คงไม่ง่ายกว่าที่จะปกปิดเครื่อง

systemctl mask apt-daily.service

?


ไม่ทำงาน - ดูหัวข้อที่1 ปิดใช้งาน systemdในข้อความของคำถาม แต่ขอบคุณสำหรับคำแนะนำต่อไป! :-)
Riccardo Murri

2
ปิดการใช้งานและปิดบังบริการไม่เหมือนกัน mask สร้าง Link to / dev / null ls -al /etc/systemd/system/ | grep alsa lrwxrwxrwx 1 root root 9 Sep 1 13:17 alsa-init.service -> /dev/nullข้อมูลว่างเปล่า

2
ฉันกำจัดการอัพเกรดแบบไม่มีใครดูแลsudo dpkg-reconfigure -plow unattended-upgradesและ forbit มัน ดังนั้นสถานะของหน่วย apt-daily.service จึงตาย

สวัสดี @Bahamut ขอบคุณสำหรับความพยายามของคุณ! อย่างไรก็ตามคำถามคือวิธีการปิดการใช้งานapt-daily.serviceจากcloud-initสคริปต์และก่อนที่จะเริ่มต้นหลังจากรีบูต VM: หมายความว่า: (1) ต้องทำแบบไม่โต้ตอบ (2) จะต้องทำก่อนที่จะapt-daily.serviceเริ่มเป็นครั้งแรก (หากความเข้าใจของฉันเกี่ยวกับ systemd ถูกต้อง (2) ไม่สามารถทำได้จริงcloud-initและapt-dailyทำงานพร้อมกัน - ดูคำตอบของฉันเองสำหรับข้อมูลเพิ่มเติม)
Riccardo Murri

1
ฉันลองสิ่งนี้กับเครื่องทางกายภาพปกติ (เช่นไม่ใช่ VM) และสามารถยืนยันได้ว่ามันไม่ทำงาน คุณจำเป็นต้องหยุดจับเวลาด้วยเช่นกัน: systemctl stop apt-daily.timer; systemctl ปิดการใช้งาน apt-daily.timer
happyskeptic

0

สิ่งนี้จะรอ 1 วินาทีในการวนลูปและตรวจสอบว่ามีการปลดล็อคหรือไม่

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.