CentOS 7 Systemd 이해하기
CentOS 7로 배포판 버전이 바뀌면서 가장 크게 바뀐것이 Systemd 입니다. 기존의 볼수 없었던 서비스 하나일뿐이라고 생각할 수 있지만 Systemd 는 단지 서비스 하나의 문제가 아닙니다.
Linux 의 기본 뼈대 프로세스
Linux는 운영체제 입니다. 전원을 넣고 부팅이 되는 과정에서 시스템을 초기화하고 기타 서비스들을 위한 환경을 조성하고 그들을 시작시켜주는 일을 하는 초기화 프로세스가 필요합니다.
CentOS 6 까지는 Sys V 라고해서 init 프로세스가 이것을 담당했습니다. 커널이 메모리에 로딩되면 가장 먼저 실행되는 프로세스로 init 프로세스를 실행시킵니다. 이 프로세스는 init 스크립트, init 설정등을 기반으로 RunLevel 이나 각 서비스별 실행 스크립트를 실행시키는 겁니다.
CentOS 7 로 올라오면서 Sys V 의 init 프로세스를 버리고 Systemd 로 바꾼 겁니다. 이는 Linux 의 기본 뼈대 프로세스를 바꾼 것으로 매우 큰 변화라고 할만 합니다. Systemd 는 기준의 Sys V init 보다 훨씬 많은 기능을 제공 합니다.
- 시스템 부팅 프로세스
- Service Management
- cgroup 을 이용한 프로세스 자원관리
- 서비스 프로세스 관리
흔히들 Daemon 프로그램들을 위한 로깅, 자원할당, 부팅관리등 Systemd 로 모두 할 수 있습니다.
주요한 명령어들
Systemd 를 위한 주요한 명령어들은 다음과 같습니다.
- systemctl
- systemd-analyze
- systemd-cgls
- systemd-cgtop
- systemd-loginctl
현재 작동하고 있는 서비스들 목록은 다음과 같이 확인 가능 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
~]# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point sys-devices-pci0000:00-0000:00:01.1-ata2-host1-target1:0:0-1:0:0:0-block-sr0.device loaded active plugged QEMU_DVD-ROM sys-devices-pci0000:00-0000:00:03.0-virtio0-net-eth0.device loaded active plugged Virtio network device sys-devices-pci0000:00-0000:00:04.0-sound-card0.device loaded active plugged 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (QEMU Virtual Machine) sys-devices-pci0000:00-0000:00:05.0-virtio1-block-vda-vda1.device loaded active plugged /sys/devices/pci0000:00/0000:00:05.0/virtio1/block/vda/vda1 sys-devices-pci0000:00-0000:00:05.0-virtio1-block-vda-vda2.device loaded active plugged /sys/devices/pci0000:00/0000:00:05.0/virtio1/block/vda/vda2 sys-devices-pci0000:00-0000:00:05.0-virtio1-block-vda.device loaded active plugged /sys/devices/pci0000:00/0000:00:05.0/virtio1/block/vda sys-devices-platform-serial8250-tty-ttyS1.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS1 sys-devices-platform-serial8250-tty-ttyS2.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS2 sys-devices-platform-serial8250-tty-ttyS3.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS3 sys-devices-pnp0-00:04-tty-ttyS0.device loaded active plugged /sys/devices/pnp0/00:04/tty/ttyS0 sys-module-configfs.device loaded active plugged /sys/module/configfs sys-subsystem-net-devices-eth0.device loaded active plugged Virtio network device -.mount loaded active mounted / dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File System run-user-0.mount loaded active mounted /run/user/0 |
위 목록은 현재 동작중인 서비스들만 보여주는데, 모든 서비스들을 보고 싶다면 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
~]# systemctl list-unit-files UNIT FILE STATE session-2.scope static arp-ethers.service disabled auditd.service enabled autovt@.service disabled avahi-daemon.service enabled blk-availability.service disabled brandbot.service static console-getty.service disabled console-shell.service disabled container-getty@.service static cpupower.service disabled crond.service enabled dbus-org.fedoraproject.FirewallD1.service enabled dbus-org.freedesktop.Avahi.service enabled dbus-org.freedesktop.hostname1.service static dbus-org.freedesktop.locale1.service static dbus-org.freedesktop.login1.service static dbus-org.freedesktop.machine1.service static dbus-org.freedesktop.network1.service invalid |
서비스 활성화, 비활성화, 시작, 정지, 재시작
부팅시에 서비스를 시작하도록 하기위 해서는 다음과 같이 해줍니다.
1 2 |
~]# systemctl enable vsftpd Created symlink from /etc/systemd/system/multi-user.target.wants/vsftpd.service to /usr/lib/systemd/system/vsftpd.service. |
서비스 비활성화, 시작, 중지, 재시작, 릴로드는 다음과 같습니다.
1 2 3 4 5 |
~]# systemctl disable vsftpd ~]# systemctl start vsftpd ~]# systemctl stop vsftpd ~]# systemctl restart vsftpd ~]# systemctl reload vsftpd |
서비스가 활성화, 실행중인지 다음과 같이 질의를 할 수 있습니다.
1 2 3 4 |
~]# systemctl is-enabled vsftpd [enabled, disabled] ~]# systemctl is-active vsftpd [inactive, active, failed] |
서비스 및 설정 파악
서비스에 대한 systemd 설정에 대한 모든 정보를 다음과 같이 확인할 수 있습니다.
1 |
]# systemctl show http.service |
각 서비스들은 서로간의 의존관계를 가지고 있습니다. 이는 다음과 같은 명령어로 확인이 가능합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
~]# systemctl list-dependencies default.target ● ├─auditd.service ● ├─avahi-daemon.service ● ├─brandbot.path ● ├─crond.service ● ├─dbus.service ● ├─irqbalance.service ● ├─kdump.service ● ├─mariadb.service ● ├─network.service ● ├─NetworkManager.service ● ├─nginx.service ● ├─openstack-glance-api.service ● ├─openstack-glance-registry.service ● ├─php-fpm.service ● ├─plymouth-quit-wait.service ● ├─plymouth-quit.service |
특정 서비스에 대한 의존성을 알고 싶다면 서비스명을 주면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
~]# systemctl list-dependencies mariadb.service mariadb.service ● ├─-.mount ● ├─system.slice ● └─basic.target ● ├─firewalld.service ● ├─microcode.service ● ├─rhel-autorelabel-mark.service ● ├─rhel-autorelabel.service ● ├─rhel-configure.service ● ├─rhel-dmesg.service ● ├─rhel-loadmodules.service ● ├─paths.target ● ├─slices.target ● │ ├─-.slice ● │ └─system.slice |
Systemd 자체를 재시작하기 위해서는 다음과 같이 합니다.
1 |
]# systemctl daemon-reload |
Unit File 편집
다음과 같이 Unit file 출력도 지원합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
]# systemctl cat ntpd.service # /usr/lib/systemd/system/ntpd.service [Unit] Description=Network Time Service After=syslog.target ntpdate.service sntp.service [Service] Type=forking EnvironmentFile=-/etc/sysconfig/ntpd ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS PrivateTmp=true [Install] WantedBy=multi-user.target |
Systemd 는 기본적으로 /usr/lib/system 디렉토리에 Unit File 을 보관합니다. 그런데, 커스터마이징 하기위해서 이 파일들을 직접 편집하기 보다는 /etc/systemd/system/ntpd.service.d 처럼 커스터마이징 하고 싶은 서비스의 디렉토리를 만들고 .conf 로 끝나는 설정파일을 만들어서 바꾸고자하는 설정을 넣으면 됩니다. 만일 이러한 과정이 귀찮다면 단순하게 다음과 같이 함으로써 자동으로 알아서 커스터마이징 설정파일을 만들어줍니다.
1 |
]# systemctl edit ntpd |
위 명령어는 다음을 수행 합니다.
- /etc/systemd/system/ntpd.service.d 디렉토리 생성
- 시스템에 등록된 기본 편집기(대부분 VIM)을 연다.
- 내용을 입력하고 저장하면 1에서 생성한 디렉토리에 override.conf 파일을 생성하고 내용을 읽는다. (여기서 systemctl daemon-reload 는 불필요)
만일 /usr/lib/system/system/ntpd.service Unit File 자체를 편집하고 싶다면 –full 옵션을 주면 됩니다.
1 |
]# systemctl edit ntpd --full |
부팅 상태 분석
Systemd 의 주요한 임무는 부팅 과정을 관리하고 정보를 제공하는 것입니다. 부팅 시간 정보는 다음과 같이 확인할 수 있습니다.
1 2 |
]# systemd-analyze Startup finished in 474ms (kernel) + 2.750s (initrd) + 1min 25.289s (userspace) = 1min 28.514s |
총 1분 28초 정도 부팅하는데 걸렸다는 걸 알수 있습니다.
부팅과정에 각 서비스별 초기화하는데 걸린 시간은 다음과 같이 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
]# systemd-analyze blame 1min 4.411s kdump.service 16.581s mariadb.service 11.789s tuned.service 9.934s nginx.service 6.167s postfix.service 5.610s NetworkManager-wait-online.service 5.402s dev-vda2.device 4.589s firewalld.service 3.102s vsftpd.service 1.745s NetworkManager.service 1.723s systemd-logind.service |
초기화하는데 걸린 시간을 기준으로 정렬해서 정보를 보여줍니다. kdump.service 가 1분 4초정도의 시간을 소비했습니다.
이러한 분석은 다음과 같이 html 파일로 덤프해서 볼 수도 있습니다.
1 |
]# systemd-analyze plot > plot.html |
plot.html 은 다음과 같습니다.
부팅시에 시간이 많이 걸리는 서비스들에 대해서 빨강색으로 표시해줍니다. 이 정보는 부팅과정에서 소비되는 시간을 측정해서 개선점을 찾게 도와줍니다.
시간을 많이 잡아먹는 서비스들을 트리형태로 엮어서(chain)로 볼수도 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
~]# 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 @37.350s └─mariadb.service @20.768s +16.581s └─network.target @20.696s └─network.service @19.797s +898ms └─NetworkManager.service @12.438s +1.745s └─firewalld.service @7.848s +4.589s └─basic.target @7.819s └─sockets.target @7.819s └─dbus.socket @7.819s └─sysinit.target @7.804s └─swap.target @7.804s └─dev-disk-by\x2duuid-5b371896\x2d7383\x2d405b\x2d8ef2\x2da702722db7d9.swap @7.761s +42ms └─dev-disk-by\x2duuid-5b371896\x2d7383\x2d405b\x2d8ef2\x2da702722db7d9.device @7.761s |
MariaDB 서비스에 대해서 엮여서 시간을 많이 소모하는 하는 서비스들을 보여 줍니다.
특정 서비스에 대해서 critical-chain 을 보고 싶다면 인수로 서비스명을 주면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
~]# systemd-analyze critical-chain firewalld.service 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. firewalld.service +4.589s └─basic.target @7.819s └─sockets.target @7.819s └─dbus.socket @7.819s └─sysinit.target @7.804s └─swap.target @7.804s └─dev-disk-by\x2duuid-5b371896\x2d7383\x2d405b\x2d8ef2\x2da702722db7d9.swap @7.761s +42ms └─dev-disk-by\x2duuid-5b371896\x2d7383\x2d405b\x2d8ef2\x2da702722db7d9.device @7.761s |
서비스 실행을 실패한 서비스들은 다음과 같이 체크 가능 합니다.
1 2 3 4 |
~]# systemctl --failed UNIT LOAD ACTIVE SUB DESCRIPTION ● kdump.service loaded failed failed Crash recovery kernel arming ● vsftpd.service loaded failed failed Vsftpd ftp daemon |
타겟바꾸기
Systemd 에서 타겟(Target)은 동시에 서비스들을 시작하는걸 허용하기 위한 그룹 메커니즘입니다. 이는 Sys V 에 Run Level 과 비슷합니다. Sys V 에서는 init 명령어를 통해서 Run Level 를 바꿀 수 있었는데, Systemd 는 타겟을 바꿀 수 있습니다.
1 2 3 |
]# systemctl rescue ]# systemctl isolate runlevel3.target (혹은 multi-user.target) ]# systemctl isolate graphical.target |
이 타겟에 따라서 부팅시 시작되는 서비스들이 달라집니다. 기본 값은 muti-user.target 입니다. 기본 값은 다음과 같이 바꿀 수 있습니다.
1 2 3 |
]# systemctl set-default graphical.target # 타겟 바꾸기 ]# systemctl get-default graphical.target |