Fullmoon System

운영을 잇다 03 — 장애 전환과 복구로 검증한 인프라

EdwardMoon

이 글에 자주 나오는 용어
  • PROD·DEV·STG: 각각 운영·개발·검증 환경입니다.
  • HA(고가용성): 일부 서버가 고장 나도 다른 서버가 역할을 이어받도록 구성하는 방식입니다. 실제 전환 시간과 남는 장애 지점은 별도로 확인합니다.
  • Proxy·Bastion: Proxy는 모니터링 데이터를 모아 전달하는 중계 서버, Bastion은 관리자가 SSH로 접속할 때 거치는 경유 서버입니다.
  • 인벤토리·Workflow·Job: 각각 자동화 대상 서버 목록, 여러 작업을 연결한 실행 흐름, 개별 실행 작업입니다. 뒤의 번호는 실행 기록을 찾는 식별 번호입니다.
  • VIP·IPAM·쿼럼: VIP는 서비스 접속용 공용 가상 IP, IPAM은 IP 주소와 자산의 관계 관리, 쿼럼은 여러 노드가 과반수로 장애와 역할을 판단하는 기준입니다.

검증의 기준은 화면이 열리는지보다 데이터와 경로가 실제로 이어지는지다. 이 글은 2026년 9월 20일 VirtualBox 실습에서 실행한 작업과 관측 결과를 기록한다. 설계상의 기대, 실제 시험, 아직 수행하지 않은 범위를 구분한다.

이 글의 순서

1. 검증 환경과 판정 기준

Rocky Linux 10.2, Zabbix 7.0.30 LTS, NetBox 4.7.1, AWX 24.6.1을 사용했다. 중앙 두 VM과 quorum, Gateway, Provision, 세 환경의 Proxy/Bastion을 구성했다. 모든 VM은 한 물리 PC의 메모리·CPU·스토리지를 공유한다.

정상 등록과 운영 준비는 PXE 설치 → 승인된 SSH 경로 → 실제 자산 수집 → NetBox 네이티브 IPAM → Zabbix 등록 → NetBox 정보로 AWX 대상 서버 목록 동기화 → 실제 최신 값 확인까지 모두 성공해야 통과다. API 등록 응답과 최신 데이터 수신은 다른 체크 항목이다.

2. 실제 정상 서버 등록·운영 준비 기록

운영 환경 대상은 빈 32GiB 디스크와 내부망 네트워크 장치 하나로 설치했다. 경유 서버를 통한 SSH 접속으로 Rocky Linux 10.2, 관리 IP 10.77.20.101/24, SELinux 보안 정책 적용 상태와 PXE 설치 완료 표식을 확인했다. 설치 후 메모리를 4GiB에서 1GiB로 조정했다.

증거 관측 결과
AWX 자동화 실행 흐름(Workflow) 실행 #22 — 성공
서버 등록 작업 작업 #23 — 성공
NetBox 기반 대상 서버 목록 갱신 갱신 작업 #24 — 성공
결과 검증 작업 작업 #26 — 성공
Git 소스 버전 식별값(커밋) 58bb87b9842c159b1986784062916c4d9eb97c00
NetBox 자산 가상 서버 레코드 #1, fml-prod-app-01
IP 관계 네트워크 인터페이스 #1 → IP 주소 레코드 #1 → 대표 관리 IP 10.77.20.101/24
수집 상태 수집 완료, 수집 오류 없음
Zabbix 모니터링 대상 #10683 / 중계 서버 #1 / 적용 템플릿 #10343
실제 수집 서버 가동 시간 수집 항목(system.uptime) #50799 / 정상 상태 / 오류 없음

결과 검증 작업에서 서버의 실제 최신 가동 시간 데이터가 들어오는 것을 확인했다. 대상 등록 성공에 그치지 않고 모니터링 데이터 수집까지 이어졌다는 점을 통과 기준으로 삼았다.

NetBox에는 vCPU 1, 게스트 OS가 인식한 총메모리 954MiB, 디스크 32768MiB, Rocky Linux 10.2, 가상화 유형 VirtualBox, 관리 NIC enp0s3, PROD 환경과 실제 파티션 구조가 저장됐다. 게스트의 메모리 관측값 954MiB와 VirtualBox 할당값 1024MiB는 서로 다른 값이다.

AWX의 NetBox 기반 대상 서버 목록에는 ansible_host=10.77.20.101, ansible_user=labadmin, fml_environment=prod, fml_subnet=20이 들어왔다. 단순히 자산 이름만 동기화한 것이 아니라 관리 IP와 Bastion 경로 계산에 필요한 환경 변수를 함께 확인했다.

