Lunatine
· 9 min read

systemd 살펴보기

systemd 살펴보기

우선, systemd가 이렇게 급 부상하게 될 줄은 솔직히 몰랐다. 워낙 많은 오픈소스 프로젝트들이 나오고 있기 때문에 그 중 하나 정도로만 생각했는데 어느 순간 Fedora에 적용이 되더니 당연한 수순대로 RHEL7에 도입이 되었다. 아직 Debian/Ubuntu 계열은 기본으로 채택되지 않았지만 조만간 릴리즈되는 버전에서 새로운 PID 1으로 자리잡게 될 것 같다.

이러한 분위기에 맞추어 systemd가 무엇이고 이에 대해서 간단히 짚어 볼 필요가 있을 듯 하여 간단히 소개해 본다. (늘 그렇듯이 상세한 내용은 공식홈페이지의 문서를 참고하는 것이 좋다)

사실 RHEL6가 등장하고 Upstart가 도입되었을 때는 그저 초기화 스크립트 관리 방안이 바뀌었을 뿐이기에 크게 신경쓰지 않았고 주변에 관련내용 공유도 별로하지 않았다. (설정에 꼭 필요한 방법만 공유했었다) 하지만, systemd의 경우는 Upstart와 비교되지 않는 물건이기 때문에 이렇게 문서까지 작성해서 공유하게 되었다.

systemd는?

systemd가 처음 소개되고 프로젝트가 진행 될 때 커뮤니티 반응은 시끌벅적했다. 우선 systemd는 전통적으로 Unix계열 운영체제의 PID 1이었던 init(System V Init)을 교체하는 역할 뿐만 아니라 초기화 스크립트 관리자이고 로그시스템 관리자이기도 하다. 또한, 하드웨어에 대한 부분과 cgroup 관리 등 시스템 전반적인 부분에 관여하고 있다. 심지어 기존 SysV에서 공통적으로 사용되었던 프로세스 데몬을 만들기 위한 setsid() 콜도 필요없고 PID파일을 따로 관리할 필요도 없다. 이러한 systemd는 유닉스의 철학인 **'한 가지만 잘하자'**와 상반되기 때문에 논란이 되곤 했었다. PulseAudio 개발자라는 이유(커뮤니케이션이 잘 안되기로 유명했다 한다)로 싸우는건 또 다른 논란이었고...

여러 논란가운데 결국 대표적인 배포판에 입성하게 되었는데 논란의 결과가 어찌되었건 납득할 만한 디자인과 성능을 가지고 있기에 채택되지 않았을까 한다.

이 프로젝트의 철학(?)을 알고 싶다면 개발자인 Nennart의 블로그를 읽어보는 것도 좋다.

준비물

실제 systemd가 어떠한 물건인지 알아보기 위한 간단한 실습을 위해서 당연히 systemd를 사용중인 배포판을 설치해서 사용해 보는 것이 좋다.

  • RHEL7
  • CentOS 7
  • Fedora
  • OpenSUSE

Debian이나 Ubuntu에서 사용하는 방법은 나중에 시간 될 때 다른 문서를 통해서 공유하겠다. (아마 그 전에 정식채택 될 것 같다. - 관련내용)

실행하며 살펴보기

아래 내용은 RHEL7에서 실행한 내용이며 어느 배포판을 사용하더라도 크게 차이는 없다.

1. PID 1

먼저 ps 명령을 통해서 PID 1 프로세스를 확인해 보자

$ ps -p 1 ef
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 24

늘 익숙했던 init 대신에 systemd가 PID 1로 자리잡고 있다.

2. 설정파일

systemd는 /etc/systemd 아래에 설정파일을 두고 있다.

$ ls /etc/systemd
bootchart.conf  journald.conf  logind.conf  system  system.conf  user  user.conf

이러한 설정파일과 시스템에 미리 정의 된 Service, Target 파일을 통해서 시스템을 컨트롤하게 되는데 Service, Target 파일은 아래에 정의 되어있으며 보통 /etc/systemd에서 설정하면서 심볼릭 링크를 통해서 사용한다.

바이너리 실행파일은 아래 경로에서 확인 가능하며
$ ls /lib/systemd/

