서버가 한 대인데도 Proxmox를 올린 이유
지원이 끝난 OS에서 쿠버네티스를 돌리고 있었다. 서버 한 대에 Proxmox를 올리고 가상 머신 4대로 나눴다. 이중화는 할 수 없지만, 잘못돼도 되돌릴 수 있게 됐다. 그 과정에서 막힌 다섯 가지를 정리했다.
배경 — 왜 필요했나
서버 한 대에 CentOS 7과 쿠버네티스 단일 노드가 올라가 있었다. 잘 돌아갔지만 세 가지가 걸렸다.
- OS가 EOL이었다. 2024년 6월 지원 종료. 보안 패치가 안 나오는 OS로 외부에 열린 서비스를 계속 돌릴 순 없다.
- 되돌릴 수가 없었다. OS·쿠버네티스·데이터가 디스크 하나에 한 겹으로 얹혀 있었다. 실패하면 돌아갈 곳이 없어 결국 아무 실험도 못 하게 된다. 이게 가장 큰 비용이었다.
- 노드가 하나였다. 스토리지를
hostPath로 붙여 놔서 노드에 묶여 있었다. 한 대씩 비우고 재시작하는 것도 노드가 하나면 의미가 없다.
선택 — 왜 하이퍼바이저를 한 겹 넣었나
| 안 | 내용 | 판단 |
|---|---|---|
| A | 새 OS로 재설치 + 단일 노드 유지 | 빠르지만 문제 2·3이 그대로 |
| B | 하이퍼바이저 + VM 다중 노드 | 부담을 지는 대신 격리와 스냅샷을 얻는다 |
| C | 서버를 한 대 더 산다 | 진짜 해답이지만 이번 범위 밖 |
B를 골랐다. 다만 한 가지는 분명하다.
물리 서버가 한 대인 이상, 하이퍼바이저를 넣어도 고가용성은 생기지 않는다. 그 한 대가 죽으면 VM 네 대가 같이 죽는다.
얻은 것은 가용성이 아니라 격리와 되돌릴 수 있음이다. VM 단위 스냅샷이 생기고, 워커 한 대만 비워 실험할 수 있다. 실패하면 그 VM만 되돌리면 된다.
Proxmox VE를 고른 이유는 단순했다. VM과 컨테이너를 한곳에서 다루며, 라이선스가 없고 스냅샷·핫플러그를 기본으로 쓴다. 특히 NFS 서버를 무거운 VM 대신 컨테이너로 띄울 수 있었다.
적용 — 어떻게 했나
디스크는 두 장이었다. 이 조건이 계획을 정했다.
- 작은 SSD → 하이퍼바이저 OS 전용. 새로 설치.
- 큰 SSD → 포맷하지 않는다. 기존 데이터가 그대로 있었고, 건드리지 않는 것이 곧 롤백 계획이었다.
[물리 서버 1대]
└─ Proxmox VE
├─ VM 컨트롤플레인 × 1
├─ VM 워커 × 3
└─ LXC NFS 서버 × 1
- NFS는 컨테이너로 분리했다. 호스트는 가상화만 한다.
hostPath볼륨을 전부 폐기하고 NFS로 통일했다. 노드가 넷이 된 이상 노드에 묶인 볼륨은 짐이 된다.- IP는 작업 전에 표로 확정해 뒀다. 설정에서 헤맬 일이 없었다.
- 돌아가는 것들은 이미 GitOps로 선언돼 있어 복구가 아니라 동기화였다. 1.5일 만에 끝난 결정적 이유다.
실수한 것들
1. VM 안에서 지워도 호스트 공간이 안 는다
thin 풀이 92%까지 찼다. VM에서 fstrim을 돌려도 호스트 쪽은 그대로였다.
원인은 VM 디스크에 discard 옵션이 없었던 것이다. 게스트가 “이 블록은 이제 안 쓴다”고 알려도 그 통보가 호스트까지 전달되지 않는다.
qm set <vmid> --scsi0 <storage>:vm-XX-disk-0,discard=on,ssd=1
옵션을 넣고 재부팅한 뒤 fstrim을 돌리니 92% → 72%. 이후 주간 정리 작업에 fstrim -av를 넣었다.
쓴 만큼만 잡아 두는 방식에서 discard는 선택이 아니다. 없으면 사용량은 늘기만 한다.
2. pvmove에 물리 볼륨만 던지면 OS까지 딸려 간다
thin 풀만 새 디스크로 옮기려 했지만, pvmove /dev/sdaX처럼 물리 볼륨만 지정하면 그 위의 모든 볼륨이 이동한다. swap과 root까지 따라간다.
pvmove -n <vg>/data_tdata /dev/sdaX /dev/sdcX # 옮길 볼륨을 하나씩 명시
pvmove는 서비스를 멈추지 않아도 된다. VM이 도는 중에 60GB를 옮기는 데 10분 걸렸고 중단은 없었다.
3. RAID 컨트롤러 뒤의 디스크는 SMART가 안 보인다
$ smartctl -i /dev/sdc
... please try adding '-d megaraid,N'
컨트롤러가 물리 디스크를 가려 일반 경로로는 읽을 수 없다. 컨트롤러를 거쳐 디스크 번호를 지정해야 한다.
smartctl -d sat+megaraid,0 /dev/sda
여기서 헷갈리기 쉽다. /dev/sdX는 컨트롤러로 들어가는 문일 뿐이라 무엇을 쓰든 상관없다. 실제 대상은 뒤의 번호가 정한다.
4. 게스트 에이전트가 없는데 쓰라고 설정해 뒀다
메모리를 늘리려고 qm reboot을 했더니 응답이 없었고 VM이 정지 상태로 멈췄다. 설정에서 게스트 에이전트(가상 머신 안에서 호스트와 대화하는 프로그램)를 켜 뒀지만, 정작 프로그램은 설치하지 않았다. 호스트가 대답을 기다리다 시간이 다 됐다.
- 멈춘 VM은 다시 시작하면 된다(설정은 이미 반영돼 있다).
- 안전한 순서는 노드 비우기 → 정지 → 시작. 에이전트에 기대지 않고, 파드를 비우는 과정에서 정상 종료된다.
- 메모리 변경은 게스트 안에서 재부팅해선 반영되지 않는다. 호스트 레벨에서 정지 후 시작해야 새 설정으로 뜬다. 노드당 1~2분.
5. 나머지 (짧게)
- 파일 서버 경로가 안 맞았다 — 기존 볼륨이 기대하는 경로와 달라 연결 실패
- 노드에 파일 서버 클라이언트가 없었다 — VM 템플릿에 넣어 두지 않으면 노드를 추가할 때마다 반복된다
- 전원을 켠 채 디스크를 꽂았더니 OS가 못 알아봤다 — 컨트롤러는 인식했는데 OS에 안 보였다. SCSI 재스캔이 필요하다
결과
| 항목 | before | after |
|---|---|---|
| 호스트 OS | CentOS 7 (EOL) | Proxmox VE 9 |
| 쿠버네티스 | 단일 노드 v1.26 | 컨트롤플레인 1 + 워커 3, v1.36 |
| 스토리지 | hostPath 5개 (노드 종속) | NFS로 단일화 |
| thin 풀 | 62.5GB / 79.8% | 500GB / 9.98% |
| 호스트 메모리 | 64GB | 128GB |
| 롤백 | 사실상 불가 | VM 단위로 가능 |
| 전환 소요 | — | 약 1.5일 |
스토리지의 “NFS로 단일화”는 이때의 1차 결정이고, 이후 두 번 더 바뀌어 지금은 공유와 블록 두 갈래다 — 클러스터를 어떻게 배치했나에 적었다.
수치보다 중요한 변화는 실험할 수 있게 된 것이다. 워커 한 대를 비우고 재부팅하는 일이 더는 사건이 아니다.
남는 것
- 단일 장애점은 그대로다. 호스트가 죽으면 전부 죽는다. 하이퍼바이저를 넣었다는 이유로 “이제 HA”라고 오해하지 않는 것이 중요하다.
- thin 풀을 한 디스크에 몰아 둔 것도 득실을 맞바꾼 선택이다. 수명이 다른 두 디스크에 걸치는 위험은 없앴지만, 그 한 장이 데이터 전부를 지고 있다.
- 게스트 에이전트는 아직 안 깔았다. 4번은 우회 절차로 덮어 둔 상태다.
- OS 디스크 수명이 40% 가까이 닳았다. 교체 시점을 보고 있다.
서버 한 대짜리 환경에서 하이퍼바이저는 가용성을 위한 도구가 아니라 되돌리기 위한 도구다. 그렇게 보면 감수할 만한 부담이었다.