Ubuntuのcgroupsを使用してコマンドのCPUとメモリ使用量を制限する

Ubuntuデスクトップの動作が遅くなったり、サーバーのメモリが不足したりするコマンドがある場合は、そのコマンドとその子プロセスを、CPUクォータとメモリ上限を設定したsystemd管理のcgroupに配置してください。現在のUbuntuリリースでは、systemd-run --scopeこれが最も手っ取り早い方法です。コマンドを一時的なスコープで起動し、systemdがcgroup制御を通じて制限を適用します。

以下の例では、ワークロードをCPUの半分の容量と1GiBのメモリに制限しています。これらは子プロセスを含む全体の範囲に対する制限であり、プログラムが特定の速度で動作することを保証するものではありません。

プロセスにcgroup制限が必要な理由

負荷の高いプロセスは対話型アプリケーションと競合する可能性があり、メモリを大量に消費するプロセスはマシンをメモリ解放モードまたはメモリ不足状態に陥らせる可能性があります。cgroupはプロセスをその子孫プロセスとグループ化することで、カーネルがそのグループを管理および制御できるようにします。Ubuntuのsystemdは、これらの制御を行うための便利なインターフェースを提供します。

CPU とメモリの設定は動作が異なります。はCPUQuota=50%、スケジューリング期間の平均で、1 つの CPU の容量の半分に CPU 時間を制限します。 の値は、200%利用可能な場合、最大 2 つの CPU 分の時間を表します。これは上限であり、CPU の優先度や予約ではありません。 は、MemoryMax=1Gcgroup に割り当てられたメモリの上限を厳密に設定します。ワークロードがこの上限を下回らない場合、カーネルはメモリを解放するか、その cgroup 内のプロセスに対してメモリ不足による強制終了を実行する可能性があります。アプリケーションとその子プロセスに余裕を持たせた制限を選択してください。

1. Ubuntuがcgroup v2を使用していることを確認します。

systemdを使用するUbuntuシステムでは、一般的に統合cgroup v2階層が使用されます。後述のパスを使用する前に、アクティブな設定を確認してください。

stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1

最初のコマンドは を報告するはずですcgroup2fs。もし別のファイルシステムタイプを報告する場合は、この記事に記載されている cgroup v2 ファイルパスはそのままでは適用されません。systemd プロパティは異なる階層でもサポートされる可能性がありますが、v2 パスをコピーするのではなく、対応するディストリビューションのドキュメントを参照してください。

プロパティが拒否された場合は、systemd の正確なバージョンも確認してください。Ubuntu の Noble ドキュメントではCPUQuota=、とをMemoryMax=リソース制御設定として説明しています。古い Ubuntu リリースでは、異なる systemd バージョンがパッケージ化されている場合があります。

2. 作業範囲を限定して開始する

実際の実行ファイルと引数を置き換えて、プログラムを実行しますsystemd-run。現在のディレクトリにあるコマンドの場合は、を使用し./、すべての引数を : の後に渡します--。

systemd-run --scope \
  -p CPUQuota=50% \
  -p MemoryMax=1G \
  -- ./my-program --input data.csv
Ubuntuターミナルでsystemd-runを実行し、CPUQuotaを50%、MemoryMaxを1Gに設定してコマンドを実行する。
CPUとメモリの制限を設定した一時的なsystemdスコープ内でコマンドを実行します。

ユーザー所有のコマンドの場合は、sudoまずroot権限なしで実行してみてください。systemdが要求されたコントローラまたはプロパティが利用できないと報告した場合、ユーザーマネージャに委任する権限がない可能性があります。システム全体のワークロードではroot権限での再試行が適切な場合もありますが、コマンドのセキュリティコンテキストが変更されます。信頼できないプログラムを安易にroot権限で実行しないでください。システムマネージャをroot権限で使用する必要がある場合は、sudo systemd-run --scope ...その変更を考慮してからのみ使用してください。

