Systemd 타겟 이해하기: 핵심 개념 설명

systemd 타겟, 기본 부트 타겟, 런레벨 매핑, 격리, 사용자 정의 타겟 및 문제 해결 명령어를 이해합니다.

Systemd 타겟 이해하기: 핵심 개념 설명

Systemd 타겟은 서비스로 생각하지 않으면 이해하기 쉽습니다. 서비스는 프로세스를 시작합니다. 타겟은 유닛을 명명된 시스템 상태로 그룹화합니다. 시스템이 multi-user.target으로 부팅될 때, systemd는 "multi-user"라는 프로그램을 시작하는 것이 아닙니다. 해당 타겟이 원하는 유닛이 시작되었거나 최소한 시작 작업이 시도된 상태에 도달하려고 하는 것입니다.

이러한 구분은 부팅 문제를 디버깅할 때 도움이 됩니다. graphical.target이 느리다면, 타겟 자체가 문제인 경우는 드뭅니다. 해당 타겟으로 끌어들인 디스플레이, 로그인, 네트워크, 마운트 또는 애플리케이션 유닛 중 하나가 느리거나 실패하는 것입니다. 타겟은 지도를 제공합니다.

Systemd 타겟이란 무엇인가?

systemd 생태계에서 타겟은 중요한 조직적 목적을 제공하는 특별한 유형의 유닛 파일(예: .service 또는 .socket 파일)입니다. 특정 프로세스를 시작하거나 중지하는 방법을 정의하는 서비스 유닛과 달리, 타겟 유닛은 시스템 상태 또는 함께 활성화되어야 하는 유닛 모음을 정의합니다. 이들은 다른 systemd 유닛의 논리적 그룹화 지점 및 동기화 지점 역할을 합니다.

타겟을 시스템 운영 여정의 이정표로 생각하십시오. systemd가 부팅될 때, 임의로 서비스 목록을 시작하는 것이 아니라 특정 타겟을 달성하기 위해 작업합니다. 이 타겟은 차례로 해당 상태를 충족하는 데 필요한 모든 서비스, 소켓, 마운트 지점 및 기타 타겟을 끌어들입니다. 이러한 종속성 기반 접근 방식은 예측 가능하고 효율적인 부팅 프로세스를 보장합니다.

SysVinit와 같은 이전 Linux init 시스템에 익숙한 사람들에게 systemd 타겟은 런레벨의 현대적인 등가물입니다. SysVinit에는 고정된 런레벨 세트(예: 다중 사용자 텍스트 모드의 런레벨 3, 다중 사용자 그래픽 모드의 런레벨 5)가 있었지만, systemd 타겟은 더 유연합니다. 이름으로 지정되며 숫자가 아니며 사용자 정의 타겟을 정의할 수 있어 더 큰 세분성과 확장성을 제공합니다.

타겟 작동 방식: 그룹화 및 종속성

타겟은 유닛 파일 내에 정의된 명시적 종속성을 통해 그룹화 및 상태 정의 기능을 달성합니다. 이를 위해 사용되는 주요 지시문은 Wants=, Requires=, After=Before=입니다.

  • Wants=: "약한" 종속성을 지정합니다. target Aunit BWants=하면, systemd는 target A가 활성화될 때 unit B를 시작하려고 시도합니다. 그러나 unit B가 시작에 실패하더라도 target A는 계속 시작됩니다. 이는 바람직하지만 필수적이지 않은 관련 서비스를 그룹화하는 데 일반적으로 사용됩니다.
  • Requires=: "강한" 종속성을 지정합니다. target Aunit BRequires=하면, target A가 활성화되려면 unit B가 성공적으로 시작되어야 합니다. unit B가 실패하면 target A도 실패하거나 시작되지 않습니다. 이는 중요한 종속성에 사용됩니다.
  • After=: 순서 종속성을 정의합니다. target AAfter= unit B가 있으면, target Aunit B가 시작된 후에만 시작됩니다. 이는 성공에 대한 종속성을 의미하지 않으며 순서만 의미합니다.
  • Before=: After=의 반대입니다. target ABefore= unit B가 있으면, unit Btarget A가 시작된 후에만 시작됩니다.
  • Conflicts=: 특정 유닛이 동시에 활성화되지 않도록 합니다. target Aunit BConflicts=하면, target A를 활성화하면 실행 중인 unit B가 중지되고 그 반대의 경우도 마찬가지입니다.

