Systemd κι έλεγχος logging
Για την εκκίνηση ενός συστήματος Linux υπάρχουν διάφορες μέθοδοι και μία από τις πλέον σύγχρονες, την οποία βρίσκουμε στα διαδεδομένα κι όχι μόνο distributions, υλοποιείται από το Systemd. Το Systemd κάνει πολλά περισσότερα από το να ξεκινά ένα σύστημα Linux. Κάθε διαχειριστής οφείλει τουλάχιστον να γνωρίζει τη λογική του: ακόμη κι αν δεν το χρησιμοποιεί ήδη, είναι σχεδόν βέβαιο ότι δεν θα καταφέρει να το αποφεύγει για πάντα.
Το Systemd από (αρκετά) ψηλά⌗
Προκειμένου το Systemd να διαχειρίζεται τις υπηρεσίες του λειτουργικού συστήματος αλλά και τις καταστάσεις στις οποίες είναι δυνατόν να βρεθεί, εισάγει την έννοια των στόχων (targets). Γενικά, με το Systemd έχουμε στόχους που πρέπει να επιτυγχάνονται, με κάθε στόχο να έχει τα προαπαιτούμενα ή αλλιώς τις εξαρτήσεις του (dependencies). Επιγραμματικά, κατά την εκκίνηση του λειτουργικού θα μπορούσαμε να πούμε ότι το Systemd δρα ως ακολούθως:
-
Φορτώνει αρχεία ρυθμίσεων, τα οποία συνήθως βρίσκονται στον κατάλογο
/etc/systemd
. -
Καθορίζει ποιο είναι το λεγόμενο boot goal, μ’ άλλα λόγια ποια είναι η κατάσταση στην οποία πρέπει να βρεθεί το σύστημα μετά την ολοκλήρωση της διαδικασίας εκκίνησης. Το boot goal συνήθως υποδεικνύεται από το αρχείο
default.target
(εντός του καταλόγου/etc/systemd/system
), το οποίο αποτελεί symbolic link προς το αρχείο που πράγματι περιγράφει τον στόχο εκκίνησης και βρίσκεται στον κατάλογο/usr/lib/systemd/system
. -
Εντοπίζει όλες τις εξαρτήσεις που έχει το boot goal και προσπαθεί να τις ικανοποιήσει.
Όπως το παλιό System V έφερνε το λειτουργικό σύστημα σε κάποιο runlevel, ομοίως και το Systemd φέρνει το λειτουργικό σε μία κατάσταση που περιγράφεται από ένα εκ των ακόλουθων αρχείων *.target
:
poweroff.target
– το σύστημα κλείνει (shutdown, αντίστοιχο του runlevel 0)
rescue.target
– το σύστημα φορτώνει σε single user mode και για την ακρίβεια μόνον ο χρήστης root μπορεί να συνδεθεί και δικτύωση δεν υφίσταται (αντίστοιχο του runlevel 1)
multi-user.target
– το σύστημα φορτώνει σε multiuser mode, δηλαδή κάθε χρήστης μπορεί να συνδέεται, ενώ υπάρχει δικτύωση (αντίστοιχο του runlevel 3)
graphical.target
– το σύστημα υποστηρίζει πολλούς χρήστες, προσφέρει περιβάλλον γραφικών, υπάρχει και δικτύωση (αντίστοιχο του runlevel 5)
reboot.target
– το σύστημα επανεκκινεί (αντίστοιχο του runlevel 6)
Το default.target
σε ένα σύστημα desktop συνήθως δείχνει στο αρχείο graphical.target
(εντός του /usr/lib/systemd/system
). Σε ένα σύστημα server, από την άλλη, το default.target
δείχνει στο multi-user.target
(ναι, επίσης εντός του /usr/lib/systemd/system
). Τώρα, τα βασικά αρχεία με τα οποία το Systemd δουλεύει ονομάζονται μονάδες (units). Υπάρχουν units διαφόρων τύπων, κι αυτό διότι το Systemd πέρα από τη διαχείριση υπηρεσιών διεκπεραιώνει κι άλλες εργασίες όπως, π.χ., είναι η προσάρτηση συστημάτων αρχείων ή η παρακολούθηση network sockets. Επιγραμματικά, παραθέτουμε τρεις συνηθισμένους τύπους units:
-
service units (αρχεία με κατάληξη
.service
) – προορίζονται για την εκκίνηση υπηρεσιών (services), όπως, π.χ., είναι o Apache ή ο OpenSSH server -
mount units (αρχεία με κατάληξη
.mount
) – χρησιμεύουν για την προσάρτηση συστημάτων αρχείων -
target units (αρχεία με κατάληξη
.target
) – πρόκειται για αρχεία που ομαδοποιούν άλλα units
Έχουμε ήδη εισάγει αρκετούς νέους όρους, οπότε νομίζουμε ότι είναι ώρα για λίγη πρακτική εξάσκηση. Είναι άλλωστε ο μόνος τρόπος προκειμένου να μαθαίνουμε ουσιαστικά κι όχι απλά να στοιβάζουμε πληροφορίες.
Για τις ανάγκες του παρόντος δουλέψαμε σε ένα σύστημα με openSUSE Leap. Εννοείται, φυσικά, ότι τους πειραματισμούς σας μπορείτε να τους κάνετε και σ’ οποιαδήποτε άλλη διανομή Linux με Systemd.
Σε κάθε διανομή Linux το
systemd
ξεκινάει απευθείας από τον πυρήνα, έχει process ID το 1 κι αγνοεί το θανατηφόρο signal 9, το οποίο τερματίζει κάθε άλλη διεργασία. Όλα τα άλλα προγράμματα του συστήματος ξεκινούν είτε απευθείας από το systemd
είτε από κάποια διεργασία-απόγονό του (child process).
Πρώτη (καλή) γνωριμία⌗
Είπαμε προηγουμένως ότι το boot goal υποδεικνύεται από το αρχείο default.target
, το οποίο σε ένα σύστημα desktop, όπως μπορεί να είναι το openSUSE Leap, εξ ορισμού δείχνει στο αρχείο graphical.target
. Υποθέστε ότι θέλουμε να χρησιμοποιήσουμε το μηχάνημά μας προσωρινά ως server. Ένα τέτοιο σύστημα δεν έχει λόγο να φορτώνει το υποσύστημα γραφικών. Το ιδανικό boot goal, λοιπόν, είναι το multi-user.target
. Ένας τρόπος ώστε να ξεκινήσουμε το σύστημα στο multi-user.target
, είναι να περάσουμε στον πυρήνα την παράμετρο systemd.unit=multi-user.target
. Συγκεκριμένα, στην αρχική οθόνη του GRUB επιλέγουμε τον πυρήνα πρoς εκκίνηση (με τα πάνω και κάτω βελάκια) και πατάμε το πλήκτρο [E] (από το Edit). Εμφανίζεται ένα παράθυρο με κείμενο, όπου βλέπουμε όλες τις οδηγίες προς τον GRUB. Με τα βελάκια του δρομέα μεταβαίνουμε στη γραμμή που αρχίζει με linux
, και καθορίζει την έκδοση του πυρήνα προς φόρτωση. Στο τέλος της γραμμής αφήνουμε ένα κενό και προσθέτουμε το systemd.unit=multi-user.target
(χωρίς τα εισαγωγικά, βλ. και screenshot που ακολουθεί). Για την εκκίνηση του λειτουργικού πατάμε το συνδυασμό πλήκτρων [CTRL+X].
Προσωρινή αλλαγή boot goal μέσα από τον GRUB, περνώντας στον πυρήνα την κατάλληλη παράμετρο.
Το σύστημα desktop των δοκιμών μας μόλις ξεκίνησε χωρίς περιβάλλον γραφικών. Υποστηρίζει ωστόσο δικτύωση κι επιτρέπει σύνδεση σε πολλούς χρήστες. Το boot goal του Systemd ήταν το
multi-user.target
, αντίστοιχο του runlevel 3 που έχει το System V.
Υπενθυμίζουμε ότι η αλλαγή target με τον τρόπο που μόλις δείξαμε είναι προσωρινή, υπό την έννοια ότι στο επόμενο reboot το σύστημα θα ξεκινήσει στο προκαθορισμένο target, το οποίο για εμάς είναι το graphical.target
. Εκτός από το GRUB η προσωρινή αλλαγή target γίνεται κι από τη γραμμή εντολών, χωρίς επανεκκίνηση του συστήματος. Απλά πληκτρολογούμε:
sudo systemctl isolate multi-user.target
Αργότερα, όταν θα θέλουμε και πάλι να επιστρέψουμε στο graphical.target
, θα γράψουμε:
sudo systemctl isolate graphical.target
Τι κάνουμε όμως αν θέλουμε μόνιμη αλλαγή boot goal, ώστε κάθε φορά που ανοίγουμε ή επανεκκινούμε τον υπολογιστή να βρισκόμαστε στο νέο target; Κοιτάξτε, μπορούμε να πραγματοποιήσουμε την αλλαγή είτε από τη γραμμή εντολών είτε από το όποιο εργαλείο διαχείρισης για το περιβάλλον γραφικών διαθέτει η διανομή μας (στο openSUSE χρησιμοποιούμε το YaST). Συγκεκριμένα, από τη γραμμή εντολών πληκτρολογούμε:
sudo ln -sf /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target
Όπως βλέπετε, αυτό που κάναμε μόλις ήταν, απλά, να αλλάξουμε το αρχείο .target
, στο οποίο δείχνει το default.target
: έδειχνε στο graphical.target
, τώρα δείχνει στο multi-user.target
, άρα το λειτουργικό σε κάθε εκκίνηση/επανεκκίνηση θα υποστηρίζει πολλούς χρήστες και δικτύωση, χωρίς όμως να φορτώνει περιβάλλον γραφικών. Αν εξάλλου προτιμάμε τα εργαλεία για το GUI, πραγματοποιούμε αλλαγή boot goal με τη βοήθεια του YaST – και συγκεκριμένα μέσα από το module ονόματι Services Manager.
Αλλαγή boot goal με τη βοήθεια του YaST – και συγκεκριμένα μέσα από το module ονόματι Services Manager.
Διαχείριση υπηρεσιών και προαπαιτούμενα στόχων⌗
Το systemctl
είναι το βασικό εργαλείο για τη διαχείριση των υπηρεσιών στον κόσμο του Systemd. Το χρησιμοποιήσαμε στην προηγούμενη ενότητα, ώστε ν’ αλλάξουμε προσωρινά target. Είναι ώρα να το γνωρίσουμε καλύτερα. Το συντακτικό που καταλαβαίνει το systemctl
έχει ως ακολούθως:
systemctl [γενικές επιλογές] υποεντολή [επιλογές υποεντολής]
Δίνοντας σε ένα τερματικό systemctl
χωρίς τίποτε άλλο, επιστρέφονται όλα τα units που έχουν φορτωθεί. Δοκιμάστε να δώσετε την εντολή – και μην αποθαρρυνθείτε από την πληθώρα των αποτελεσμάτων. Παρατηρήστε ότι επειδή δεν χωρούν όλα σε μία οθόνη, το systemctl
τα στέλνει σε έναν pager. Έτσι, με το που γεμίζει η οθόνη πατάμε [Space] για συνέχεια ή τα βελάκια του δρομέα για πάνω/κάτω ή το πλήκτρο [Q] για έξοδο. Αν πάλι δεν θέλουμε pager, δίνουμε στο systemctl
τη γενική επιλογή --no-pager
. Με τη δε υποεντολή list-unit-files
το systemctl
επιστρέφει όλα τα παρόντα στο σύστημα unit files, ασχέτως της κατάστασής τους. Και πάλι μιλάμε για πολλή πληροφορία –περισσότερη από πριν–, οπότε ίσως θέλουμε να δούμε μόνο τα unit files που αντιστοιχούν σε υπηρεσίες. Σ’ αυτή την περίπτωση, στην υποεντολή list-unit-files
δίνουμε την επιλογή --type=service
. Συνοψίζοντας: Προκειμένου να δούμε όλες τις διαθέσιμες στο Systemd υπηρεσίες χωρίς τα αποτελέσματα να περάσουν από pager, γράφουμε:
systemctl --no-pager list-unit-files --type=service
Θα παρατηρήσετε ότι το παραπάνω δεν ξεχωρίζει ενεργές από μη-ενεργές υπηρεσίες και τις επιστρέφει όλες. Ένας τρόπος ώστε να δούμε μόνο τις ενεργές, είναι να δώσουμε άλλη μια επιλογή στην υποεντολή list-unit-files
. Δείτε:
systemctl --no-pager list-unit-files --type=service --state=enabled
Παρεμπιπτόντως, η προηγούμενη γραμμή έχει απ’ όλα: εντολή (systemctl
), γενική επιλογή (--no-pager
), υποεντολή (list-unit-files
), επιλογές υποεντολής (--type=service
και --state=enabled
). Μπορείτε τώρα να φανταστείτε πώς παίρνουμε μια λίστα με όλες τις υπηρεσίες που δεν είναι ενεργές; Και βέβαια μπορείτε: αντί για --state=enabled
, δίνουμε --state=disabled
.
Λίστα με όλες τις ενεργές υπηρεσίες του συστήματος των δοκιμών μας. Για μια λίστα με τις μη-ενεργές υπηρεσίες, στην υποεντολή
list-unit-files
δίνουμε την επιλογή --state=disabled
.
Αν παρατηρήσετε λίγο τη λίστα με τις ανενεργές υπηρεσίες, θα δείτε ότι μεταξύ αυτών είναι και εκείνη του OpenSSH daemon (βλ. unit file ονόματι sshd.service
). Για την κατάσταση μιας υπηρεσίας της οποίας γνωρίζουμε το unit file, πληκτρολογούμε:
systemctl status sshd.service
Αποτέλεσμα:
sshd.service - OpenSSH Daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled)
Active: inactive (dead)
Όπως βλέπετε, το αρχείο sshd.service
έχει φορτωθεί (loaded) αλλά η υπηρεσία είναι απενεργοποιημένη (disabled). Είναι επίσης και ανενεργή (inactive). Λογικά θ’ αναρωτηθείτε τώρα για τη διαφορά –αν υφίσταται διαφορά– μεταξύ των όρων “απενεργοποιημένος” κι “ανενεργός”. Ίσως δεν φαίνεται αμέσως, αλλά διαφορά υφίσταται. Θα την εξηγήσουμε σε πολύ λίγο, αλλά ας πούμε από τώρα ότι παρόμοια διαφορά έχουμε και με τους όρους “ενεργοποιημένος” (enabled) και “ενεργός” (active). Όταν θέλουμε να ξεκινήσουμε μια υπηρεσία που είναι ανενεργή, τότε δίνουμε στο systemctl
την υποεντολή start
ακολουθούμενη από το όνομα του αντίστοιχου unit file. Παράδειγμα:
sudo systemctl start sshd.service
Δεν παίρνουμε κάποια ειδοποίηση στο τερματικό, οπότε για να βεβαιωθούμε ότι όλα πήγαν καλά γράφουμε:
systemctl status sshd.service
Αποτέλεσμα:
sshd.service - OpenSSH Daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled)
Active: active (running) since Sun 2016-09-04 08:31:32 CEST; 1min 20s ago
Process: 2473 ExecStartPre=/usr/sbin/sshd-gen-keys-start (code=exited, status=0/SUCCESS)
Main PID: 2477 (sshd)
CGroup: /system.slice/sshd.service
└─2477 /usr/sbin/sshd -D
Θεσπέσια. Βλέπουμε ότι τώρα η υπηρεσία του OpenSSH είναι ενεργή (active). Παραμένει όμως απενεργοποιημένη (disabled), κι αυτή η φαινομενική ασυνέπεια φωνάζει ότι είναι ώρα να δοθούν εξηγήσεις και διευκρινίσεις.
-
Ενεργοποιημένη (enabled) υπηρεσία: Ξεκινά κάθε φορά που ανοίγουμε ή επανεκκινούμε τον υπολογιστή, ασχέτως αν στο προηγούμενο session την είχαμε σταματήσει.
-
Απενεργοποιημένη (disabled) υπηρεσία: Δεν ξεκινά όταν ανοίγουμε ή επανεκκινούμε τον υπολογιστή, ασχέτως αν στο προηγούμενο session την είχαμε ξεκινήσει.
-
Ενεργή (active) υπηρεσία: Στο παρόν session τρέχει, όμως αυτό δεν σημαίνει ότι θα τρέχει και μετά από επανεκκίνηση του υπολογιστή. Για να ξεκινά αυτόματα και μετά από επανεκκίνηση, η υπηρεσία θα πρέπει να είναι και ενεργοποιημένη (enabled).
-
Ανενεργή (inactive) υπηρεσία: Στο παρόν session δεν τρέχει, όμως αυτό δεν σημαίνει ότι δεν θα τρέχει και μετά από επανεκκίνηση του υπολογιστή. Για να μην τρέχει και μετά από επανεκκίνηση, η υπηρεσία θα πρέπει να είναι και απενεργοποιημένη (disabled).
Και μετά τα προηγούμενα, νομίζουμε ότι οι διαφορές μεταξύ των όρων enabled/active και disabled/inactive έχουν γίνει φανερές. Είδαμε εξάλλου ότι μετά την εκκίνηση του SSH daemon η υπηρεσία παραμένει disabled. Προκειμένου να είναι και enabled, και συνεπώς να ξεκινά κάθε φορά που ανοίγουμε ή επανεκκινούμε τον υπολογιστή, η υποεντολή που δίνουμε στο systemctl
είναι η enable
:
sudo systemctl enable sshd.service
Αυτό που μόλις έγινε, είναι ότι δημιουργήθηκε ένα symbolic link από το sshd.service
του καταλόγου /etc/systemd/system/multi-user.target.wants
, προς το αρχείο sshd.service
του καταλόγου /usr/lib/systemd/system
.
Ξεκινάμε την υπηρεσία του OpenSSH (1) και βεβαιωνόμαστε ότι όλα πήγαν καλά (2). Παρατηρούμε ότι η υπηρεσία, παρά το γεγονός ότι τώρα τρέχει, δεν είναι ενεργοποιημένη και συνεπώς δεν θα ξεκινήσει αυτόματα κατά την επόμενη εκκίνηση ή επανεκκίνηση του λειτουργικού. Θέλουμε η υπηρεσία να είναι διαθέσιμη ανά πάσα στιγμή, οπότε την ενεργοποιούμε (3). Μετά από έναν ακόμα έλεγχο, βλέπουμε ότι όλα είναι όπως τα θέλουμε: η υπηρεσία είναι και ενεργή και ενεργοποιημένη (4).
Γενικά, από τις ονομασίες και μόνο κάποιων καταλόγων αμέσως υποψιαζόμαστε τι ισχύει. Παράδειγμα: Το muti-user.target
–όπως άλλωστε κι άλλα targets– έχει μια σειρά από προαπαιτούμενα. Αυτά παρατίθενται, εν είδη συμβολικών δεσμών, μέσα στον κατάλογο multi-user.target.wants
. Ένας τρόπος προκειμένου να μάθουμε για όλα τα προαπαιτούμενα του multi-user.target
, είναι απλά να δούμε τα περιεχόμενα του καταλόγου /etc/systemd/system/multi-user.target.wants
.
Για τα προαπαιτούμενα του
multi-user.target
αρκεί να δούμε τους συμβολικούς δεσμούς που περιλαμβάνονται εντός του καταλόγου /etc/systemd/system/multi-user.target.wants
.
Το σύστημα στο οποίο εργαζόμαστε γι’ αυτή την παρουσίαση, το χρησιμοποιούμε ως desktop. Το default.target
, λοιπόν, είναι το graphical.target
. Μετά την ενεργοποίηση του SSH daemon, όμως, αρχίσαμε να ασχολούμαστε με το multi-user.target
και τα προαπαιτούμενά του, στον κατάλογο multi-user.target.wants
. Δεν θα έπρεπε να ασχοληθούμε με το graphical.target
και τα περιεχόμενα του καταλόγου graphical.target.wants
– ή κάτι τέτοιο; Λογική η σκέψη, όμως όπως εύκολα μπορείτε να διαπιστώσετε ο προαναφερθείς κατάλογος δεν υπάρχει εντός του /etc/systemd/system
(στον οποίο κατοικεί ο multi-user.target.wants
). Τι συμβαίνει εδώ; Δύο πράγματα πρέπει να λάβουμε υπόψη. Κατά πρώτον, όπως μπορούμε να διαπιστώσουμε παρατηρώντας το περιεχόμενο του αρχείου /usr/lib/systemd/system/sshd.service
, η υπηρεσία του SSH εγκαθίσταται για το multi-user.target
, αφού αυτό το target τη θέλει.
Εξετάζοντας το αρχείο
/usr/lib/systemd/system/sshd.service
, διαπιστώνουμε ότι η υπηρεσία του SSH απαιτείται από το multi-user.target
. Έτσι, μετά την ενεργοποίησή της θα είναι διαθέσιμη τόσο σ’ αυτό όσο και σε κάθε άλλο target που εμπεριέχει το multi-user.target
. Παρατηρήστε εξάλλου ότι η υπηρεσία ενεργοποιείται μετά το network.target
. Λογικό, από τη στιγμή που έχουμε να κάνουμε με δικτυακή υπηρεσία.
Κατά δεύτερον, το graphical.target
απαιτεί την ενεργοποίηση του multi-user.target
– είναι υπερσύνολό του, όπως θα έλεγε ενθουσιωδώς ένα μαθηματικός. Άρα, από τη στιγμή που η υπηρεσία του SSH ενεργοποιείται για το multi-user.target
, παραμένει ενεργοποιημένη και για το graphical.target
. Προκειμένου να δούμε τι απαιτεί το graphical.target
, αρκεί να εξετάσουμε το περιεχόμενο του ομώνυμου αρχείου εντός του καταλόγου /usr/lib/systemd/system
.
Ρίχνοντας μια ματιά στο περιεχόμενο του αρχείου
/usr/lib/systemd/system/graphical.target
, καταλαβαίνουμε ότι το αντίστοιχο target απαιτεί το multi-user.target
. Επιπρόσθετα, το graphical
ενεργοποιείται μετά το multi-user
, ενώ θέλει και την υπηρεσία του display manager. Δεν ξέρουμε πώς το βλέπετε, νομίζουμε όμως ότι το περιεχόμενο των target files συμβαδίζει με αρκετά απ’ όσα γνωρίζουμε από την καθημερινή μας ενασχόληση με το Linux – τι λέτε κι εσείς;
Χρήσιμες υποεντολές⌗
Από τη συζήτηση που ξεκινήσαμε για το systemctl
και μέσα από το παράδειγμα με την υπηρεσία του SSH, έχουμε ήδη κάνει σημαντική πρόοδο στο θέμα της διαχείρισης υπηρεσιών σε ένα σύστημα Linux με Systemd. Παραθέτουμε στη συνέχεια μερικές χρήσιμες υποεντολές και τη χρησιμότητα καθεμιάς. Εκτός από μια ανάγνωση, σας προτρέπουμε να πειραματιστείτε στο δικό σας σύστημα.
start
: Εκκίνηση υπηρεσίας για το τρέχον session. Οφείλουμε να γνωρίζουμε το όνομα του αντίστοιχου service unit. Παράδειγμα: sudo systemctl start sshd.service
. Αν θέλουμε η υπηρεσία να ξεκινά αυτόματα σε κάθε (επαν)εκκίνηση, τότε πρέπει να την ενεργοποιήσουμε κιόλας. Δείτε παρακάτω.
stop
: Ομαλός τερματισμός υπηρεσίας για το τρέχον session. Παράδειγμα: sudo systemctl stop sshd.service
. Αν θέλουμε η υπηρεσία να μην ξεκινά αυτόματα κατά την (επαν)εκκίνηση, τότε πρέπει να την απενεργοποιήσουμε κιόλας. Δείτε παρακάτω.
restart
: Ομαλός τερματισμός υπηρεσίας κι αμέσως μετά εκ νέου εκκίνηση. Αν η υπηρεσία δεν έτρεχε, τότε απλά ξεκινά. Παράδειγμα: sudo systemctl restart sshd.service
try-restart
: Επανεκκίνηση υπηρεσίας αλλά μόνον αν τρέχει ήδη. Παράδειγμα: sudo systemctl try-restart sshd.service
reload
: Υποχρεώνει μια υπηρεσία να διαβάσει εκ νέου τα αρχεία ρυθμίσεων, χωρίς όμως να επανεκκινήσει. Ίσως, π.χ., έχουμε τροποποιήσει το configuration file του SSH daemon, ώστε να δέχεται μόνο key-based authentication ή/και για να αφουγκράζεται αιτήσεις πελατών από εναλλακτικό port (το στάνταρτ είναι το 22/TCP). Για να δουλέψει το reload
πρέπει να υποστηρίζεται από την αντίστοιχη υπηρεσία. Παράδειγμα: sudo systemctl reload sshd.service
reload-or-restart
: Υποχρεώνει μια υπηρεσία να διαβάσει εκ νέου τα αρχεία ρυθμίσεων. Σε περίπτωση που η υπηρεσία δεν υποστηρίζει το reload
, τότε η παρούσα εντολή την επανεκκινεί. Αν η υπηρεσία δεν έτρεχε, τώρα ξεκινά. Παράδειγμα: sudo systemctl reload-or-restart sshd.service
reload-or-try-restart
: Υποχρεώνει μια υπηρεσία να διαβάσει εκ νέου τα αρχεία ρυθμίσεων. Σε περίπτωση που η υπηρεσία δεν υποστηρίζει το reload
, τότε η παρούσα εντολή την επανεκκινεί αλλά μόνον αν έτρεχε ήδη. Παράδειγμα: sudo systemctl reload-or-try-restart sshd.service
status
: Λεπτομερείς πληροφορίες για την κατάσταση μιας υπηρεσίας. Αν η εντολή πληκτρολογηθεί με δικαιώματα root, στην έξοδό της περιλαμβάνονται και τα πλέον πρόσφατα μηνύματα που παρήγαγε η υπηρεσία.
Παράδειγμα:
sudo systemctl status sshd.service
Αποτέλεσμα:
sshd.service - OpenSSH Daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled)
Active: active (running) since Sun 2016-09-11 09:17:53 CEST; 12s ago
Process: 2609 ExecStartPre=/usr/sbin/sshd-gen-keys-start (code=exited, status=0/SUCCESS)
Main PID: 2612 (sshd)
CGroup: /system.slice/sshd.service
└─2612 /usr/sbin/sshd -D
Sep 11 09:17:53 osuse-vm.localdomain sshd-gen-keys-start[2609]: Checking for missing server keys in /etc/ssh
Sep 11 09:17:53 osuse-vm.localdomain systemd[1]: Started OpenSSH Daemon.
Sep 11 09:17:53 osuse-vm.localdomain sshd[2612]: Server listening on 0.0.0.0 port 22.
Sep 11 09:17:53 osuse-vm.localdomain sshd[2612]: Server listening on :: port 22.
is-active
: Πληροφορία για την κατάσταση της υπηρεσίας στο τρέχον session (ενεργή ή ανενεργή).
Παράδειγμα:
systemctl is-active sshd.service
Αποτέλεσμα:
active
Άλλο παράδειγμα:
systemctl is-active ModemManager.service
Αποτέλεσμα:
inactive
enable
: Ενεργοποίηση υπηρεσίας, ώστε να ξεκινά αυτόματα κατά την (επαν)εκκίνηση του λειτουργικού. Αν η υπηρεσία δεν τρέχει, αυτή τη στιγμή δεν θα ξεκινήσει από μόνη της.
Παράδειγμα:
sudo systemctl enable sshd.service
Το αποτέλεσμα είναι ίδιο με το να δίναμε την ακόλουθη εντολή:
ln -s '/usr/lib/systemd/system/sshd.service' '/etc/systemd/system/multi-user.target.wants/sshd.service'
disable
: Απενεργοποίηση υπηρεσίας, ώστε να μην ξεκινά αυτόματα κατά την (επαν)εκκίνηση του λειτουργικού. Αν η υπηρεσία τρέχει, αυτή τη στιγμή δεν θα τερματιστεί από μόνη της.
Παράδειγμα:
sudo systemctl disable sshd.service
Το αποτέλεσμα είναι ίδιο με το να δίναμε την ακόλουθη εντολή:
rm '/etc/systemd/system/multi-user.target.wants/sshd.service'
is-enabled
: Πληροφορία για το αν η υπηρεσία είναι ενεργοποιημένη ή απενεργοποιημένη.
Παράδειγμα:
systemctl is-enabled sshd.service
Αποτέλεσμα:
enabled
Άλλο παράδειγμα:
systemctl is-enabled ModemManager.service
Αποτέλεσμα:
disabled
reenable
. Απενεργοποίηση υπηρεσίας κι αμέσως μετά ενεργοποίηση εκ νέου. Η εντολή είναι χρήσιμη όποτε χρειάζεται να επαναφέρουμε τα symbolic links που αφορούν στην ενεργοποίηση της υπηρεσίας, με τον τρόπο που περιγράφεται στο τμήμα [Install]
του αντίστοιχου service unit.
Παράδειγμα:
sudo systemctl reenable sshd.service
Το αποτέλεσμα είναι ίδιο με εκείνο των ακόλουθων δύο εντολών:
rm '/etc/systemd/system/multi-user.target.wants/sshd.service'
ln -s '/usr/lib/systemd/system/sshd.service' '/etc/systemd/system/multi-user.target.wants/sshd.service'
mask
: Μετά την απενεργοποίηση μιας υπηρεσίας, σε περίπτωση που δεν είναι ενεργή κάλλιστα μπορούμε να την ξεκινήσουμε χειροκίνητα. Αν όμως είναι μασκαρισμένη, τότε δεν μπορούμε.
Έχουμε μια υπηρεσία που είναι ενεργοποιημένη και προς το παρόν ανενεργή (1). Μπορούμε φυσικά να την απενεργοποιήσουμε (2). Αν επιπρόσθετα τη μαρκάρουμε (3), τότε το χειροκίνητο ξεκίνημά της δεν θα είναι δυνατό (4).
unmask
: Μία υπηρεσία που είναι μασκαρισμένη της αφαιρούμε τη μάσκα μ’ αυτή την εντολή. Έτσι, μπορούμε και πάλι να την ξεκινήσουμε χειροκίνητα.
Έχουμε μια υπηρεσία που είναι απενεργοποιημένη και μασκαρισμένη (1). Το χειροκίνητο ξεκίνημά της προς το παρόν δεν είναι δυνατό. Αν όμως της αφαιρέσουμε τη μάσκα (2), μπορούμε τότε να την ξεκινήσουμε (3), (4).
Απαιτήσεις κι επιθυμίες⌗
Μια χρήσιμη υποεντολή του systemctl είναι η show
, η οποία μεταξύ άλλων επιστρέφει τις ιδιότητες των μονάδων. Δοκιμάστε να δώσετε
systemctl --no-pager show graphical.target
και θα πάρετε ουκ ολίγες λεπτομέρειες για το graphical.target
. Η υποεντολή show
, όμως, δέχεται και κάποιες παραμέτρους που την κάνουν πολύ πιο χρήσιμη. Αν, για παράδειγμα, πληκτρολογήσουμε
systemctl --no-pager show -p "Requires" graphical.target
τότε βλέπουμε τα προαπαιτούμενα του graphical.target
:
Requires=multi-user.target
(πρέπει να έχει προηγηθεί το multi-user.target
). Αν πάλι πληκτρολογήσουμε
systemctl --no-pager show -p "Wants" graphical.target
τότε μαθαίνουμε για τις υπηρεσίες που είναι επιθυμητές από το graphical.target, αλλά όχι απαραίτητες:
Wants=display-manager.service YaST2-Firstboot.service systemd-readahead-replay.service YaST2-Second-Stage.service systemd-readahead-collect.service systemd-update-utmp-runlevel.service
Διαχείριση αρχείων καταγραφής⌗
To Systemd είναι ικανό να διαχειρίζεται το ίδιο τα αρχεία καταγραφής (log files), συνεπώς δεν υπάρχει ανάγκη χρήσης κάποιας άλλης σχετικής υπηρεσίας (τύπου syslog
). Πιο συγκεκριμένα, τα log files στον κόσμο του Systemd είναι υπό την εποπτεία και την ευθύνη του λεγόμενου journal, το οποίο δεν είναι τίποτε άλλο από μια υπηρεσία που διαχειρίζεται το ίδιο το Systemd. Το πλήρες όνομα του αντίστοιχου service unit είναι systemd-journald.service
και, όπως εύκολα διαπιστώνουμε, η υπηρεσία είναι στατική (static) και ενεργοποιημένη:
systemctl status systemd-journald.service
systemctl status systemd-journald.service
Αποτέλεσμα:
systemd-journald.service - Journal Service
Loaded: loaded (/usr/lib/systemd/system/systemd-journald.service; static)
Active: active (running) since Sun 2016-09-11 14:16:19 CEST; 2h 41min ago
Docs: man:systemd-journald.service(8)
man:journald.conf(5)
Main PID: 374 (systemd-journal)
Status: "Processing requests..."
CGroup: /system.slice/systemd-journald.service
└─374 /usr/lib/systemd/systemd-journald
Το
static
, στη θέση όπου θα περιμέναμε να δούμεenabled
,disabled
ήmasked
, σημαίνει ότι η αντίστοιχη υπηρεσία δεν μπορεί να ενεργοποιηθεί: Είτε κάνει μία συγκεκριμένη εργασία και μετά τερματίζεται, είτε αποτελεί προαπαιτούμενο άλλου unit και δεν πρέπει να χρησιμοποιείται από μόνη της.
Το journal συλλέγει κι οργανώνει δεδομένα logging αντλώντας τα από τον πυρήνα, τις διεργασίες και τις υπηρεσίες. Αναλόγως της διανομής οι πληροφορίες καταγραφής είναι πιθανό να χάνονται κατά το reboot. Μπορούμε, βεβαίως, να επιβάλλουμε τη διατήρησή τους: με δικαιώματα root ανοίγουμε το αρχείο /etc/systemd/journald.conf
και φροντίζουμε ώστε στην ενότητα [journal]
να υπάρχει η γραμμή
Storage=persistent
(και φυσικά να μην είναι “σχολιασμένη”). Αποθηκεύουμε τις αλλαγές κι επανεκκινούμε την υπηρεσία του logging:
sudo systemctl restart systemd-journald.service
Πλέον, τα δεδομένα καταγραφής θα οργανώνονται εντός του καταλόγου /var/log/journal
– και θα διατηρούνται και μετά από reboot. Αναλόγως της χρήσης που κάνουμε ή ακόμα και του ρόλου που έχει ο υπολογιστής, ο συνολικός όγκος των δεδομένων καταγραφής είναι πιθανό να ξεφύγει προς τα πάνω, δεσμεύοντας αποθηκευτικό χώρο που ίσως είναι κρίσιμος για άλλες εφαρμογές και υπηρεσίες. Πληκτρολογήστε
man 5 journald.conf
ώστε να δείτε πώς θα αποκλείσετε ένα τέτοιο ενδεχόμενο. Προσέξτε, π.χ., την παράμετρο SystemMaxUse
, η οποία εξ ορισμού ισούται με το 10% του μεγέθους της κατάτμησης όπου αποθηκεύονται τα δεδομένα καταγραφής. Τις δυνατότητες και την ευελιξία του journal θα τις εκτιμήσουμε αφού αρχίσουμε να χρησιμοποιούμε το journalctl
, το οποίο είναι το εργαλείο λήψης πληροφοριών από τα αρχεία καταγραφής. Στη συνέχεια της παρουσίασής μας δίνουμε μερικά παραδείγματα.
Εμφάνιζε ζωντανά (επιλογή -f
) τα είκοσι πιο πρόσφατα μηνύματα του journal (παράμετρος -n 20
):
sudo journalctl -n 20 -f
Εμφάνισε μόνο μηνύματα του πυρήνα (επιλογή -k
):
sudo journalctl --no-pager -k
(αν παραλείψουμε την επιλογή --no-pager
, τα αποτελέσματα εμφανίζονται με τη βοήθεια pager).
Χωρίς τη χρήση pager (επιλογή --no-pager
), εμφάνισε τα είκοσι πιο πρόσφατα μηνύματα (παράμετρος -n 20
) που αφορούν στο service unit του SSH daemon (παράμετρος -u sshd
):
sudo journalctl --no-pager -n 20 -u sshd
Τα μηνύματα που αφορούν στην πιο πρόσφατη αλλά και στις προηγούμενες εκκινήσεις (boots) καταγράφονται στο journal. Προκειμένου να δούμε τα διαθέσιμα boots που έχει καταγράψει το journal, πληκτρολογούμε:
sudo journalctl --list-boots
Δώστε την παραπάνω εντολή στο σύστημά σας. Μην αποθαρρυνθείτε από το πλήθος των πληροφοριών που θα επιστραφούν. Προσέξτε μόνο τους αριθμούς στην πρώτη στήλη από αριστερά: το 0 είναι το πιο πρόσφατο boot, το -1 το προηγούμενο, το -2 εκείνο πριν το προηγούμενο κ.ο.κ. Δείτε εξάλλου ότι για κάθε boot υπάρχει και το αντίστοιχο timestamp. Αν τώρα θέλουμε τα μηνύματα του πιο πρόσφατου boot, γράφουμε:
sudo journalctl --no-pager -b 0
Ειδικά γι’ αυτό μπορούμε να παραλείψουμε τον αριθμό του (δηλαδή το 0). Για όλα τα προηγούμενα, όμως, τον συμπεριλαμβάνουμε υποχρεωτικά:
sudo journalctl --no-pager -b -5
Εμφάνιζε ζωντανά (επιλογή -f
) όλα τα μηνύματα από τώρα και στο εξής (παράμετρος --since "now"
):
sudo journalctl -f --since "now"
Χωρίς pager (επιλογή --no-pager
) εμφάνισε όλα τα σημερινά μηνύματα (παράμετρος --since "today"
) αλλά έως τις δύο και μισή μετά το μεσημέρι (παράμετρος --until "14:30"
):
sudo journalctl --no-pager --since "today" --until "13:00"
Εναλλακτικά, μιας και άγρια χαράματα έχει παρατηρηθεί παράξενη συμπεριφορά στο πρόσφατο παρελθόν, με χρήση pager για δώσε λίγο όλα τα μηνύματα μεταξύ τέσσερις έως έξι, να δω κάτι:
sudo journalctl --since "04:00" --until "06:00"
Δώσε όλα τα μηνύματα που αφορούν στο χρήστη με user ID το 1000 (παράμετρος _UID=1000
), ξεκινώντας από τις επτά το βράδυ (παράμετρος --since "19:00"
):
sudo journalctl --since "19:00" _UID=1000
(Το τελευταίο ήταν παράδειγμα φιλτραρίσματος με βάση συγκεκριμένο πεδίο: το UID
.)
Κλείνουμε την παρουσίασή μας με ένα απλό σενάριο διερεύνησης προβλημάτων περί υπηρεσιών. Ας υποθέσουμε ότι χρησιμοποιούμε τον SSH daemon και κάποια στιγμή αποφασίζουμε ν’ αλλάξουμε το τυπικό port που χρησιμοποιεί η υπηρεσία: είναι το 22, αλλά για λόγους ασφαλείας θέλουμε να το αλλάξουμε στο 50022. Με δικαιώματα διαχειριστή, λοιπόν, ανοίγουμε το αρχείο /etc/ssh/sshd_config
και τροποποιούμε αναλόγως την παράμετρο Port
. Βέβαιοι πως όλα πήγαν καλά, αποθηκεύουμε την αλλαγή, ξεχνάμε το όλο θέμα και συνεχίζουμε τις δουλειές μας. Αργότερα, ίσως και μια άλλη μέρα, συνειδητοποιούμε ότι είναι αδύνατον να συνδεθούμε απομακρυσμένα στο μηχάνημά μας μέσω SSH. Με το που θα βρεθούμε ξανά μπροστά του, αρχικά γράφουμε:
systemctl status sshd.service
Διαπιστώνουμε ότι για κάποιον λόγο η υπηρεσία δεν έχει ξεκινήσει. Με τη βοήθεια του journalctl
εμφανίζουμε τις τελευταίες δεκαπέντε γραμμές του log που αφορούν ειδικά στο service unit του SSH:
sudo journalctl --no-pager -n 15 -u sshd
Ανάμεσα στις γραμμές βρίσκεται και η εξήγηση για την αποτυχία εκκίνησης της υπηρεσίας:
[...]
Sep 11 21:59:01 osuse-vm.localdomain sshd[2369]: /etc/ssh/sshd_config line 13: Badly formatted port number.
[...]
Κάτι δεν πάει καλά με το port, προφανώς: Ανοίγοντας το /etc/ssh/sshd_config
βλέπουμε ότι αντί για το port 50022 είχαμε καθορίσει το (ανύπαρκτο) port 500022. Ένα μηδενικό ήταν ο υπαίτιος, αλλά χάρη στο journalctl
το βρήκαμε αμέσως.
Διαβάστε το man page του journalctl
για όλες τις άλλες δυνατότητές του. Επίσης: Καλωσορίσατε στον κόσμο του Systemd. Τέλος: Το Systemd έχει την ικανότητα παράλληλης εκκίνησης υπηρεσιών, παραβιάζοντας, φαινομενικά, τις μεταξύ τους εξαρτήσεις. Μπορείτε να διερευνήσετε περισσότερο, ώστε να διαπιστώσετε πώς είναι δυνατόν να καταφέρνει κάτι τέτοιο; Καλή σας διασκέδαση!
Διερεύνηση του πραγματικού αιτίου για την αποτυχία εκκίνησης του SSH deamon. Με το
systemctl
διαπιστώνουμε ότι έχουμε πρόβλημα, με το journalctl
βρίσκουμε σε τι οφείλεται.
Από το YaST, το πολυεργαλείο διαχείρισης συστήματος του openSUSE, δεν θα μπορούσε να λείπει κι ένα module για τη διαχείριση του journal. Ξέρουμε βέβαια ότι αγαπάτε την κονσόλα και τη γραμμή εντολών, κάνουμε ωστόσο και την αναφορά μας στο YaST για τους 7 αναγνώστες που προτιμούν το περιβάλλον γραφικών.
Άρθρα της σειράς⌗
-
Το Systemd κι ο έλεγχος του logging