コマンドの実行中は、端末はスコープに接続されたままになります。キーを押すと、Ctrl+Cフォアグラウンドの操作が中断されます。スコープは一時的なもので、通常はプロセスが終了すると消滅します。これは、将来の起動のための永続的なポリシーではなく、制限付きでコマンドを開始する便利な方法です。

3. スコープを見つけ、その限界を検査する

systemd-run作成したユニット名を出力します。通常は のようになりますrun-….scope。コマンドがまだ実行中の場合は、cgroup ツリーを一覧表示します。

systemd-cgls

一時的なスコープを見つけ、対象プログラムとその子プログラムがそのスコープ内に存在することを確認してください。スコープ外で実行される子プログラムは、同じcgroupの上限範囲に含まれないため、これは重要です。

プログラムと2つのワーカープロセスを含む一時的な実行スコープを示す端末cgroupツリー
cgroupツリーを使用して、プログラムとそのワーカーがトランジェントスコープの下にグループ化されていることを確認します。

次のコマンドでは、表示されたスコープ名を使用してください。run-abc.scope実際の名前に置き換えてください。

systemctl show run-abc.scope \
  -p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax

CPUQuotaPerSecUSec=50000systemd のクォータ期間が 100 ms の場合、50% のクォータと一致します。MemoryMax=1073741824これは 1 GiB バイトです。親 cgroups と利用可能なコントローラによって実際の結果が制限される可能性があるため、すべてのホストがすべてのリクエストをそのまま受け入れると仮定するよりも、ライブ値の方が有用です。

一時的なスコープにおけるコントロールグループ、CPUクォータ、およびメモリの最大値を含むsystemctl showの出力
スコープが報告する制御グループと、設定されているCPUおよびメモリの上限値を確認してください。

4. カーネルのcgroupファイルを検証し、安全に調整する

このControlGroupプロパティは、cgroup パスを から相対的に指定します/sys/fs/cgroup。これをシェル変数に格納して、コマンドがマシン上で実際に割り当てられたパスに従うようにします。

UNIT=run-abc.scope
CG=$(systemctl show "$UNIT" -p ControlGroup --value)
printf 'Group: %s\n' "$CG"
cat "/sys/fs/cgroup$CG/cpu.max"
cat "/sys/fs/cgroup$CG/memory.max"

cgroup v2 では、cpu.maxクォータとマイクロ秒単位の期間が含まれます。たとえば、 は、50000 100000100 ミリ秒ごとに 50 ミリ秒の CPU 時間を意味します。 は、memory.maxメモリの上限をバイト単位で表示します。ファイルが見つからない場合は、スコープがまだアクティブであり、カーネルが cgroup v2 を使用していることを確認してください。

ターミナルでsysfs cgroup v2のsystemdスコープからcpu.maxとmemory.maxを読み取る
カーネルのcgroup v2ファイルを読み込んで、設定されているクォータとメモリ上限を確認してください。

名前付きの長時間実行ユニットを開始し、その制限を調整する必要がある場合、systemd はアクティブなユニットのリソース プロパティの変更をサポートしています。たとえば、 のsudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1Gように指定します。これはそのサービスの cgroup に適用され、適切な権限が必要です。 PID がわかっているという理由だけで、既に実行中の任意のプロセスにアタッチされることはありません。一時的なプロセスの場合は、正常に停止してから、制限されたスコープで再起動してください。永続的なサービスの場合は、サービス ユニットまたは systemd ドロップインでプロパティを設定し、適切なメンテナンス ウィンドウで再起動してください。

結果を確認する

検査中はワークロードをアクティブな状態に保ってください。systemd-cglsプロセスとその子プロセスが意図したスコープ内に配置され、systemctl show要求されたプロパティが報告され、対応するファイルcpu.maxとmemory.maxファイルが有限の値で存在することを確認してください。プロセスが終了すると、一時的なスコープが削除されるため、cgroup ファイルが消える可能性があります。