이러한 지시문을 통해 타겟은 강력한 오케스트레이터 역할을 하여 필요에 따라 서비스 및 기타 타겟을 끌어들이고 시작 순서를 정의할 수 있습니다. 예를 들어, multi-user.target은 일반적으로 network.target 및 다양한 기타 서비스를 Wants=하여 시스템이 다중 사용자 상태에 도달할 때 활성화되도록 합니다.

타겟 유닛 파일의 내용을 검사하여 종속성을 확인할 수 있습니다:

systemctl cat multi-user.target

이 명령은 multi-user.target 유닛 파일의 내용을 출력하여 Description, Documentation, 그리고 중요한 것은 다중 사용자 상태를 구성하는 Wants=, Requires=, After= 및 기타 지시문을 보여줍니다.

일반적인 Systemd 타겟 설명

Systemd는 각각 특정 시스템 상태 또는 기능에 해당하는 다양한 사전 정의된 타겟을 제공합니다. 이를 이해하는 것은 시스템 관리에 중요합니다:

  • default.target: 시스템이 부팅될 기본 상태를 정의하므로 가장 중요한 타겟입니다. 일반적으로 graphical.target(데스크탑용) 또는 multi-user.target(서버용)에 대한 심볼릭 링크입니다.
  • graphical.target: 이 타겟은 일반적으로 그래픽 데스크탑 환경이 있는 시스템에 사용됩니다. multi-user.target을 끌어들이고 그래픽 로그인 관리자 및 디스플레이 서버(예: GDM, LightDM, Xorg, Wayland)에 필요한 서비스를 추가합니다.
  • multi-user.target: 그래픽 인터페이스가 없는 다중 사용자 시스템의 표준 상태입니다. 서버에 일반적이며 명령줄 액세스, 네트워킹 및 대부분의 데몬 작업에 필요한 모든 서비스를 제공합니다.
  • basic.target: 기본 작업에 필요한 기본 시스템 서비스를 포함하지만 multi-user.target 이전의 최소 상태입니다. 일반적으로 sysinit.target 및 기타 필수 서비스를 끌어들입니다.
  • sysinit.target: 이 타겟은 부팅 프로세스 초기에 도달합니다. /etc/fstab 파일 시스템 마운트(원격 파일 시스템 제외), 스왑 설정 및 기타 하드웨어 관련 초기화와 같은 핵심 시스템 초기화 작업을 담당합니다.
  • local-fs.target: /etc/fstab에 지정된 모든 로컬 파일 시스템이 마운트되었는지 확인합니다.
  • remote-fs.target: /etc/fstab에 지정된 모든 원격 파일 시스템(예: NFS, CIFS)이 마운트되었는지 확인합니다.
  • network.target: 기본 네트워크 연결이 가능함을 나타냅니다(예: 네트워크 인터페이스가 작동 중). 완전한 인터넷 연결 또는 IP 주소 할당을 보장하지는 않습니다.
  • network-online.target: 네트워크 관리자가 네트워크가 온라인 상태라고 간주할 때까지 기다리려는 서비스를 위한 동기화 지점입니다. 인터넷, DNS 또는 원격 API에 연결할 수 있음을 증명하지 않으며 관련 wait-online 서비스가 활성화된 경우에만 예상대로 작동합니다.
  • rescue.target: 최소한의 서비스가 실행되고 로컬 파일 시스템이 마운트된 단일 사용자 셸을 제공합니다. 시스템 복구 및 문제 해결에 유용합니다.
  • emergency.target: rescue.target보다 더 최소한의 환경입니다. 일반적으로 읽기 전용으로 마운트된 루트 파일 시스템에서 셸을 제공합니다. 다른 서비스는 시작되지 않습니다. 중요한 비상 상황에 사용됩니다.
  • poweroff.target, reboot.target, halt.target: 이 타겟은 각각 시스템을 종료, 재시작 또는 중단하는 데 사용됩니다. 활성화되면 대부분의 서비스를 중지하고 원하는 전원 상태를 위해 시스템을 준비합니다.

