0Pricing
DevOps Bootcamp · Lekcja

Sterowanie usługami systemd i pisanie plików jednostek

Steruj usługami za pomocą systemctl i twórz niestandardowe pliki jednostek oraz timerów dla demonów uruchamianych przez skrypty.

Sterowanie usługami systemd i pisanie plików jednostek to bezpłatna lekcja DevOps Bootcamp na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej DevOps Bootcamp, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs DevOps Bootcamp zawiera 4 lekcji w sumie.

Wprowadzenie do systemd i systemctl

systemd to system init i menedżer usług używany przez większość współczesnych dystrybucji Linuksa. Odpowiada za uruchamianie, zatrzymywanie i zarządzanie usługami systemowymi, a także za obsługę sekwencji rozruchu i stanu systemu.

Podstawowym narzędziem do pracy z systemd jest systemctl. Za jego pomocą mogą Państwo:

  • uruchamiać i zatrzymywać usługi
  • włączać lub wyłączać automatyczne uruchamianie usług podczas rozruchu
  • sprawdzać stan usług i dzienniki
  • przeładowywać konfigurację bez ponownego uruchamiania usługi

Wszystkie usługi zarządzane przez systemd są definiowane przez pliki jednostek — deklaratywne pliki konfiguracyjne przechowywane w katalogu /etc/systemd/system/ (dla całego systemu) lub ~/.config/systemd/user/ (dla konkretnego użytkownika).

Podstawowe polecenia systemctl

Oto najczęściej używane polecenia systemctl do codziennego zarządzania usługami. Każde polecenie działa na nazwie jednostki, takiej jak nginx.service lub po prostu nginx.

  • systemctl start <unit> — natychmiast uruchamia usługę
  • systemctl stop <unit> — zatrzymuje działającą usługę
  • systemctl restart <unit> — zatrzymuje, a następnie uruchamia usługę (pełny restart)
  • systemctl reload <unit> — wysyła sygnał SIGHUP, aby przeładować konfigurację bez zatrzymywania usługi
  • systemctl enable <unit> — tworzy dowiązania symboliczne, aby jednostka uruchamiała się podczas startu systemu
  • systemctl disable <unit> — usuwa te dowiązania symboliczne
  • systemctl status <unit> — wyświetla stan, PID i ostatnie wiersze dziennika
#!/usr/bin/env bash
# Quick reference: inspect and control an nginx service
# (Requires nginx to be installed; run as root or with sudo)

systemctl status nginx
systemctl start nginx
systemctl enable nginx
systemctl reload nginx
systemctl restart nginx
systemctl stop nginx
systemctl disable nginx

Szczegółowe sprawdzanie stanu usługi

systemctl status wyświetla szczegółowy obraz stanu jednostki. Zrozumienie tych informacji jest niezbędne do szybkiego diagnozowania problemów.

  • Loaded: ścieżka do pliku jednostki oraz informacja, czy jest ona włączona podczas uruchamiania systemu
  • Active: bieżący stan — active (running), inactive (dead), failed
  • Main PID: identyfikator procesu głównego procesu usługi
  • CGroup: wszystkie procesy potomne należące do usługi
  • Log lines: najnowsze wpisy dziennika dotyczące tej jednostki

Można również sprawdzić tylko stan aktywności za pomocą systemctl is-active, a stan włączenia za pomocą systemctl is-enabled. Polecenia te idealnie nadają się do użycia w skryptach.

#!/usr/bin/env bash
# Script-friendly service health check
SERVICE="sshd"

if systemctl is-active --quiet "$SERVICE"; then
    echo "$SERVICE is running."
else
    echo "$SERVICE is NOT running. Attempting restart..."
    systemctl restart "$SERVICE"
fi

if systemctl is-enabled --quiet "$SERVICE"; then
    echo "$SERVICE is enabled at boot."
else
    echo "WARNING: $SERVICE is not enabled at boot."
fi

Wyświetlanie i filtrowanie jednostek

Podczas zarządzania wieloma usługami potrzebne są wydajne sposoby wyświetlania i filtrowania jednostek. systemctl list-units pokazuje wszystkie aktualnie załadowane jednostki, natomiast list-unit-files pokazuje wszystkie zainstalowane pliki jednostek oraz ich stan włączenia.

Przydatne opcje filtrowania:

  • --type=service — pokazuje tylko jednostki usług
  • --state=failed — pokazuje tylko jednostki, które zakończyły się niepowodzeniem
  • --state=active — pokazuje tylko aktywne jednostki
  • --all — uwzględnia na liście nieaktywne jednostki