개발 환경도 빈 디스크에서 PXE 설치 후 자동화 실행 #30을 수행했다. 서버 등록 작업 #31, 대상 서버 목록 갱신 #32, 결과 검증 #34가 모두 성공했다. 모니터링 대상 #10684는 개발 환경 중계 서버 #2에 연결됐으며, 운영 환경과 분리된 경로에서 실제 데이터 수집을 확인했다.

STG는 설치 완료 감지로 자동 실행

STG의 첫 SSH 신원을 VirtualBox serial console의 공개키·fingerprint로 승인한 뒤 설치 RAM을 4GiB에서 1GiB로 줄였다. 설치 완료 컨트롤러가 승인 키, 설치 표식, hostname·운영체제 고유 식별값(machine ID)을 확인하고 Git 소스·최초 설치용 승인 서버 목록을 동기화했다. 이후 관리자가 실행 버튼을 누르지 않아도 자동화 실행 #38이 시작됐다.

STG 증거 결과
자동화 실행 #38 정상 동작 확인
서버 등록 / 대상 서버 목록 갱신 / 결과 검증 등록 작업 #39 / 목록 갱신 #40 / 검증 작업 #42 — 모두 성공
Git 소스 버전 식별값(커밋) 8877198864680095a1a8b5684d3382b9034237e9
NetBox 가상 서버 #3 → 네트워크 인터페이스 #3 → IP 주소 레코드 #3, 관리 IP 10.77.40.101/24
수집 상태 수집 완료, 수집 오류 없음
Zabbix 모니터링 대상 #10685 / 중계 서버 #3 / 서버 가동 시간 수집 항목 #51005
검증 데이터 실제 최신 데이터 수신 확인
컨트롤러 상태 해당 운영체제 고유 식별값(machine ID)와 자동화 실행 #38을 성공으로 저장

검증 환경에서도 실제 최신 모니터링 데이터를 확인했다. AWX의 대상 서버 목록에는 운영·개발·검증 환경의 세 서버와 각 관리 IP·환경 변수가 반영됐다. 최초 SSH 신원 승인은 관리자의 확인 단계로 유지했으며, 승인되지 않은 키를 우회해 연결하지 않았다.

3. 정상 경로까지 발견하고 수정한 문제

실행 실패 지점 원인과 수정
자동화 실행 #7 / 작업 #8 Agent RPM metadata 다운로드 Minimal ISO에 BaseOS/AppStream 경로가 없어 404. 실제 Minimal 저장소로 변경
자동화 실행 #12 / 작업 #13 NetBox API 로컬 작업 실행 전 인벤토리의 권한 상승 변수가 delegate_to localhost에도 적용되어 작업 실행환경에 설치되지 않은 sudo 호출
자동화 실행 #17 / 작업 #18 같은 로컬 작업 기존 대상 서버 목록의 변수 영향까지 고려해 task vars의 ansible_become=false와 작업 실행환경의 Python 경로를 명시
자동화 실행 #22 / 작업 #23·26 전체 흐름 자산·IPAM·관제 등록, 인벤토리 갱신, 실제 수집 검증 성공

실패한 작업도 삭제하지 않았다. 수정 커밋과 다음 작업의 실행 결과를 비교할 수 있게 남겼다. NetBox/Zabbix 등록 전에 실패한 경우를 실제 자산이 중복 생성된 상황과 혼동하지 않는다.

4. 백업과 격리 복원

NetBox 데이터베이스를 pg_dump로 백업하고 운영 DB와 분리된 검증용 DB에 pg_restore로 복원했다. 복원된 DB에서 기존 가상 서버 fml-prod-app-01과 대표 관리 IP의 연결이 유지되는지 확인했다.

백업 파일의 무결성을 비교하는 확인값(SHA-256)은 06914eb419d88edb97245ed435177b396309a625b65eb14b72ae9fb627667390이다. 기존 DB를 덮어쓰지 않고 별도의 검증 DB를 사용했다. 이 결과는 NetBox 논리 DB 복원 시험이며, 전체 VM·미디어·AWX·Git을 한 번에 복구한 재해 복구 시험은 아니다.

5. 중앙 노드 장애 시험

첫 시험 직전 PostgreSQL은 2호기(ops02)가 쓰기를 처리하고, 1호기(ops01)가 동기 복제로 대기했다. 보고된 복제 지연은 0이었다. Zabbix는 1호기가 실제 관제를 처리하고 2호기가 예비로 대기했다. 1호기 전원을 강제로 내려 VM 전원 손실을 재현했다.

