systemd –user 사용하기
Systemd 는 기존 리눅스 시스템에서 사용해왔던 init script 를 대체한다. 배포판마다 적용된 버전이 다른데, CentOS에 경우에는 7 버전부터 Ubuntu 의 경우에는 16.04 부터 적용되기 시작했다.
Systemd 는 부팅과정에서 최초로 실행되는 프로세스이며 리눅스 시스템 전체를 움직하게 하는 프로세스이다. 이 프로세스는 또 다른 프로세스들을 제어하는데 이를 위해서 systemd 프로그램을 제공한다.
부팅과정에서 자동으로 데몬들을 실행시키는 것도 systemd 가 하는데 이 프로그램은 데몬에 대한 명세서인 unit 파일을 기반으로 실행을 시켜준다. 이러한 파일들은 전역 시스템 영역에 속한다.
전역 systemd 영역
전역 systemd 영역의 파일들은 다음에 디렉토리를 가진다.
- CentOS: /usr/lib/systemd
- Ubuntu: /lib/systemd
한가지 특징이 있는데, CentOS 경우에는 전역 systemd 디렉토리가 한가지이지만 Ubuntu 의 경우에는 /lib/systemd외에 /usr/lib/systemd 도 존재하는데 /usr/lib/systemd 는 user 영역을 위한 것이다.
커스터마이징 전역 systemd 영역
앞서 살펴본 디렉토리는 배포판의 패키지를 설치할 경우에 사용되어진다. 하지만 이것외에 별도에 설치한 데몬 프로그램을 전역 systemd 에 등록하고 싶다면 다음의 디렉토리를 사용한다.
- /etc/systemd
예를들어 컴파일 설치한 프로그램, 자바 프로그램의 경우에 systemd 에 등록해서 사용하자 한다면 위 디렉토리에 unit 파일을 작성하면 된다.
사용자 systemd 영역
systemd 는 자동으로 데몬으로 실행시켜 준다. 그런데, 이러한 실행은 systemd 라는 전역적인 권한을 가진 상태에서 이루어진다. 그렇다면 사용자가 자신만의 systemd 를 운영할 수 없지않을까 하는 아이디어로 나온것이 사용자 systemd 영역이다.
동작방법은 두가지로 나뉜다.
- 사용자가 시스템에 로그인을 할때 실행
- 시스템이 부팅할때에 사용자 systemd 영역도 함께 실행
그리고 사용자 systemd 영역은 사용자 홈디렉토리에 unit 파일을 작성해야 한다. 이 디렉토리는 다음의 위치에 존재한다.
- ~/.config/systemd/user
사용자 systemd 영역 실행은 다음의 명령어를 사용한다.
- systemctl –user
사용자 systemd 영역 동작 방법
잠깐 어떻게 이게 가능한지를 설명해 본다. 이 기본적인 동작을 위해서는 PAM 이 실행되어야 하는데 /etc/pam.d/systemd-user 파일이 이 일을 하게 해준다. 이 파일은 대략 다음과 같다.
1 |
session optional pam_systemd.so |
이 PAM 모듈은 사용자가 로그인을 하게 되면 자동으로 systemd –user 명령을 실행해준다. 그리고 로그아웃을 하게되면 systemd –user 로 실행된 프로세스는 종료된다.
기본 설정
모든 사용자 systemd 영역 파일들은 ~/.config/systemd/user 에 존재하게 된다. 처음 로그인을 할때에 서비스가 실행되길 원한다면 다음과 같이 서비스를 활성화 할 수 있다.
1 |
]$ systemctl --user enable service |
한가지 팁(Tip) 으로, 만일 root 사용자라면 모든 시스템 사용자의 사용자 systemd 영역 서비스를 다음과 같이 할 수 있다.
1 |
]# systemctl --user --global enable service |
환경 변수
서비스 데몬들이 실행될때에도 환경 변수들이 필요하다. 예를들어, PATH 같은 것이 대표적이다. 문제는 사용자 systemd 영역 서비스 데몬들은 .bashrc 파일에 정의된 환경변수들을 계승하지 않는다. 이것은 environment.d 디렉토리에 정의하는데 위치는 ~/.config/environment.d/ 이며 여기에 .conf 확장자를 가지는 파일을 작성하는데 INI 형식인 NAME=VAL 식으로 작성한다.
전역적인 환경변수 파일은 다음에 위치한다. 이 파일들은 모든 사용자 unit 파일에 영향을 준다.
- /etc/environment.d/*.conf
- /usr/lib/environment.d/*.conf
- /etc/environment
모든 사용자 unit 에 영향을 주는 기본 환경변수인 DefaultEnvironment 는 /etc/systemd/user.conf 도 있다.
기존의 환경 변수들을 추가할 수도 있다. 예를들어, PATH 라는 환경변수는 사용자마다 가장 많이 커스터마이징되는 변수다. 이러한 변수를 systemd 에서 환경변수로 등록하고자 한다면 다음과 같이 해준다.
1 2 |
]$ ~/.bashrc ]$ systemctl --user import-environment PATH |
사용자 systemd 영역에 설정된 변수들을 보고 싶다면 다음과 같이 하면 된다.
1 |
]$ systemctl --user show-environment |
사용자 systemd 자동 실행
systemctl –user 사용은 사용자가 로그인을 해야만 실행이되며 사용자 세션이 닫히면, 사용자가 로그아웃을 하면 자동으로 종료 된다. 하지만 사용자의 로그인/로그아웃에 상관없이 서버가 부팅되면 자동으로 실행되고 서버가 종료되어야만 중지되게 하고 싶다면 어떻게 할가?
이것은 로그인 관련된 내용으로 링거링(Lingering) 설정에 영향을 받는다.
1 |
]$ loginctl enable-linger $USER |
multi-user.target 문제
systemd unit 파일 작성할때에 어떤 환경에서 실행될 것인지를 명시하기 위해서 다음과 같이 작성한다.
1 2 |
[Install] WantedBy=multi-user.target |
그런데, ‘systemctl –user’ 를 사용할때에는 multi-user.target 사용해서는 안된다. 이는 –user 에서 사용할 수 있는 타켓이 제한되어 있기 때문인데, 다음과 같이 확인이 가능하다.
1 2 3 4 5 |
]$ ls /usr/lib/systemd/user basic.target default.target grub-boot-success.service shutdown.target sound.target systemd-tmpfiles-setup.service bluetooth.target exit.target grub-boot-success.timer smartcard.target systemd-exit.service timers.target dbus.service graphical-session-pre.target paths.target sockets.target systemd-tmpfiles-clean.service timers.target.wants dbus.socket graphical-session.target printer.target sockets.target.wants systemd-tmpfiles-clean.timer |
위에 리스트를 보면 multi-user.target 은 존재하지 않는다. 따라서 ‘systemd –user’ 사용을 위한 systemd 유닛 파일을 작성할때에는 default.target 을 사용하는 것이 적절하다.
1 2 |
[Install] WantedBy=default.target |
ElasticSearch 에 대한 systemd unit 파일 예제.
이제 간단하게 예제하나를 작성해 보자.
전문 검색 엔진인 ElasticSearch 는 자바를 기반으로 작동한다. 그러다보니 반드시 root 로 실행할 필요가 없다. 실제로 대부분 자바기반의 서비스들은 일반 계정으로 실행하는게 대부분이다.
unit 파일에 대해서 먼저 알아둘 필요가 있다. 이 파일들은 대체로 다음에 위치한다.
- /usr/lib/systemd/systemd: 설치된 패키지에 의해서 제공된 units
- /etc/systemd/systemd: 시스템 관리자에 의해서 제공된 units
하지만 사용자 systemd 영역을 사용할 것임으로 앞에서 언급한 대로 사용자 홈디렉토리에 관련 디렉토리를 생성해 준다.
1 2 |
]$ mkdir -p ~/.config/environment.d ]$ mkdir -p ~/.config/systemd/user |
자바 프로그램은 자바를 필요로하는데, 설치가 되어 있다고 하더라도 PATH, JAVA_HOME 등의 환경변수를 설정해 줘야 한다. systemd 가 알아차릴 환경변수는 environment.d 에서 작성해야 함으로 java.conf 파일을 다음과 같이 작성해 준다.
1 2 3 |
JAVA_HOME="/opt/java" JRE_HOME="/opt/java/jre" PATH="$PATH:$JAVA_HOME/bin:$JRE_HOME/bin" |
이제 elasticsearch.service 를 다음과 같이 작성한다. 이 파일은 ElasticSearch 의 소스가 공개된 GitHub 에서 찾을 수 있다.
- elasticsearch/distribution/packages/src/common/systemd/elasticsearch.service
Ubuntu 1.604 에서 문제
한가지 문제가 있다. elasticsearch.service 파일을 보면 중간에 리소스를 조정해주는 내용이 나온다.
- LimitNOFILE=65536
- LimitNPROC=4096
그런데, 이 설정은 적용되지 않는다. Systemd 에서 시스템 자원 조정을 위한 파일들이 여럿 존재한다.
- /etc/systemd/system.conf
- /etc/systemd/system/user@1000.service.d/limit.conf – 1000 은 userid 값이다.
- .config/systemd/user/elasticsearch.service.d/limits.conf
여기서 3번째는 작동되지 않는다. 1번의 경우에는 전역적으로 모든 사용자에게 적용이 된다. 2번째 경우에는 사용자에게만 적용이 된다.
보통 시스템 리소스는 /etc/security/limits.conf 파일에서 조정하는게 보편적이지만 systemd 는 이처럼 자체적으로 리소스를 제어할 수 있도록 해준다.
systemctl –user 사용법
이제 elasticsearch.service 를 활성화하고 사용법을 익혀보자.
먼저 elasticsearch.service 를 다음과 같이 활성화 해준다.
1 |
]$ systemctl --user enable elasticsearch.service |
그리고 서비스 시작/중지는 사용자 계정으로 로그인을 하면 자동으로 시작되며 로그아웃을 하면 중지된다. 하지만 수동으로 시작,중지를 하고 싶다면 다음과 같이 하면 된다.
1 |
]$ systemctl --user [start/stop] elasticsearch.serivce |