Połączenie tych filtrów z grep pozwala tworzyć zaawansowane potoki inspekcji w skryptach konserwacyjnych.

#!/usr/bin/env bash
# List all failed services and report them
echo "=== Failed Services ==="
systemctl list-units --type=service --state=failed --no-legend

echo ""
echo "=== Services Enabled at Boot ==="
systemctl list-unit-files --type=service --state=enabled --no-legend | awk '{print $1}'

Budowa pliku jednostki usługi systemd

Plik jednostki usługi to zwykły plik tekstowy w stylu INI, złożony z sekcji. Każda sekcja steruje innym aspektem cyklu życia jednostki.

  • [Unit] — metadane: opis i zależności kolejności uruchamiania (After=, Requires=, Wants=)
  • [Service] — sposób uruchamiania i zatrzymywania procesu: ExecStart, ExecStop, Restart, User, WorkingDirectory
  • [Install] — określa, kiedy jednostka powinna zostać włączona: WantedBy=multi-user.target oznacza aktywację podczas standardowego uruchamiania systemu w trybie wielu użytkowników

Po umieszczeniu lub edycji pliku jednostki w katalogu /etc/systemd/system/ należy uruchomić systemctl daemon-reload, aby systemd wczytał zmiany.

Tworzenie pierwszego pliku jednostki usługi

Utwórzmy prosty plik jednostki usługi dla niestandardowego skryptu serwera HTTP w języku Python. Plik jednostki dokładnie określa systemd, jak zarządzać tym procesem, tak jak każdą inną usługą systemową.

Najważniejsze dyrektywy [Service] użyte w tym przykładzie:

  • Type=simple — systemd traktuje proces ExecStart jako proces główny
  • User=www-data — uruchamia proces na koncie innym niż root, co zwiększa bezpieczeństwo
  • WorkingDirectory — ustawia katalog roboczy procesu
  • Restart=on-failure — automatycznie uruchamia proces ponownie, jeśli zakończy się kodem różnym od zera
  • RestartSec=5 — odczekuje 5 sekund między próbami ponownego uruchomienia
#!/usr/bin/env bash
# Create a custom service unit file for a simple HTTP server
# Run as root

cat > /etc/systemd/system/mywebserver.service << 'EOF'
[Unit]
Description=My Custom Python Web Server
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/mysite
ExecStart=/usr/bin/python3 -m http.server 8080
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now mywebserver.service
systemctl status mywebserver.service

Typy usług i cykl życia procesów

Dyrektywa Type= w sekcji [Service] informuje systemd, jak rozpoznać, że usługa zakończyła uruchamianie. Wybór niewłaściwego typu jest częstą przyczyną błędów związanych z kolejnością uruchamiania.

  • Type=simple — domyślny; systemd uznaje usługę za uruchomioną, gdy tylko zostanie uruchomiony proces ExecStart. Nie jest wymagany sygnał gotowości.
  • Type=forking — proces ExecStart tworzy proces potomny i kończy działanie, a właściwy demon działa jako proces potomny. Należy użyć PIDFile=, aby systemd mógł go śledzić.
  • Type=notify — proces wysyła sd_notify(READY=1), gdy jest rzeczywiście gotowy. Jest to najbardziej niezawodne rozwiązanie w przypadku złożonych demonów.
  • Type=oneshot — uruchamia się raz i kończy działanie; kolejne jednostki czekają na jego zakończenie. Idealne rozwiązanie dla skryptów konfiguracyjnych.
  • Type=idle — działa podobnie jak simple, ale wykonanie jest opóźniane do czasu zakończenia wszystkich aktywnych zadań.
#!/usr/bin/env bash
# Example: oneshot service for a database migration script
# /etc/systemd/system/db-migrate.service

cat > /etc/systemd/system/db-migrate.service << 'EOF'
[Unit]
Description=Run Database Migrations
After=postgresql.service
Requires=postgresql.service

[Service]
Type=oneshot
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/scripts/migrate.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start db-migrate.service

Zmienne środowiskowe i wzmacnianie zabezpieczeń

Pliki jednostek usług obsługują kilka dyrektyw służących do przekazywania zmiennych środowiskowych i stosowania ograniczeń bezpieczeństwa — oba te aspekty są istotne w systemach produkcyjnych.

