1 Punkte von GN⁺ 5 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Ausgehend vom htop-Bildschirm unter Ubuntu Server 16.04 x64 wird anhand von /proc und Befehlsausgaben nachverfolgt, was uptime, load average, Tasks, PID, Prozessbaum, Status, CPU-Zeit, Priorität und Speicherkennzahlen tatsächlich bedeuten
  • Viele Werte auf dem Bildschirm stammen aus procfs und Systemdateien wie /etc/passwd, /etc/group, /etc/shadow und /etc/nsswitch.conf; mit strace lässt sich prüfen, welche Dateien ein Programm liest
  • Load average ist nicht dasselbe wie CPU-Auslastung, sondern ein exponentiell gedämpfter gleitender Durchschnitt, der laufende Prozesse, Prozesse in der Ausführungswarteschlange und Prozesse im uninterruptible-Zustand umfasst
  • Statuscodes wie R, S, D, Z, T und t hängen mit Signalen, kill sowie dem Verhalten von fork/exec/wait zusammen und liefern Hinweise darauf, warum ein Prozess angehalten ist oder bestehen bleibt
  • VIRT, RES, SHR und MEM% zeigen virtuellen Speicher, physischen Speicher und gemeinsam nutzbaren Speicher aus unterschiedlichen Perspektiven; aus einer einzelnen Zahl lässt sich die tatsächliche Speichernutzung daher schwer eindeutig ableiten

Woher kommen die htop-Werte?

  • uptime zeigt, wie lange das System bereits läuft; dieselbe Information lässt sich auch mit dem Befehl uptime anzeigen
  • Das Programm uptime liest /proc/uptime
    • Die erste Zahl ist die gesamte Zeit in Sekunden, seit der das System eingeschaltet ist
    • Die zweite Zahl ist die Zeit in Sekunden, in der das System im Idle-Zustand war
    • Auf Mehrkernsystemen wird die Idle-Zeit pro Core aufsummiert und kann daher größer sein als die gesamte Uptime
  • Mit strace uptime 2>&1 | grep open oder strace -e open uptime kann man sehen, welche Dateien uptime öffnet
    • Beispielausgaben enthalten /proc/uptime, /var/run/utmp und /proc/loadavg
  • Die Zahlen in /proc/uptime eignen sich gut für Programme oder Skripte, während die Ausgabe von uptime menschenlesbar formatiert ist

Load average und CPU-Auslastung

  • Die ersten drei Werte in /proc/loadavg geben die System-Load-Average der letzten 1, 5 und 15 Minuten an
  • Der vierte Wert zeigt die Zahl der aktuell laufenden Prozesse und die Gesamtzahl der Prozesse in einer Form wie 1/120; der letzte Wert ist die zuletzt verwendete PID
  • Wenn ein neuer Prozess gestartet wird, wird ihm eine PID zugewiesen; PIDs steigen normalerweise an und werden wiederverwendet, wenn der Wertebereich erschöpft ist
    • PID 1 gehört zu /sbin/init, das beim Booten gestartet wird
  • Wenn in htop nur ein laufender Prozess zu sehen ist, kann dieser eine Prozess htop selbst sein
  • sleep 30 läuft nicht aktiv, sondern befindet sich im Sleep-Zustand und erhöht daher nicht die Zahl der running processes
  • Eine Aufgabe, die wie cat /dev/urandom > /dev/null dauerhaft CPU verwendet, erhöht die Zahl der running processes und die load average
  • Die Load number zählt Prozesse, die laufen oder auf Ausführung warten, sowie Prozesse im uninterruptible-Zustand
  • Die load average ist kein einfacher Durchschnitt, sondern ein exponentiell gedämpfter gleitender Durchschnitt
    • Auch die 1-Minuten-Load-Average berücksichtigt nicht nur die letzten 60 Sekunden, sondern gewichtet die letzte Minute stärker und bezieht frühere Aktivität teilweise mit ein
  • Auf einem Ein-CPU-System kann man bei einem einzelnen CPU-bound-Prozess eine load average von 1.00 vereinfacht als 100 % CPU-Auslastung betrachten
    • Auf einem 2-Core-System entspräche dieselbe Situation vereinfacht 50 % CPU-Auslastung
    • Die load average, die auf einem 2-Core-System einer CPU-Auslastung von 100 % entspricht, lässt sich vereinfacht als 2.00 ansetzen
  • Diese Vereinfachung stimmt nicht immer, weil Prozesse im uninterruptible-Zustand in die Load einfließen
    • Es kann also auch Situationen mit hoher load average geben, in denen die CPU-Auslastung nicht hoch ist
  • Die momentane CPU-Auslastung lässt sich mit mpstat prüfen
    • sudo apt install sysstat -y
    • mpstat 1

