systemd & Logs
Use systemctl to manage services and journalctl to read structured logs. On Kubernetes nodes, kubelet, containerd, and docker all run as systemd services — these are your first stop when a node stops joining the cluster or containers won't start.
systemctl — Service Management
The primary interface to systemd: start, stop, restart, enable, and inspect services and their dependencies.
# Status and listing
systemctl status kubelet # detailed status + last log lines
systemctl status containerd
systemctl list-units --type=service --state=failed # all failed services
systemctl list-units --type=service # all loaded services
# Service lifecycle
sudo systemctl start <service>
sudo systemctl stop <service>
sudo systemctl restart <service> # stop then start
sudo systemctl reload <service> # reload config without full restart (if supported)
sudo systemctl try-reload-or-restart <service>
# Enable / disable (persist across reboots)
sudo systemctl enable <service>
sudo systemctl disable <service>
sudo systemctl enable --now <service> # enable AND start immediately
sudo systemctl is-enabled <service> # check: enabled/disabled/static
# Service file inspection
systemctl cat kubelet # show the unit file content
systemctl show kubelet # all properties (machine-readable)
systemctl show kubelet --property=ExecStart,Restart,RestartSec
# After editing unit files
sudo systemctl daemon-reload # always reload before restart after file changes
# Dependencies
systemctl list-dependencies kubelet # tree of dependencies
systemctl list-dependencies --reverse kubelet # what depends on kubeletjournalctl — Log Queries
journalctl queries the systemd journal; filter by service, time range, priority, or boot to quickly isolate the log window you care about.
# Follow a service (like tail -f)
journalctl -u kubelet -f
journalctl -u containerd -f
# Last N lines
journalctl -u kubelet -n 100
journalctl -u kubelet --no-pager -n 50 # pipe-friendly
# Time ranges — very useful during incident post-mortems
journalctl -u kubelet --since "2026-05-23 14:00:00" --until "2026-05-23 14:30:00"
journalctl -u kubelet --since "1 hour ago"
journalctl --since today
# Priority filtering (-p: emerg alert crit err warning notice info debug)
journalctl -u kubelet -p err # errors and above
journalctl -p crit # critical messages across all services
# Current boot only
journalctl -b 0 -u kubelet # this boot
journalctl -b -1 -u kubelet # previous boot (useful post-reboot)
journalctl --list-boots # list all recorded boots
# Kernel messages (equivalent to dmesg with timestamps)
journalctl -k # kernel messages
journalctl -k --since "10 min ago"
# JSON output for programmatic processing
journalctl -u kubelet -n 50 -o json | jq '.MESSAGE'
# Disk usage
journalctl --disk-usage
sudo journalctl --vacuum-size=500M # trim journal to 500 MBKubelet Service on Nodes
When a node shows NotReady in Kubernetes, the kubelet service is usually the first thing to check; these commands orient you to its configuration and recent errors.
systemctl status kubelet
journalctl -u kubelet -n 100 --no-pager | grep -iE "error|fail|warn|PLEG|OOM"
# kubelet config and flags
systemctl cat kubelet # ExecStart line shows all flags
cat /var/lib/kubelet/config.yaml # kubelet config file
cat /etc/kubernetes/kubelet.conf # kubeconfig for the kubelet
# container runtime
systemctl status containerd
journalctl -u containerd -n 50 --no-pager | grep -i error
# crictl: container runtime interface (works with containerd and CRI-O)
sudo crictl ps -a # all containers including exited
sudo crictl logs <container-id> # container logs at runtime level
sudo crictl inspect <container-id> # container details including pidWriting Unit Files
A minimal unit file covers the most common pattern: a long-running daemon that restarts on failure and is ordered after the network is up.
[Unit]
Description=My Application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp --config /etc/myapp/config.yaml
Restart=on-failure
RestartSec=5s
# Capture stdout/stderr to journal automatically
StandardOutput=journal
StandardError=journal
# Resource limits
LimitNOFILE=65536
MemoryMax=512M
CPUQuota=200%
[Install]
WantedBy=multi-user.targetsystemd Timers (Cron Replacement)
A systemd timer runs a companion .service unit on a schedule; unlike cron, output goes to the journal, failures trigger systemd alerts, and you can see last/next run times.
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer
[Timer]
OnCalendar=daily # run at midnight
RandomizedDelaySec=30m # random delay up to 30 min (avoids stampedes)
Persistent=true # run missed jobs after boot
[Install]
WantedBy=timers.target
# --- companion service ---
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup job
[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
# Enable and check
sudo systemctl enable --now backup.timer
systemctl list-timers --all | grep backup
journalctl -u backup.service -n 20Troubleshooting
- Service fails immediately:
systemctl status <service>andjournalctl -u <service> -n 30— look for missing binary path, wrong user, missing dependency. - daemon-reload required: always run
systemctl daemon-reloadafter editing unit files, or changes are silently ignored. - Journal full:
journalctl --disk-usage; configureSystemMaxUsein/etc/systemd/journald.conf. - kubelet won't start: check swap (
free -h) — kubelet requires swap disabled unless configured with--fail-swap-on=false.