VIP 10.77.10.10은 2호기로 이동했다. 그러나 전환 구간에서 NetBox 애플리케이션은 내부 서버 오류(HTTP 500)를, 실습 내부 공통 접속 주소는 서비스 이용 불가(HTTP 503)를 반환했다. Zabbix는 이후 2호기에서 active 작업을 시작하고 세 Proxy의 연결을 받았다. 이 시험을 ‘무중단 HA 성공’으로 판정하지 않았다.

관측 도구의 첫 로그 파일은 SELinux 정책과 맞지 않는 경로 때문에 생성되지 않았다. 따라서 그 시험에서 장애 발생부터 서비스 복구까지 걸린 시간을 정확하게 계산하지 않는다. 로깅 경로를 /var/log 아래로 옮기고 정상 기록을 확인한 후 재시험했다.

초기 장애 시험에서는 NetBox 캐시 연결의 재시도 때문에 응답 복구가 지연됐다. 실제 설정 코드를 확인한 뒤 로컬 Sentinel을 먼저 조회하고 연결·재시도 범위를 제한했다. 수정 후 같은 종류의 장애를 다시 시험했다.

수정 후 DB·Redis·Zabbix 활성 2호기 전원 손실

PostgreSQL·Redis·Zabbix의 활성 역할을 맡고 있던 중앙 2호기를 강제 종료했다. 중앙 1호기의 역할 전환과 각 서비스의 정상 응답을 확인했다. 전환 과정의 일시적인 응답 오류도 함께 기록했으며, 이를 무중단 전환으로 표현하지 않았다.

항목 검증 결과
1호기가 PostgreSQL 쓰기 담당 서버로 전환 정상 동작 확인
NetBox 기존 자산 API 조회 정상 동작 확인
Zabbix API 응답 정상 동작 확인
AWX 연결 상태 확인 응답 정상 동작 확인
장애 이후 수집 시각을 가진 Zabbix 값 정상 동작 확인

2호기가 꺼진 상태에서 NetBox 자산의 설명 필드에 시험 표식을 기록하고 다시 조회한 뒤 원래 내용으로 복원했다. 기존 자산과 관리 IP는 유지됐다. 조회뿐 아니라 살아남은 DB를 통한 쓰기까지 확인했다. AWX 상태 응답의 복구는 실행 중이던 자동화 작업의 무중단까지 검증한 결과는 아니다.

2호기를 다시 켠 뒤 PostgreSQL이 동기 복제 대기 상태로 복귀하고 NetBox도 정상 실행되는 것을 확인했다. 서비스가 살아남는 것과 장애 노드가 다시 예비 서버로 합류하는 것을 별도로 점검했다.

수정 후 VIP·DB·Zabbix 활성 1호기 전원 손실

반대 방향으로 중앙 1호기도 강제 종료했다. 중앙 2호기에서 공용 접속 IP와 PostgreSQL 쓰기 역할이 유지되고, NetBox 자산 조회와 Zabbix의 새로운 모니터링 데이터 수집이 재개되는 것을 확인했다. 자산 식별값과 관리 IP도 유지됐다.

AWX는 중앙 1호기에만 설치되어 있어 해당 서버가 꺼진 동안 사용할 수 없었다. 1호기를 다시 켜면 AWX가 재개됐고 DB 복제와 NetBox도 정상 상태로 돌아왔다. 이는 원래 서버 복구에 따른 서비스 재개이며 AWX 이중화 성공으로 판정하지 않았다.

두 시험 모두 전환 구간의 응답 시간 초과와 서버 오류(HTTP 500/503)을 포함한다. ‘무중단’이라고 쓰지 않는다. 비슷한 시험의 개선 전후 수치는 당시 DB 활성 위치와 부하가 다르므로 단순 비율로 성능 개선 효과를 단정하지 않는다.

6. Proxy 단절과 지연 데이터 재전송

Gateway에서 운영 환경 중계 서버 10.77.20.10과 중앙 서버 사이의 모니터링 전송 경로(TCP 10051)만 차단했다. SSH와 대상 서버의 로컬 수집, 개발 환경 경로는 유지했다. 중앙의 운영 환경 데이터 갱신은 멈췄지만 개발 환경의 수집은 계속됐다.

운영 환경 Proxy의 로컬 데이터베이스를 읽기 전용으로 조회해 중앙에 아직 전달되지 않은 데이터가 저장되는 것을 확인했다. 전체 행 수에는 이미 전송한 기록도 포함될 수 있어 행 개수를 미전송 건수로 해석하지 않았다.