Tasks, PID, Prozessbaum

  • Tasks oben rechts in htop zeigt die Gesamtzahl der Prozesse und die Zahl der laufenden Prozesse an
  • Der Linux-Kernel bezeichnet Prozesse intern als Tasks; htop verwendet Tasks statt Processes, um Platz auf dem Bildschirm zu sparen
  • Mit Shift+H kann die Anzeige von Threads umgeschaltet werden
    • Wenn etwas wie Tasks: 23, 10 thr zu sehen ist, werden Threads angezeigt
  • Mit Shift+K kann die Anzeige von Kernel-Threads umgeschaltet werden
    • Wenn etwas wie Tasks: 23, 40 kthr zu sehen ist, werden Kernel-Threads angezeigt
  • Jedes Mal, wenn ein neuer Prozess startet, wird eine PID zugewiesen
    • Bei einer Ausführung im Hintergrund wie sleep 1000 & werden Job-Nummer und PID angezeigt
    • $! in bash wird zur ID des letzten Hintergrundprozesses erweitert
  • Prozessbezogene Informationen befinden sich unter /proc/<pid>/
    • /proc/<pid>/cmdline enthält den ausgeführten Befehl; Argumente sind durch \0-Bytes getrennt
    • Mit tr '\0' '\n' < /proc/<pid>/cmdline oder strings /proc/<pid>/cmdline lässt sich das lesbarer anzeigen
    • /proc/<pid>/cwd ist ein Link auf das aktuelle Arbeitsverzeichnis, und /proc/<pid>/exe ist ein Link auf das ausgeführte Binary
  • Diagnosewerkzeuge wie htop, top und ps lesen Prozessdetails aus /proc/<pid>/<file>
  • Der Erzeuger eines neuen Prozesses ist der parent process, der neu erzeugte Prozess ist der child process; diese Beziehung bildet den Prozessbaum
  • Drückt man in htop F5, sieht man die Prozesshierarchie
    • ps f und pstree -a zeigen dieselbe Beziehung
  • Wenn man in bash date ausführt, erstellt bash mit fork eine Kopie von sich selbst, lädt mit exec /bin/date in den Speicher und wartet dann als Parent bash auf das Ende des Child-Prozesses
  • /sbin/init startet beim Booten und startet sshd; bei einer SSH-Verbindung erzeugt sshd einen Sitzungsprozess, und diese Sitzung führt eine bash-Shell aus

Prozessbenutzer und Berechtigungen

  • Jeder Prozess gehört einem Benutzer; Benutzer werden durch numerische IDs dargestellt
  • Die Benutzer-ID eines Prozesses lässt sich über den Eintrag Uid in /proc/<pid>/status prüfen
  • Ein Befehl wie id 1000 zeigt den Benutzernamen und die Gruppen zur entsprechenden numerischen ID an
  • id wählt die Quellen für die Namensauflösung gemäß der Konfiguration in /etc/nsswitch.conf aus
    • Im Beispielsystem werden /etc/passwd und /etc/group gelesen
    • compat ist der Compatibility mode und entspricht files, erlaubt aber spezielle Einträge
    • Benutzerinformationen können auch in anderen Datenbanken oder Diensten wie LDAP gespeichert sein
  • /etc/passwd und /etc/group sind Klartextdateien, die numerische IDs auf menschenlesbare Namen abbilden
  • Die eigentlichen Passwortinformationen befinden sich in /etc/shadow
    • $6$ steht für den Hashing-Algorithmus sha512
    • Danach folgen ein zufälliger Salt zum Schutz vor Rainbow-Table-Angriffen und der Hash aus Passwort+Salt
  • Programme laufen standardmäßig mit den Berechtigungen des Benutzers, der sie gestartet hat
    • Das gilt auch dann, wenn der Besitzer der ausführbaren Datei ein anderer Benutzer ist
  • Um etwas als anderer Benutzer oder als root auszuführen, verwendet man sudo
    • sudo id wird mit der UID 0 von root ausgeführt
    • Mit sudo -u daemon id kann man es als bestimmter Benutzer ausführen
  • Wenn man versucht, per direkter Umleitung in /etc/sudoers zu schreiben, kann es fehlschlagen, weil nur echo als root ausgeführt wird, das Anhängen aber als aktueller Benutzer erfolgt
    • echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee -a /etc/sudoers
    • sudo bash -c "echo '$USER ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
  • /etc/sudoers sollte mit sudo visudo bearbeitet werden
    • Der Inhalt wird vor dem Speichern geprüft, um Fehler zu vermeiden, durch die sudo nicht mehr nutzbar wäre
  • /usr/bin/passwd kann auch dann in /etc/shadow schreiben, wenn es von einem normalen Benutzer ausgeführt wird
    • Da in den Dateiberechtigungen ein s gesetzt ist, läuft es als setuid-Executable
    • Es wird mit den Rechten des Besitzers der ausführbaren Datei, also root, ausgeführt
    • Root-eigene setuid-Executables lassen sich mit find /bin -user root -perm -u+s finden