クォータはCPU時間を制限しますが、デスクトップモニターで固定の割合を保証するものではありません。また、ハードメモリの上限は、アプリケーションが上限を超えるメモリを必要とする場合に障害を引き起こす可能性があります。ワークロードが不安定になった場合は、ワークロードを停止し、制限値を測定可能な安全な値に引き上げるか、MemoryHigh=より高い値と併せてより緩やかな負荷しきい値を使用してくださいMemoryMax=。正確な動作については、インストールされているsystemdとカーネルのドキュメントを確認してください。公式のリファレンスとしては、 Ubuntu systemd-runマニュアル、Ubuntu systemd resource-controlマニュアル、およびLinuxカーネルcgroup v2ドキュメントがあります。

コメントを残す

三相電圧、電流、kW、kVA、力率の変換方法

三相電圧、電流、kW、kVA、力率の変換方法

平衡三相公式を学び、線間電圧、電流、kW、kVA、力率を段階的に変換する方法を、計算例と確認すべき限界値とともに解説します。

Ubuntuのcgroupsを使用してコマンドのCPUとメモリ使用量を制限する

Ubuntuのcgroupsを使用してコマンドのCPUとメモリ使用量を制限する

CPUQuotaとMemoryMaxを設定したsystemdスコープ内でワークロードを実行し、その後cgroup v2を通じて制限を確認します。

Ubuntu Server 24.04 上で Pi-hole アップストリーム DNS を暗号化する

Ubuntu Server 24.04 上で Pi-hole アップストリーム DNS を暗号化する

Ubuntu 24.04 上で、ローカルホスト専用のリスナー、リゾルバの選択、および DNS 切り替え前のチェック機能を備えた dnscrypt-proxy を Pi-hole のローカル DoH ブリッジとして設定します。

Wayland上でUbuntu 24.04のタッチパッドジェスチャーを動作させる方法

Wayland上でUbuntu 24.04のタッチパッドジェスチャーを動作させる方法

アプリやハードウェアのトラブルシューティングを行う前に、Ubuntuのタッチパッド設定を確認し、Waylandが有効になっていることを確認し、GNOMEに組み込まれているスワイプ操作をテストしてください。

mdadmを使用してDebian 12のRAID 1ミラーを構築する

mdadmを使用してDebian 12のRAID 1ミラーを構築する

2台のディスクで構成されるDebian 12 RAID 1データアレイを作成および検証し、安全にフォーマットした後、再起動後にアセンブルおよびマウントされるように構成します。

Debian 12のスワップ領域を起動ごとに新しいキーで暗号化する

Debian 12のスワップ領域を起動ごとに新しいキーで暗号化する

既存の Debian 12 スワップパーティションにランダムキー暗号化を設定し、アクティブな dm-crypt マッピングを確認し、ハイバネーションのトレードオフを理解する。

Ubuntu 24.04でSSHユーザーを特定のディレクトリに制限する方法(SFTP Chrootガイド)

Ubuntu 24.04でSSHユーザーを特定のディレクトリに制限する方法(SFTP Chrootガイド)

Ubuntu 24.04 の SSH アカウントを、chroot、適切なパーミッション、マッチルール、および安全なテストを使用して、指定された SFTP フォルダーに制限し、シェルアクセスを許可しないようにします。

UbuntuのAPTロックを安全に解除してアップデートを完了する

UbuntuのAPTロックを安全に解除してアップデートを完了する

Ubuntuのdpkgフロントエンドロックを所有しているプロセスを特定し、パッケージの処理を完了させ、ロックファイルを削除せずに中断されたインストールを修復します。

UbuntuデスクトップでBtrfsの自動スナップショットを設定する方法

UbuntuデスクトップでBtrfsの自動スナップショットを設定する方法

Timeshiftを使用してUbuntu Desktop上でBtrfsシステムの定期的なスナップショットを設定し、Ubuntuのサブボリュームレイアウトを確認し、保持期間を選択し、スナップショットで保護できないものを理解する。

依存関係を壊さずにDebian 12をTestingに移行する方法

依存関係を壊さずにDebian 12をTestingに移行する方法

Debian 12 から Testing へのより安全な移行を計画しましょう。Stable を経由してアップグレードし、バックアップを取り、APT ソースをクリーンアップし、依存関係の変更をシミュレートし、何が変更されたかを確認します。