시험용 차단 규칙은 자동 만료 설정에도 남아 있어 직접 제거하고 통신 복구를 확인했다. 이후 시험에서도 만료 설정에만 의존하지 않고 실제 규칙 해제 여부를 확인하도록 했다.

통신 복구 후 중앙 서버의 수집 이력을 조회해 단절 중 저장된 데이터가 원래 수집 순서와 간격을 유지하며 반영되고 최신 값도 다시 갱신되는 것을 확인했다. 이 시험의 범위는 일시적인 전송 단절과 복구다. 장기간 보관, 디스크 용량 소진, Proxy VM 자체 장애는 별도 검증 과제로 남겼다.

7. 자산 데이터 보호와 경로 검증

실제 PROD 수집 결과를 기준으로 같은 NetBox 등록을 다시 실행했다. 가상 서버 레코드 #1과 IP 주소 레코드 #1이 유지되고 같은 이름·주소가 하나씩만 존재했다. 수집 시각 갱신과 중복 자산 생성을 구분했다.

주입한 조건·실제 경로 판정
PROD 자산에 DEV 관리 IP 전달 API 변경 전 거부, 자산·주소 변경 0건
기존 자산과 다른 운영체제 고유 식별값(machine ID) 전달 API 변경 전 거부, 자산·주소 변경 0건
다른 이름의 자산에 사용 중인 IP 전달 새 자산 생성 전 거부, 자산·주소 변경 0건
CPU·디스크·네트워크 수집 실패를 명시적으로 주입 기존 CPU·파티션·제품 필드 보존, 일부 항목 수집 실패로 표시
정상 수집 결과 재적용 수집 완료 상태로 복원
다른 파일시스템을 독립적으로 보여 주는 영역(mount namespace)의 제품 프로세스 호스트의 버전 실행 파일·JAR 조회를 호출하지 않음
중앙 → PROD 대상 직접 SSH 거부
중앙 → 각 환경 Bastion SSH 허용
PROD → DEV SSH 거부
PROD → 외부 1.1.1.1:443 거부
PROD → 로컬 Proxy·내부 RPM 저장소 허용

부분 수집 실패는 시험을 위해 만든 입력이며 실제 디스크 고장 사례로 소개하지 않는다. 거부 조건을 먼저 검사한 뒤 변경하고, 일부 API만 성공한 상황은 성공한 객체를 무조건 삭제하지 않고 재실행으로 이어갈 수 있도록 했다.

8. 인터넷 없는 대상 설치와 패키지 검증

PXE 대상은 Internal Network NIC 하나만 갖고 NAT·브리지 NIC가 없다. OS는 Provision의 Rocky 10.2 Minimal 설치 트리에서 받았다. PROD의 Agent RPM 캐시를 비운 뒤 내부 저장소 두 개만 활성화하여 zabbix-agent2 7.0.30을 재설치했다. 실제 6.4MB 다운로드와 GPG 검증, 서비스 실행 상태를 확인했다.

외부 연결이 거부된 같은 대상에서 내부 저장소의 패키지 목록과 CA 검증을 사용하는 NetBox HTTPS가 200을 반환했다. 중앙 전체의 새 폐쇄망 재설치는 별도 범위다. 이번에 확인한 것은 인터넷 없는 대상의 OS 설치·Agent 배포와 내부 API 연동이다.

9. 아키텍처 화면 검증

화면·기능 결과
1920×1080 전체 화면 중앙 서비스와 세 환경의 12개 노드, 탭·설명·하단 흐름이 화면 안에 표시
화면 맞춤 배율 표시 영역과 콘텐츠 영역이 모두 1590×740픽셀로 일치해 기본 배율에서 잘림 없음
본문 폭 784px 전체 구조 표시, 설명 패널만 독립 스크롤
모바일 390×844 본문 가로 넘침 없음, 작은 구성도 아래 설명 영역 배치
전체/자동화/모니터링/장애 탭과 NetBox·IPAM 단계, Witness/NFS 장애 설명 확인
확대·복귀 125% 확대, 전체 보기 100%, 전체 화면 진입·종료 확인
브라우저 오류 수집된 브라우저 콘솔 오류 없음

아키텍처의 장애 상태와 흐름 재생은 설명용이다. 서버에 명령을 보내거나 실제 상태를 표시하는 운영 대시보드는 아니다.

추가 운영 절차의 검증 범위

위 결과는 2026년 9월 실습에서 직접 확인한 기록이다. 운영 매뉴얼의 일일·주간·월간 보고 예약 설정과 별도 1회 PDF 생성·실습 내부 수신 시험은 구분한다. 정기 예약의 여러 회차 발행, 외부 SMTP 발송, 보고 서비스의 장애 전환은 기존 시험에 포함하지 않았다.