Prozessstatus-Codes

  • Die Statusspalte in htop wird mit dem Namen S angezeigt; die wichtigsten Werte sind folgende
    • R: running oder runnable, läuft gerade oder wartet in der Run Queue
    • S: interruptible sleep, wartet auf den Abschluss eines Ereignisses
    • D: uninterruptible sleep, meist Warten auf I/O
    • Z: defunct zombie, beendet, aber vom Parent noch nicht gereapt
    • T: durch ein Job-Control-Signal angehalten
    • t: während des Tracings durch einen Debugger angehalten
    • X: dead, ein Zustand, der nicht sichtbar sein sollte
  • ps zeigt auch Substates wie Ss, R+ und Ss+ an
  • R: läuft oder ausführbar

    • Der Status R bedeutet, dass ein Prozess gerade läuft oder in der Ausführungswarteschlange wartet
    • Der Quellcode eines Programms wird nach dem Kompilieren zu CPU-Instruktionen; beim Ausführen wird er in den Speicher geladen, und die CPU führt diese Instruktionen aus
    • „Läuft“ bedeutet, dass die CPU physisch Instruktionen ausführt
  • S: unterbrechbarer Sleep

    • Im Status S werden die Instruktionen des Prozesses nicht auf der CPU ausgeführt; der Prozess wartet auf ein Ereignis oder eine Bedingung
    • Wenn das Ereignis eintritt, setzt der Kernel den Status auf running
    • sleep 1000 ist ein Beispiel für das Warten über eine angegebene Zeit
    • Dieser Zustand kann durch ein Signal unterbrochen werden
    • In htop kann man mit F9 ein Signal senden
    • kill ist ein Systemaufruf zum Senden eines Signals; /bin/kill ist ein Userland-Programm, das diesen aufruft
    • Das Standard-Signal ist TERM und fordert die Beendigung des Prozesses an
    • Signale sind Zahlen; ihre Namen werden meist in Großbuchstaben geschrieben und können das Präfix SIG tragen
    • Beispiele: INT, KILL, STOP, CONT, HUP
    • kill -INT 10089, kill -2 10089 und /bin/kill -2 10089 bewirken dasselbe
    • Wenn man CTRL+C drückt, sendet bash ein SIGINT an den foreground process
    • Ein Prozess beendet sich nicht zwingend, nur weil man SIGINT oder SIGTERM sendet
    • Programme können einen Signal-Handler einrichten und das Signal etwa so behandeln, dass sie nach Aufräumarbeiten beendet werden
    • SIGKILL bzw. 9 veranlasst den Kernel, den Prozess zwangsweise zu beenden, ohne ihm Gelegenheit zur Reaktion zu geben
  • D: nicht unterbrechbarer Sleep

    • Der Status D kann nicht durch Signale geweckt werden; da auch SIGKILL ein Signal ist, kann man einen solchen Prozess nicht killen
    • Dieser Zustand wird verwendet, wenn ein Prozess ohne Unterbrechung warten muss oder wenn erwartet wird, dass ein Ereignis schnell eintritt
    • Beispiel: Lesen/Schreiben auf der Festplatte
    • Ein uninterruptible process kann sich typischerweise in einem Zustand befinden, in dem er nach einem Page Fault auf I/O wartet
    • Bei Verzögerungen beim Lesen/Schreiben über NFS kann dieser Zustand auftreten
    • Er kann auch auftreten, wenn zu wenig verfügbarer Speicher vorhanden ist und Prozesse stark swappen
    • Führt man als Beispiel sudo mount 8.8.8.8:/tmp /tmp & aus, geht /sbin/mount.nfs in den Status D
    • Mit strace sieht man, dass der Systemaufruf mount den Prozess blockiert
    • Mit der Option intr für mount kann man ihn interruptible ausführen
    • sudo mount 8.8.8.8:/tmp /tmp -o intr
  • Z: Zombie-Prozess

    • Der Status Z bedeutet, dass ein Prozess beendet wurde, der Parent ihn aber noch nicht gereapt hat
    • Wenn Zombie-Prozesse nur kurz existieren, kann das normal sein
    • Länger verbleibende Zombie-Prozesse können auf einen Programmfehler hinweisen
    • Zombie-Prozesse verbrauchen keinen Speicher, sondern belegen nur eine PID
    • Der Zombie-Prozess selbst kann nicht mit kill beendet werden
    • Man kann dem parent process SIGCHLD senden, um ihn aufzufordern, den Zombie zu reap’en
    • Wenn man den parent process beendet, kann man den Parent und dessen Zombies entfernen
    • Der Zombie-Zustand lässt sich mit einem C-Programm reproduzieren, in dem nach fork das Child exit(0) aufruft und der Parent sleep(20) ausführt
    • Wenn der Parent endet, verschwindet der Zombie
    • Der Grund dafür, dass der Zombie erhalten bleibt, ist, dass der Parent den Exit-Code des Childs über den Systemaufruf wait abfragen können muss
  • T und t: angehaltene Prozesse

    • Der Status T bedeutet, dass der Prozess durch ein Job-Control-Signal angehalten wurde
    • Wenn man während der Ausführung von cat /dev/urandom > /dev/null CTRL+Z drückt, wechselt er in den Status T
    • Mit fg kann man ihn wieder ausführen
    • Man kann ihn auch mit dem Signal STOP anhalten und mit dem Signal CONT fortsetzen
    • Der Status t bedeutet, dass der Prozess während des Tracings durch einen Debugger angehalten ist
    • Wenn man mit sudo gdb -p <pid> an einen per nc -l 1234 & gestarteten Prozess attacht, wechselt er in den Status t

