Ubuntu 클라우드 VM 이미지에서`apt-daily.service`를 비활성화하는 방법은 무엇입니까?


59

Ubuntu 16.04 서버 VM 이미지는 12 시간 정도마다 "apt-daily.service"를 시작합니다. 이 서비스는 사용 가능한 패키지 목록 새로 고침, 필요한 경우 무인 업그레이드 수행 등과 같은 다양한 APT 관련 작업을 수행합니다.

VM "스냅 샷"에서 시작할 때 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?

Ansible이 컴퓨터 설정 (일반적으로 패키지 설치 포함)을 완료 할 때까지이 자동 APT 작업을 비활성화해야합니다. 자세한 정보 및 컨텍스트는 https://github.com/gc3-uzh-ch/elasticluster/issues/304 를 참조 하십시오 .

에 대한 "사용자 데이터"스크립트를 통해 "무인 업그레이드"기능을 비활성화하는 다양한 옵션을 시도했지만 cloud-init지금까지 모두 실패했습니다.

1. 시스템 작업 비활성화

systemd 작업 apt-daily.service이에 의해 트리거됩니다 apt-daily.timer. 다음 명령의 다양한 조합으로 하나 또는 다른 또는 둘 다를 비활성화하려고했습니다. 여전히 apt-daily.serviceVM이 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 명령 줄과 함께)와 루트 시스템 프로세스가 별도의 파일 시스템과 프로세스 공간에서 실행 되는 것처럼 보입니다 .

질문

내가 놓친 것이 분명합니까? 아니면 내가 알지 못하는 네임 스페이스 마술이 있습니까?

가장 중요한 것은 : 스크립트를 apt-daily.service통해 비활성화하는 방법은 cloud-init무엇입니까?


2
공식 패키지 업데이트에 들어갈 때까지는 도움이되지 않지만, 데비안 버그 # 844453에 방금 게시 한 패치 를 참조하십시오 .
— zwol

변경 사항을 즉시 적용하기 위해 명령에서 --now플래그 가 누락되었을 수 있습니다 systemctl disable. 그게 내 문제 였어
— Daniel F

@DanielF no disable --now는 stop뒤에 오는 것과 같습니다 disable.
— sourcejedi

1
분명히이되어 마침내 2019 2 월 systemd에 고정 : github.com/systemd/systemd/issues/5659를 . 우분투 20.04에있을 것입니다.
— 스냅

답변:


37

그렇습니다. 제가 빠진 것이 분명했습니다.

Systemd 모든 서비스 동시 시작에 대해, 그래서 cloud-init스크립트가 실행되는 동시에 (가) apt-daily.service시작됩니다. 시간 cloud-init이 지날 수록 사용자 지정 페이로드 apt-get update가 실행되고 있습니다. 따라서 네임 스페이스 마법 때문에 두 번째와 세 번째 시도는 실패했지만 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 실행되지 않는 시간 창이 있지만 재고 우분투 16.04 클라우드 이미지에서 작동 할 수있는 다른 솔루션을 상상할 수는 없습니다.


이 우분투 16.04, 솔루션에 대한 감사 AWS에 나를 위해 일한
— krisdigitx

예, 맞춤형 AMI를 생성하는 길을 가고 있습니다. 또한 공통 서비스 설치 속도가 빨라집니다.
— giorgiosironi

이것은 여전히 인스턴스 낙오되어, 내가 거기에 찾을 충분하지 않는 것apt-get -o Acquire::http::AllowRedirect=false update
— 에드워드 Z. 양

11

참고 : 제안 된 호출이 Ubuntu 18.04 이상 에서만 작동 하기 때문에 아래 솔루션의 일부 는 질문자 시스템 과 같은 Ubuntu 16.04 시스템에서 작동하지 않습니다 (자세한 내용은 주석 참조 ). 이 질문은 사용중인 우분투 버전에 관계없이 여전히 인기있는 히트이기 때문에 여기에 답을 남겨 두겠습니다 ...systemd-run

