Lesson 9: systemd & Services

⏱ 約 15 分钟 6 个核心概念 15 条实战命令

Lesson 9: systemd & Services

systemd Overview

systemd is the init system (PID 1) and service manager on modern Linux. It manages: - Services (.service) — daemons - Sockets (.socket) — IPC/listen - Timers (.timer) — cron replacement - Targets (.target) — boot milestones (like runlevels) - Paths (.path) — filesystem monitoring

Service Management

systemctl status nginx          # Status (active, enabled, logs)
systemctl start nginx           # Start now
systemctl stop nginx            # Stop now
systemctl restart nginx         # Stop + start
systemctl reload nginx          # Reload config (SIGHUP)
systemctl enable nginx          # Auto-start at boot
systemctl disable nginx         # No auto-start
systemctl is-enabled nginx      # Check enabled state
systemctl mask nginx            # Prevent start entirely
systemctl unmask nginx          # Unmask

Listing Units

systemctl list-units --type=service              # All loaded services
systemctl list-units --type=service --state=running  # Running only
systemctl list-unit-files --type=service         # All unit files (enabled/disabled)
systemctl list-dependencies nginx                # Show dependencies
systemctl list-dependencies --reverse nginx      # What depends on nginx

Logs with journalctl

journalctl -u nginx             # All logs for nginx
journalctl -f -u nginx          # Follow live
journalctl -u nginx -n 50       # Last 50 lines
journalctl -u nginx --since "1 hour ago"  # Time range
journalctl -u nginx --since "2024-11-01" --until "2024-11-02"
journalctl -p err -u nginx      # Only errors
journalctl -xeu nginx           # Verbose with explanations

Boot Targets (Runlevels)

Target Description Runlevel Equivalent
poweroff.target Shutdown 0
rescue.target Single-user 1
multi-user.target Multi-user, no GUI 3
graphical.target Multi-user + GUI 5
reboot.target Reboot 6
systemctl get-default           # Current default target
systemctl set-default multi-user.target  # Change default
systemctl isolate multi-user.target      # Switch now

Unit File Structure

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
Requires=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/home/ubuntu/myapp/run.sh
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Key Directives

Directive Purpose
Type=simple Default; process runs in foreground
Type=forking Daemon forks; PID file needed
Type=oneshot Runs once, exits (for timers)
Restart=always\|on-failure\|on-abnormal Auto-restart policy
User=ubuntu Run as specific user
WorkingDirectory= Set cwd
Environment= Set env vars
ExecStartPre= Command before start
ExecStartPost= Command after start

Creating Custom Service

# 1. Create unit file
sudo tee /etc/systemd/system/myapp.service > /dev/null <<'EOF'
[Unit]
Description=My App
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/home/ubuntu/myapp/venv/bin/python app.py
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

# 2. Reload systemd
sudo systemctl daemon-reload

# 3. Enable & start
sudo systemctl enable --now myapp

# 4. Check
systemctl status myapp
journalctl -u myapp -f

Timers (Cron Replacement)

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1h

[Install]
WantedBy=timers.target
sudo systemctl enable --now backup.timer
systemctl list-timers

Practice

# 1. Check nginx status
systemctl status nginx

# 2. View recent nginx logs
journalctl -u nginx -n 20

# 3. List running services
systemctl list-units --type=service --state=running

# 4. Create a simple timer service
cat > /tmp/test-timer.service <<'EOF'
[Unit]
Description=Test Timer

[Service]
Type=oneshot
ExecStart=/bin/date >> /tmp/timer.log
EOF

cat > /tmp/test-timer.timer <<'EOF'
[Unit]
Description=Run test every minute

[Timer]
OnCalendar=*:*:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo cp /tmp/test-timer.* /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now test-timer.timer
systemctl list-timers
# Wait a minute, check /tmp/timer.log

💻 实战命令速查

systemctl status nginx

Show service status

$ systemctl status nginx
● nginx.service - A high performance web server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2024-11-01 10:00:00 UTC; 5min ago
systemctl start nginx

Start service now

$ sudo systemctl start nginx
systemctl stop nginx

Stop service now

$ sudo systemctl stop nginx
systemctl restart nginx

Restart service

$ sudo systemctl restart nginx
systemctl reload nginx

Reload config without restart

$ sudo systemctl reload nginx
systemctl enable nginx

Enable auto-start at boot

$ sudo systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service
systemctl disable nginx

Disable auto-start at boot

$ sudo systemctl disable nginx
systemctl is-enabled nginx

Check if enabled

$ systemctl is-enabled nginx
enabled
systemctl list-units --type=service --state=running

List running services

$ systemctl list-units --type=service --state=running | head -10
UNIT                    LOAD   ACTIVE SUB     DESCRIPTION
nginx.service           loaded active running A high performance web server
ssh.service             loaded active running OpenBSD Secure Shell server
systemctl list-unit-files --type=service

List all service unit files (enabled/disabled)

$ systemctl list-unit-files --type=service | grep nginx
nginx.service                    enabled
journalctl -u nginx

View logs for specific service

$ journalctl -u nginx
-- Logs begin at Fri 2024-11-01 10:00:00 UTC --
Nov 01 10:00:00 server systemd[1]: Starting nginx...
Nov 01 10:00:00 server nginx[1234]: nginx: configuration test is successful
journalctl -f -u nginx

Follow service logs live

$ journalctl -f -u nginx
journalctl --since '1 hour ago'

Logs from last hour

$ journalctl --since '1 hour ago' --until '30 min ago'
systemctl daemon-reload

Reload systemd after unit file changes

$ sudo systemctl daemon-reload
systemctl cat nginx

Show unit file content

$ systemctl cat nginx
# /lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server
After=network.target

🧠 课后测验

Q1. What does `systemctl enable nginx` do?

Q2. Difference between `restart` and `reload`?

Q3. Which command shows logs for a specific service?