CPU-Zeit, Niceness, Priority

  • Linux ist ein Multitasking-Betriebssystem; daher wirkt es selbst auf einer einzelnen CPU so, als würden mehrere Prozesse gleichzeitig laufen
  • Tatsächlich kann eine einzelne CPU immer nur eine Anweisung auf einmal ausführen, daher wird Time Sharing verwendet
    • Ein Prozess läuft kurz und wird dann angehalten
    • Andere Prozesse, die auf Ausführung warten, werden der Reihe nach ausgeführt
    • Der kurze Abschnitt, in dem ein Prozess läuft, wird Time Slice genannt
  • Eine Time Slice dauert meist nur wenige Millisekunden und fällt daher kaum auf, solange die Systemlast nicht hoch ist
  • Liegt der Load Average auf einem einzelnen Core bei 1.0, kann man davon ausgehen, dass die CPU zu 100 % ausgelastet war
    • Liegt er über 1.0, gibt es mehr Prozesse, die laufen wollen, als die CPU verarbeiten kann; dadurch können Slowdowns oder Delays entstehen
    • Liegt er unter 1.0, ist die CPU zeitweise idle
  • Auch warum die Running Time eines Prozesses nicht exakt der tatsächlich verstrichenen Zeit entsprechen muss, lässt sich durch Time Sharing erklären
  • Wenn es mehr auszuführende Tasks gibt als verfügbare CPU-Cores, muss entschieden werden, welcher Task zuerst läuft
  • Der Scheduler des Linux-Kernels wählt den nächsten Prozess aus der Run Queue aus; das hängt vom Scheduler-Algorithmus des Kernels ab
  • Im Allgemeinen kann man den Scheduler nicht direkt steuern, aber man kann angeben, welche Prozesse wichtiger sind
  • Die als NI angezeigte Niceness ist die User-Space-Priority
    • Der Bereich reicht von -20 bis 19
    • -20 ist die höchste Priorität, 19 die niedrigste
    • Ein „nicerer“ Prozess gibt weniger „nicen“ Prozessen eher den Vortritt
  • PRI ist die vom Linux-Kernel verwendete Kernel-Space-Priority
    • Der Bereich reicht von 0 bis 139
    • 0~99 ist für Real Time, 100~139 ist der Bereich für User-Prozesse
  • Die Beziehung zwischen Nice-Wert und Priority lässt sich mit PR = 20 + NI erklären
    • -20~+19 von NI wird zu 0~39 von PR, was wiederum auf 100~139 gemappt wird
  • Die Niceness vor dem Start wird mit nice -n niceness program gesetzt
  • Die Niceness eines laufenden Prozesses wird mit renice -n niceness -p PID geändert
  • Die Farben der CPU-Auslastung bedeuten Folgendes
    • Blue: Thread mit niedriger Priorität, nice > 0
    • Green: Thread mit normaler Priorität
    • Red: Kernel-Thread

Speicherkennzahlen: VIRT, RES, SHR, MEM%

  • Ein Prozess wirkt so, als existiere er allein im Speicher; umgesetzt wird das über virtuellen Speicher
  • Ein Prozess greift nicht direkt auf den physischen Speicher zu, sondern besitzt einen eigenen virtuellen Adressraum
  • Der Kernel kann virtuelle Speicheradressen in physischen Speicher übersetzen oder Teile davon auf Disk mappen
  • Deshalb kann es so aussehen, als würde ein Prozess mehr Speicher verwenden, als im Computer installiert ist
  • Die Speichernutzung eines Prozesses hängt davon ab, ob die folgenden Elemente einbezogen werden
    • Shared Library
    • Disk-mapped Memory
    • Swapped-out Memory
  • Die Farben der Speichernutzung bedeuten Folgendes
    • Green: used memory
    • Blue: buffers
    • Orange: cache
  • VIRT/VSZ

    • VIRT ist die gesamte Menge an virtuellem Speicher, die ein Task verwendet
    • Enthalten sind Code, Daten, Shared Libraries, ausgelagerte Pages sowie gemappte, aber nicht verwendete Pages
    • Fordert eine Anwendung 1 GB an und nutzt nur 1 MB, kann VIRT trotzdem als 1 GB erscheinen
    • Auch wenn eine 1-GB-Datei per mmap eingebunden, aber tatsächlich nicht genutzt wird, kann VIRT als 1 GB angezeigt werden
    • In den meisten Fällen ist VIRT keine nützliche Zahl
  • RES/RSS

    • RES ist nicht ausgelagerter physischer Speicher, also die Nutzung von Resident Memory, der sich aktuell im physischen Speicher befindet
    • RES kann die tatsächliche Speichernutzung besser abbilden als VIRT, hat aber Einschränkungen
    • Swapped-out Memory ist nicht enthalten
    • Ein Teil des Speichers kann mit anderen Prozessen geteilt sein
    • Wenn ein Prozess 1 GB Speicher nutzt und danach fork() aufruft, kann RES bei beiden Prozessen jeweils als 1 GB erscheinen; wegen Copy-on-Write in Linux kann tatsächlich aber nur 1 GB verwendet werden
  • SHR

    • SHR ist die Menge an Shared Memory, die ein Task verwendet
    • Es spiegelt Speicher wider, der potenziell mit anderen Prozessen geteilt werden kann
    • Das Beispiel-C-Programm zeigt, wie sich die Werte VIRT, RES und SHR durch malloc, teilweise Speichernutzung, fork und zusätzliche Schreibzugriffe auf Speicher verändern
    • Der entsprechende Abschnitt mit dem Speicherbeispiel ist als TODO belassen
  • MEM%

    • MEM% ist der Anteil des aktuell von einem Task verwendeten verfügbaren physischen Speichers
    • Er entspricht RES geteilt durch den gesamten RAM
    • Beispiel: Wenn RES 400M beträgt und der RAM 8 GB groß ist, ergibt sich 400/8192*100 = 4.88%