기본적인 시스템의 Service, Target은 아래에 위치하고 있다
$ ls /lib/systemd/system

3. 부팅시간

systemd는 최소한의 서비스만을 실행시키고 병렬화해서 실행시키는데 주안점을 두고 있기 때문에 기존에 순차적 방식으로 처리하는 SysV에 비해서 부팅속도가 빠른 편이다. RHEL7이 RHEL6보다 부팅속도가 매우 빠른건 systemd 때문이다.

그러면, 부팅에 걸린 시간을 알아보자

$ systemd-analyze
Startup finished in 421ms (kernel) + 1.206s (initrd) + 25.873s (userspace) = 27.501s

총, 27초 정도가 소요 된 것을 확인 할 수 있는데 커널 초기화 작업에는 1초미만 램디스크 초기화에 1.2초 그리고 실제 systemd 프로세스에 의해서 초기화 작업이 진행 된 시간은 26초 정도 이다. 이를 토대로 부팅 시간을 단축 시킬(즉, 불필요한 프로세스가 있는지 여부부터 오동작으로 인해 시간을 많이 잡아먹는지) 방안에 대해서 생각해 볼 수 있다.

$ systemd-analyze blame
         20.732s kdump.service
          1.395s firewalld.service
          1.040s postfix.service
          1.031s lvm2-monitor.service
           997ms tuned.service
           974ms boot.mount
           782ms network.service
           588ms lvm2-pvscan@8:2.service
           571ms iprupdate.service
           571ms iprinit.service
           423ms sshd.service
           348ms systemd-logind.service
           324ms avahi-daemon.service
           312ms iprdump.service
           296ms NetworkManager.service
           269ms rsyslog.service
           192ms systemd-fsck-root.service
           191ms kmod-static-nodes.service
           ... 하략 ...

상기 결과는 가상머신에 올린 게스트 머신이기 때문인지 kdump 서비스가 차지하는 시간이 많은 것으로 나타났다. 이 blame 결과를 통해서 불필요한 서비스를 제거하거나 이상이 있는 서비스를 확인해 볼 수 있다. (Blame Game 참고)

또한, 시간이 많이 소요된 서비스에 대해 실행과 대기에 대해서 체인형태로 확인하는 방법도 있다.

$ systemd-analyze critical-chain
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

multi-user.target @25.865s
└─kdump.service @5.131s +20.732s
  └─network.target @5.130s
    └─network.service @4.346s +782ms
      └─NetworkManager.service @4.049s +296ms
        └─firewalld.service @2.649s +1.395s
          └─basic.target @2.646s
            └─paths.target @2.646s
              └─brandbot.path @2.645s
                └─sysinit.target @2.638s
                  └─systemd-update-utmp.service @2.630s +7ms
                    └─auditd.service @2.517s +111ms
                      └─local-fs.target @2.513s
                        └─boot.mount @1.538s +974ms
                          └─systemd-fsck@dev-disk-by\x2duuid-b4f107ad\x2df256\x2d48b4\x2d9558\x2d24
                            └─dev-disk-by\x2duuid-b4f107ad\x2df256\x2d48b4\x2d9558\x2d2483cbca6a7d.

그 외에 systemd-analyze 툴을 통해서 부팅 과정을 그래프화 해서 볼 수 있으며

$ systemd-analyze dot | dot -Tsvg > systemd.svg
$ systemd-analyze plot > systemd.svg

이러한 부팅 분석 툴만으로도 기존 init에 비해서 프로파일링이 편리해졌음을 확인 할 수 있다.

4. Run Level 변경

systemd는 기존 init 커맨드와 달리 숫자 기반의 런레벨이 아니라 각 런레벨에 대한 설정 세트를 통해서 런레벨을 변경합니다.

싱글모드(기존 런레벨1)

$ systemctl rescue

멀티유저모드(기존 런레벨3)

$ systemctl isolate multi-user.target
$ systemctl isolate runlevel3.target

과거 init 시스템에 익숙한 사용자를 위해서 runlevel3라는 이름으로 multi-user.target 파일을 심볼릭 링크를 걸어두었기 때문에 위 두가지 명령이 모두 사용가능 하다.

