UbuntuクラウドVMイメージで「apt-daily.service」を無効にする方法は?


60

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タスクを無効にします

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コマンドラインと一緒に)とルートのsystemdプロセスが別々のファイルシステムとプロセス空間で実行されるかのように見えます...

ご質問

私が行方不明になっていることは明らかですか?または、私が知らない名前空間の魔法がありますか?

最も重要なこと:スクリプトをapt-daily.service介して 無効にするにはどうすればよいcloud-initですか?


2
これは公式のパッケージアップデートに移行するまでは役に立ちませんが、Debianバグ#844453に投稿したばかりパッチをご覧ください。
-zwol

変更をすぐに有効にするため--nowに、systemctl disableコマンドのフラグが欠落している可能性があります。それが私の問題でした。
ダニエルF

@DanielFなし、ためdisable --nowに同等であるstopが続きますdisable
sourcejedi

1
どうやらこれはされていFINALLY:2019年2月にsystemdにして固定github.com/systemd/systemd/issues/5659。ですから、Ubuntu 20.04になることを願っています。
スナップ

回答:


38

はい、私が行方不明になったことは明らかでした。

systemdには、すべてのサービスを同時に開始についてですので、cloud-initスクリプトが実行されると同時にapt-daily.service起動されます。cloud-initユーザーが指定したペイロードを実行するまでに、 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 16.04クラウドイメージで機能する別のソリューションは想像できません。


これはUbuntuの16.04、ソリューションのおかげで、AWS上で私のために働いた
krisdigitx

はい、カスタムAMIを作成する道を進んでいます。これにより、共通サービスのインストールも高速化されます。
giorgiosironi

これはまだのインスタンス散在している、私はそこに見つける十分ではないようですapt-get -o Acquire::http::AllowRedirect=false update
エドワード・ヤンZ.

12

注:残念ながら、以下のソリューションの一部はUbuntu 16.04システム(質問者のシステムなど)では機能しません。これは、推奨されるsystemd-run呼び出しがUbuntu 18.04以上でのみ機能するためです(詳細についてはコメントを参照してください)。この質問は、使用しているUbuntuのバージョンに関係なく人気が高いため、ここに答えを残します...

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。これはデフォルトの動作です。)
リッカルドムリ

私は訂正しました:与えられたsystemd-run呪文はUbuntu 16.04 ではまったく機能しませ。エラーメッセージUnknown assignment After = apt-daily.service apt-daily-upgrade.serviceで終了します。一部のユニットプロパティがで使用できなかったようsystemd-runです。たとえば、こちらを
リッカルドムリ

@ riccardo-murriあなたが私を得た:-)!私は実際に16.04 / 18.04の違いについて疑問に思っていたので(イタチが「2つまで」)、警告を入れるのを忘れていました。どのような変更を提案しますか?
アノン

私はそれがUbuntuの16.04で使用することはできませんと言って答えの上部に大きな警告を追加します残念だ@リッカルド・murriああ
アノン

サービスを無効にして再起動すると動作します!
digz6666

4

これを無効にするには、「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

インスタンスにsshした後、適切なソース/リストを移動するため、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

2

ユニットをマスクするのは簡単ではありません

systemctl mask apt-daily.service


動作しません-セクション1を参照してください。質問のテキストでsystemdタスク無効にします。とにかく提案に感謝します!:-)
リッカルドムリ

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-initapt-daily
リッカルドムリ

1
これを通常の物理マシン(VMではない)で試しましたが、動作しないことを確認できます。タイマーも停止する必要があります。systemctl stop apt-daily.timer; systemctl disable apt-daily.timer
happyskeptic

1

これは、whilループで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.