Standardprozesse von Ubuntu Server 16.04

  • Untersucht wurden die Prozesse, die auf einem frischen Ubuntu Server 16.04.1 LTS x64 auf einem Digital-Ocean-Droplet gestartet werden

  • /sbin/init

    • /sbin/init koordiniert den restlichen Boot-Prozess und richtet die Benutzerumgebung ein
    • Wird zum Parent oder Grandparent automatisch gestarteter Prozesse
    • dpkg -S /sbin/init ergibt systemd-sysv: /sbin/init; auf diesem System ist es also systemd
    • Auch wenn man ihn killt, passiert nichts
  • /lib/systemd/systemd-journald

    • systemd-journald ist ein Systemdienst, der Logging-Daten sammelt und speichert
    • Erstellt und pflegt ein strukturiertes, indiziertes Journal auf Basis von Log-Informationen aus verschiedenen Quellen
    • Verwendet statt einfacher Klartext-Logdateien ein spezielles, für Lognachrichten optimiertes Dateiformat
    • Wird mit journalctl abgefragt
    • journalctl _COMM=sshd
    • journalctl _COMM=sshd -o json-pretty
    • journalctl --since yesterday
    • journalctl -b
    • journalctl -f
    • journalctl --disk-usage
    • journalctl --vacuum-size=1G
    • Entfernen oder Deaktivieren scheint nicht möglich zu sein; man kann lediglich das Logging abschalten
  • /sbin/lvmetad -f

    • lvmetad cached LVM-Metadaten, damit LVM-Befehle Metadaten ohne Disk-Scan lesen können
    • Disk-Scans kosten Zeit und können den normalen Betrieb von System und Festplatte stören
    • LVM kann man als „dynamische Partitionen“ verstehen, mit denen sich Logical Volumes erstellen, vergrößern/verkleinern und löschen lassen, während Linux läuft
    • Fazit: Wenn LVM verwendet wird, sollte man ihn beibehalten
  • /lib/systemd/udevd

    • systemd-udevd lauscht auf Kernel-uevents und führt für jedes Event die passenden Anweisungen aus den udev-Rules aus
    • udev ist der Device Manager des Linux-Kernels und verwaltet hauptsächlich die Device Nodes im Verzeichnis /dev
    • Ob es auf einem virtuellen Server nötig ist, ist unklar
  • /lib/systemd/timesyncd

    • systemd-timesyncd ist ein Systemdienst, der die lokale Systemuhr mit einem entfernten NTP-Server synchronisiert
    • Ersetzt ntpd
    • Im Beispielsystem zeigt timedatectl status für network time und NTP synchronized jeweils yes an
    • In der Ausgabe von netstat ist nur der SSH-Port im Listening-Zustand zu sehen; anders als ntpd unter Ubuntu 14.04 öffnet es nicht mehrere UDP-123-Ports
  • /usr/sbin/atd -f

    • atd führt Jobs aus, die für eine spätere Ausführung in eine Queue gestellt wurden
    • at und batch lesen Befehle von stdin oder aus einer Datei und führen sie später aus
    • Anders als cron, das wiederholte Ausführungen plant, führt at einmalig zu einem bestimmten Zeitpunkt aus
    • Im Beispiel wird mit echo "touch /tmp/yolo.txt" | at now + 1 minute eine Datei nach einer Minute erstellt
    • Wenn es nicht verwendet wird, entfernt man es mit sudo apt remove at -y --purge
  • /usr/lib/snapd/snapd

    • Snappy Ubuntu Core wird als Ubuntu-Variante mit transactional updates vorgestellt
    • snap wird als universelles Linux-Paketformat beschrieben, mit dem ein einziges Binary Package auf Linux-Desktop, Server, Cloud und Devices läuft
    • Man kann es sich als vereinfachtes deb-Paket vorstellen, bei dem Dependencies in einem einzelnen Snap gebündelt und verteilt werden
    • Da auf Servern keine Anwendungen per snappy deployed oder distributed wurden, wurde es mit sudo apt remove snapd -y --purge entfernt
  • /usr/bin/dbus-daemon

    • D-Bus ist ein IPC- und RPC-Mechanismus zwischen mehreren Prozessen, die gleichzeitig auf derselben Machine laufen
    • Für Desktop Environments ist er nötig, bei einem Server, der eine Web-App ausführt, ist fraglich, ob er gebraucht wird
    • Nach dem Entfernen von dbus schlug timedatectl status mit Failed to create bus connection: No such file or directory fehl
    • Deshalb lautet das Fazit: besser beibehalten
  • /lib/systemd/systemd-logind

    • systemd-logind ist ein Systemdienst, der Benutzer-Logins verwaltet
  • /usr/sbin/cron -f

    • cron ist ein Daemon, der geplante Befehle ausführt
    • -f bedeutet Foreground Mode, also nicht daemonisieren
    • Regelmäßig auszuführende Aufgaben können mit cron geplant werden
    • crontab -e
    • Unter Ubuntu werden häufig /etc/cron.hourly, /etc/cron.daily usw. verwendet
    • Logs kann man auf folgende Weise ansehen
    • grep cron /var/log/syslog
    • journalctl _COMM=cron
    • journalctl _COMM=cron --since="date" --until="date"
    • cron wird man wahrscheinlich beibehalten
    • Wenn man ihn nicht entfernt, kann man ihn mit sudo systemctl stop cron und sudo systemctl disable cron stoppen bzw. deaktivieren
    • apt remove cron kann dazu führen, dass postfix oder Ähnliches installiert werden soll
    • Grund ist, dass cron einen Mail Transport Agent suggestet
  • /usr/sbin/rsyslogd -n

    • rsyslogd ist ein System-Utility zur Unterstützung von Message Logging
    • Es befüllt Logdateien unter /var/log/, etwa /var/log/auth.log
    • Die Konfigurationsdateien liegen in /etc/rsyslog.d
    • Es kann Logs an einen Remote-Server senden und so centralized logging ermöglichen
    • Mit dem Befehl logger kann ein Background Script Nachrichten in /var/log/syslog schreiben
    • Auch wenn systemd-journald bereits vorhanden ist, haben rsyslog und das Journal unterschiedliche Eigenschaften; der gemeinsame Einsatz kann daher sinnvoll sein
    • Deshalb vorerst beibehalten
  • /usr/sbin/acpid

    • acpid ist der ACPI Event Daemon
    • Er ist dafür ausgelegt, User-Space-Programme über ACPI-Events zu informieren
    • ACPI wird unter anderem für Hardware Component Discovery/Configuration, Power Management und Status Monitoring verwendet
    • Da auf dem virtuellen Server kein Suspend/Resume beabsichtigt war, wurde testweise entfernt
    • reboot funktionierte, aber nach halt wurde der Digital-Ocean-Server weiterhin als eingeschaltet erkannt, sodass im Webinterface Power Off ausgeführt werden musste
    • Daher lautet das Fazit: besser beibehalten
  • /usr/bin/lxcfs /var/lib/lxcfs/

    • lxcfs ist ein für LXC-Container entwickeltes FUSE-Filesystem
    • Es bietet eine virtualisierte Sicht auf einige Dateien unter /proc sowie gefilterten Zugriff auf das cgroup-Filesystem des Hosts
    • Dadurch liefern uptime, top usw. innerhalb eines Containers „korrektere“ Ergebnisse
    • Wenn keine LXC-Container verwendet werden, kann man es mit sudo apt remove lxcfs -y --purge entfernen
  • /usr/lib/accountservice/accounts-daemon

    • AccountsService stellt ein D-Bus-Interface und eine Implementierung zum Abfragen und Manipulieren von Benutzerkonto-Informationen bereit
    • Die Implementierung basiert auf den Befehlen usermod(8), useradd(8) und userdel(8)
  • Was nach der Entfernung kaputtgeht, bleibt unter „Time will tell“ offen

  • /sbin/mdadm

    • mdadm ist ein Linux-Utility zum Verwalten und Überwachen von Software-RAID-Devices
    • RAID ist eine Methode, mehrere Festplatten wie eine einzige zu nutzen
    • RAID 0 erweitert die Drive Capacity
    • RAID 1, RAID 5, RAID 6 und RAID 10 dienen dazu, bei einem Drive Failure Datenverlust zu verhindern
    • Es kann mit sudo apt remove mdadm -y --purge entfernt werden
  • /usr/lib/policykit-1/polkitd --no-debug

    • polkitd ist der PolicyKit-Daemon; polkit ist ein Authorization Framework
    • Es lässt sich als fein abgestuftes sudo verstehen
    • Damit kann einem nicht privilegierten User das Recht gegeben werden, bestimmte Actions als root auszuführen
    • Beispiel: Reboot auf einem Desktop-Linux erlauben
    • Für Server wird zusammengefasst, dass es mit sudo apt remove policykit-1 -y --purge entfernt werden kann
    • Was dadurch kaputtgeht, bleibt weiterhin offen
  • /usr/sbin/sshd -D

    • sshd ist der OpenSSH-Daemon
    • Die Option -D sorgt dafür, dass er sich nicht detacht und nicht als Daemon in den Hintergrund geht, was Monitoring erleichtert
  • /sbin/iscsid

    • iscsid ist ein Background-Daemon, der gemäß der iSCSI-Konfiguration arbeitet und Connections verwaltet
    • iSCSI ist ein IP-basierter Storage-Networking-Standard, der SCSI-Commands über ein IP-Network überträgt und so Remote Storage wie eine lokale Disk nutzbar macht
    • Es kann mit sudo apt remove open-iscsi -y --purge entfernt werden
  • /sbin/agetty --noclear tty1 linux

    • agetty ist ein alternatives Linux-getty
    • getty verwaltet physische oder virtuelle Terminals; wenn eine Verbindung erkannt wird, zeigt es einen Username-Prompt an und startet anschließend das Programm login
    • Bei Digital Ocean kann man über Console in den Droplet Details im Browser mit diesem Terminal interagieren
    • Nach dem Entfernen der zu getty@tty1.service gehörenden Dateien und einem Reboot war SSH-Zugriff möglich, über die Web Console von Digital Ocean konnte man sich jedoch nicht einloggen
  • SSH-Session, bash, htop

    • sshd: root@pts/0 bedeutet, dass die SSH-Session des Users root dem Pseudoterminal pts/0 zugeordnet wurde
    • Ein Pseudoterminal emuliert ein echtes Textterminal
    • bash ist die verwendete Shell
    • Wenn wie bei -bash vorne ein Dash steht, wurde sie als Login-Shell gestartet
    • Eine Shell, bei der das erste Zeichen von Argument zero - ist oder die mit der Option --login gestartet wurde, ist eine Login-Shell
    • In diesem Fall liest sie ein anderes Set von Configuration Files
    • htop ist der im Screenshot laufende interaktive Process Viewer