Systemd 타겟 관리

systemd 타겟과의 상호 작용은 주로 systemctl 명령줄 유틸리티를 통해 이루어집니다.

활성 및 기본 타겟 보기

시스템이 현재 실행 중인 타겟을 확인하려면:

systemctl get-default

현재 로드된 모든 타겟 유닛을 나열하려면:

systemctl list-units --type=target

이 명령은 설명과 함께 활성, 로드 및 정적 타겟을 표시합니다.

기본 부트 타겟 변경

시스템이 기본적으로 부팅되는 타겟을 변경할 수 있습니다. 예를 들어, multi-user.target을 기본값으로 설정하려면:

sudo systemctl set-default multi-user.target

graphical.target으로 되돌리려면:

sudo systemctl set-default graphical.target

이 명령은 /etc/systemd/system/default.target에서 원하는 타겟 파일로의 심볼릭 링크를 생성합니다.

임시로 다른 타겟으로 부팅

때로는 한 번만 특정 타겟으로 부팅해야 할 때가 있습니다(예: 문제 해결). 부팅 중에 커널 매개변수를 추가하여 이를 수행할 수 있습니다. GRUB 부팅 메뉴가 나타나면 부팅 항목을 편집하고(보통 e 키를 눌러) 커널 명령줄에 systemd.unit=target_name.target을 추가합니다.

예를 들어, 복구 모드로 부팅하려면:

systemd.unit=rescue.target

런타임 중 타겟 전환

systemctl isolate 명령을 사용하여 시스템이 실행 중인 동안 다른 타겟으로 전환할 수 있습니다. 이 명령은 새 타겟에 필요하지 않은 모든 서비스를 중지하고 새 타겟에 필요한 모든 서비스를 시작합니다.

경고: systemctl isolate를 사용하면 시스템 작동이 중단될 수 있습니다. 특히 데스크탑 시스템에서 graphical.target에서 multi-user.target과 같은 훨씬 낮은 수준의 타겟으로 전환하는 경우 주의하십시오.

graphical.target에서 multi-user.target으로 전환하려면:

sudo systemctl isolate multi-user.target

graphical.target으로 돌아가려면(이전 상태였다고 가정):

sudo systemctl isolate graphical.target

사용자 정의 타겟 생성

systemd는 많은 유용한 타겟을 제공하지만 사용자 정의 타겟을 생성하는 것이 유리한 상황이 있을 수 있습니다. 이는 특히 항상 함께 시작 및 중지되어야 하는 여러 서비스를 그룹화하거나 애플리케이션에 대한 특정 환경을 정의해야 하는 복잡한 애플리케이션 배포에서 그렇습니다.

사용자 정의 타겟을 생성하려면:

  1. .target 파일 생성: /etc/systemd/system/에 배치합니다. 예: my-application.target.
    # /etc/systemd/system/my-application.target
    [Unit]
    Description=My Custom Application Target
    Wants=my-database.service my-webserver.service
    After=my-database.service my-webserver.service
    
    • Description: 사람이 읽을 수 있는 설명.
    • Wants=: 이 타겟이 끌어들여야 할 서비스 또는 기타 타겟을 나열합니다.
    • After=: 순서를 정의합니다. 타겟은 이러한 유닛 후에 시작됩니다.
  2. 서비스 생성: my-database.servicemy-webserver.service(또는 나열한 모든 서비스)가 존재하고 올바르게 구성되었는지 확인합니다.
  3. systemd 다시 로드: 새 유닛 파일에 대해 systemd에 알립니다.
    
    

