systemd ๋
systemd(system daemon)์ Unix ์์คํ ๋ถํ ํ ๊ฐ์ฅ ๋จผ์ ์์ฑ๋ ํ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ฅผ ์คํํ๋ init ์ญํ ์ ํ๋ ๋ฐ๋ชฌ์ด๋ค. RedHat ์์ ๊ฐ๋ฐ์ ์์ํ๊ณ RHEL/CentOS ์ Ubuntu ๋ Arch ๋ฑ ๋๋ถ๋ถ์ ๋ฆฌ๋ ์ค ์์คํ ์ ๊ณต์์ ์ผ๋ก ์ฑํ๋์ด ์ฌ์ฉ์ค์ด๋ค.
systemd ๋ PID 1๋ฒ์ ๊ฐ์ผ๋ฉฐ ๋ถํ ๋ถํฐ ์๋น์ค๊ด๋ฆฌ, ๋ก๊ทธ๊ด๋ฆฌ ๋ฑ์ ๋ด๋นํ๋ค. ๋ถํ ์ ๋ณ๋ ฌ๋ก ์คํ๋๊ธฐ ๋๋ฌธ์ ๋ถํ ์๋ ์ญ์ ๋น ๋ฅด๋ค.
๋ถํ
์ ํ์ํ ์์
์ systemd unit ์ผ๋ก ๋ฑ๋กํ์ฌ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ํด๋น ํ์ผ๋ค์ /etc/systemd/system
์ ์์นํ๋ค.
Unit๊ณผ ๊ตฌ์ฑ ์์
systemd Unit ํ์ผ ๊ตฌ์กฐ
[Unit]
Description=Systemd Test
[Service]
ExecStart=/usr/local/bin/example.sh
[Install]
WantedBy=multi-user.target
systemd ํ์ผ์ ์น์
- Unit
- Description: ์๋น์ค ์ค๋ช
- Service
- ExecStart: ์๋น์ค๋ฅผ ์์ํ๊ธฐ ์ํ ์คํํ์ผ
- Timer
- Install
- โฆ
Unit ํ์
- service: ๋ฐ๋ชฌ/์๋น์ค ๊ด๋ฆฌ (.service)
- socket: ์์ผ ํ์ฑํ (.socket)
- timer: ์์ ์ค์ผ์ค (.timer)
- target: ๋ถํธ ๋ชฉํ/๋ฐ๋ ๋ฒจ ์ ์ฌ ๊ฐ๋ (.target)
- path: ํ์ผ/๋๋ ํฐ๋ฆฌ ๋ณ๊ฒฝ ๊ฐ์ ํ ํธ๋ฆฌ๊ฑฐ (.path)
- mount/automount: ๋ง์ดํธ ๊ด๋ฆฌ (.mount, .automount)
- device: udev ๋๋ฐ์ด์ค ์ด๋ฒคํธ (.device)
- swap: ์ค์ ๊ด๋ฆฌ (.swap)
- slice/scope: cgroups๋ก ๋ฆฌ์์ค ๊ทธ๋ฃนํ (.slice, .scope)
์๋น์ค ๊ด๋ฆฌ
Service ์ฃผ์ ์ต์
- Type: simple | forking | oneshot | notify | dbus | idle
- simple(๊ธฐ๋ณธ): ExecStart ์คํ ํ ๊ณง๋ฐ๋ก ํ์ฑํ๋ก ๊ฐ์ฃผ
- forking: ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ํฌํฌํ๋ ๋ฐ๋ชฌ์ ์ฌ์ฉ (PIDFile ๊ถ์ฅ)
- oneshot: ๋จ๋ฐ์ฑ ์์ (์ค์ ์คํฌ๋ฆฝํธ) โ RemainAfterExit=true์ ํจ๊ป ์ฌ์ฉ
- notify: systemd-notify๋ก ์ค๋น ์๋ฃ ์ ํธ๋ฅผ ๋ณด๋
- ExecStart, ExecStartPre, ExecStartPost, ExecReload, ExecStop
- Restart: no | on-success | on-failure | on-abnormal | always ๋ฑ
- RestartSec: ์ฌ์์ ์ง์ฐ
- User/Group: ์คํ ๊ณ์ ์ง์ , WorkingDirectory
- Environment/EnvironmentFile: ํ๊ฒฝ๋ณ์
- LimitNOFILE, Nice, IOSchedulingClass ๋ฑ ๋ฆฌ์์ค ์ ํ
์์กด์ฑ๊ณผ ์ค์น(Install)
- [Unit]
- Requires=, Wants=: ๊ฐ/์ฝ ์์กด
- After=, Before=: ์คํ ์์
- [Install]
- WantedBy=multi-user.target ๋ฑ: enable ์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๊ฐ ์์ฑ๋๋ ๋์
- enable/disable๋ ๋ถํ ์ ์๋ ์์ ์ฌ๋ถ๋ง ์ ์ด, start/stop์ ์ฆ์ ์คํ ์ ์ด
๋ถํ ๊ณผ Target
Target (๋ฐ๋ ๋ฒจ ๋งคํ)
- graphical.target โ runlevel5, multi-user.target โ runlevel3, rescue.target โ runlevel1
- ๊ธฐ๋ณธ ํ๊น ํ์ธ/์ค์ :
systemctl get-default
,systemctl set-default multi-user.target
์ด์ ๋ช ๋ น์ด
์์ฃผ ์ฐ๋ systemctl
- ์ํ/์ ์ด
systemctl status <unit>
systemctl start|stop|restart <unit>
systemctl enable|disable <unit>
systemctl daemon-reload
(์ ๋ ํ์ผ ์์ ํ)
- ๋์ด/๊ฒ์
systemctl list-units --type=service
systemctl list-unit-files --type=service
journalctl (๋ก๊ทธ)
journalctl -u <service>
: ์๋น์ค ๋ก๊ทธjournalctl -u <service> -f
: ์ค์๊ฐ ํ๋ก์ฐjournalctl -b
: ํ์ฌ ๋ถํ ์ฌ์ดํด ๋ก๊ทธ-p info|warning|err
,--since "2025-09-17 09:00"
์ค์ผ์ค๋ง๊ณผ ํ์ฑํ
Timer vs cron
- .timer ์ ๋์ผ๋ก ์ค์ผ์ค ์ ์, .service ์คํ์ ํธ๋ฆฌ๊ฑฐ
- ๋ชจ๋: OnCalendar= (์บ๋ฆฐ๋), OnBootSec=/OnUnitActiveSec= (์๋์๊ฐ)
- ์ฅ์ : ์ ๋ ์์กด์ฑ, ๋ก๊น (journal), ์คํจ ์ Restart ์ ์ฑ ๊ณผ ํตํฉ
์์ (.timer):
[Unit]
Description=DB ๋ฐฑ์
ํ์ด๋จธ
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
์์ (.service):
[Unit]
Description=DB ๋ฐฑ์
์คํ
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
์์ผ/ํจ์ค ํ์ฑํ
- socket: ํฌํธ/์์ผ ์ ๊ทผ์ด ์์ ๋ ๊ด๋ จ .service๋ฅผ ์ง์ฐ ๊ธฐ๋
- path: ํ์ผ ์์ฑ/๋ณ๊ฒฝ ์ .service ํธ๋ฆฌ๊ฑฐ (PathChanged=, PathExists= ๋ฑ)
๋ฆฌ์์ค ์ ์ด
cgroups์ ๋ฆฌ์์ค ์ ์ด
- systemd๋ cgroups์ ํตํด ๊ฐ ์ ๋ ๋ฆฌ์์ค๋ฅผ ์ถ์ /์ ํ
- CPUAccounting=, MemoryMax=, IPAddressDeny=/Allow= ๋ฑ์ผ๋ก ์ ์ด ๊ฐ๋ฅ (๋ฒ์ ์์กด)
ํธ๋ฌ๋ธ์ํ
- ์ ๋ ํ์ผ ๋ณ๊ฒฝ ํ
systemctl daemon-reload
- ๊ถํ/๊ฒฝ๋ก ํ์ธ: ExecStart ๊ฒฝ๋ก, ์คํ๊ถํ, WorkingDirectory
- ํ๊ฒฝ ๋ณ์: EnvironmentFile ๊ฒฝ๋ก/๊ถํ
- SELinux/AppArmor ์ ์ฑ ์ผ๋ก ์ธํ ๊ฑฐ๋ถ ์ฌ๋ถ ํ์ธ
- ๋ถํ
์ ์คํจ:
systemctl --failed
,journalctl -b -p err