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

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

Ubuntu 16.04サーバーのVMイメージは、約12時間ごとに「apt-daily.service」を起動しているようです。このサービスは、利用可能なパッケージのリストの更新、必要に応じて無人アップグレードの実行など、さまざまなAPT関連のタスクを実行します。

このサービスは、仮想マシン「スナップショット」から起動するとトリガーされます。まもなく、(おそらく)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値を取得したにもかかわらず、プログラムは引き続き実行されます。0unattended-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-initSSHコマンドラインとともに、スクリプトとルートシステムプロセスが別々のファイルシステムとプロセススペースで実行されているようです。

質問

私は明らかなものを見逃していますか?それとも私が知らないネームスペース魔法が進んでいるのでしょうか?

最も重要なのは:スクリプトapt-daily.serviceでどのようにcloud-init無効にするのですか?

答え1

はい、明らかに何かが落ちました。

Systemdはサービスの同時起動に関するものなので、cloud-initスクリプトの実行同時にトリガーされますapt-daily.servicecloud-initユーザーが指定したペイロードが実行されると、 apt-get updateすでに実行中です。そのため、試み2と3は、名前空間の魔法のためではなく、システムに遅すぎるためにapt.systemd.daily変更を受け入れることができなかったために失敗しました。

これは基本的に方法がないことを意味します。防止 apt.systemd.daily実行を防ぎます。開始した後にのみ終了してください。

この "userdata"スクリプトは次のパスを使用します。

#!/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クラウドイメージで動作する他のソリューションは想像できません.

答え2

注: 残念ながら、以下のソリューションの一部です。Ubuntu 16.04システムには適用されません。(例:質問者の)提案されたsystemd-run電話は次にのみ適用されます。Ubuntu 18.04以上(より詳しくはコメントをつけてください)。どのUbuntuバージョンを使用しても、この質問はまだ人気があるのでここに答えを残します。

Ubuntu 18.04(以降)では、起動時に適切なアップデート/アップグレードに最大2つのサービスを含めることができます。最初はapt-daily.serviceパッケージのリストを更新します。ただし、apt-daily-upgrade.serviceセキュリティにとって重要な2番目のパッケージが実際にインストールされている可能性があります。一つ「コマンドが返される前に、無人アップグレードの終了と無効/削除」に応答してください。この質問は、これらの2つのタスクが完了するのを待つ方法の良い例を提供します(便宜のためにここにコピーされます)。

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

(これはrootとして実行する必要があります。)将来のリリースでこれらのサービスを無効にするには、次の2つのサービスをブロックする必要があります。

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

あるいは、systemctl disableサービスと関連タイマー(例:apt-daily.timerapt-daily-upgrade.timer)の両方を使用できます。

この回答のブロック/無効化技術は、今後の実行時に更新/アップグレードのみをブロックします。現在の起動時にすでに実行されている場合はブロックしません。

答え3

"bootcmd" cloud-initモジュールを使用してこの機能を無効にできます。ネットワークが起動する前に実行されます。これは、適切なアップデートが実行される前に必要です。

#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

答え4

このデバイスを隠す方が簡単ではないでしょうか?

systemctl mask apt-daily.service

関連情報