Dyrektywy środowiskowe:

  • Environment="KEY=value" — ustawia pojedynczą zmienną bezpośrednio w konfiguracji
  • EnvironmentFile=/etc/myapp/env — wczytuje zmienne z pliku (po jednej parze KEY=value w każdym wierszu)

Typowe dyrektywy wzmacniania zabezpieczeń:

  • NoNewPrivileges=true — uniemożliwia procesowi uzyskanie dodatkowych uprawnień za pomocą setuid
  • ProtectSystem=strict — montuje katalogi /usr, /boot i /etc w trybie tylko do odczytu
  • PrivateTmp=true — przydziela usłudze własny, odizolowany katalog /tmp
  • CapabilityBoundingSet= — usuwa wszystkie uprawnienia systemu Linux
#!/usr/bin/env bash
# Hardened service unit with environment file

cat > /etc/systemd/system/secureapp.service << 'EOF'
[Unit]
Description=Secure Application Daemon
After=network.target

[Service]
Type=simple
User=secureapp
Group=secureapp
WorkingDirectory=/opt/secureapp
EnvironmentFile=/etc/secureapp/env
ExecStart=/opt/secureapp/bin/server
Restart=on-failure
RestartSec=10

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
CapabilityBoundingSet=
ReadWritePaths=/var/lib/secureapp /var/log/secureapp

[Install]
WantedBy=multi-user.target
EOF

# Create the environment file separately so secrets stay out of the unit file
install -m 600 -o secureapp /dev/null /etc/secureapp/env
echo 'APP_PORT=9000' >> /etc/secureapp/env
echo 'DB_URL=postgresql://localhost/mydb' >> /etc/secureapp/env

systemctl daemon-reload

Wprowadzenie do jednostek timerów systemd

Timer systemd to jednostka, która zgodnie z harmonogramem aktywuje inną jednostkę (zwykle .service). Zastępuje tradycyjne zadania cron bardziej zintegrowanym, rejestrowanym w dzienniku i łatwiejszym do kontrolowania mechanizmem.

Każda jednostka timera (foo.timer) jest powiązana z jednostką usługi o tej samej nazwie bazowej (foo.service), która wykonuje właściwą pracę. Należy włączyć i uruchomić timer, a nie usługę bezpośrednio.

Typy timerów:

  • Timery czasu rzeczywistego (kalendarzowe) — uruchamiają się o określonych porach zegarowych na podstawie wyrażeń OnCalendar=, takich jak daily, weekly lub Mon *-*-* 02:00:00
  • Timery monotoniczne — uruchamiają się względem zdarzenia systemowego na podstawie OnBootSec=, OnActiveSec= lub OnUnitActiveSec=

Tworzenie pliku jednostki timera

Utwórzmy kompletną parę timera i usługi, która codziennie o 02:00 uruchamia skrypt kopii zapasowej. Należy zauważyć, że sekcja [Timer] znajduje się we własnym pliku .timer, natomiast wykonywana praca jest zdefiniowana w powiązanym pliku .service.

Najważniejsze dyrektywy [Timer]:

  • OnCalendar= — wyrażenie kalendarzowe określające harmonogram
  • Persistent=true — jeśli system był wyłączony w chwili planowanego uruchomienia timera, uruchamia go natychmiast przy następnym starcie systemu
  • RandomizedDelaySec= — dodaje losowe opóźnienie o długości do N sekund, aby zapobiec jednoczesnemu obciążeniu wielu hostów korzystających z tego samego harmonogramu
  • Unit= — jawnie wskazuje docelową jednostkę (opcjonalne, jeśli nazwy są zgodne)
#!/usr/bin/env bash
# Create a daily backup timer pair
# Run as root

# 1. The service that does the work
cat > /etc/systemd/system/daily-backup.service << 'EOF'
[Unit]
Description=Daily Database Backup
After=network.target postgresql.service

