Ubuntu 24.04에서 systemctl로 실패한 서비스를 확인하고 원인을 분석하는 방법

안녕하세요. 일본서버, 미국서버 호스팅 전문 지구 IDC 기술팀입니다.

오늘은 Ubuntu 24.04에서 systemctl로 실패한 서비스를 확인하고 원인을 분석하는 방법을 알아보겠습니다. 서버 부팅 후 일부 기능이 동작하지 않거나 애플리케이션이 갑자기 중지되었다면 서비스를 무조건 재시작하기보다 어떤 systemd 유닛이 failed 상태인지 먼저 확인하고, 종료 코드와 journal 로그를 기준으로 원인을 좁혀야 합니다.

Ubuntu 24.04는 systemd 255 계열을 사용합니다. systemctl --failed로 실패한 유닛을 찾고, systemctl status, systemctl show, journalctl -u를 함께 사용하면 실행 파일 누락, 잘못된 설정, 권한 문제, 의존성 실패, 포트 충돌, 디스크 부족, OOM, 시작 제한과 같은 대표 원인을 단계적으로 확인할 수 있습니다.

적용 환경

문서 적용 기준
항목 내용
운영체제 Ubuntu 24.04 LTS
서비스 관리자 systemd / systemctl
로그 조회 journalctl
예시 서비스명 SERVICE_NAME.service — 실제 서비스 유닛명으로 변경

실패한 서비스를 분석하는 순서

  1. systemctl --failed --type=service로 서버 전체의 실패 서비스를 확인합니다.
  2. systemctl status로 Active, Result, 종료 코드와 최근 로그를 확인합니다.
  3. systemctl show로 정규화된 실패 결과와 실행 상태를 확인합니다.
  4. journalctl -u로 현재 부팅에서 발생한 전체 오류 흐름을 확인합니다.
  5. 유닛 파일과 drop-in, 실행 파일, 사용자·그룹, 설정 파일과 의존성을 점검합니다.
  6. 포트 충돌, 디스크·inode 부족, 읽기 전용 파일시스템, OOM, AppArmor 등 시스템 원인을 확인합니다.
  7. 원인을 수정한 뒤 서비스를 다시 시작하고 필요할 때만 reset-failed를 사용합니다.

서버 전체에서 실패한 서비스 확인

가장 먼저 현재 systemd가 failed 상태로 기록하고 있는 서비스 유닛을 확인합니다.

systemctl --failed --type=service --no-pager

출력에서 UNIT, LOAD, ACTIVE, SUB, DESCRIPTION을 확인합니다. 실제 분석 대상은 ACTIVE 또는 SUB에 failed가 표시된 서비스입니다.

서비스뿐 아니라 mount, socket, timer 등 모든 실패 유닛을 확인하려면 유형 제한 없이 실행합니다.

systemctl --failed --no-pager

시스템 전체 운영 상태도 확인할 수 있습니다.

systemctl is-system-running

running이면 systemd 관점에서 정상 운영 상태이며, degraded는 하나 이상의 유닛이 실패했지만 시스템 자체는 계속 운영 중인 상태를 의미합니다.

개별 서비스 상태와 종료 코드 확인

실패한 서비스 이름을 확인했다면 전체 상태를 줄임 없이 출력합니다. 아래의 SERVICE_NAME.service는 실제 유닛명으로 변경하십시오.

sudo systemctl status SERVICE_NAME.service -l --no-pager

특히 다음 항목을 확인합니다.

  • Loaded: 유닛 파일이 정상적으로 로드되었는지, masked 또는 bad-setting 상태인지 확인합니다.
  • Active: failed가 된 시간과 현재 상태를 확인합니다.
  • Result: exit-code, timeout, signal, oom-kill, start-limit-hit 등 실패 종류를 확인합니다.
  • ExecStart 관련 줄: 실제 실행 명령과 status= 값을 확인합니다.
  • 상태 출력 하단: 서비스가 실패하기 직전 journal 메시지를 확인합니다.

복잡한 상태 출력에서 핵심 속성만 분리하려면 systemctl show를 사용합니다.

systemctl show SERVICE_NAME.service \
  -p LoadState \
  -p ActiveState \
  -p SubState \
  -p Result \
  -p MainPID \
  -p ExecMainCode \
  -p ExecMainStatus \
  -p FragmentPath