Experiment zum Entfernen von Diensten

  • Die reguläre Entfernungsliste sieht wie folgt aus
    • sudo apt remove lvm2 -y --purge
    • sudo apt remove at -y --purge
    • sudo apt remove snapd -y --purge
    • sudo apt remove lxcfs -y --purge
    • sudo apt remove mdadm -y --purge
    • sudo apt remove open-iscsi -y --purge
    • sudo apt remove accountsservice -y --purge
    • sudo apt remove policykit-1 -y --purge
  • Die Extreme Edition umfasst die folgenden Schritte
    • sudo apt remove dbus -y --purge
    • sudo apt remove rsyslog -y --purge
    • sudo apt remove acpid -y --purge
    • sudo systemctl stop cron && sudo systemctl disable cron
    • sudo rm /etc/systemd/system/getty.target.wants/getty@tty1.service
    • sudo rm /lib/systemd/system/getty@.service
  • Die Konfiguration von nginx, PHP7 und MySQL gemäß der Anleitung unattended installation of WordPress on Ubuntu Server funktioniert

Anhang: Recherchewerkzeuge und Shell-Verhalten

  • Quellcode finden

    • Wenn strace allein nicht ausreicht, kann man sich den source code ansehen
    • Mit which uptime findet man den binary-Speicherort, mit dpkg -S /usr/bin/uptime das Ubuntu-Package
    • Im Beispiel gehört uptime zum Package procps
    • Auf packages.ubuntu.com kann man nach dem Package suchen und den Link zum Source Repository finden
  • File Descriptors und Redirection

    • Um stderr nach stdout umzuleiten, verwendet man 2>&1
    • echo something > file schreibt stdout in file und entspricht echo something 1> file
    • echo something 2> file schreibt stderr in file
    • echo something 2>1 bedeutet, stderr in eine Datei mit dem Namen 1 umzuleiten
    • Bei 2>&1 mit & ist 1 kein Dateiname, sondern eine Stream-ID
  • Farbproblem in PuTTY

    • Wenn Elemente von htop in PuTTY zu fehlen scheinen, lässt sich das in den Einstellungen unter Window → Colours beheben
    • Rechtsklick auf die title bar
    • Change settings...
    • Window → Colours
    • Both radio button auswählen
    • Apply
  • Einfache Shell in C

    • Eine einfache in C geschriebene Shell zeigt die Verwendung der Systemaufrufe fork, exec und wait
    • Wenn die Eingabe exit lautet, beendet sie sich als Shell-Built-in
    • Andere Befehle werden nach fork im Child mit execlp ausgeführt, und der Parent wartet mit waitpid auf den Exit-Status
    • Ausführungsbeispiele mit date, true und false geben jeweils den Exit-Code des Child aus
    • Der Grund, warum die Beendigungsnachricht eines Background Process wie sleep 1 & erst nach dem Drücken von Enter erscheint, ist, dass die Shell auf Eingabe wartet und beim Eingeben eines Befehls den Status des Background Process prüft