$ ls -l /lib/systemd/system/runlevel3.target
lrwxrwxrwx. 1 root root 17 Oct 21 00:28 /lib/systemd/system/runlevel3.target -> multi-user.target

그래픽모드(기존 런레벨5)

$ systemctl isolate graphical.target
$ systemctl isolate runlevel5.target

멀티유저모드와 마찬가지로 2가지 명령으로 전환 가능하며 실제 기존 형태의 런레벨+숫자 형태의 Target 파일은 아래와 같이 심볼릭 링크로 연결되어있다.

lrwxrwxrwx. 1 root root 15 Oct 21 00:28 runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 Oct 21 00:28 runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 Oct 21 00:28 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Oct 21 00:28 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Oct 21 00:28 runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 Oct 21 00:28 runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 Oct 21 00:28 runlevel6.target -> reboot.target

즉, 시스템 종료/재부팅을 위한 런레벨도 여전히 사용가능하다.

런레벨 기본 값 설정

상기에서 전환하는 런레벨 Target을 아래와 같은 명령을 통해서 기본 값으로 설정 할 수 있다. 또한, 현재 설정된 기본 값을 확인 할 수도 있다

$ systemctl set-default multi-user.target
$ systemctl get-default
multi-user.target

시스템 명령

앞서 각각의 런레벨 파일이 poweroff.target 등 으로 연결되어있는 것을 확인하였는데 isolate 명령이 아닌 시스템 명령을 통해서 해당 Target을 바로 적용하는게 가능하다. 아래는 몇 가지 예시이다.

$ systemctl poweroff (Shutdown처리 후 Power-Off처리)
$ systemctl emergency (Rescue와 유사하지만 root 파일시스템만 읽기전용으로 마운트한다)
$ systemctl halt (Shutdown처리 후 Halt처리)
$ systemctl reboot (Shutdown처리 후 리부팅처리)
$ systemctl kexec (kexec를 통해서 리부팅한다)
$ systemctl suspend (시스템 정지)
$ systemctl hibernate (시스템 Hibernate)
$ systemctl hybrid-sleep (시스템을 Hibernate하고 정지시킨다)

5. 서비스 목록

systemctl을 통해서 서비스를 관리 할 수 있는데 먼저 서비스 목록 확인 방법을 알아보자.

서비스 목록은 간단하게 systemctl 명령만 실행해도 확인 할 수 있으며 이를 상태기준으로 보기편하게 아래와 같이 확인 할 수도 있다.

$ systemctl list-unit-files
UNIT FILE                                   STATE
sys-fs-fuse-connections.mount               static
sys-kernel-config.mount                     static
sys-kernel-debug.mount                      static
tmp.mount                                   disabled
brandbot.path                               disabled
systemd-ask-password-console.path           static
systemd-ask-password-plymouth.path          static
systemd-ask-password-wall.path              static
session-1.scope                             static
session-2.scope                             static
auditd.service                              enabled
autovt@.service                             disabled
avahi-daemon.service                        enabled
... 하략 ...

그 외에 Listening하는 소켓관련 목록을 확인 할 수도 있고 각 서비스를 의존성에 따라 확인 할 수도 있다.

$ systemctl list-sockets
LISTEN                          UNIT                         ACTIVATES
/dev/initctl                    systemd-initctl.socket       systemd-initctl.service
/dev/log                        systemd-journald.socket      systemd-journald.service
/run/dmeventd-client            dm-event.socket              dm-event.service
/run/dmeventd-server            dm-event.socket              dm-event.service
/run/lvm/lvmetad.socket         lvm2-lvmetad.socket          lvm2-lvmetad.service
/run/systemd/journal/socket     systemd-journald.socket      systemd-journald.service
/run/systemd/journal/stdout     systemd-journald.socket      systemd-journald.service
/run/systemd/shutdownd          systemd-shutdownd.socket     systemd-shutdownd.service
/run/udev/control               systemd-udevd-control.socket systemd-udevd.service
/var/run/avahi-daemon/socket    avahi-daemon.socket          avahi-daemon.service
/var/run/dbus/system_bus_socket dbus.socket                  dbus.service
kobject-uevent 1                systemd-udevd-kernel.socket  systemd-udevd.service

12 sockets listed.