systemctl status는 사람이 읽기 좋은 형태의 진단에 적합하고, systemctl show는 서비스 상태와 결과 값을 속성별로 정확하게 확인할 때 유용합니다.

서비스가 부팅 시 자동 시작되도록 설정되었는지 여부는 별도로 확인합니다.

systemctl is-enabled SERVICE_NAME.service
systemctl is-active SERVICE_NAME.service
systemctl is-failed SERVICE_NAME.service

enabled는 부팅 또는 의존 관계를 통해 활성화될 수 있도록 등록된 상태이고, active는 현재 실행 상태입니다. 두 값은 서로 다른 개념입니다.

journalctl로 서비스 실패 시점 로그 분석

systemctl status에는 최근 로그 일부만 표시되므로 정확한 원인을 찾으려면 서비스별 journal을 확인해야 합니다. 현재 부팅에서 해당 서비스가 기록한 로그를 최근 200줄 기준으로 확인합니다.

sudo journalctl -u SERVICE_NAME.service -b -n 200 --no-pager

오류 우선순위만 빠르게 확인하려면 다음 명령을 사용합니다.

sudo journalctl -u SERVICE_NAME.service -b -p err --no-pager

서비스를 다시 시작하면서 발생하는 로그를 실시간으로 확인하려면 첫 번째 터미널에서 다음 명령을 실행합니다.

sudo journalctl -fu SERVICE_NAME.service

다른 터미널에서 서비스를 시작하거나 재시작합니다.

sudo systemctl restart SERVICE_NAME.service

부팅 직후부터 서비스가 실패한 경우 systemd 자체와 커널의 높은 우선순위 로그도 함께 확인합니다.

sudo journalctl -b -p err --no-pager
sudo journalctl -k -b -p warning --no-pager

유닛 파일과 drop-in 설정 확인

서비스 실행 명령, 사용자, 환경 변수 또는 override 설정이 잘못되면 패키지 자체가 정상이어도 서비스가 시작되지 않을 수 있습니다. systemd가 실제로 읽는 유닛과 drop-in 파일을 한 번에 확인합니다.

systemctl cat SERVICE_NAME.service

실제 유닛 파일 경로와 drop-in 경로도 확인합니다.

systemctl show SERVICE_NAME.service -p FragmentPath -p DropInPaths

직접 만든 서비스 또는 수동으로 수정한 유닛이라면 유닛 문법을 검증할 수 있습니다. 먼저 실제 경로를 확인한 뒤 해당 파일을 지정하십시오.

sudo systemd-analyze verify /etc/systemd/system/SERVICE_NAME.service

유닛 파일이나 drop-in을 수정했다면 systemd가 새 설정을 다시 읽도록 합니다.

sudo systemctl daemon-reload

daemon-reload는 systemd 설정을 다시 읽을 뿐 서비스를 자동으로 재시작하지 않습니다. 변경 내용을 적용하려면 원인을 수정한 뒤 해당 서비스를 별도로 재시작해야 합니다.

대표 systemd 종료 코드 해석

systemctl status의 status= 값은 문제 원인을 빠르게 좁히는 단서입니다. Ubuntu 24.04의 systemd는 프로세스 실행 준비 단계에서 실패한 경우 200번대의 systemd 전용 종료 코드를 사용할 수 있습니다.

자주 확인되는 종료 코드와 점검 방향
상태 의미 우선 점검
status=1/FAILURE 애플리케이션이 일반 실패 코드로 종료 journal과 애플리케이션 자체 로그, 설정 검사 명령
status=200/CHDIR WorkingDirectory=로 이동하지 못함 디렉터리 존재 여부, 권한, 마운트 상태
status=203/EXEC 실행 파일을 실제로 실행하지 못함 ExecStart= 경로, 실행 권한, shebang, 파일 존재 여부
status=216/GROUP 서비스 그룹 설정 실패 Group= 값과 그룹 존재 여부
status=217/USER 서비스 사용자 자격 설정 실패 User= 값, 계정 존재 여부와 사용자 DB 상태
Result=timeout 시작 또는 종료가 제한 시간 안에 완료되지 않음 서비스 내부 작업, 외부 DB·DNS·스토리지 의존성, timeout 설정
Result=oom-kill Out-Of-Memory 상황에서 프로세스 종료 메모리·swap 사용량, 커널 OOM 로그
Result=start-limit-hit 짧은 시간에 반복 실패하여 시작 제한 도달 최초 실패 원인 수정 후 reset-failed

