systemd,每個使用者的 cpu 和/或記憶體限制
有類似的問題: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/login1
UserNew(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