list-dependencies의 경우 뒤에 Service/Target 이름을 별도로 지정 가능하다.

$ systemctl list-dependencies swap.target
swap.target
├─dev-disk-by\x2did-dm\x2dname\x2drhel\x2dswap.swap
├─dev-disk-by\x2did-dm\x2duuid\x2dLVM\x2dWu6fS25DomohkfmsDzYY8SzAfEPmpojKfhfiV6D6AYa86f2Bb7nOkSq...
├─dev-disk-by\x2duuid-c3591b93\x2d0cc0\x2d457c\x2db1f5\x2d79ea0658d54d.swap
├─dev-dm\x2d1.swap
├─dev-mapper-rhel\x2dswap.swap
├─dev-mapper-rhel\x2dswap.swap
└─dev-rhel-swap.swap

실패 서비스 확인

부팅하는 과정에서 실패한 서비스에 대해서 아래와 같이 확인이 가능하다. 또한, 위에서 언급되었던 list-sockets 같은 명령에도 옵션으로 지정하여 실패한 항목을 확인 할 수 있다.

$ systemctl --failed
systemctl --failed
UNIT          LOAD   ACTIVE SUB    DESCRIPTION
rhnsd.service loaded failed failed LSB: Starts the Spacewalk Daemon

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

1 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

6. 서비스 관리

서비스를 설정하고 관리하는 방법은 기본적으로 아래와 같다.

- 서비스 활성화
$ systemctl enable [서비스명]

- 서비스 비활성화
$ systemctl disable [서비스명]

- 서비스 시작
$ systemctl start [서비스명]

- 서비스 종료
$ systemctl stop [서비스명]

- 서비스 재시작
$ systemctl restart [서비스명]

- 서비스 갱신
$ systemctl reload [서비스명]

그리고, 각각의 서비스에 대해서 부팅 때 실행되도록 설정 되었는지 여부 및 현재 실행 여부 등을 확인 할 수 있으며 간단한 응답으로 종료하기 때문에 스크립트 작성할 때 좋다.

$ systemctl is-enabled [서비스명]
$ systemctl is-active [서비스명]

예시)
$ systemctl is-enabled crond
enabled
$ systemctl is-active auditd
active

이렇게 변경한 서비스 설정 정보를 데몬에 반영하기 위해서는 아래와 같이 실행하면 된다

$ systemctl daemon-reload

서비스 상태도 확인이 가능한데 이 상태 확인은 기존 init 스크립트가 제공하던 실행 여부 이상으로 각 서비스의 CGroup 관련 정보 및 로그정보까지 확인이 가능하다. (-ㅣ 옵션은 한 줄을 넘어서는 라인을 축약하지 말고 전부 보여주라는 옵션이다)

$ systemctl status crond -l
crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
   Active: active (running) since Tue 2014-10-21 00:31:58 EDT; 2h 10min ago
 Main PID: 583 (crond)
   CGroup: /system.slice/crond.service
           └─583 /usr/sbin/crond -n

Oct 21 00:31:58 localhost.localdomain systemd[1]: Started Command Scheduler.
Oct 21 00:31:58 localhost.localdomain crond[583]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 2% if used.)
Oct 21 00:31:59 localhost.localdomain crond[583]: (CRON) INFO (running with inotify support)

상태확인 뿐만 아니라 kill 명령을 통해서 서비스 관련 모든 프로세스에 kill 시그널을 보낼 수도 있다.

$ systemctl kill httpd

웹서버(http) 관련 프로세스가 모두 죽어있음을 확인할 수 있다.

7. 로그 관리

systemd는 단순한 init 대체제가 아니라 시스템 전반적인 부분을 관리하는 프로그램이기 때문에 로그에 대한 관리 부분도 있다. 로그는 systemd-journald를 통해서 관리되며 이를 제어하는 툴은 journalctl이다.

단순히 전체 이벤트 로그를 확인하기 위해서는 journalctl 만 실행하면 되며 몇 가지 유용한 커맨드를 소개한다.

바이너리에 대한 이벤트

프로세스로 실행이 가능한 특정 바이너리에 대한 이벤트는 아래와 같이 확인 할 수 있다.