Ubuntu 18.04 이상에서는 부팅 시간에 적절한 업데이트 / 업그레이드와 관련된 서비스가 최대 2 개있을 수 있습니다. 첫 번째 apt-daily.service는 패키지 목록을 새로 고칩니다. 그러나 apt-daily-upgrade.service실제로 보안에 중요한 패키지를 설치 하는 초가있을 수 있습니다 . "종료 및 활성화 / 비활성화 명령이 리턴하기 전에 무인 업그레이드를 제거"를에 답 질문 (편의상 여기에 복사) 완료 이들 모두 대기하는 방법의 좋은 예를 제공합니다 :

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

(이것은 루트로 실행되어야합니다). 향후 부팅시 이러한 서비스를 비활성화하려는 경우 두 서비스를 모두 마스크해야합니다.

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

또는 systemctl disable서비스와 관련 타이머 (예 : apt-daily.timer및 apt-daily-upgrade.timer)를 모두 사용할 수 있습니다 .

이 답변의 마스킹 / 비활성화 기술은 향후 부팅시 업데이트 / 업그레이드 만 방지합니다. 현재 부팅에서 이미 실행중인 경우 중지되지 않습니다.


2
훌륭한 답변, 감사합니다! 그러나 systemd-runUbuntu 16.04에서는 --wait옵션 을 지원하기에는 너무 오래 되었지만 실제로는 그 목적에 필요하지는 않습니다. (매뉴얼 페이지에 따르면 , 유닛 --wait이 종료 될 때까지 기다리지 만 기본 동작 인 시작을 기다리는 것으로 충분합니다 systemd-run.)
— Riccardo Murri

나는 정정했다 : 주어진 명령 은 우분투 16.04에서 전혀 작동 systemd-run하지 않는다 . 알 수없는 할당 After = apt-daily.service apt-daily-upgrade.service 오류 메시지와 함께 종료 됩니다. 그것은 몇 가지 단위 속성에서 사용할 수없는 것처럼 보이는 systemd-run, 예를 들어 볼 여기
— 리카르도 Murri 지역

@ riccardo-murri 당신은 저를 얻었다 :-)! 나는 실제로 16.04 / 18.04의 차이점에 대해 궁금해하고 있었으므로 (따뜻한 "최대 2") 경고를 넣는 것을 잊었습니다. 어떤 변화를 제안 하시겠습니까?
— Anon

나는 그것이 우분투 16.04에 사용할 수 없다는 대답의 상단에 큰 경고를 추가 할 것이다 너무 나쁘다 @ 리카르도-Murri은 아
— 익명

서비스를 비활성화하고 다시 시작하면 작동합니다!
— digz6666

3

"bootcmd"cloud-init 모듈을 통해이를 비활성화 할 수 있습니다. 이것은 네트워크가 시작되기 전에 실행되며 apt 업데이트가 실행되기 전에 필요합니다.

#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

Woudn은 장치를 마스킹하기가 쉽지 않습니다

systemctl mask apt-daily.service

?


작동하지 않음- 질문 1에서 시스템 작업 을 비활성화하십시오 . 그러나 어쨌든 제안에 감사드립니다! :-)
— Riccardo Murri

2
서비스 비활성화 및 마스킹은 동일하지 않습니다. mask / 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하고 그것을 버린다. 따라서 apt-daily.service 단위의 상태가 종료되었습니다.

노력해 주셔서 감사합니다 @Bahamut! 그러나 문제 apt-daily.service는 cloud-init스크립트 에서 비활성화하는 방법 과 VM 재부팅 후 시작하기 전에 : (1) 비 대화식으로 수행해야하고, (2) apt-daily.service처음으로 시작하기 전에 수행해야 함을 의미합니다 . (systemd에 대한 이해가 올바른 경우, (2) 할 수없는 사실로 수행 할 수 cloud-init와 apt-daily동시에 실행 -. 더 내 자신의 답변을 참조)
— 리카르도 Murri 지역

1
VM이 아닌 일반 물리적 컴퓨터에서 시도했지만 작동하지 않는 것을 확인할 수 있습니다. 또한 타이머를 중지해야합니다. systemctl stop apt-daily.timer; systemctl disable 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.