LabHub
배우기 러닝패스 코스

LFCS — 리눅스 재단 시스템 관리자 · libvirt 와 LDAP — 개념으로 · 이론

VM 은 XML 한 장이고, 계정은 nsswitch 가 정한다 — libvirt 와 LDAP

LabHub 에서 이어서 보기

한 줄 요약

LFCS 의 Operations 도메인에는 "libvirt 로 가상 머신을 만들고 관리하라" 가, Users and Groups 도메인에는 "LDAP 계정을 구성하라" 가 있다. 둘 다 이 플랫폼의 VM 안에서 실제로 하기에는 무겁다(중첩 가상화, LDAP 서버). 그래서 이 모듈은 개념만 다룬다. 핵심은 둘이다. libvirt 에서 VM 은 XML 문서 한 장이고 virsh 는 그 문서를 다루는 도구다. LDAP 계정은 /etc/passwd 를 대신하는 것이 아니라 nsswitch 가 정한 순서의 한 자리다.

왜 이게 필요했나

노드의 리눅스를 다루다 보면 두 상황을 만난다. 하나는 "이 서버 위에 VM 이 몇 개 도는데 하나가 안 뜬다" 이고, 다른 하나는 "이 계정은 /etc/passwd 에 없는데 로그인이 된다" 이다. 앞은 libvirt, 뒤는 LDAP/sssd 의 영역이다. 둘 다 시험 범위이고, 둘 다 "어디에 무엇이 적혀 있는가" 를 알면 절반이 풀린다.

이 실습 환경은 KubeVirt 위의 VM 이다. 그 안에서 다시 KVM 을 켜려면 중첩 가상화(vm_nested)가 필요하고, LDAP 서버를 세우고 클라이언트를 붙이는 것은 한 실습으로 담기엔 크다. 그래서 여기서는 문서에서 확인한 구조를 정리하고, 퀴즈로 점검한다.

어떻게 동작하나

