Làm cách nào để tắt `apt-Daily.service` trên hình ảnh máy chủ đám mây Ubuntu?


60

Hình ảnh VM máy chủ Ubuntu 16.04 rõ ràng bắt đầu "apt-Daily.service" cứ sau 12 giờ hoặc lâu hơn; dịch vụ này thực hiện các nhiệm vụ khác nhau liên quan đến APT như làm mới danh sách các gói có sẵn, thực hiện nâng cấp không giám sát nếu cần, v.v.

Khi bắt đầu từ "snapshot" VM, dịch vụ được kích hoạt ngay lập tức , vì (tôi đoán) systemd nhận ra nhanh chóng rằng bộ định thời gian đã tắt từ lâu.

Tuy nhiên, một APT đang chạy sẽ ngăn các apttiến trình khác chạy khi nó khóa /var/lib/dpkg. Thông báo lỗi cho biết điều này trông như thế này:

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?

Tôi cần phải tắt tác vụ APT tự động này cho đến khi Ansible hoàn thành cài đặt máy (thường bao gồm cài đặt các gói); xem https://github.com/gc3-uzh-ch/elasticluster/issues/304 để biết thêm thông tin và bối cảnh.

Tôi đã thử nhiều tùy chọn khác nhau để vô hiệu hóa tính năng "nâng cấp không giám sát" thông qua tập lệnh "dữ liệu người dùng" cloud-init, nhưng tất cả chúng đều thất bại.

1. Vô hiệu hóa tác vụ systemd

nhiệm vụ systemd apt-daily.serviceđược kích hoạt bởi apt-daily.timer. Tôi đã cố gắng vô hiệu hóa cái này hoặc cái kia, hoặc cả hai, với các kết hợp khác nhau của các lệnh sau; Tuy nhiên, apt-daily.servicekhoảnh khắc được bắt đầu sau khi VM sẵn sàng chấp nhận kết nối SSH ::

    #!/bin/bash

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

2. Tắt tùy chọn cấu hình APT::Periodic::Enable

Script /usr/lib/apt/apt.systemd.dailyđọc một vài biến cấu hình APT; cài đặt sẽ APT::Periodic::Enablevô hiệu hóa chức năng hoàn toàn (dòng 331--337). Tôi đã thử vô hiệu hóa nó với đoạn script sau ::

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

Tuy nhiên, mặc dù APT::Periodic::Enablecó giá trị 0từ dòng lệnh (xem bên dưới), unattended-upgradeschương trình vẫn chạy ...

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

3. Hủy bỏ /usr/lib/apt/apt.systemd.dailyhoàn toàn

Tập cloud-initlệnh sau sẽ loại bỏ hoàn toàn tập lệnh nâng cấp không giám sát ::

    #!/bin/bash

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

Tuy nhiên, tác vụ chạy và tôi có thể thấy nó trong bảng quy trình! mặc dù tập tin không tồn tại nếu được thăm dò từ dòng lệnh ::

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

Dường như cloud-inittập lệnh (cùng với dòng lệnh SSH) và quy trình hệ thống gốc thực thi trong các hệ thống tệp và không gian xử lý riêng biệt ...

Câu hỏi

Có một cái gì đó rõ ràng tôi đang thiếu? Hoặc có một số ma thuật không gian tên đang diễn ra mà tôi không biết?

Quan trọng nhất: làm thế nào tôi có thể vô hiệu hóa apt-daily.servicethông qua một cloud-inittập lệnh?


2
Điều này sẽ không giúp bạn cho đến khi nó được đưa vào bản cập nhật gói chính thức, nhưng vui lòng xem bản vá tôi vừa đăng lên lỗi Debian # 844453 .
zwol

Có thể bạn đã thiếu --nowcờ trong systemctl disablelệnh để thay đổi có hiệu lực ngay lập tức. Đó là vấn đề của tôi.
Daniel F

@DanielF không, vì disable --nowtương đương với stoptheo sau disable.
nguồnjedi