200번대 종료 코드가 보일 때는 애플리케이션 설정 자체보다 systemd가 프로세스를 실행하기 전에 필요한 경로, 실행 파일, 사용자 또는 그룹을 준비하는 과정에서 실패했는지 먼저 확인하면 진단 시간을 줄일 수 있습니다.

의존성·마운트·네트워크 조건 확인

서비스 자체 설정이 정상이어도 필수 의존 유닛이 실패하면 시작되지 않을 수 있습니다. 의존 관계를 확인합니다.

systemctl list-dependencies SERVICE_NAME.service --no-pager

서버 전체의 실패 유닛과 비교하여 필요한 mount, socket, network 관련 유닛이 함께 실패했는지 확인합니다.

systemctl --failed --no-pager

서비스가 특정 파일시스템을 필요로 한다면 현재 마운트 상태를 확인합니다.

findmnt
findmnt /path/required/by/service

네트워크 연결 이후에만 정상 동작하는 서비스는 네트워크 상태와 DNS도 확인합니다.

ip -br addr
ip route
resolvectl status

의존성 오류가 보인다면 실패한 하위 유닛의 systemctl status와 journalctl -u를 별도로 확인해야 합니다. 상위 서비스만 반복 재시작해서는 근본 원인이 해결되지 않습니다.

권한·포트·디스크·OOM·AppArmor 점검

실행 파일과 경로 권한 확인

유닛의 ExecStart=, WorkingDirectory=, User=, Group= 값을 확인합니다.

systemctl show SERVICE_NAME.service \
  -p ExecStart \
  -p WorkingDirectory \
  -p User \
  -p Group

로그에 표시된 실제 실행 파일과 디렉터리의 존재·권한을 확인합니다.

ls -l /path/to/executable
namei -l /path/to/executable
getent passwd SERVICE_USER
getent group SERVICE_GROUP

SERVICE_USER, SERVICE_GROUP과 경로는 실제 유닛 설정에 맞게 변경하십시오.

포트 충돌 확인

웹 서버, 데이터베이스, 프록시처럼 특정 TCP/UDP 포트를 사용하는 서비스는 이미 다른 프로세스가 같은 포트를 점유하면 시작에 실패할 수 있습니다.

sudo ss -lntup

예를 들어 8080번 포트를 확인하려면 다음과 같이 범위를 좁힐 수 있습니다.

sudo ss -lntp 'sport = :8080'

포트를 점유한 정상 서비스를 원인 확인 없이 강제로 종료하지 말고 어느 프로세스가 필요한 포트를 사용해야 하는지 먼저 확인하십시오.

디스크 용량과 inode 확인

서비스가 PID 파일, 소켓, 로그, 임시 파일이나 데이터 파일을 생성하지 못하면 시작 실패로 이어질 수 있습니다.

df -hT
df -iT
findmnt -no TARGET,FSTYPE,OPTIONS /

No space left on device가 보이면 일반 저장 용량뿐 아니라 inode 사용률도 함께 확인합니다. 파일시스템이 ro로 마운트되어 있다면 커널·스토리지 오류부터 조사해야 하며 임의로 쓰기 가능 상태로 강제 전환하지 않는 것이 안전합니다.

OOM 종료 확인

Result=oom-kill 또는 메모리 부족이 의심되면 현재 메모리와 swap을 확인합니다.

free -h
swapon --show
sudo journalctl -k -b | grep -Ei 'out of memory|oom|killed process'

OOM이 확인되면 단순 재시작보다 메모리를 많이 사용하는 프로세스, 서비스의 메모리 제한, 동시 처리량과 swap 구성을 함께 점검해야 합니다.

AppArmor 차단 확인

Ubuntu는 AppArmor를 사용하므로 파일 권한이 정상이어도 보안 프로파일이 접근을 차단할 수 있습니다. 커널 로그에서 AppArmor 거부 기록을 확인합니다.

sudo journalctl -k -b | grep -i 'apparmor="DENIED"'

start-limit-hit 오류 해결

