계속해서 등장하는 데몬이라는 개념, linux 기반 OS에서 사용하는 이 "daemon" 이라는 용어는 정확하게 의미하는 것이 뭘까? 사실 아주 단순하게 보면 기본중의 기본 개념이다.
이름의 유래는 맥스웰의 도깨비에서 따왔다고 한다, "맥스웰의 사고 실험 - 열역학 제2법칙은 같은 온도를 갖는 두 물체가 자발적으로 서로 온도가 달라지는 것" 의 실험 설명에서 작은 '도깨비' 가 방문을 지킨다고 하는데, 눈에 보이지 않는데 열심히 일을 하는 모습에서 해당 이름을 따온 것은 아닐까 한다.
운영체제에서 사용자가 직접 제어하지 않아도, 백그라운드에서 여러가지의 작업을 하는 프로그램을 뜻한다. 즉, 메모리에 머무르고 있으면서 특정 요청이 오면 바로 그에 대한 대응을 할 수 있도록 대기중인 프로세스를 말한다.
또한 부모 프로세스를 갖지 않으며, 대부분 프로세스 트리에서 init 바로 아래 위치한다. 즉, 시스템의 첫 프로세스인 (pid가 1인) systemd 의 바로 하위 프로세스가 된다. (원래 Init이 PID 1인 루트 프로세스였는데 이를 개선한 것이 systemd 이다. systemd 는 프로세스 트리에서 가장 상위의 프로세스이고 모든 프로세스의 직간접 부모인 데몬이다.)
데몬이 되는 방법은 일반적으로 자식 프로세스를 포크(fork)하여 생성하고 자식을 분기한 자신을 죽이면서 init이 고아가 된 자식 프로세스를 자기 밑으로 데려가도록 하는 방식이다. 이러한 방법을 ‘fork off and die’ 라 부르기도 한다. 그렇기 때문에, 데몬은 부모 프로세스가 없어서 PPID(부모 프로세스 ID)는 1이다.
MS윈도우의 서비스(Service)와 유사하고 실제로 '서비스'라고 부르기도 하다. 데몬 프로그램의 명령어는 'd'로 끝난다. (ex. syslogd, ftpd, mysqld, httpd...)
독립적으로 실행되며, 요청에 의해 실행되기 때문에 메모리에 항상 대기하는 데몬 방식이다.
따라서 요청에 대한 응답속도가 빠르지만, 항상 백그라운드에서 대기해야하므로 메모리 효율이 좋지 않다.
스탠드얼론은 /etc/init.d/
나 /etc/rc.d/init.d/
에 있는 스크립트 파일로 실행된다. 대표적으로 SSH 서비스를 찾아볼 수 있으며 이는 '해당 서비스 절대경로' + start/stop/restart
나 'service 서비스 이름' + start/stop/restart
로 데몬을 시작하거나 멈추는 등 관리할 수 있다.
init 말고, systemd 에 대한 설명은 아래에 더 자세하기 한다.
Super Daemon이라는 특별한 데몬에 의해 간접적으로 실행되는 데몬이다.
사용자에 의한 요청이 발생할 경우, xinetd 프로그램이 해당 요청을 분석하여 필요한 데몬을 메모리에서 실행하여 응답하는 방식이다. (xinetd 자체는 standalone 방식으로 작동한다.) 원래는 inetd 이었으나 보안상 이유로 xinetd를 사용한다.
standalone방식보다 응답속도가 느리지만, 메모리 효율은 그에 비해 훨씬 좋다. 따라서 매우 빠른 응답속도가 필요하지 않을 경우에 사용한다.
Ubuntu에서는 기본적으로 Super daemon이 설치되지 않기에 Package Manager를 통해 설치해줘야 한다. sudo apt install netkit-inetd
/etc/xinetd.d/
디렉토리의 각 서비스파일에 등록되어 있는 데몬들이 root 계정으로 실행되고 있는지 확인
/etc/xinetd.d/
디렉토리의 각 서비스파일에 대한 일반유저의 권한은 실행, 읽기, 쓰기 모두 배제. 읽기 권한이 있다면 서버에서 어떤 서비스를 하고 있는지 알고 실행파일의 위치까지도 파악이 가능하기 때문이다.
서버관리자의 실수든 해킹된 것이든 /etc/xinetd.d/
내의 파일들에게 쓰기( write ) 권한이 설정되어 있다면 어떤 프로그램이든지 만들어서 이 파일에 등록해 두면 root 의 권한으로 실행이 가능하게 되는 최악의 상황이 발생할 수 있다.
우선 둘 다(systemctl, service) 기본적으로 daemon (service)를 실행하기 위한 command line 이다.
systemctl에 대해 더 자세히 알아보자면, systemd 를 알아야 한다. (ubuntu) cat /proc/1/status
command를 쳐보자. PID가 1인 프로세스가 init이 아니라, systemd 인 것을 확인할 수 있다. (또는 top
command 로 1번 PID를 보자!)
예전의 PID 1이었던 init은 현재로부터 수 십 년 전에 처음 소개된 프로그램인데 그 때의 구조를 거의 바꾸지 않고 계속 기능이 추가되며 날이 갈수록 복잡해지는 프로그램들로 인해 효율이 떨어졌다.
init은 시작할 프로그램을 구동하는 쉘 스크립트를 특정 run-level의 rc 디렉토리에 추가하는 방식의 구조를 가졌다. init은 부팅 과정에서 단계적으로 run-level을 올려가며 해당 run-level에 포함된 스크립트들을 순차적으로 실행시키니 설정이 복잡하고, 속도가 순차의 depth가 깊을수록 느려졌다.
이런 문제들을 해결하기 위해 Red Hat의 Lennart Poettering과 Kay Sievers이 systemd를 만들기 시작했다 - (GNU 약소 GPL 라이선스). systemd는 당연하지만 init보다 좋은 성능과 직관적인 설정을 가졌다.
의존성을 해치지 않으며 가능한 한 "병렬"로 시작 프로그램들을 실행시키는 것으로 부팅 속도를 끌어올리고, 프로그램 실행을 위한 파일로는 쉘 스크립트가 아니라 .service라는 systemd만의 unit을 통해 체계적이면서 가독성이 좋게 설정이 가능해졌다. 병렬로 서비스를 수행하기 때문에 서비스간의 종속성 및 실행 순서 관리가 매우 중요하다. 그리고 프로세스간의 통신은 D-bus 에서 담당한다. (소켓, D-bus 지원)
게다가 systemd는 단지 init 뿐만 아니라 다른 프로그램들의 기능들마저 가져와 추가하기 시작했다.
이렇게 systemd가 여러 영역을 아우르는 것을 보고 혹자들은 하나만 잘하자 라는 UNIX의 철학에 어긋난다고 말하기도 한다.
systemd
: init 데몬
systemd-journald
: 다른 데몬(프로세스)들의 출력(syslog, 표준, 에러 출력), 로그 저장 데몬
systemd-logind
: 사용자 로그인, 세션 등 관리 데몬
systemd-udevd
: 장치 관리자 데몬
systemd-networkd
: 네트워크 관리 데몬. DHCP 뿐만 아니라 Virtual Lan 설정까지 가능
systemd-resolved
: DNS 해석 데몬
systemd-timesyncd
: NTP로 컴퓨터 시간 동기화 데몬
systemd-boot
: UEFI 부트로더
몇몇 구성부분이 더 있지만 사용자가 어느정도 자주 접할 수 있는 것들은 위와 같다.
위에서부터 4개는 필수적으로 필요한 것 이고, 나머지들은 대체할 다른 프로그램이 있다면 설정, 실행하지 않아도 괜찮은 것들이다. 이러한 데몬이나 systemd의 사용자 설정파일은 /etc/systemd/
에 존재한다.
man systemd-user.conf
와 같이 man 명령어를 통해 해당 디렉토리에 있는 것들에 대한 메뉴얼 확인이 가능하다. 서비스 목록 확인
systemctl list-unit-files
systemctl list-units --type=service
를 통해 type이 service인것만 쉽게 볼 수 있다.서비스 시작, 종료, 재시작, 상태 확인
systemctl start|stop|restart|status [서비스명]
서비스 활성화, 비활성화
systemctl enable|disable [서비스명]
/etc/systemd/system/[target]/
경로에 링크파일을 생성한다.서비스 갱신
systemctl reload [서비스명]
시스템 중지, 재부팅
systemctl halt|reboot
[Unit]
Description=Sample Service
Requires=local-fs.target
After=local-fs.target
[Service]
Type=simple
PIDFile=/var/run/sample.pid
ExecStart=/usr/sbin/sampled -d
ExecStop=/usr/sbin/sampled -k
[Install]
WantedBy=multi-user.target
기존에 시스템에서 데몬을 조작하기 위한 service 명령어다. 위 init 대신 systemd 가 어떻게 탄생했는지 다시 생각해 보자.
/etc/init.d
디렉토리에 있는 링크파일들 대상으로 start, stop, restart, reload, status 를 할 수 있다.
위와 같이 systemd 가 등장하면서 systemctl
명령어를 사용할 수 있게 된 것이다. 사실 OS 특정 버전 부터는 (리눅스 기반인 OS) service를 수행해도 redirecting to /bin/systemctl start ***.service
라고 리다이렉팅 되어 systemctl로 실행이 되는 것이다.
사실 이제 service와 init은 잊고, systemctl 을 기억하는게 옳은 접근 방법 인 것이다.
centos6까지는 /etc/rc.d/init.d
디렉토리에 서비스 관련 파일들이 있었고 이를 service 명령어를 통해 제어한다.
ex) service [데몬이름] start
centos7부터는 서비스들이 대부분 Unit으로 분리되었고, 서비스.service
형식의 파일명을 가지며, systemctl
명령어로 제어한다.
ex) systemctl start [데몬이름]
centos에서 데몬을 다루는 방법에 대해 더 자세한 명령어는 이 글을 꼭 확인하길 바란다
ㅗㅜㅑ 매우 정리 잘하셧네요... 감동했습니다. 벨로그에 이런 명포스팅이 있다니...