2026년 10월 검수에서는 AWX 객체 번호를 초기 설정 결과에서 읽도록 보완했고, 새 번호 연결·잘못된 번호 거부·기존 상태 보존을 오프라인 검사했다. 임시 디렉터리에서 새 설정 생성, 컨테이너가 읽는 파일의 권한, 중앙 두 노드의 비밀 일치와 기존 출력 덮어쓰기 거부를 확인했다. VM 생성 도구의 PowerShell 구문, 구성의 Python·Bash·YAML 구문과 사전 점검·커널·Apache·Tomcat의 Ansible 구문 검사는 통과했다.

무서명·서명 오류 응답의 거부와 동일·하위 커널 거부는 모의 입력을 사용한 정책 검사다. 실제 RPM 비교 라이브러리, 패키지 설치와 재부팅, 업무 서비스 정상 응답을 검증한 결과가 아니다. 신규 VM 전체 재구축과 실제 업그레이드·재부팅·복구 시험은 각 환경의 실행 기록을 별도로 남겨야 한다.

10. 검증 체크리스트와 경계

점검 항목 결과·근거
Rocky 실제 설치 / SELinux Enforcing PROD·DEV·STG 실제 게스트 확인
NetBox 상세 필드·IPAM·대표 관리 IP 실제 자산·Interface·IPAddress 관계 확인
NetBox 기반 AWX 대상 서버 목록 Workflow의 source update와 접속 변수 확인
Zabbix API 등록 이후 실제 데이터 운영·개발·검증 환경별 서버 가동 시간과 최근 수집 시각 확인
설치 완료 감지 → AWX 자동 실행 승인 신원 확인 후 STG 자동화 실행 #38 자동 실행·성공
자산 재실행·주소 충돌·식별자 변경 중복 없음, 충돌 입력 변경 전 거부
부분 수집 실패의 기존값 보존 주입 시험 통과 후 정상 관측으로 복원
중앙 활성 노드 전원 손실 DB 승격·API 재개·새 관제 데이터·쓰기 확인
장애 노드 복귀 PostgreSQL 동기 복제 대기 상태·복제 지연 0·애플리케이션 정상
Proxy 전송 단절 Proxy의 로컬 DB 보관과 복구 후 중앙 서버로 누락 이력 재전송 확인
환경 통신 제한 / Bastion 경로 허용·거부 경로별 접속 확인
내부 RPM 다운로드 / 서명 캐시를 비운 실제 재다운로드·재설치 성공
NetBox 논리 DB 백업·복원 별도 DB에서 같은 자산·IP 참조 확인
전체 화면·모바일 아키텍처 FHD 1920×1080, 본문 784px, 모바일 390px 확인
물리 서버 UEFI/BMC/RAID 미실행
중앙 전체 신규 폐쇄망 재구축 절차 작성, 전체 재설치 시험 미실행
NFS·quorum·Gateway·Proxy VM 자체 장애 영향 분석, 해당 장애 주입은 미실행
전체 시스템 재해 복구·부하·장시간 내구 시험 미실행

실제 물리 서버의 UEFI PXE, BMC·RAID 자동화, 두 물리 호스트 간 장애, 스토리지 전체 장애, 모든 상용 DB/WAS 제품 버전 탐지는 이 VM 실습으로 검증했다고 하지 않는다. 각 기능의 구현과 실제 시험 범위를 분리한다.

온라인 초기 설치와 인터넷 없는 대상의 설치·Agent 배포도 구분한다. 중앙 전체를 새 폐쇄망에서 처음부터 재설치하는 시험은 반입 묶음의 의존성 검증까지 포함해야 한다. 기존 서비스에서 외부 NIC만 끊은 결과로 이를 대신하지 않는다.

이 실습에서 통과한 항목과 다음 검증 과제를 같은 표에 남겼다. 개인 PC 한 대의 결과를 운영 SLA나 모든 장애에서의 데이터 무손실 보장으로 바꾸어 표현하지 않는다.

함께 읽기와 구성 자료

포트폴리오 원문 · 온라인망·폐쇄망 구축 가이드 · 장애 시나리오·검증 기록

실습 설정·자동화 소스 ZIP · ZIP 무결성 확인값(SHA-256)

공개 ZIP에는 구성 템플릿과 자동화 소스를 담았습니다. OS·RPM·컨테이너 이미지와 자격 증명은 포함하지 않습니다. 자신의 주소·공개 CA·승인 SSH 키·비밀 저장소로 구성한 뒤 적용합니다.