1
Rõ ràng điều này đã được cuôi cung cố định trong systemd năm 2019 Tháng Hai: github.com/systemd/systemd/issues/5659 . Vì vậy, hy vọng nó sẽ có trong Ubuntu 20.04.
chụp

Câu trả lời:


38

Vâng, có một cái gì đó rõ ràng mà tôi đã mất tích.

Systemd là tất cả về khởi động đồng thời các dịch vụ, vì vậy cloud-inittập lệnh được chạy cùng lúc với trình apt-daily.servicekích hoạt. Đến lúc cloud-initthực hiện tải trọng do người dùng chỉ định, apt-get updateđã chạy. Vì vậy, các nỗ lực 2. và 3. thất bại không phải vì một số phép thuật không gian tên, mà vì chúng đã thay đổi hệ thống quá muộn apt.systemd.dailyđể chọn các thay đổi.

Điều này cũng có nghĩa là về cơ bản không có cách nào để ngăn chặn việc apt.systemd.daily chạy - người ta chỉ có thể giết nó sau khi nó bắt đầu.

Kịch bản "dữ liệu người dùng" này có tuyến đường này ::

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

Vẫn còn một cửa sổ thời gian mà đăng nhập SSH có thể chưa apt-get chạy, nhưng tôi không thể tưởng tượng một giải pháp khác có thể hoạt động trên hình ảnh đám mây Ubuntu 16.04.


cái này hiệu quả với tôi trên
aws ub

Vâng, tôi đang đi trên con đường tạo ra một AMI tùy chỉnh. Điều này cũng tăng tốc độ cài đặt các dịch vụ phổ biến.
giorgiosironi

Điều này dường như là không đủ, tôi thấy vẫn còn những trường hợp đáng kinh ngạc củaapt-get -o Acquire::http::AllowRedirect=false update
Edward Z. Yang

12

Lưu ý: Thật không may, một phần của giải pháp bên dưới không hoạt động trên các hệ thống Ubuntu 16.04 (chẳng hạn như của người hỏi) vì systemd-runlời gọi được đề xuất chỉ hoạt động trên Ubuntu 18.04 trở lên (xem các nhận xét để biết chi tiết ). Tôi sẽ để lại câu trả lời ở đây vì câu hỏi này vẫn là một câu hỏi phổ biến bất kể bạn đang sử dụng phiên bản Ubuntu nào ...

Trên Ubuntu 18.04 (trở lên), có thể có tới hai dịch vụ liên quan đến cập nhật / nâng cấp apt thời gian khởi động. Việc đầu tiên apt-daily.servicelàm mới danh sách các gói. Tuy nhiên, có thể có một giây apt-daily-upgrade.servicethực sự cài đặt các gói bảo mật quan trọng. Một câu trả lời cho "Chấm dứt và vô hiệu hóa / gỡ bỏ nâng cấp giám sát trước khi trở về lệnh" câu hỏi đưa ra một ví dụ tuyệt vời về cách để chờ đợi cho cả hai để kết thúc (sao chép ở đây cho thuận tiện):

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

(lưu ý điều này phải được chạy dưới quyền root). Nếu bạn đang cố gắng vô hiệu hóa các dịch vụ này trên các bốt trong tương lai, bạn sẽ cần che dấu các dịch vụ BÓNG:

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

Ngoài ra, bạn có thể systemctl disablecả hai dịch vụ VÀ bộ tính giờ liên quan của chúng (tức là apt-daily.timerapt-daily-upgrade.timer).

Lưu ý các kỹ thuật che / tắt trong câu trả lời này chỉ ngăn việc cập nhật / nâng cấp cho những đôi giày trong tương lai - chúng sẽ không dừng chúng nếu chúng đang chạy trong khởi động hiện tại.