서비스가 짧은 시간 안에 반복적으로 실패하면 systemd의 시작 제한에 걸려 Result=start-limit-hit가 표시될 수 있습니다. 이 상태에서는 단순히 systemctl start를 반복하기보다 최초 실패 원인을 먼저 확인해야 합니다.

sudo systemctl status SERVICE_NAME.service -l --no-pager
sudo journalctl -u SERVICE_NAME.service -b --no-pager

유닛에 설정된 시작 제한과 자동 재시작 정책을 확인합니다.

systemctl show SERVICE_NAME.service \
  -p Restart \
  -p NRestarts \
  -p StartLimitIntervalUSec \
  -p StartLimitBurst

설정 오류나 실행 환경 문제를 수정한 뒤 실패 상태와 시작 제한 카운터를 초기화합니다.

sudo systemctl reset-failed SERVICE_NAME.service
sudo systemctl start SERVICE_NAME.service

조치 후 정상 상태 확인

원인을 수정했다면 서비스를 다시 시작하고 실행 상태를 확인합니다.

sudo systemctl restart SERVICE_NAME.service
systemctl is-active SERVICE_NAME.service
sudo systemctl status SERVICE_NAME.service -l --no-pager

is-active가 active이고 상태 출력에서 새로운 실패 메시지가 없는지 확인합니다. 서비스 특성상 정상 종료하는 oneshot 유닛은 별도의 정상 상태를 가질 수 있으므로 해당 유닛의 Type=과 설계도 함께 확인하십시오.

서비스가 정상화된 뒤 서버 전체의 실패 유닛도 다시 확인합니다.

systemctl --failed --type=service --no-pager
systemctl is-system-running

서비스는 복구되었지만 이전 실패 기록만 남아 있다면 원인을 해결한 것이 확인된 후 해당 유닛의 failed 상태를 초기화할 수 있습니다.

sudo systemctl reset-failed SERVICE_NAME.service

마지막으로 실제 서비스 기능도 검증하십시오. 웹 서버라면 HTTP 요청, 데이터베이스라면 로컬 접속, SSH라면 별도 터미널 접속처럼 애플리케이션 자체의 정상 동작까지 확인해야 합니다.

자주 발생하는 증상과 해결 방향

systemd 서비스 실패 진단표
증상 가능한 원인 확인 방법 해결 방향
status=203/EXEC 실행 파일 누락, 잘못된 경로 또는 실행 불가 systemctl cat, ls -l, namei -l ExecStart= 경로와 실행 권한, 스크립트 shebang 수정
status=217/USER 유닛에 지정한 사용자가 존재하지 않음 systemctl show -p User, getent passwd 올바른 서비스 계정 복구 또는 유닛 사용자 설정 수정
Address already in use 다른 프로세스가 동일 포트를 사용 중 ss -lntup 중복 서비스 또는 포트 설정을 확인하고 정상 서비스 기준으로 정리
Permission denied 파일 권한, 디렉터리 접근 권한 또는 AppArmor 차단 namei -l, 서비스 로그, AppArmor DENIED 로그 서비스 계정에 필요한 최소 권한과 프로파일 규칙만 수정
No space left on device 디스크 용량 또는 inode 소진 df -hT, df -iT 원인 데이터를 안전하게 정리하고 보존 정책 수정
Result=oom-kill 물리 메모리 부족 또는 서비스 메모리 한도 초과 free -h, 커널 OOM 로그, 서비스 자원 제한 메모리 사용 원인과 서비스 설정, swap·RAM 규모 점검
Result=start-limit-hit 반복 시작 실패로 rate limit 도달 최초 실패 로그, Restart=, 시작 제한 속성 근본 원인 수정 후 reset-failed하고 다시 시작
Dependency failed for ... 필수 mount, socket, target 또는 다른 서비스 실패 list-dependencies, 전체 failed 유닛 확인 실패한 하위 의존 유닛부터 복구

설정 변경 원상복구 방법

서비스 장애를 수정하는 과정에서 유닛 파일이나 drop-in을 변경해야 한다면 수정 전에 현재 설정을 백업하십시오.

sudo cp -a /etc/systemd/system/SERVICE_NAME.service \
  /etc/systemd/system/SERVICE_NAME.service.backup

패키지 제공 유닛은 직접 수정하기보다 systemctl edit로 drop-in을 사용하는 것이 좋습니다. 문제가 된 drop-in을 제거해 원래 패키지 설정으로 돌아가려면 먼저 적용된 파일을 확인합니다.

