Systemd

systemd,每個使用者的 cpu 和/或記憶體限制

  • November 5, 2020

有類似的問題:Cgroups, limit memory per user,但該解決方案在“現代”系統中不起作用,其中 cgroups 層次結構由 systemd 管理。

直接的解決方案 - 模板化 user-UID.slice - 不起作用,因為它不受支持,請參閱https://github.com/systemd/systemd/issues/2556

有什麼方法可以達到預期的效果——按使用者管理 CPU 和/或記憶體資源?

UPD:為了歷史,我會保留我的解決方案,但systemctl set-property應該在登錄時呼叫,使用pam_exec,請參閱https://github.com/hashbang/shell-etc/pull/183。在這種方法中,在使用者登錄和設置限制之間沒有時間視窗。

我的解決方案對象介面org.freedesktop.login1.Manage發出/org/freedesktop/login1UserNew(u uid, o object_path)信號。我編寫了一個簡單的守護程序,它監聽信號並且每次發出信號時都CPUAccounting=true為剛剛登錄使用者的切片設置。

UPD:為了歷史,我會保留我的解決方案,但systemctl set-property應該在登錄時呼叫,使用pam_exec,請參閱https://github.com/hashbang/shell-etc/pull/183。在這種方法中,在使用者登錄和設置限制之間沒有時間視窗。

舊解決方案

這是一個非常簡單的腳本,可以完成這項工作

#!/bin/bash

STATE=1 # 1 -- waiting for signal; 2 -- reading UID

dbus-monitor --system "interface=org.freedesktop.login1.Manager,member=UserNew" |
while read line
do
   case $STATE in
   1) [[ $line =~ member=UserNew ]] && STATE=2 ;;
   2) read dbus_type ID <<< $line
      systemctl set-property user-$ID.slice CPUAccounting=true
      STATE=1
   ;;
   esac
done

它可以輕鬆擴展以支持每個使用者的記憶體限制。

在具有 2 個 CPU 和 2 個使用者的 VM 上對其進行了測試。第一個使用者執行dd if=/dev/zero of=/dev/null | dd if=/dev/zero of=/dev/null命令和第二個使用者只執行一個dd. 如果沒有執行此腳本,每個實例都dd使用了大約 70% 的 CPU。

然後我啟動腳本,重新登錄使用者,並dd再次啟動命令。這次dd第一個使用者的兩個程序每個只佔用了 50% 的 CPU,而第二個使用者的程序佔用了 100% 的 CPU。此外,systemd-cgtop顯示,每個/user.slice/user-UID1.slice/user.slice/user-UID2.slice佔用 100% 的 CPU 時間,但第一個切片有 6 個任務,第二個切片只有 5 個任務。

當我殺死dd第二個使用者的任務時,第一個使用者開始消耗 200% 的 CPU 時間。因此,我們有公平的資源分配,沒有“每個使用者只能使用一個核心”之類的人為限制。

從 systemd v239 開始,您可以使用外掛 https://github.com/systemd/systemd/commit/5396624506e155c4bc10c0ee65b939600860ab67

# mkdir -p /etc/systemd/system/user-.slice.d
# cat > /etc/systemd/system/user-.slice.d/50-memory.conf << EOF
[Slice]
MemoryMax=1G
EOF
# systemctl daemon-reload

引用自:https://serverfault.com/questions/874274