[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/backup-db.sh
StandardOutput=journal
StandardError=journal
EOF

# 2. The timer that schedules it
cat > /etc/systemd/system/daily-backup.timer << 'EOF'
[Unit]
Description=Run Daily Database Backup at 02:00

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now daily-backup.timer

# Verify
systemctl list-timers daily-backup.timer

Analizowanie dzienników i rozwiązywanie problemów z jednostkami

systemd kieruje wszystkie dane wyjściowe usług do dziennika, który można przeszukiwać za pomocą journalctl. Centralizuje to dzienniki wszystkich jednostek w jednym, przeszukiwalnym magazynie.

Najważniejsze opcje journalctl przy diagnozowaniu problemów z usługami:

  • -u <unit> — filtruje według nazwy jednostki
  • -f — śledzi dziennik w czasie rzeczywistym (jak tail -f)
  • -n 50 — wyświetla tylko ostatnie 50 wierszy
  • --since "1 hour ago" — ogranicza wyniki według czasu
  • -p err — wyświetla tylko wpisy o priorytecie błędu lub wyższym
  • -b — wyświetla tylko dzienniki z bieżącego uruchomienia systemu

Gdy jednostka nie uruchamia się, najpierw należy wykonać journalctl -u <unit> -n 30 --no-pager, a następnie systemctl status <unit>, aby zebrać kontekst ostatniego błędu.

#!/usr/bin/env bash
# Troubleshooting helper: dump unit status and recent logs
# Usage: ./service-debug.sh <unit-name>

UNIT="${1:-nginx.service}"

echo "=============================="
echo "STATUS: $UNIT"
echo "=============================="
systemctl status "$UNIT" --no-pager -l

echo ""
echo "=============================="
echo "RECENT LOGS (last 50 lines): $UNIT"
echo "=============================="
journalctl -u "$UNIT" -n 50 --no-pager

echo ""
echo "=============================="
echo "ERRORS ONLY (current boot)"
echo "=============================="
journalctl -u "$UNIT" -b -p err --no-pager

Sprawdzenie wiedzy: pliki jednostek systemd

Sprawdź swoją wiedzę na temat konfiguracji jednostek usług i timerów systemd.

Podsumowanie lekcji: sterowanie usługami systemd i tworzenie plików jednostek

W tej lekcji poznali Państwo najważniejsze koncepcje zarządzania usługami systemd oraz tworzenia plików jednostek na poziomie profesjonalnym. Oto podsumowanie omówionych zagadnień:

  • Podstawy systemctl — start, stop, restart, reload, enable, disable, status, is-active i is-enabled do wykonywania przyjaznych skryptom kontroli
  • Wyświetlanie i filtrowanie — list-units i list-unit-files z opcjami --type i --state do wyodrębniania usług, które zakończyły się niepowodzeniem, lub usług włączonych
  • Budowa pliku jednostki — trzy sekcje: [Unit], [Service] i [Install] oraz ich najważniejsze dyrektywy
  • Typy usług — simple, forking, notify, oneshot oraz sytuacje, w których należy użyć każdego z nich
  • Środowisko i bezpieczeństwo — EnvironmentFile, NoNewPrivileges, ProtectSystem i PrivateTmp do wzmacniania zabezpieczeń demonów
  • Jednostki timerów — łączenie plików .timer i .service, wyrażenia OnCalendar oraz nadrabianie pominiętych uruchomień dzięki Persistent
  • Journalctl — filtrowanie według jednostki, czasu, uruchomienia systemu i priorytetu w celu sprawnego diagnozowania awarii

Dzięki tym umiejętnościom mogą Państwo zarządzać dowolną usługą systemową, niezawodnie planować cykliczne zadania oraz tworzyć gotowe do użycia w środowisku produkcyjnym pliki jednostek dla własnych demonów.

Często zadawane pytania

Czy lekcja „Sterowanie usługami systemd i pisanie plików jednostek” jest bezpłatna?

Tak — pełny tekst „Sterowanie usługami systemd i pisanie plików jednostek” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu DevOps Bootcamp, przejdź na CoddyKit PRO. Kurs DevOps Bootcamp zawiera 4 lekcji w sumie.

Co nauczysz się w „Sterowanie usługami systemd i pisanie plików jednostek”?

Steruj usługami za pomocą systemctl i twórz niestandardowe pliki jednostek oraz timerów dla demonów uruchamianych przez skrypty. Ćwiczysz DevOps Bootcamp z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć DevOps Bootcamp?

Nie wymagamy żadnego doświadczenia. DevOps Bootcamp w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Sterowanie usługami systemd i pisanie plików jednostek”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji DevOps Bootcamp?

Tak. Każda lekcja DevOps Bootcamp zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Automatyzacja tworzenia użytkowników i grup
  2. Sterowanie usługami systemd i pisanie plików jednostek
  3. Automatyzacja dysków, systemów plików i montowania
  4. Tworzenie skryptów do kontroli kondycji systemu i alertów
← Powrót do DevOps Bootcamp