cgroups v2 όρια πόρων με systemd
11 λεπτά ανάγνωσης - 3 Ιουνίου 2026

Ορισμός ορίων CPU, μνήμης και I/O με cgroups v2 και systemd. Πρακτική διαμόρφωση για multi-tenant Linux hosts, με παρακολούθηση PSI και απομόνωση slice.
Όρια πόρων cgroups v2 με systemd
Το cgroups v2 είναι το ενοποιημένο πλαίσιο ελέγχου πόρων του πυρήνα Linux. Αντικαθιστά την κατακερματισμένη ιεραρχία της έκδοσης v1 με ένα ενιαίο δέντρο που διαχειρίζεται με συνέπεια την CPU, τη μνήμη και τις εισόδους/εξόδους (I/O) και υποστηρίζει την απομόνωση των κοντέινερ σε Docker, Kubernetes και systemd. Αυτή η ανάρτηση καλύπτει τον τρόπο ενεργοποίησης του cgroups v2, τον καθορισμό ορίων μέσω του systemd και την εφαρμογή του σε πραγματικά σενάρια φιλοξενίας πολλαπλών χρηστών.
Ενεργοποίηση cgroups v2
Οι σύγχρονες διανομές διατίθενται με τα cgroups v2 ενεργοποιημένα από προεπιλογή: Ubuntu 21.10+, Debian 11+, Fedora 31+ και RHEL/Rocky 9+. Τα παλαιότερα συστήματα ενδέχεται να εκτελούν μια υβριδική ιεραρχία ή να εξακολουθούν να χρησιμοποιούν την έκδοση v1 από προεπιλογή. Ελέγξτε με:
stat -fc %T /sys/fs/cgroup/
Το αποτέλεσμα της εντολής cgroup2fs επιβεβαιώνει ότι το v2 είναι ενεργό. tmpfs συνήθως σημαίνει v1.
Για να μετατρέψετε ένα υβριδικό σύστημα σε καθαρό v2, επεξεργαστείτε το /etc/default/grub και προσθέστε το ακόλουθο στο GRUB_CMDLINE_LINUX_DEFAULT:
systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all
Στη συνέχεια, δημιουργήστε εκ νέου το GRUB και επανεκκινήστε:
sudo update-grub
sudo reboot
Για παραγωγή, εκτελέστε τον πυρήνα 5.2 ή νεότερο, ώστε να έχετε το cgroup freezer για το v2 και το systemd 244+ για πλήρη cpuset ανάθεση. Στο Rocky Linux 8 και στο RHEL 8 ίσως χρειαστεί επίσης να ενεργοποιήσετε ρητά τη λογιστική προσθέτοντας αυτές τις γραμμές στο /etc/systemd/system.conf:
DefaultCPUAccounting=yes
DefaultMemoryAccounting=yes
DefaultIOAccounting=yes
Επανεκκινήστε με sudo systemctl daemon-reexec. Μετά την επανεκκίνηση, επαληθεύστε ποιοι ελεγκτές είναι διαθέσιμοι:
cat /sys/fs/cgroup/cgroup.controllers
Θα πρέπει να δείτε cpu, memory, io, και pids να αναφέρονται. Αυτοί οι ελεγκτές δεν είναι ενεργοποιημένοι για τα υπο-cgroups από προεπιλογή. Για να τους ενεργοποιήσετε, γράψτε στο αρχείο ελέγχου του υποδέντρου root:
echo "+cpu +memory +io" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
Για μια αναλυτική παρουσίαση των εσωτερικών διαφορών μεταξύ της v2 και της v1, η ομιλία του Michael Kerrisk στο NDC TechTown αποτελεί την καλύτερη πηγή:
Πώς οργανώνει το systemd τα cgroups
Το systemd δημιουργεί ένα cgroup για κάθε υπηρεσία που ξεκινά, με όνομα που προέρχεται από τη μονάδα. nginx.service λαμβάνει /sys/fs/cgroup/system.slice/nginx.service/, και κάθε διαδικασία που δημιουργεί βρίσκεται μέσα σε αυτό το cgroup. Τρεις τύποι μονάδων αντιστοιχούν άμεσα στην ιεραρχία:
| Τύπος μονάδας | Ρόλος | Περιγραφή |
|---|---|---|
.slice | Εσωτερικός κόμβος | Ομαδοποιεί σχετικές υπηρεσίες και ορίζει κοινά όρια |
.service | Τερματικός κόμβος | Διαχειρίζεται διεργασίες που ξεκίνησαν από το systemd |
.scope | Φύλλο κόμβου | Παρακολουθεί διεργασίες που ξεκίνησαν εξωτερικά (φορτία κοντέινερ, συνεδρίες σύνδεσης) |
Τέσσερα προεπιλεγμένα τμήματα διατίθενται έτοιμα προς χρήση: -.slice (root), system.slice, user.sliceκαι machine.slice. Οποιοδήποτε όριο εφαρμόζεται σε ένα slice εφαρμόζεται αυτόματα σε κάθε υπηρεσία που βρίσκεται σε αυτό.
Ένας κανόνας της έκδοσης v2 που αξίζει να θυμάστε: οι διεργασίες μπορούν να υπάρχουν μόνο σε τελικούς κόμβους. Μια ομάδα cgroup με υποομάδες cgroup δεν μπορεί να φιλοξενήσει απευθείας διεργασίες, γι' αυτό το systemd δεν τοποθετεί ποτέ υπηρεσίες στον κορμό ενός slice.
Ορίστε πάντα τα όρια μέσω του systemd αντί να γράφετε απευθείας στο /sys/fs/cgroup/ απευθείας. Οι χειροκίνητες εγγραφές δεν διατηρούνται μετά από επανεκκινήσεις και έρχονται σε σύγκρουση με την αποκλειστική κυριότητα της ιεραρχίας από το systemd. Χρησιμοποιήστε systemctl set-property για εφάπαξ αλλαγές και προσωρινές μονάδες (systemctl edit nginx.service) για μόνιμες αλλαγές.
Όρια CPU
Το cgroups v2 σας παρέχει δύο ελέγχους CPU: ένα ανώτατο όριο (cpu.max, που εμφανίζεται ως CPUQuota στο systemd) και ένα αναλογικό βάρος (cpu.weight / CPUWeight).
CPUQuota είναι ένα απόλυτο ανώτατο όριο. CPUQuota=50% επιτρέπει μισό πυρήνα· CPUQuota=200% επιτρέπει χρόνο ίσο με δύο πλήρεις πυρήνες. Η υπηρεσία περιορίζεται αν προσπαθήσει να πάει ψηλότερα, ανεξάρτητα από το πόσο αδρανής είναι η υπόλοιπη CPU.
CPUWeight έχει σημασία μόνο σε περίπτωση διεκδίκησης. Το εύρος είναι από 1 έως 10.000, με προεπιλογή το 100. Τρεις υπηρεσίες με βάρη 150, 100 και 50 λαμβάνουν περίπου το 50%, το 33% και το 17% του χρόνου CPU όταν όλες τον θέλουν ταυτόχρονα. Όταν η CPU είναι αδρανής, οι συντελεστές βαρύτητας δεν περιορίζουν τίποτα.
Για φόρτους εργασίας ευαίσθητους στην καθυστέρηση, καθηλώστε τις διεργασίες σε συγκεκριμένους πυρήνες με AllowedCPUs=. Αυτό μειώνει την εναλλαγή περιβάλλοντος και διατηρεί την προσωρινή μνήμη ανά πυρήνα ενεργή:
[Service]
CPUQuota=200%
CPUWeight=150
AllowedCPUs=0-3
Χρησιμοποιήστε ένα σταθερό όριο όταν χρειάζεστε προβλέψιμο κόστος (χρέωση πολλαπλών χρηστών, απομόνωση θορυβωδών γειτόνων). Χρησιμοποιήστε βαρύτητες όταν θέλετε μέγιστη αξιοποίηση του υλικού και χρειάζεστε απλώς σειρά προτεραιότητας κατά τη διάρκεια αιχμών.
Όρια μνήμης με cgroups v2
Η μνήμη έχει δύο επίπεδα: memory.high (soft, throttling) και memory.max (σκληρό, OOM). Για πληροφορίες σχετικά με το swap, την ανάκτηση σελίδων και το kernel OOM killer, ανατρέξτε στη σχετική ανάρτησή μας σχετικά με τη διαχείριση μνήμης στο Linux.
Ρυθμίστε memory.high περίπου 10 έως 20% κάτω memory.max. Ο πυρήνας αρχίζει να ανακτά σελίδες και να περιορίζει τις εκχωρήσεις μόλις memory.high υπερβεί το όριο, κάτι που συνήθως επιτρέπει στο φορτίο εργασίας να ανακάμψει πριν ενεργοποιηθεί ο OOM killer. Εάν η χρήση φτάσει memory.max, ο πυρήνας τερματίζει διεργασίες στο cgroup.
Μια τυπική ρύθμιση:
[Service]
MemoryHigh=400M
MemoryMax=512M
MemorySwapMax=0
MemorySwapMax=0 απενεργοποιεί το swap για αυτό το cgroup. Αξίζει να το κάνετε για φόρτους εργασίας ευαίσθητους στην καθυστέρηση (βάσεις δεδομένων, ροή σε πραγματικό χρόνο) όπου το swap I/O θα κατέστρεφε την καθυστέρηση ουράς.
Για ομάδες εργαζομένων όπου η παραμονή ορφανών αδελφών θα αλλοίωνε την κοινόχρηστη κατάσταση, γράψτε 1 στο αρχείο memory.oom.group . Όταν μια διεργασία τερματίζεται λόγω OOM, ο πυρήνας τερματίζει όλες τις διεργασίες στο cgroup μαζί.
Ελέγξτε memory.events για να δείτε πόσο συχνά μια υπηρεσία έχει υποστεί περιορισμό ή τερματισμό λόγω OOM:
cat /sys/fs/cgroup/system.slice/nginx.service/memory.events
Το high και oom_kill σας δείχνουν αν τα όριά σας έχουν ρυθμιστεί σωστά. Οι σταθερές τιμές διαφορετικές από το μηδέν σημαίνουν ότι το φορτίο εργασίας χρειάζεται περισσότερο περιθώριο.
Όρια I/O
Ο ελεγκτής I/O έχει τον ίδιο σχεδιασμό δύο λειτουργιών: απόλυτα όρια μέσω io.max και αναλογική κατανομή μέσω io.weight.
Τα όρια ισχύουν ανά συσκευή μπλοκ, που προσδιορίζεται από αριθμούς major:minor. Βρείτε τα με το lsblk -o NAME,MAJ:MIN. Μια τυπική ρύθμιση του systemd:
[Service]
IOReadBandwidthMax=/dev/sda 50M
IOWriteBandwidthMax=/dev/sda 30M
IOReadIOPSMax=/dev/sda 1000
IOWriteIOPSMax=/dev/sda 500
io.weight λειτουργεί όπως cpu.weight: εύρος 1 έως 10.000, προεπιλογή 100. Η εκχώρηση 500 σε μια υπηρεσία που απευθύνεται σε πελάτες και 50 σε ένα νυχτερινό αντίγραφο ασφαλείας εμποδίζει το αντίγραφο ασφαλείας να κορεστεί ο δίσκος κατά τις ώρες αιχμής, αλλά του επιτρέπει να χρησιμοποιεί πλήρες εύρος ζώνης όταν δεν το χρειάζεται τίποτα άλλο.
Τα όρια I/O ισχύουν μόνο όταν στοχεύετε τη σωστή συσκευή. Ο πυρήνας παρακολουθεί το I/O ανά συσκευή μπλοκ, οπότε ένα όριο στο /dev/sda δεν έχει καμία επίδραση στην I/O που πηγαίνει στο /dev/nvme0n1. Σε κεντρικούς υπολογιστές με πολλούς δίσκους, ορίστε όρια ανά συσκευή.
Απομόνωση πολλαπλών ενοικιαστών με τμήματα
Για κοινόχρηστα περιβάλλοντα, ορίστε ένα slice ανά tenant. Δημιουργήστε /etc/systemd/system/tenant-a.slice:
[Slice]
CPUQuota=200%
CPUWeight=150
MemoryHigh=3584M
MemoryMax=4096M
MemorySwapMax=0
IOReadBandwidthMax=/dev/sda 200M
TasksMax=512
TasksMax=512 περιορίζει τον συνολικό αριθμό διεργασιών και νημάτων, γεγονός που εμποδίζει μια fork bomb σε έναν ενοικιαστή να καταρρίψει τον κεντρικό υπολογιστή. Τοποθετήστε τις υπηρεσίες ενοικιαστών σε αυτό το slice (μέσω Slice=tenant-a.slice στα αρχεία μονάδων τους) και κληρονομούν τα πάντα αυτόματα.
Αυτό το μοτίβο λειτουργεί επίσης για τον διαχωρισμό της θορυβώδους εργασίας στο παρασκήνιο από τις υπηρεσίες που απευθύνονται στους χρήστες. Τοποθετήστε τα αντίγραφα ασφαλείας, την εναλλαγή αρχείων καταγραφής και τις εργασίες παρτίδας σε ένα background.slice με χαμηλό CPUWeight και io.weight τιμές. Λαμβάνουν πλήρεις πόρους όταν το σύστημα είναι αδρανές και αποσύρονται όταν φτάνει η κυκλοφορία παραγωγής.
Για περιβάλλοντα εκτέλεσης κοντέινερ όπως το Docker και το Podman, προσθέστε Delegate=yes στα αρχεία μονάδων systemd τους. Αυτό τους επιτρέπει να διαχειρίζονται τις δικές τους υπο-cgroups χωρίς δικαιώματα root, ενώ τα όρια που έχουν οριστεί στο γονικό τμήμα εξακολουθούν να ισχύουν για όλα τα υποκείμενα στοιχεία.
Παρακολούθηση με systemd-cgtop και PSI
Για μια ζωντανή προβολή τύπου top της CPU, της μνήμης και του I/O ανά cgroup, εκτελέστε:
systemd-cgtop
Για τη στατική ιεραρχία και το πού βρίσκονται οι διαδικασίες, χρησιμοποιήστε systemd-cgls.
Η πιο χρήσιμη λειτουργία της έκδοσης v2 για την παρακολούθηση της παραγωγής είναι το Pressure Stall Information (PSI). Το PSI αναφέρει το ποσοστό του χρόνου που οι εργασίες σε ένα cgroup παρέμειναν σε αναμονή για έναν πόρο, το οποίο εμφανίζεται σε τρία αρχεία ανά cgroup:
cat /sys/fs/cgroup/tenant-a.slice/cpu.pressure
cat /sys/fs/cgroup/tenant-a.slice/memory.pressure
cat /sys/fs/cgroup/tenant-a.slice/io.pressure
Μια CPU με 100% χρήση και 0% πίεση είναι υγιής. Κάθε εργασία που θέλει CPU την παίρνει. Η ίδια CPU με 80% χρήση αλλά 30% πίεση σημαίνει ότι οι εργασίες περιμένουν στην ουρά για χρόνο εκτέλεσης. Ειδοποιήστε για το PSI, όχι για τη χρήση: εντοπίζει συγκρούσεις που οι μετρήσεις χρήσης παραλείπουν εντελώς.
Προσαρμόστε τα όρια σε πραγματικό χρόνο χωρίς να επανεκκινήσετε τίποτα:
sudo systemctl set-property tenant-a.slice MemoryMax=6144M
Η αλλαγή εφαρμόζεται αμέσως και παραμένει σε ισχύ μετά από επανεκκινήσεις. Σε συνδυασμό με τις ειδοποιήσεις βάσει PSI, αυτό σας επιτρέπει να ανταποκρίνεστε σε μεταβολές φορτίου πριν μετατραπούν σε τερματισμούς OOM ή ανεξέλεγκτη καθυστέρηση.
Εάν εκτελείτε φορτία εργασίας υψηλής πυκνότητας με πολλούς χρήστες και χρειάζεστε έναν κεντρικό υπολογιστή με το περιθώριο να εφαρμόσει αυτές τις πολιτικές καθαρά, οι αποκλειστικοί διακομιστές μας έχουν κατασκευαστεί για αυτό.
Γιατί είναι σημαντικό να έχετε ένα ισχυρό και unmetered VPS
Ένα unmetered VPS παρέχει σταθερό εύρος ζώνης σε σταθερή ταχύτητα θύρας. Πώς διαφέρει από τα μετρούμενα πακέτα, πότε αποδίδει και τι πρέπει να ελέγξετε πριν από την αγορά.
7 λεπτά ανάγνωσης - 9 Μαΐου 2025
Διαχείριση μνήμης Linux: Swap, OOM Killer & Cgroups
12 λεπτά ανάγνωσης - 31 Μαΐου 2026

Έχετε ερωτήσεις ή χρειάζεστε μια προσαρμοσμένη λύση
Ευέλικτες επιλογές
Παγκόσμια εμβέλεια
Άμεση ανάπτυξη
Ευέλικτες επιλογές
Παγκόσμια εμβέλεια
Άμεση ανάπτυξη