libvirt 의 VM 은 도메인(domain)이라 부르고, XML 로 정의된다. [libvirt 도메인 XML 형식](https://libvirt.org/formatdomain.html) 문서가 그 문법 전체다. 최상위 <domain type='kvm'> 아래에 <name>, <memory>, <vcpu>, <os>(부팅 방식), <devices>(디스크·네트워크·콘솔) 가 온다. 디스크는 <disk type='file' device='disk'> 안의 <source file='…'/><target dev='vda' bus='virtio'/> 로 "어느 파일을 게스트의 어느 장치로" 를 적는다. 네트워크는 <interface type='network'> 가 libvirt 가 관리하는 가상 네트워크(기본 default, NAT)에 붙고, <interface type='bridge'> 가 호스트 브리지에 붙는다.

[virsh](https://libvirt.org/manpages/virsh.html) 는 그 XML 을 다루는 셸이다. 자주 쓰는 동사를 상태 전이로 보면 외우기 쉽다.

| 하는 일 | 명령 | 비고 |
| --- | --- | --- |
| 정의만(정지 상태로 등록) | virsh define 파일.xml | 영구 도메인 |
| 정의하고 바로 시작 | virsh create 파일.xml | 일시(transient) 도메인 |
| 시작 / 정상 종료 / 강제 종료 | virsh start / shutdown / destroy | destroy 는 전원 차단이다 |
| 정의 삭제 | virsh undefine | 디스크 파일은 남는다 |
| 정의 보기 / 편집 | virsh dumpxml / virsh edit | edit 은 검증 뒤 저장 |
| 목록 | virsh list --all | --all 이 없으면 도는 것만 |
| 부팅 때 자동 시작 | virsh autostart | |

destroy 라는 이름이 함정이다. 지우는 것이 아니라 전원을 뽑는 것이고, 정의는 남는다. 정의를 지우는 것은 undefine 이며, 그것도 디스크 이미지는 지우지 않는다.

스냅샷은 두 종류다. [libvirt 스냅샷 안내](https://libvirt.org/kbase/snapshots.html) 는 내부(internal) 스냅샷과 외부(external) 스냅샷을 구분한다. 내부 스냅샷은 qcow2 이미지 안에 상태를 담고, 외부 스냅샷은 새 오버레이 파일을 만들어 원본을 읽기 전용 백킹으로 둔다. [스냅샷 XML 형식](https://libvirt.org/formatsnapshot.html) 이 <domainsnapshot> 문서를 정의하고, virsh snapshot-create-as 로 만든다. 디스크만 담는 스냅샷과 메모리 상태까지 담는 스냅샷이 다르다는 것, 그리고 외부 스냅샷의 체인은 관리(블록 커밋)가 필요하다는 것이 실무에서 부딪히는 자리다.

LDAP 계정은 nsswitch 의 한 줄에서 시작한다. [nsswitch.conf(5)](https://man7.org/linux/man-pages/man5/nsswitch.conf.5.html) 는 passwd, group, shadow 같은 데이터베이스마다 "어느 소스를 어느 순서로" 를 정한다. passwd: files sss 는 먼저 /etc/passwd 를 보고 없으면 sssd 에 묻는다는 뜻이다. getent passwd 이름 이 이 순서를 그대로 타므로, "이 계정은 어디서 오는가" 를 묻는 첫 명령이 getent 다.

그 뒤에 있는 것이 [SSSD](https://sssd.io/docs/introduction.html) 다. sssd 는 LDAP·Kerberos·AD 같은 원격 계정 저장소와 로컬 시스템 사이의 데몬으로, NSS(계정 조회)와 PAM(인증) 양쪽에 모듈을 제공하고 오프라인 캐시를 둔다. 그래서 LDAP 서버가 잠시 죽어도 캐시된 계정은 로그인이 된다. 설정은 /etc/sssd/sssd.conf 의 도메인 절에 id_provider = ldap, ldap_uri, ldap_search_base 를 적는 형태이고, RHEL 9 의 [인증과 권한 구성 문서](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_authentication_and_authorization_in_rhel/index) 가 authselect 로 nsswitch 와 PAM 을 함께 맞추는 절차를 설명한다.

LDAP 자체를 두드리는 도구는 [ldapsearch](https://www.openldap.org/software/man.cgi?query=ldapsearch) 다. -H ldap://서버 로 어디에, -b "dc=example,dc=com" 으로 어느 가지 아래에서, -x 로 단순 인증으로, 마지막 인자가 필터((uid=alice))다. 결과는 LDIF 로 나오고 uid, uidNumber, gidNumber, homeDirectory, loginShell 같은 posixAccount 속성이 곧 /etc/passwd 의 열과 대응한다. sssd 가 못 찾는 계정을 ldapsearch 로 직접 찾아보는 것이 진단의 기본이다.

현장에서 만나는 모습

"VM 이 안 뜬다" 는 virsh list --all 로 상태를 보고 virsh dumpxml 로 디스크 <source file> 이 실제로 있는지 본다. 스토리지를 옮긴 뒤 경로가 낡아 있는 경우가 흔하다. virsh destroy 를 "삭제" 로 오해해 급히 눌렀다가 서비스가 끊기는 사고도 드물지 않다.

"LDAP 사용자가 로그인이 안 된다" 는 순서대로 좁힌다. getent passwd 이름 이 비어 있으면 NSS(nsswitch·sssd 조회) 문제이고, 나오는데 로그인이 안 되면 PAM(인증) 문제다. sssd 의 캐시 때문에 서버를 고친 뒤에도 옛 결과가 남을 수 있어 sss_cache -E 로 비우고 다시 본다. 그리고 ldapsearch 로 서버에서 직접 그 항목이 조회되는지가 마지막 분기다.

다음 퀴즈에서 확인할 것

virsh definecreate 의 차이, destroyundefine 이 각각 무엇을 남기는지, 도메인 XML 에서 디스크가 어느 요소에 적히는지, 내부·외부 스냅샷의 차이, nsswitch.confpasswd: files sss 가 뜻하는 순서, sssd 가 NSS 와 PAM 에서 하는 일, ldapsearch-b 와 필터. 퀴즈는 이 읽기에서 설명한 것만 묻는다.