Offene Recherchepunkte und Änderungshistorie

  • Punkte, die noch weiter untersucht werden sollen, sind Process State Substatus, Kernel Thread, /dev/pts, CODE-/DATA-/SWAP-Speicher, Time-Slice-Länge, Linux-Scheduler-Algorithmen, Core Pinning, Manual Page, Farben der CPU-/Memory-Bars, Process-ID-Limit und Fork Bomb, lsof, ionice, schedtool usw.
  • Zu den wichtigsten Korrekturen und Updates gehören die folgenden
    • Die Idle Time von /proc/uptime ist die Summe aller Cores
    • Die printf-Ausgaben von Parent/Child im Zombie-C-Beispiel wurden korrigiert
    • Es wurde ergänzt, dass apt remove cron wegen einer MTA-Dependency versucht, postfix zu installieren
    • id kann über /etc/nsswitch.conf Informationen auch aus anderen Quellen als /etc/passwd laden
    • Eine Erklärung des Password-Hash-Formats von /etc/shadow wurde ergänzt
    • /etc/sudoers sollte sicher mit visudo bearbeitet werden
    • Die Erklärung zu MEM% wurde ergänzt
    • Der Abschnitt zu Load Average wurde neu geschrieben
    • Das Standardsignal von kill 1234 wurde von INT auf TERM korrigiert
    • Eine Erklärung der CPU- und Memory-Color-Bars wurde ergänzt