sudo systemctl daemon-reload 4. **활성화 및 시작**: 이제 사용자 정의 타겟을 활성화하고 시작할 수 있으며, 그러면 원하는 서비스가 시작됩니다. bash sudo systemctl enable my-application.target sudo systemctl start my-application.target ```

이를 통해 관련 서비스 그룹을 단일 논리 단위로 관리하여 복잡한 애플리케이션 배포를 단순화할 수 있습니다.

런레벨 및 타겟 (추상적인 설명 없이)

SysVinit에서 왔다면 대략적인 매핑은 다음과 같습니다:

이전 런레벨 개념 일반적인 systemd 타겟
단일 사용자 복구 모드 rescue.target
다중 사용자 텍스트 모드 multi-user.target
다중 사용자 그래픽 모드 graphical.target
재부팅 reboot.target
전원 끄기 poweroff.target

이것을 완벽한 모델이 아닌 번역 도구로 취급하십시오. SysV 런레벨은 작고 고정된 번호 상태 집합이었습니다. Systemd 타겟은 종속성이 있는 명명된 유닛이며 여러 개가 있을 수 있습니다. 패키지는 자체 타겟을 설치할 수 있습니다. 배포 워크플로우를 위해 하나를 만들 수 있습니다. 일부 타겟은 격리되도록 설계되었습니다. 다른 타겟은 부팅 중에 사용되는 그룹화 지점일 뿐입니다.

다음을 사용하여 격리를 허용하는 타겟을 확인할 수 있습니다:

systemctl show multi-user.target -p AllowIsolate
systemctl show basic.target -p AllowIsolate

이것은 systemctl isolate가 무해한 "보기 전환" 명령이 아니기 때문에 중요합니다. 새 타겟 트랜잭션의 일부가 아닌 유닛을 중지합니다. 데스크탑에서 multi-user.target을 격리하면 일반적으로 그래픽 세션이 중지됩니다. 원격 서버에서 잘못된 타겟을 격리하면 네트워킹 또는 로그인 서비스가 중지되어 잠길 수 있습니다.

서비스가 타겟의 일부가 되는 방법

대부분의 일상적인 타겟 멤버십은 서비스 파일의 [Install] 섹션에서 비롯됩니다:

[Install]
WantedBy=multi-user.target

다음을 실행할 때:

sudo systemctl enable myapp.service

systemd는 다음과 같은 디렉토리 아래에 심볼릭 링크를 생성합니다:

/etc/systemd/system/multi-user.target.wants/myapp.service

이 심볼릭 링크는 부팅 중에 multi-user.target이 서비스를 원하게 만듭니다. 서비스 파일은 활성화되지 않고 존재하고 완전히 유효할 수 있습니다. 이 경우 multi-user.target을 시작해도 자동으로 서비스가 끌어들여지지 않습니다.

이것이 systemctl start myapp.servicesystemctl enable myapp.service가 다른 문제를 해결하는 이유입니다. start는 지금 실행합니다. enable은 미래의 부트 타겟에 연결합니다. enable --now는 둘 다 수행합니다.

서비스가 타겟에 대해 활성화되었는지 확인하려면:

systemctl is-enabled myapp.service
systemctl list-dependencies multi-user.target | grep myapp

서비스가 수동으로 시작되지만 부팅 시 시작되지 않는 경우, 이것이 가장 먼저 확인해야 할 사항 중 하나입니다.

실제로 유용한 작은 사용자 정의 타겟

사용자 정의 타겟은 운영자에게 관련 유닛 그룹에 대한 하나의 명령을 제공할 때 가장 유용합니다. 간단한 애플리케이션 스택을 상상해보십시오:

app-api.service
app-worker.service
app-scheduler.service

다음을 생성할 수 있습니다:

# /etc/systemd/system/app-stack.target
[Unit]
Description=Application stack
Wants=app-api.service app-worker.service app-scheduler.service
After=network-online.target
Wants=network-online.target
AllowIsolate=no

그런 다음 각 서비스를 타겟에 추가합니다:

[Install]
WantedBy=app-stack.target

daemon-reload 후 원하는 동작에 따라 서비스 또는 타겟을 활성화합니다:

sudo systemctl daemon-reload
sudo systemctl enable app-api.service app-worker.service app-scheduler.service
sudo systemctl start app-stack.target

이것은 타겟이 프로세스 감독자라고 가장하지 않고 읽기 쉬운 그룹화를 제공합니다. app-worker.service가 실패하면 해당 서비스를 검사하십시오. 타겟은 단지 그룹화 지점일 뿐입니다.

타겟을 중지하면 모든 스택 서비스가 중지되도록 하려면 각 서비스에 PartOf=app-stack.target을 추가하십시오:

[Unit]
PartOf=app-stack.target

이제 systemctl stop app-stack.target이 멤버 서비스로 전파됩니다. 이것은 사용자 정의 타겟 예제에서 종종 누락된 부분입니다.

타겟을 사용한 문제 해결

타겟은 부팅 문제 또는 서비스 실패를 해결하는 데에도 매우 중요합니다:

  • 종속성 식별: 서비스가 시작에 실패하면 해당 서비스가 속한 타겟을 검사하여 누락되거나 실패한 종속성을 찾을 수 있습니다. systemctl status <service_name>systemctl list-dependencies <target_name>을 사용하십시오.
  • 최소 타겟으로 부팅: 시스템이 graphical.target 또는 multi-user.target으로 부팅되지 않으면 커널 매개변수 방법을 사용하여 rescue.target 또는 emergency.target으로 부팅해 보십시오. 이는 많은 실행 서비스의 복잡성 없이 문제를 진단할 수 있는 최소 환경을 제공합니다.
  • 로그 확인: 타겟 또는 서비스 시작을 시도한 후 항상 journalctl 로그에서 오류를 확인하십시오:
    journalctl -b -u <target_or_service_name>
    

모범 사례 및 팁

  • network-online.target을 신중하게 사용: 서비스가 시작 전에 네트워크 구성이 필요한 경우 After=network-online.targetWants=network-online.target을 결합하고 적절한 wait-online 유닛이 활성화되었는지 확인하십시오. 그래도 원격 종속성에 대한 재시도 로직을 애플리케이션에 유지하십시오.
  • 부팅 순서 이해: sysinit.target에서 basic.target, 그 다음 multi-user.target/graphical.target으로의 일반적인 흐름을 숙지하십시오. 이는 부팅 프로세스 초기에 실패하는 서비스를 디버깅하는 데 도움이 됩니다.
  • default.target에 주의: default.target을 변경하면 시스템의 부팅 동작이 크게 변경될 수 있습니다. 항상 프로덕션이 아닌 환경에서 사용자 정의 구성을 먼저 테스트하십시오.
  • 비핵심 종속성에는 Wants= 사용: 타겟이 "작동 중"으로 간주되는 데 엄격히 필요하지는 않지만 유용한 서비스의 경우 Requires= 대신 Wants=를 사용하십시오. 이는 단일 선택적 서비스 실패가 연쇄적으로 발생하여 전체 타겟 활성화를 방해하는 것을 방지합니다.

유지해야 할 정신 모델

타겟은 데몬이 아닌 명명된 상태입니다. default.target은 일반 부팅 대상을 결정합니다. multi-user.target은 일반적인 서버 상태입니다. graphical.target은 디스플레이 스택을 추가합니다. rescue.targetemergency.target은 복구 도구입니다. 사용자 정의 타겟은 작업을 더 명확하게 할 때 그룹화 도구입니다.

타겟 관련 문제가 발생하면 먼저 타겟을 비난하지 마십시오. 어떤 유닛이 끌어들여졌는지, 어떤 순서 규칙이 지연시켰는지, 어떤 종속성이 실패했는지 물어보십시오. systemctl cat, systemctl list-dependencies, systemctl showjournalctl -b는 일반적으로 일반 부팅 다이어그램을 읽는 것보다 이러한 질문에 더 빨리 답할 것입니다.