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::Enable0을 얻음에도 불구하고 (아래 참조) 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 --nowstop뒤에 오는 것과 같습니다 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.timerapt-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.servicecloud-init스크립트 에서 비활성화하는 방법 VM 재부팅 후 시작하기 전에 : (1) 비 대화식으로 수행해야하고, (2) apt-daily.service처음으로 시작하기 전에 수행해야 함을 의미합니다 . (systemd에 대한 이해가 올바른 경우, (2) 할 수없는 사실로 수행 할 수 cloud-initapt-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.