systemctl cat SERVICE_NAME.service
systemctl show SERVICE_NAME.service -p DropInPaths

직접 만든 잘못된 drop-in만 제거한 뒤 설정을 다시 읽습니다. 아래 경로는 실제 확인한 drop-in 파일로 변경하십시오.

sudo rm /etc/systemd/system/SERVICE_NAME.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart SERVICE_NAME.service

관련 지구 IDC 기술자료

공식 참고자료

기관 문서 확인 내용 조회일
Ubuntu Manpages systemctl(1) — Ubuntu 24.04 --failed, 상태 조회, is-system-running, failed 상태의 의미
Ubuntu Manpages journalctl(1) — Ubuntu 24.04 서비스별 -u, 현재 부팅 -b, 우선순위 필터와 로그 조회
Ubuntu Manpages systemd.exec(5) — Ubuntu 24.04 Result 값, OOM·timeout·start-limit 결과와 200번대 systemd 실행 종료 코드
Ubuntu Manpages systemd.unit(5) — Ubuntu 24.04 StartLimitIntervalSec, StartLimitBurst와 reset-failed의 시작 제한 카운터 초기화 동작
Canonical Ubuntu 24.04 LTS release notes Ubuntu 24.04 LTS 지원 상태와 지원 기간

자주 묻는 질문

systemctl --failed에 아무것도 나오지 않으면 모든 서비스가 정상인가요?

systemd가 현재 failed 상태로 기록한 유닛이 없다는 의미입니다. 그러나 애플리케이션 내부 오류, 응답 지연, 외부 DB 연결 실패처럼 프로세스 자체는 실행 중이지만 기능이 비정상인 문제까지 보장하지는 않습니다. 해당 서비스의 실제 기능과 애플리케이션 로그도 함께 확인해야 합니다.

서비스가 active인데 systemctl --failed에 과거 실패가 남을 수 있나요?

서비스의 현재 상태와 failed 기록은 상황에 따라 다르게 보일 수 있습니다. 현재 서비스가 정상화되었고 원인도 해결되었다면 systemctl reset-failed SERVICE_NAME.service로 기록과 시작 제한 카운터를 초기화할 수 있습니다.

systemctl status만 보면 충분하지 않나요?

systemctl status는 최근 로그 일부와 현재 상태를 빠르게 확인하는 데 적합하지만 전체 실패 흐름이 잘릴 수 있습니다. 원인 분석에는 journalctl -u SERVICE_NAME.service -b를 함께 사용하여 실패 전후 로그를 확인하는 것이 좋습니다.

systemctl reset-failed를 먼저 실행해도 되나요?

권장하지 않습니다. 이 명령은 실패 원인을 수정하지 않고 systemd가 보관한 failed 상태와 시작 제한 관련 카운터를 초기화합니다. 먼저 journal과 종료 코드를 기록하고 원인을 수정한 뒤 사용하는 편이 진단에 유리합니다.

서비스를 재설치하면 대부분 해결되나요?

아닙니다. 포트 충돌, 잘못된 사용자, 권한, AppArmor, 디스크 부족, 데이터 손상과 같은 문제는 패키지를 다시 설치해도 그대로 남을 수 있습니다. 재설치는 파일 누락이나 패키지 손상이 확인된 경우에만 검토하고, 데이터 디렉터리와 사용자 설정이 영향을 받지 않는지 먼저 확인하십시오.

마무리

오늘은 Ubuntu 24.04에서 systemctl --failed로 실패한 서비스를 확인하고, systemctl status, systemctl show, journalctl을 이용해 종료 코드와 실제 실패 원인을 분석하는 방법을 설명드렸습니다.

서비스가 시작되지 않을 때는 재설치나 강제 종료보다 로그와 유닛 설정을 먼저 확인하는 것이 중요합니다. 특히 203/EXEC, 217/USER, oom-kill, start-limit-hit 같은 상태 값은 점검 범위를 빠르게 줄이는 데 도움이 됩니다.

지구 IDC는 일본서버와 미국서버를 포함한 다양한 서버 호스팅 환경에서 안정적인 운영에 도움이 되는 기술정보를 지속적으로 제공하겠습니다.

  • 0 사용자에게 유용한 정보 제공
이 답변이 도움이 되었나요?
« Back