Ο φύλακας μας επανεκκίνησε τις υπηρεσίες που είχαμε σταματήσει σκόπιμα
Λειτουργίες
Ένας από τους φύλακές μας εκκινεί οποιαδήποτε από τις υπηρεσίες μας που είναι ενεργοποιημένη αλλά δεν εκτελείται. Δύο φορές τον Οκτώβριο εκκίνησε υπηρεσίες που είχαμε σταματήσει σκόπιμα. Τη δεύτερη φορά, οι επισκέπτες ενός από τους ιστότοπούς μας έλαβαν σφάλματα για περίπου 45 λεπτά.
Γιατί υπάρχει αυτός ο φύλακας
Μια υπηρεσία που τερματίζεται ομαλά όταν λαμβάνει SIGTERM, για παράδειγμα επειδή κάτι τη σκότωσε με το όνομά της, δεν θεωρείται «αποτυχημένη» από την άποψη του systemd. Το Restart=on-failure δεν την επαναφέρει και το systemctl --failed δεν την εμφανίζει στη λίστα. Παραμένει σταματημένη μέχρι κάποιος να το προσέξει τυχαία. Έτσι, ο φύλακας αναζητά υπηρεσίες που είναι ενεργοποιημένες αλλά δεν εκτελούνται, και τις εκκινεί.
Το πρόβλημα είναι ότι μια υπηρεσία που σταματήσατε χειροκίνητα φαίνεται ακριβώς το ίδιο.
Η πρώτη φορά
Στις 7 Οκτωβρίου σταματήσαμε έναν εργαζόμενο βίντεο με systemctl stop στις 12:47 για να επεξεργαστούμε την ουρά εργασιών του. Στις 12:55 εκτελούνταν ξανά: ο φύλακας την είχε εκκινήσει.
Η δεύτερη φορά
Στις 21 Οκτωβρίου χρειαζόματε τη μνήμη του μηχανήματος που εξυπηρετεί επίσης δύο από τους ιστότοπούς μας για μια δοκιμή μοντέλου. Ένα σενάριο σταμάτησε τις εφαρμογές ιστού των ιστότοπων, μια εργασία συγχρονισμού και ένα κοντέινερ βάσης δεδομένων, και πάλι με systemctl stop. Περίπου πέντε λεπτά αργότερα ένας χρονοδιακόπτης που παρακολουθεί τους ιστότοπους, και στις 19:14 ο φύλακας, επανέφεραν τη σήραγγα και τις εφαρμογές ιστού.
Η σήραγγα δέχτηκε ξανά κίνηση, αλλά οι εφαρμογές ιστού δεν μπορούσαν να απαντήσουν: το μοντέλο υπό δοκιμή κατείχε 114 GiB της μνήμης του μηχανήματος. Από τις 19:14 περίπου έως τις 20:00, ορισμένοι επισκέπτες λάμβαναν σφάλματα 502. Στις 20:00 απενεργοποιήσαμε τη σήραγγα, τις εφαρμογές ιστού και την εργασία συγχρονισμού, και σταματήσαμε τον χρονοδιακόπτη παρακολούθησης.
Ο κανόνας που χρησιμοποιούμε τώρα
- Σταματήστε μια υπηρεσία απενεργοποιώντας την:
sudo systemctl disable --now <unit>. Επαναφέρετέ την μεsudo systemctl enable --now <unit>. Ο φύλακάς μας εξετάζει μόνο τις ενεργοποιημένες υπηρεσίες, οπότε μια απενεργοποιημένη αφήνεται ήσυχη. - Σταματήστε τα πάντα που μπορούν να την επαναφέρουν: τη σήραγγα μπροστά της και οποιονδήποτε χρονοδιακόπτη την παρακολουθεί.
- Μια σύντομη διακοπή είναι αγώνας δρόμου. Αν χρησιμοποιήσετε μόνο το
stop, ολοκληρώστε πριν από τον επόμενο έλεγχο, ο οποίος στις μηχανές μας έρχεται μέσα σε λεπτά.
Δύο ακόμη παγίδες του systemd από τους ίδιους μήνες
- Η εντολή
systemctl mask --runtimeδεν κάνει τίποτα για ένα αρχείο μονάδας στον φάκελο /etc/systemd/system. Οι μονάδες στον φάκελο /etc έχουν προτεραιότητα έναντι της προσωρινής απόκρυψης στον φάκελο /run, οπότε η εντολή εκτελείται επιτυχώς αλλά η υπηρεσία εξακολουθεί να ξεκινά. Για να κρατήσετε μια υπηρεσία σε αναμονή, χρησιμοποιούμε ένα drop-in μεConditionPathExists=!/etc/<name>.hold: όσο αυτό το αρχείο υπάρχει, η υπηρεσία δεν θα ξεκινήσει, ούτε κατά την εκκίνηση ούτε χειροκίνητα. - Η εντολή
systemctl is-activeεμφανίζει ως ανενεργή μια εκτελούμενη υπηρεσία τύπου oneshot. Ενώ εκτελείται μια υπηρεσίαType=oneshot, η κατάστασή της είναι "activating", οπότε ηis-activeεμφανίζει αυτήν την τιμή και επιστρέφει 3. Ένας βρόχος όπωςwhile systemctl is-active --quiet job.service; do sleep 60; done, που προορίζεται να περιμένει μια νυχτερινή εργασία, τερματίζεται αμέσως. Διαβάστε αντίθετα την κατάσταση: οι τιμές active, activating, reloading ή deactivating σημαίνουν όλες ότι η διαδικασία συνεχίζεται.
Factory Floor παρακολουθεί τις ενεργοποιημένες υπηρεσίες που δεν εκτελούνται. Από προεπιλογή, αναφέρει μόνο αυτές και τις ξεκινά μόνο αν το ενεργοποιήσετε εσείς. Από την έκδοση 1.0.3, η ειδοποίησή του αναφέρει επίσης πώς να θέσετε σε παύση μια υπηρεσία σκόπιμα, και το εγχειρίδιο λειτουργίας αναφέρει το ίδιο.