LFCS 2노드 실습 서비스 준비
NFS, iSCSI, DNS, NTP, HTTP backend, LDAP client와 libvirt 실습에 필요한 재현 가능한 fixture 준비
이 문서는 LFCS task의 정답이 아니라 client/server 실습을 재현하기 위한 fixture다. 복원 가능한 전용 VM에서만 사용하고 운영 network·directory·storage에 적용하지 않는다. package·service 이름과 설정 문법은 현재 배포판의 local documentation에서 다시 확인한다.
작성·검증 상태: AI 보조 초안이다. RHEL 10·upstream 공식 문서와 정적으로 대조했지만, 모든 fixture를 동일한 깨끗한 2노드 Rocky Linux 10 VM에서 연속 실행한 상태는 아니다. 각 절의 검증이 통과하기 전에는 다음 lab의 전제조건으로 사용하지 않는다.
fixture의 역할
한 대의 VM만으로는 다음 competency의 실제 동작을 충분히 확인하기 어렵다.
- DNS와 time server
- OpenSSH client/server
- NFS와 iSCSI
- packet forwarding·NAT·static route
- reverse proxy·load balancer
- LDAP identity client
실습 환경 구성의 2-node topology를 먼저 준비한다.
| 이름 | 주소 | 역할 |
|---|---|---|
lfcs-node1.lab.example | 192.168.56.11 | client, initiator, proxy, 관리 대상 |
lfcs-node2.lab.example | 192.168.56.12 | DNS, NTP, NFS, iSCSI target, HTTP backend |
| private network | 192.168.56.0/24 | 외부와 분리된 실습망 |
주소와 interface 이름은 자신의 실습망에 맞게 치환한다.
1. 시작 전 snapshot과 상태
두 VM을 정상 종료한 상태에서 10-two-node-clean snapshot을 만든다. 부팅한 뒤 양쪽에서 기록한다.
hostname
cat /etc/os-release
ip -brief address
ip route
ss -lntup
systemctl --failed
getenforce 2>/dev/null || true
firewall-cmd --get-active-zones 2>/dev/null || true
node1에서 node2의 private address가 도달하는지 확인한다.
ping -c 2 192.168.56.12
아직 DNS fixture가 없으므로 먼저 양쪽 /etc/hosts에 관리용 이름을 추가할 수 있다.
192.168.56.11 lfcs-node1.lab.example lfcs-node1
192.168.56.12 lfcs-node2.lab.example lfcs-node2
기존 중복 entry가 없는지 확인한 뒤 추가하고 getent hosts로 NSS 결과를 검증한다.
IPv6 실습을 함께 할 경우 private connection에 documentation prefix 주소도 둔다. PRIVATE_CONNECTION은 각 VM의 실제 connection profile 이름으로 치환한다.
# node1
nmcli connection modify PRIVATE_CONNECTION \
ipv6.method manual ipv6.addresses 2001:db8:56::11/64
# node2
nmcli connection modify PRIVATE_CONNECTION \
ipv6.method manual ipv6.addresses 2001:db8:56::12/64
각 VM의 console에서 profile을 다시 올린 뒤 주소와 양방향 ping을 확인한다. management connection은 수정하지 않는다.
2. package 준비
모든 package를 무조건 설치하지 말고 각 fixture를 만들 때 필요한 묶음만 설치한다. RHEL-compatible 예:
node1
dnf install -y \
man-db man-pages git acl attr \
lvm2 xfsprogs e2fsprogs nfs-utils autofs iscsi-initiator-utils \
chrony openssh-clients firewalld nftables NetworkManager \
nginx haproxy podman policycoreutils-python-utils \
qemu-kvm libvirt libvirt-daemon-config-network virt-install qemu-img \
sssd sssd-ldap sssd-tools openldap-clients oddjob-mkhomedir \
sysstat iotop lsof tcpdump bind-utils nmap-ncat openssl \
at cronie
node2
dnf install -y \
bind bind-utils chrony openssh-server \
nfs-utils targetcli python3 firewalld tcpdump
repository와 배포판 minor version에 따라 package 이름·가용성이 다를 수 있다. 실패한 package 하나 때문에 전체 묶음을 반복하지 말고 dnf info, dnf provides, 활성 repository에서 해당 기능을 제공하는 package를 찾는다.
설치 검증:
rpm -q bind chrony nfs-utils targetcli python3
command -v named chronyd exportfs targetcli python3
node2의 SSH server도 fixture로 준비하고 private zone에 SSH를 허용한다.
systemctl enable --now sshd
ss -lntp | grep ':22 '
firewall-cmd --permanent --zone=ZONE --add-service=ssh
firewall-cmd --reload
container task를 offline 상태에서도 반복하려면 network가 되는 준비 단계에서 사용할 image를 cache한다. tag가 실제로 pull되었는지 확인하고, 모의시험 도중 다른 tag로 바꾸지 않는다.
podman pull docker.io/library/nginx:stable-alpine
podman image exists docker.io/library/nginx:stable-alpine
podman image inspect docker.io/library/nginx:stable-alpine \
--format '{{.Id}} {{.RepoTags}}'
3. DNS fixture
이 fixture는 node2를 lab.example의 authoritative test DNS로 사용한다. 전용 VM의 기존 BIND 설정을 먼저 백업한다.
node2 설정
cp -a /etc/named.conf /etc/named.conf.before-lfcs
/etc/named.conf의 최소 학습용 예:
options {
listen-on port 53 { 127.0.0.1; 192.168.56.12; };
listen-on-v6 port 53 { ::1; 2001:db8:56::12; };
directory "/var/named";
allow-query { localhost; 192.168.56.0/24; 2001:db8:56::/64; };
recursion no;
};
zone "lab.example" IN {
type master;
file "lab.example.zone";
};
/var/named/lab.example.zone:
$TTL 300
@ IN SOA ns1.lab.example. hostmaster.lab.example. (
2026081301 3600 900 604800 300 )
IN NS ns1.lab.example.
ns1 IN A 192.168.56.12
lfcs-node1 IN A 192.168.56.11
lfcs-node2 IN A 192.168.56.12
app IN A 192.168.56.12
nfs IN A 192.168.56.12
iscsi IN A 192.168.56.12
lfcs-node1 IN AAAA 2001:db8:56::11
lfcs-node2 IN AAAA 2001:db8:56::12
app IN AAAA 2001:db8:56::12
문법·label·service를 확인한다.
chown root:named /var/named/lab.example.zone
chmod 0640 /var/named/lab.example.zone
restorecon -Rv /etc/named.conf /var/named
named-checkconf
named-checkzone lab.example /var/named/lab.example.zone
systemctl enable --now named
firewalld가 active인 경우 private NIC가 속한 zone을 확인하고 그 zone에만 DNS service를 허용한다.
firewall-cmd --get-active-zones
firewall-cmd --permanent --zone=ZONE --add-service=dns
firewall-cmd --reload
firewall-cmd --zone=ZONE --list-services
node1 검증
먼저 DNS server 자체에 직접 질의한다.
dig @192.168.56.12 app.lab.example A
dig @192.168.56.12 lab.example SOA
그 다음 사용 중인 network manager에서 private connection의 DNS를 설정하고 NSS까지 확인한다.
nmcli connection show
nmcli connection modify PRIVATE_CONNECTION \
ipv4.dns 192.168.56.12 \
ipv4.dns-search lab.example \
ipv4.ignore-auto-dns yes
nmcli connection up PRIVATE_CONNECTION
getent hosts app.lab.example
management NIC의 public DNS를 보존해야 한다면 private profile이 모든 query의 유일한 DNS가 되지 않도록 split DNS·priority를 현재 NetworkManager 문서에서 확인한다.
static route·forwarding·NAT용 destination
node2 뒤에 실제 destination이 있어야 node1의 static route와 forwarding·source NAT를 packet으로 검증할 수 있다. node2의 network namespace와 veth pair로 폐기 가능한 downstream network를 만든다. network namespace와 veth는 reboot 때 사라지므로 전용 oneshot unit이 시작할 때 다시 만들게 한다.
install -d -m 0755 /usr/local/libexec
cat > /usr/local/libexec/lfcs-dst-fixture <<'EOF'
#!/usr/bin/bash
set -eu
if ip netns list | awk '{print $1}' | grep -Fxq lfcs-dst; then
ip link show dst-host >/dev/null
ip netns exec lfcs-dst ip link show dst-ns >/dev/null
ip -4 address show dev dst-host | grep -Fq '198.51.100.1/24'
ip netns exec lfcs-dst ip -4 address show dev dst-ns |
grep -Fq '198.51.100.2/24'
ip netns exec lfcs-dst ip route show default |
grep -Fq 'default via 198.51.100.1'
exit 0
fi
if ip link show dst-host >/dev/null 2>&1; then
printf 'STOP: dst-host exists without the expected namespace\n' >&2
exit 1
fi
ip netns add lfcs-dst
ip link add dst-host type veth peer name dst-ns
ip link set dst-ns netns lfcs-dst
ip address add 198.51.100.1/24 dev dst-host
ip link set dst-host up
ip netns exec lfcs-dst ip link set lo up
ip netns exec lfcs-dst ip address add 198.51.100.2/24 dev dst-ns
ip netns exec lfcs-dst ip link set dst-ns up
ip netns exec lfcs-dst ip route add default via 198.51.100.1
EOF
chmod 0755 /usr/local/libexec/lfcs-dst-fixture
/etc/systemd/system/lfcs-dst-fixture.service:
[Unit]
Description=LFCS downstream network namespace fixture
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/libexec/lfcs-dst-fixture
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
systemd-analyze verify /etc/systemd/system/lfcs-dst-fixture.service
systemctl daemon-reload
systemctl enable --now lfcs-dst-fixture.service
ip -brief address show dev dst-host
ip netns exec lfcs-dst ip -brief address
ip netns exec lfcs-dst ping -c 2 198.51.100.1
systemctl is-enabled lfcs-dst-fixture.service
systemctl is-active lfcs-dst-fixture.service
node1에 198.51.100.0/24 via 192.168.56.12 route를 추가하고 node2에서 forwarding과 filter/NAT를 구성하면 ping 198.51.100.2로 end-to-end 경로를 확인할 수 있다. namespace 쪽에서 source address를 관찰하면 masquerade 적용 여부도 구분할 수 있다. fixture snapshot을 만들기 전에 한 번 reboot하고 unit이 namespace를 재생성하는지도 확인한다.
4. isolated NTP fixture
node2는 외부 time source가 없어도 local reference로 보이는 연습용 server가 된다. 실제 정확한 시간 서비스로 사용하지 않는다.
node2
기존 /etc/chrony.conf를 한 번만 백업하고 전용 drop-in을 읽게 한다. 이미 confdir /etc/chrony.d가 있으면 중복 추가하지 않는다.
test -e /etc/chrony.conf.before-lfcs || \
cp -a /etc/chrony.conf /etc/chrony.conf.before-lfcs
install -d -m 0755 /etc/chrony.d
grep -Eq '^[[:space:]]*confdir[[:space:]]+/etc/chrony\.d([[:space:]]|$)' \
/etc/chrony.conf || printf '\nconfdir /etc/chrony.d\n' >> /etc/chrony.conf
/etc/chrony.d/60-lfcs-server.conf:
local stratum 10
allow 192.168.56.0/24
allow 2001:db8:56::/64
chronyd -p
systemctl enable --now chronyd
systemctl restart chronyd
chronyc tracking
ss -lunp | grep ':123 '
firewalld가 active이면 private zone에 NTP를 허용한다.
firewall-cmd --permanent --zone=ZONE --add-service=ntp
firewall-cmd --reload
node1
기존 public source를 보존해야 하는지 task 조건을 먼저 정한다. fixture에서는 node2 전용 source file을 추가한다.
test -e /etc/chrony.conf.before-lfcs || \
cp -a /etc/chrony.conf /etc/chrony.conf.before-lfcs
install -d -m 0755 /etc/chrony.d
grep -Eq '^[[:space:]]*confdir[[:space:]]+/etc/chrony\.d([[:space:]]|$)' \
/etc/chrony.conf || printf '\nconfdir /etc/chrony.d\n' >> /etc/chrony.conf
/etc/chrony.d/60-lfcs-client.conf:
server 192.168.56.12 iburst prefer
chronyd -p
systemctl restart chronyd
chronyc sources -v
chronyc tracking
chronyd active만으로 synchronization을 증명하지 못한다. source marker, reachability, stratum과 reference를 확인한다.
5. HTTP backend 두 개
reverse proxy와 load balancer 실습에서 서로 다른 응답을 내는 backend를 node2에 만든다. Python HTTP server는 fixture일 뿐 LFCS 정답 command가 아니다.
content와 environment file
install -d -m 0755 \
/srv/lfcs-backend/one \
/srv/lfcs-backend/two \
/etc/lfcs-backend
printf 'backend-one\n' > /srv/lfcs-backend/one/index.html
printf 'backend-two\n' > /srv/lfcs-backend/two/index.html
cat > /etc/lfcs-backend/one <<'EOF'
PORT=8081
ROOT=/srv/lfcs-backend/one
EOF
cat > /etc/lfcs-backend/two <<'EOF'
PORT=8082
ROOT=/srv/lfcs-backend/two
EOF
template unit
/etc/systemd/system/lfcs-backend@.service:
[Unit]
Description=LFCS fixture HTTP backend %i
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
EnvironmentFile=/etc/lfcs-backend/%i
ExecStart=/usr/bin/python3 -m http.server ${PORT} --bind 192.168.56.12 --directory ${ROOT}
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemd-analyze verify /etc/systemd/system/lfcs-backend@.service
systemctl daemon-reload
systemctl enable --now lfcs-backend@one.service lfcs-backend@two.service
systemctl --no-pager --full status \
lfcs-backend@one.service lfcs-backend@two.service
ss -lntp | grep -E ':8081|:8082'
필요하면 private zone과 source subnet으로 범위를 제한해 두 port를 연다. node1에서 실제 응답을 확인한다.
firewall-cmd --permanent --zone=ZONE --add-port=8081/tcp
firewall-cmd --permanent --zone=ZONE --add-port=8082/tcp
firewall-cmd --reload
curl http://192.168.56.12:8081/
curl http://192.168.56.12:8082/
한 backend를 중지해 proxy failover를 시험하고, 끝나면 다시 시작한다.
systemctl stop lfcs-backend@one.service
systemctl start lfcs-backend@one.service
6. NFS fixture
node2 export
같은 numeric UID·GID로 쓰기 동작을 검증할 전용 account를 양쪽 VM에 준비한다.
getent group lfcslab >/dev/null || groupadd -g 4900 lfcslab
getent passwd labwriter >/dev/null || \
useradd -u 4900 -g 4900 -m -s /bin/bash labwriter
install -d -o labwriter -g lfcslab -m 2770 /srv/nfs/projects
printf 'nfs fixture\n' > /srv/nfs/projects/README.txt
chown labwriter:lfcslab /srv/nfs/projects/README.txt
/etc/exports.d/lfcs.exports:
/srv/nfs/projects 192.168.56.0/24(rw,sync,root_squash)
client와 options 사이에 공백을 넣지 않는다. client(options)와 client (options)는 export 범위가 달라질 수 있다.
systemctl enable --now nfs-server
exportfs -rav
exportfs -v
firewalld가 active이고 showmount까지 연습한다면 private zone에 필요한 NFS service를 연다.
firewall-cmd --permanent --zone=ZONE --add-service=nfs
firewall-cmd --permanent --zone=ZONE --add-service=rpc-bind
firewall-cmd --permanent --zone=ZONE --add-service=mountd
firewall-cmd --reload
node1 client 확인
getent group lfcslab >/dev/null || groupadd -g 4900 lfcslab
getent passwd labwriter >/dev/null || \
useradd -u 4900 -g 4900 -m -s /bin/bash labwriter
showmount -e 192.168.56.12
install -d -m 0755 /mnt/nfs-fixture
mount -t nfs -o vers=4 192.168.56.12:/srv/nfs/projects /mnt/nfs-fixture
findmnt /mnt/nfs-fixture
runuser -u labwriter -- touch /mnt/nfs-fixture/from-node1.txt
stat -c '%U:%G %a %n' /mnt/nfs-fixture/from-node1.txt
NFS identity는 이름이 아니라 numeric UID·GID 매핑과 server 정책의 영향을 받는다. root write 실패를 no_root_squash로 곧바로 우회하지 않는다.
7. iSCSI fixture
이 fixture는 node2의 file-backed LUN 하나를 node1에 제공한다. LUN 파일은 실제 data가 없는 실습 전용이다.
node1 initiator IQN 확인
rpm -q iscsi-initiator-utils
grep '^InitiatorName=' /etc/iscsi/initiatorname.iscsi
InitiatorName= 뒤의 전체 IQN을 node2의 ACL 값으로 사용한다.
node2 target
install -d -m 0700 /var/lib/lfcs-iscsi
systemctl enable --now target
targetcli interactive shell에서 현재 tree를 확인한 뒤 생성한다. 아래 INITIATOR_IQN은 node1의 실제 값으로 치환한다.
targetcli
/> ls
/> backstores/fileio create name=lfcs_lun file_or_dev=/var/lib/lfcs-iscsi/lun0.img size=2G
/> iscsi/ create iqn.2026-08.example.lab:storage.lun0
/> iscsi/iqn.2026-08.example.lab:storage.lun0/tpg1/portals ls
# 0.0.0.0:3260 portal이 표시될 때만 다음 delete 실행
/> iscsi/iqn.2026-08.example.lab:storage.lun0/tpg1/portals delete 0.0.0.0 3260
/> iscsi/iqn.2026-08.example.lab:storage.lun0/tpg1/portals create 192.168.56.12 3260
/> iscsi/iqn.2026-08.example.lab:storage.lun0/tpg1/luns create /backstores/fileio/lfcs_lun
/> iscsi/iqn.2026-08.example.lab:storage.lun0/tpg1/acls create INITIATOR_IQN
/> saveconfig
/> ls
/> exit
target 생성 시 기본 0.0.0.0:3260 portal이 자동으로 생겼다면 private address portal을 만들기 전에 현재 tree를 확인하고 전용 lab target의 wildcard portal만 제거한다. 다른 target의 portal을 삭제하지 않는다.
firewall-cmd --permanent --zone=ZONE --add-port=3260/tcp
firewall-cmd --reload
ss -lntp | grep ':3260'
targetcli ls
node1 discovery와 login
login 전 block device 목록을 저장한다.
lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,MOUNTPOINTS \
> /root/lsblk.before-iscsi.txt
iscsiadm -m discovery -t sendtargets -p 192.168.56.12:3260
iscsiadm -m node \
-T iqn.2026-08.example.lab:storage.lun0 \
-p 192.168.56.12:3260 --login
iscsiadm -m session -P 1
lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,MOUNTPOINTS
새 device 이름을 sdb라고 가정하지 않는다. session 상세와 /dev/disk/by-path/를 연결한다.
ls -l /dev/disk/by-path | grep -i iscsi
filesystem을 만들기 전 새 device가 정확히 2 GiB fixture LUN이고 mount·PV signature가 없는지 확인한다.
logout 전에는 LUN 위 filesystem·LVM·swap이 사용 중이지 않은지 확인한다.
findmnt
swapon --show
pvs
iscsiadm -m session
8. bridge·bond용 interface
영속적인 bridge·bond와 failover를 제대로 검증하려면 node1에 management NIC 외에 최소 세 개의 실습 NIC를 추가하는 편이 가장 단순하다.
| interface 역할 | 수량 |
|---|---|
| management | 1 |
| bridge port | 1 |
| active-backup bond slaves | 2 |
hypervisor에서 NIC를 추가한 뒤 MAC address와 guest interface 이름을 연결한다.
ip -brief link
nmcli -f GENERAL.DEVICE,GENERAL.HWADDR,GENERAL.STATE device show
추가 physical/virtual NIC가 없으면 dummy·veth로 object 관계만 연습할 수 있지만 실제 carrier loss와 hypervisor switch 경로를 검증한 것으로 세지 않는다. 네트워킹 실습의 Green 판정에는 별도 NIC에서 failover까지 확인한다.
9. libvirt fixture
node1 안에서 guest domain을 실제 실행하려면 nested virtualization과 libvirt daemon이 필요할 수 있다. 먼저 환경 구성의 nested virtualization 항목을 확인한다.
rpm -q qemu-kvm libvirt virt-install
# RHEL 10의 modular libvirt daemon socket을 현재 session에서 시작한다.
for drv in qemu network nodedev nwfilter secret storage interface; do
systemctl start virt${drv}d{,-ro,-admin}.socket
done
virt-host-validate
systemctl list-unit-files | grep -E 'libvirtd|virtqemud'
virsh uri
virsh list --all
Rocky/RHEL minor version이나 다른 배포판에서 daemon 구조가 다르면 존재하지 않는 unit 이름을 추측하지 않는다. 설치된 libvirt package 문서와 systemctl list-unit-files 'virt*d*.socket' 결과를 기준으로 현재 환경의 socket 또는 monolithic libvirtd를 시작한다.
XML에 연결할 default virtual network도 확인한다. inactive이면 시작하고, host boot 뒤에도 사용할 fixture라면 autostart를 켠다.
virsh net-list --all
virsh net-info default
# Active가 no일 때만 실행
virsh net-start default
virsh net-autostart default
virsh net-info default
default network가 없으면 이름을 추측해 XML 생성을 진행하지 않는다. RHEL-compatible 환경에서는 libvirt-daemon-config-network 설치 여부와 virtnetworkd socket 상태를 확인한다.
연습용 empty qcow2와 persistent XML을 만든다. bootable OS가 없는 disk이므로 이 fixture의 목적은 domain definition·start·autostart·block/interface 조회이며 guest OS login이 아니다.
install -d -m 0711 /var/lib/libvirt/images
qemu-img create -f qcow2 /var/lib/libvirt/images/web01.qcow2 2G
virt-install \
--name web01 \
--memory 768 \
--vcpus 1 \
--disk path=/var/lib/libvirt/images/web01.qcow2,format=qcow2 \
--network network=default,model=virtio \
--osinfo detect=off,name=generic \
--import \
--print-xml > /root/web01.xml
virt-xml-validate /root/web01.xml domain
virsh dominfo web01 2>/dev/null && \
printf 'STOP: web01 is already defined; restore the clean fixture snapshot\n' >&2 || true
현재 virt-install version에서 option이 다르면 virt-install --help와 installed documentation을 사용한다. 이미 web01 domain이나 image가 있으면 덮어쓰지 않고 다른 전용 이름을 사용한다. 이 fixture는 XML과 disk만 준비하고 domain을 정의하지 않는다. 정의·시작·autostart는 실제 libvirt lab에서 수행한다.
10. LDAP client fixture의 경계
LFCS의 공개 competency는 시스템이 LDAP user·group account를 사용하도록 구성하는 것이다. LDAP server 자체 구축은 별도의 복잡한 주제이므로 실전에서는 제공된 다음 정보를 client가 정확히 소비하는 연습에 집중한다.
LDAP URI
Base DN
test user와 group
server certificate를 서명한 CA chain
anonymous search 또는 bind DN 정책
authentication 방식
provider는 node2의 Red Hat Directory Server/389 Directory Server, OpenLDAP 또는 별도 폐기 가능한 directory lab을 사용할 수 있다. provider 준비 완료 조건:
- forward/reverse에 필요한 이름 해석 또는 확정 hostname
- node1과 동기화된 시간
- TLS certificate의 SAN에 접속 hostname 포함
- CA certificate를 node1에 안전하게 전달
- POSIX attribute가 있는 test user·group
- test password와 허용된 search base
- local recovery account와 console
provider 확인:
openssl s_client -connect ldap.lab.example:636 \
-servername ldap.lab.example \
-verify_hostname ldap.lab.example \
-verify_return_error \
-CAfile /path/to/lab-ca.pem </dev/null
LDAPTLS_CACERT=/path/to/lab-ca.pem \
ldapsearch -x -H ldaps://ldap.lab.example \
-b dc=lab,dc=example '(uid=TEST_USER)' dn uid uidNumber gidNumber
TLS와 directory search가 먼저 성공한 뒤 사용자·그룹 고급 lab의 SSSD client 구성을 수행한다. provider를 직접 만들 때는 아래 official Directory Server 설치 절차를 따르고 비밀번호를 command line·shell history·공개 문서에 넣지 않는다.
11. fixture 완료 점검
node1에서:
getent hosts app.lab.example
chronyc sources -v
curl http://192.168.56.12:8081/
curl http://192.168.56.12:8082/
showmount -e 192.168.56.12
iscsiadm -m discovery -t sendtargets -p 192.168.56.12:3260
nc -zv -w 3 192.168.56.12 22
systemctl is-enabled lfcs-dst-fixture.service
ip netns exec lfcs-dst ping -c 2 198.51.100.1
virsh net-info default
virt-xml-validate /root/web01.xml domain
각 command의 성공이 해당 전체 competency의 완료를 의미하지는 않는다. fixture가 준비됐다는 뜻일 뿐, 실제 task에서 client 설정·영속성·오류 복구를 별도로 수행한다.
완료 뒤 두 VM을 정상 종료하고 20-fixtures-ready snapshot을 만든다. 모의시험은 이 snapshot보다 더 깨끗한 상태 또는 문제별 제공 상태에서 시작한다.
12. fixture 정리 기준
가장 안전한 정리는 10-two-node-clean snapshot 복원이다. 수동 정리가 필요하다면 dependency 역순으로 진행한다.
- node1의 NFS mount와 iSCSI 위 filesystem·LVM·swap 사용 해제
- iSCSI logout·node record 삭제
- node2 target ACL·LUN·target·backstore 삭제
- NFS client unmount 후 export 제거
- HTTP fixture unit disable·stop, unit과 content 제거
- DNS·chrony 설정을 백업본으로 복원
- downstream namespace fixture unit을 disable·stop하고 전용 namespace·veth만 제거
- firewall에서 이 fixture에 추가한 rule만 제거
각 단계에서 다른 lab·service가 같은 객체를 사용하지 않는지 먼저 확인한다. nft flush ruleset, 전체 LVM·target 삭제처럼 범위가 넓은 정리 명령은 사용하지 않는다.