2
Câu trả lời tuyệt vời, cảm ơn bạn! Mặc dù, lưu ý rằng systemd-runtrên Ubuntu 16.04 quá cũ để hỗ trợ --waittùy chọn, nhưng nó không thực sự cần thiết cho mục đích trong tay. (Theo trang của người đàn ông, --waitchờ đợi chấm dứt một đơn vị nhưng đủ để chờ bắt đầu, đó là hành vi mặc định của systemd-run.)
Riccardo Murri

Tôi đã sửa chữa: systemd-runcâu thần chú đã cho không hoạt động trên Ubuntu 16.04; nó chết với thông báo lỗi Phân công không xác định After = apt-Daily.service apt-Daily-nâng.service . Có vẻ như một số thuộc tính đơn vị không có sẵn systemd-run, xem ví dụ ở đây
Riccardo Murri

@ riccardo-murri bạn đã cho tôi :-)! Tôi đã thực sự tự hỏi về sự khác biệt 16.04 / 18.04 (do đó "lên đến hai" đáng sợ) và sau đó quên đặt cảnh báo vào. Bạn sẽ đề nghị thay đổi gì?
Anon

@ riccardo-murri ah thật tệ, tôi sẽ thêm một cảnh báo lớn vào đầu câu trả lời rằng nó không thể được sử dụng trên Ubuntu 16.04
Anon

Vô hiệu hóa các dịch vụ và khởi động lại và nó hoạt động!
digz6666

4

Bạn có thể vô hiệu hóa điều này thông qua mô-đun đám mây "bootcmd". Điều này chạy trước khi mạng được đưa lên, điều này là bắt buộc trước khi cập nhật apt có thể có cơ hội chạy.

#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

Khi bạn ssh vào ví dụ, bạn cũng nên đợi các giai đoạn cuối cùng của cloud-init kết thúc, vì nó di chuyển các nguồn / danh sách apt xung quanh.

# 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

Điều này cũng hữu ích để xem bootcmd chạy sớm như thế nào:

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

Bạn có thể xác minh điều này hoạt động như sau:

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

2

Sẽ không dễ dàng hơn để che dấu đơn vị

systemctl mask apt-daily.service

?


Không hoạt động - xem phần 1. Vô hiệu hóa tác vụ systemd trong văn bản của câu hỏi. Nhưng dù sao cũng cảm ơn vì lời đề nghị! :-)
Riccardo Murri

2
vô hiệu hóa và che dấu một dịch vụ không giống nhau. mặt nạ tạo một Liên kết đến / dev / null. ls -al /etc/systemd/system/ | grep alsa lrwxrwxrwx 1 root root 9 Sep 1 13:17 alsa-init.service -> /dev/nullDữ liệu trống.

2
tôi thoát khỏi nâng cấp không giám sát sudo dpkg-reconfigure -plow unattended-upgradesvà bỏ qua nó. Vì vậy, trạng thái của đơn vị apt-Daily.service đã chết.

Xin chào @Bahamut cảm ơn những nỗ lực của bạn! Câu hỏi đặt ra, tuy nhiên, là làm thế nào để vô hiệu hóa apt-daily.servicetừ một cloud-initkịch bản trước khi nó bắt đầu sau khi khởi động lại máy ảo: điều này có nghĩa: (1) nó phải được thực hiện không tương tác, (2) nó phải được thực hiện trước khi apt-daily.servicecháy cho lần đầu tiên. (Nếu sự hiểu biết của tôi về systemd là chính xác, (2) thực sự không thể được thực hiện cloud-initapt-dailychạy đồng thời - hãy xem câu trả lời của riêng tôi để biết thêm.)
Riccardo Murri

1
Tôi đã thử điều này trên một máy vật lý bình thường (không phải là VM) và có thể xác nhận nó không hoạt động. Bạn cũng cần dừng bộ hẹn giờ: systemctl dừng apt-Daily.timer; systemctl vô hiệu hóa apt-Daily.timer
happyskeptic

1

Cái này đợi 1 giây trong một vòng lặp và kiểm tra xem khóa có được giải phóng không.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.