1 Kommentare

 
GN⁺ 5 시간 전
Meinungen auf Hacker News
  • In letzter Zeit bin ich zu btop gewechselt; die Oberfläche ist so modern und nützlich wie nötig und liefert ausreichend viele Informationen.
    Wie andere schon sagten, scheint es auch den Stromverbrauch (Watts) anzuzeigen, dazu Netzwerk-, GPU- und Festplatteninformationen.
    https://github.com/aristocratos/btop

    • btop ist gut, hat aber auch Nachteile: Es gibt keine zram/zswap-Statistiken (htop unterstützt auch nur zram), keine detaillierte Aufschlüsselung von ZFS-Statistiken und noch keine Unterstützung für Arc-GPUs.
      Die Balken für die Festplattenauslastung lassen sich nicht abschalten, sodass die I/O-Geschwindigkeitsdiagramme stark zusammengedrückt wirken, wenn das Konsolenfenster nicht sehr groß ist.
    • Ich nutze btop schon lange; was mir fehlt, ist im Grunde nur eine Port-Spalte neben den anderen Spalten.
      Die CPU/GPU-Diagramme sind viel zu groß angelegt, und insgesamt würde ich mir wünschen, dass die Tabelle der geöffneten Dateien mehr Platz bekommt.
    • Gelegentlich nutze ich immer noch Alpine als Basis-Image für Container, aber btop fällt dort weg, weil es musl offenbar nicht unterstützt.
    • Ich bin ein btop-Anhänger und habe auf meinem neuen MacBook damit sogar iStatMenu ersetzt.
  • Es gibt zwei Einstellungen, die ich jedes Mal ändere, wenn ich htop benutze, und sie machen einen großen Unterschied.
    Erstens schalte ich User-Threads aus. Meist machen sie die htop-Ansicht nur unübersichtlich und liefern kaum nützliche Informationen.
    Zweitens schalte ich die Prozessbaumansicht ein. Oft ist wichtiger, wo ein Prozess gestartet wurde, als andere Informationen; außerdem lassen sich Dinge wie Compiler-Prozesse, die viele Dateien verarbeiten und CPU fressen, leichter nachverfolgen.
    Meiner Meinung nach sollten beide Verhaltensweisen in htop die Standardeinstellung sein.

    • Die Prozessbaumansicht ist gut, aber schade ist, dass beim Einschalten die dynamische Aktualisierung und Neusortierung der Prozessliste stoppt.
  • Ich finde die Erklärung gut, dass man virtuellem Speicher nur schwer trauen kann. Der Windows-Task-Manager zeigt standardmäßig genau diese Art von Wert an, und das ist ziemlich schlecht.
    Die Resident Set Size (RSS) ist die verlässlichste Kennzahl; andere Werte können durch Dinge wie Memory-mapped Files, die tatsächlich kein Problem verursachen, fälschlich aufgebläht werden.
    Wenn man zum Beispiel eine 2-GB-Logdatei per Memory Mapping einbindet, werden Seiten nur dann geladen, wenn der entsprechende Abschnitt gelesen wird; realer Speicher wird dadurch nicht einfach belegt. Trotzdem schaut ein Nutzer auf den Prozess und fragt: „Warum verbraucht diese App so viel Speicher?“
    Auch Chrome hatte eine Zeit lang dieses Problem und reduzierte deshalb die Nutzung von Memory-mapped Files — nicht weil Memory-mapped Files schlecht wären, sondern weil Nutzer auf einen Wert überreagierten, der nicht die tatsächliche Nutzung des physischen Speichers zeigte.
    Im Web gibt es sogar Guides, die empfehlen, die Nutzung anhand der Menge des allokierten virtuellen Speichers zu beurteilen; dieser Artikel stellt zumindest diesen Punkt richtig dar.

    • Tatsächlich ist die Proportional Set Size (PSS) genauer als RSS.
      Siehe: https://en.wikipedia.org/wiki/Proportional_set_size
    • Wenn man Memory-mapped Files verwendet, werden gecachte Seiten in die Resident Set Size dieses Prozesses eingerechnet.
      Bei normalem Datei-I/O ist das nicht der Fall. In HPC-Clustern, die den Speicherverbrauch einzelner Jobs überwachen und sie beenden, wenn sie die angeforderte Menge überschreiten, führt das zu ziemlich interessanten Ergebnissen.
    • Die Resident Set Size ist nicht die Speichermenge, die ein Prozess haben möchte, sondern die Menge, die das Betriebssystem diesem Prozess zugewiesen hat.
      Sobald Speicherdruck einsetzt, ist sie nicht mehr repräsentativ. Wegen dieses Missverständnisses habe ich einige falsche Entscheidungen gesehen und diesen Wert einmal aus Charts entfernt, um zu verhindern, dass ein Teammitglied in die falsche Richtung entscheidet.
    • Genau genommen verwendet der Windows-Task-Manager als Standardwert für den Speicherverbrauch eines Prozesses das Private Working Set und schließt Seiten aus, die mit anderen Prozessen geteilt werden, etwa Bibliotheken oder Memory-mapped Files.
      Wie der Name sagt, zeigt es nur den Teil, der auf prozessprivat allokierten physischen Speicher gemappt ist, und liegt näher am Resident Set unter Unix.
      Vermutlich war die Speichernutzung im Performance-Tab gemeint, aber da man das als alle Speicherverbrauchswerte missverstehen kann, wollte ich es getrennt klarstellen.
  • Wenn man in top das Zeichen > verwendet, wird nach Speicherverbrauch sortiert.
    Ich nutze das gelegentlich, wenn ich herausfinden will, warum ein Host langsam wird, und man kann auch sehen, wenn swapd CPU frisst.

    • Für Speicher bevorzuge ich den Großbuchstaben M, für CPU den Großbuchstaben P.
  • Wenn ich solche Artikel lese, merke ich, dass ich Linux zwar seit über 20 Jahren täglich nutze, aber immer noch nur einen Teil seines Potenzials ausschöpfe. Guter Artikel.

  • Es fühlt sich an, als würde HN wieder zu sich kommen.
    Ich hoffe, das ist nicht die Phase, in der HN als wandelnder Geist unterwegs ist.

    • Auf der Startseite stehen zwar drei KI-bezogene Beiträge, aber einer davon macht minderwertige generierte Inhalte nieder, also schöpfe ich Hoffnung.
    • Vielleicht erholt es sich gerade, indem es zu Beiträgen aus der Zeit vor Slop vor sieben Jahren zurückkehrt.
  • Wer nmon nicht kennt, sollte sich das auch einmal ansehen.
    Mit h erscheint die Liste der verfügbaren Monitore, erneutes Drücken blendet sie wieder aus, und mit q beendet man das Programm.
    https://nmon.sourceforge.io/pmwiki.php
    Besonders der über die Tasten d und D sichtbare Festplattendurchsatz und I/O ist ziemlich nützlich.

    • Ich habe es über die AIX-Maschinen bei der Arbeit kennengelernt, und topas kommt mir dabei ebenfalls in den Sinn.
    • Ein sehr nützliches Tool, deshalb installiere ich es auf jeder Maschine, die ich kontrolliere.
      Das Wide-CPU-Auslastungsdiagramm gefällt mir, weil es mit hohen Core-Zahlen gut zurechtkommt.
  • Im Unterschied zur Nutzung von *top-Tools bevorzuge ich inzwischen eher ruhige differenzielle Reports im Stil von ps und systemweite Reports wie bei vmstat.
    So bleibt alles im Scrollback-Puffer des Terminals erhalten: https://github.com/c-blake/procs
    Es ist in der ungewöhnlich effizienten und ausdrucksstarken Sprache Nim geschrieben.

  • Ich habe diesen Artikel seit 2016 als Lesezeichen gespeichert und über die Jahre mehrfach wieder zurate gezogen.