$ journalctl /sbin/crond
-- Logs begin at Tue 2014-10-21 00:31:54 EDT, end at Tue 2014-10-21 04:01:01 EDT. --
Oct 21 00:31:58 localhost.localdomain crond[583]: (CRON) INFO (RANDOM_DELAY will be scaled with fac
Oct 21 00:31:59 localhost.localdomain crond[583]: (CRON) INFO (running with inotify support)
lines 1-3/3 (END)

기간 조회

특정 일자부터의 이벤트 로그를 확인하는 방법은 아래와 같은데

$ journalctl --since=today

today 대신에 yesterday, tomorrow 같은 단어도 가능하다. 또한, "YYYY-MM-DD HH:MM:SS" 형태의 시간 값을 이용해서 구간 별 조회가 가능한데 시간을 생략하면 0시0분0초를 기준으로 하게 된다.

$ journalctl --since=2014-10-21 --until=2014-10-22
-- Logs begin at Tue 2014-10-21 00:31:54 EDT, end at Tue 2014-10-21 04:01:01 EDT. --
Oct 21 00:31:54 localhost.localdomain systemd-journal[81]: Runtime journal is using 8.0M (max 92.0M
Oct 21 00:31:54 localhost.localdomain systemd-journal[81]: Runtime journal is using 8.0M (max 92.0M
Oct 21 00:31:54 localhost.localdomain kernel: Initializing cgroup subsys cpuset

마지막 부팅 이후의 로그는 -b 옵션으로 확인이 가능하며

$ journalctl -b

속성에 따른 조회

특정, 우선순위에 따른 (syslog에서 지정하는 debug, info, err 등) 조회도 가능하다.

$ journalctl -p err
-- Logs begin at Tue 2014-10-21 00:31:54 EDT, end at Tue 2014-10-21 04:01:01 EDT. --
Oct 21 00:31:54 localhost.localdomain kernel: Detected CPU family 6 model 69
Oct 21 00:31:54 localhost.localdomain kernel: Warning: Intel CPU model - this hardware has not unde
Oct 21 00:31:54 localhost.localdomain kernel: tsc: Fast TSC calibration failed
Oct 21 00:31:54 localhost.localdomain systemd-fsck[260]: fsck failed with error code 8.
Oct 21 00:31:56 localhost.localdomain kernel: piix4_smbus 0000:00:07.0: SMBus base address uninitia
Oct 21 00:31:58 localhost.localdomain audispd[544]: No plugins found, exiting
Oct 21 00:32:00 localhost.localdomain systemd[1]: Failed to start LSB: Starts the Spacewalk Daemon.
lines 1-8/8 (END)

기타 옵션들

이 외에 tail -f로 로그파일을 걸어둔 것 같은 효과를 갖는 -f 옵션과 json을 비롯한 다양한 포맷으로 로그를 재포매팅 하는 옵션인 -o 옵션 등이 있다.

$ journalctl -f
$ journalctl -p err -o json-pretty
{
        "__CURSOR" : "s=ee396e27b84346d4a5163e52bb6a839c;i=5b;b=03fa23106cc04ce99a97bf6a5e45e6aa;m=
        "__REALTIME_TIMESTAMP" : "1413865914539904",
        "__MONOTONIC_TIMESTAMP" : "459391",
        "_BOOT_ID" : "03fa23106cc04ce99a97bf6a5e45e6aa",
        "_MACHINE_ID" : "a73fc4e71dd64fe98f580bffe567ea29",
        "_HOSTNAME" : "localhost.localdomain",
        "_SOURCE_MONOTONIC_TIMESTAMP" : "0",
        "_TRANSPORT" : "kernel",
        "SYSLOG_IDENTIFIER" : "kernel",
        "PRIORITY" : "2",
        "MESSAGE" : "Detected CPU family 6 model 69"
}

8. CGroup 관리

리소스 정보 조회

systemd에는 CGroup(control group)을 관리하는 기능도 포함되어있다. (홈페이지에서 문서를 읽다보면 없는게 있을까 싶을 정도로 너무 많은 기능을 가지고 있다. 문서 서두에 이야기 한 것 처럼 이로 인해 Unix 철학과 대치 된다고 논란이 있던 프로그램이다)

먼저 systemd-cgls 명령은 현재 cgroup에 대한 정보를 타입별로 출력해준다.

$ systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
├─user.slice
│ ├─user-1000.slice
│ │ └─session-2.scope
│ │   ├─10191 sshd: lunatine [priv
│ │   ├─10195 sshd: lunatine@pts/0
│ │   └─17794 systemd-cgls
│ └─user-0.slice
│   └─session-1.scope
│     ├─ 595 login -- root
│     └─7805 -bash
└─system.slice
  ├─httpd.service
  │ ├─17779 /usr/sbin/httpd -DFOREGROUND
  │ ├─17780 /usr/sbin/httpd -DFOREGROUND
  │ ├─17781 /usr/sbin/httpd -DFOREGROUND
  │ ├─17782 /usr/sbin/httpd -DFOREGROUND
  │ ├─17783 /usr/sbin/httpd -DFOREGROUND
  │ └─17784 /usr/sbin/httpd -DFOREGROUND
... 하략 ...

systemd-cgtop의 경우는 흔히 알고 있는 top 명령과 같이 cgroup에 대하여 CPU, Memory, I/O에 대한 정렬 결과를 출력해 준다. 본인이 설정한 cgroup에 대해 적합하게 리소스가 분배되고 있는지 확인하는데 유용하다.

리소스 관리

앞서 살펴보았던 systemctl의 경우 set-property 명령을 통해서 리소스 값을 제어할 수 있는데 실제로는 systemctl로 설정하면 systemd.resource-control이라는 프로그램이 해당 리소스 할당작업을 수행한다.

$ systemctl set-property httpd.service CPUShares=200
$ systemctl show -p CPUShares httpd.service
CPUShares=200
$ cat /sys/fs/cgroup/cpu/system.slice/httpd.service/cpu.shares
200

systemctl을 통해서 설정을 하지만 실제로 systemd.resource-control에 의해서 설정되기 때문에 상세한 설정 옵션에 대해서는 systemd.resource-control의 man 페이지를 확인해야 한다.

이러한 리소스관리 툴도 포함되어있기 때문에 cgroup 설정을 위한 스크립트 작성이 한결 간편해지고 체계적이 될 수 있다.

9. 호스트명 설정

systemd에는 hostnamectl이란 툴도 있는데 이 툴로 호스트명 설정도 가능하다.

$ hostnamectl
   Static hostname: rhel7
         Icon name: computer
           Chassis: n/a
        Machine ID: a73fc4e71dd64fe98f580bffe567ea29
           Boot ID: 711ec89043a543fa8751aa686257dd81
    Virtualization: oracle
  Operating System: Red Hat Enterprise Linux Server 7.0 (Maipo)
       CPE OS Name: cpe:/o:redhat:enterprise_linux:7.0:GA:server
            Kernel: Linux 3.10.0-123.el7.x86_64
      Architecture: x86_64

$ hostnamectl set-hostname new-rhel7

위 명령은 /etc/hostname 설정파일을 변경하게 된다. 옵션 중에 --transient는 DHCP, mDNS에 의해서 변경가능한 커널에 의해 관리되는 호스트명을 수정하고 --pretty는 UTF-8 인코딩으로 호스트명을 지정한다.

10. 로케일 설정

systemd에 포함된 localectl은 시스템의 로케일을 설정한다. 현재 설정된 정보는 localectl 실행 결과로 확인 할 수 있다.

$ localectl
   System Locale: LANG=en_US.UTF-8
       VC Keymap: us
      X11 Layout: us

로케일 변경은 set-locale로 키맵은 set-keymap, X서버를위한 키맵은 set-x11-keymap으로 변경 가능하다. 이 툴은 /usr/lib/locale/locale-archive 정보를 바탕으로 /var/run/dbus/system_bus_socket을 통해서 변경을 수행한다.

$ localectl set-locale LANG=ko_KR.UTF-8
$ localectl set-keymap fr
$ localectl set-x11-keymap fr
$ localectl
   System Locale: LANG=ko_KR.UTF-8
       VC Keymap: fr
      X11 Layout: fr

변경가능한 로케일, 키맵 등은 list-locales, list-keymaps, list-x11-keymap-models, list-x11-keymap-layouts, list-x11-keymap-variants, list-x11-keymap-options으로 확인 가능하다.

11. 사용자 관리

loginctl 툴을 이용해서 현재 사용자 세션에 대해서 관리가 가능하다.

$ loginctl list-users
       UID USER
      1000 lunatine

1 users listed.

list-session으로 현재 세션들을 확인 할 수 있으며 lock-session 등의 명령으로 세션을 잠글 수 있다. 또한, show-user를 통해 사용자 정보 조회도 가능하고 kill-user를 통해서 사용자 프로세스에 시그널을 보낼 수도 있다.

자세한 내용은 loginctl --help로 확인해 보도록 하자.

12. 시간 설정

timedatectl은 시간대를 조회하고 설정하는 기능을 제공한다. set-time은 시간을 set-timezone은 시간대를 설정한다. 또한, set-ntp를 통해 NTP 활성화 여부도 설정이 가능하다.

$ timedatectl
      Local time: Tue 2014-10-21 09:45:29 EDT
  Universal time: Tue 2014-10-21 13:45:29 UTC
        RTC time: Tue 2014-10-21 13:45:29
        Timezone: America/New_York (EDT, -0400)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: yes
 Last DST change: DST began at
                  Sun 2014-03-09 01:59:59 EST
                  Sun 2014-03-09 03:00:00 EDT
 Next DST change: DST ends (the clock jumps one hour backwards) at
                  Sun 2014-11-02 01:59:59 EDT
                  Sun 2014-11-02 01:00:00 EST

$ timedatectl set-timezone Asia/Seoul
$ timedatectl
      Local time: Tue 2014-10-21 22:46:04 KST
  Universal time: Tue 2014-10-21 13:46:04 UTC
        RTC time: Tue 2014-10-21 13:46:04
        Timezone: Asia/Seoul (KST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

13. 원격 관리

systemd의 모든 명령어들은 -H옵션을 제공하는데 이 옵션을 통해서 원격지 서버에 ssh 접속을 통해 설정 및 정보조회가 가능하다. 아래 예제는 원격지 서버의 호스트명을 수정하는 내용이다.

$ hostnamectl -H root@rhel7.test.com set-hostname rhel7-new
root@rhel7.test.com's password:

$ hostnamectl -H root@rhel7.test.com
root@rhel7's password:
   Static hostname: rhel7-new
         Icon name: computer
           Chassis: n/a
        Machine ID: a73fc4e71dd64fe98f580bffe567ea29
           Boot ID: 711ec89043a543fa8751aa686257dd81
    Virtualization: oracle
  Operating System: Red Hat Enterprise Linux Server 7.0 (Maipo)
       CPE OS Name: cpe:/o:redhat:enterprise_linux:7.0:GA:server
            Kernel: Linux 3.10.0-123.el7.x86_64
      Architecture: x86_64

마치며

본 문서에서 systemd의 기능들을 간단히 알아보았다. systemd는 마치 맥가이버칼 처럼 다양한 시스템 설정 기능을 포함하고 있으며 계속해서 개선되고 추가되고 있다. Unix의 '한 가지만 잘하자' 철학에 위배되는 프로그램일지 모르지만 실제는 내부적으로 한가지 일을 잘 하는 툴 들로 구성되어있기 때문에 위배라고 보기도 어렵다.

그리고 systemd는 기존 System V Init에 익숙한 사용자를 위해 디렉토리 구조 및 호환성을 일부 제공하고 있다. 심볼릭 링크이지만 init도 존재하고 0123456qQuUsS 옵션도 제공한다. 이 때문에 runlevel$.target 심볼릭링크 파일이 존재한다.

대표적인 리눅스 배포판에서 선택되었으며 이제는 엔터프라이즈 리눅스 배포판에도 선택이 되었다. 머지 않아 Debian 계열 배포판에서도 기본으로 채택이 될 것이라고 하니 이제 슬슬 System V Init을 떠나 보낼 때가 왔나보다.

기존 시스템 관리에 사용하던 자동화 스크립트를 systemd에 맞춰서 수정 할 일만 남았다.

끝...

p.s: 나중에 기회가 되면 systemd의 활용 및 트러블슈팅에 대해서도 정리해 볼 생각이다.