--- kind: CASE slug: declared-memory-and-disk-are-ceilings-not-occupancy title: 5120MB 를 줬는데 353MB 를 쓰고 있었다 — 선언한 양과 실제로 드는 양 topic: lab-environment-build topicName: 실험대 환경 구성 project: virtualization status: 게시 전 lastVerifiedOn: 2026-09-10 sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6 source: - final/document.md#198-자원-할당과-실사용은-다르다 - final/document.md#199-디스크-오버레이는-얼마나-쓰나 - final/document.md#202-철거-실제-출력-전문 - final/document.md#197-측정-환경 - final/document.md#195-이-부의-출처와-범위 - final/document.md#211-이-부의-출처와-범위 --- # 5120MB 를 줬는데 353MB 를 쓰고 있었다 — 선언한 양과 실제로 드는 양 k3s 만 올린 상태에서 kc-lab-1 은 5120MB 를 할당받고 353MB 를 쓰고 있었다. k3s 두 노드에 8240MB 를 선언해 실제 점유는 654MB 였고, 디스크는 40GB 를 선언해 2.1GB 를 썼다. 2026-09-10 에 test-server 에서 쟀다. ## 관계 - **이 호스트의 가상 머신들은 설정한 메모리와 지금 잡고 있는 메모리가 얼마나 다른가** 그 물음이 묻는 세 값 가운데 configured 와 게스트 사용량이 여기서 나왔다. 호스트 resident 는 비어 있어서 그 물음은 닫히지 않았다. - **이 disk image 는 qcow2 인가 RAW 인가, 그리고 Guest 가 보는 크기와 Host 가 실제로 쓰는 크기는 얼마나 다른가** 그 물음이 요구하는 세 값 가운데 `qemu-img info` 와 `ls` 가 여기서 나왔고 `du` 는 돌리지 않았다. - **QEMU 프로세스가 실제로 붙잡고 있는 호스트 메모리는 얼마이고 어떻게 나뉘어 있는가** 게스트 안에서 본 실사용과 호스트가 실제로 잡아 둔 양은 다른 수다. 후자를 그 물음이 받는다. - **qcow2 파일 안 — 매핑표와 클러스터, 그리고 항목이 0 이면 바닥에 다시 묻는다** 20GB 를 선언한 파일이 1.4GiB 인 까닭을 그 글이 매핑표와 오버레이로 설명한다. - **실험대를 철거하고 무엇이 남는지 확인한다** 회수량 3.1GB 를 낸 철거 절차가 그 기록에 있다. - **실험대를 껐다 켜고 게스트 메모리를 다시 나눈다** `kc-lab-1` 이 3584M 에서 5120MB 가 된 재배분 절차가 그 기록에 있다. - **도구가 낸 출력은 대상의 상태가 아니다 — 그 명령이 무엇을 세는지부터 가른다** `dommemstat` 의 `actual`, `free` 의 `available`, `pool-info` 의 `Allocation` 이 셋 다 이름과 다른 것을 센다. ## 문제 제1~4부에는 이 호스트에서 잰 값이 하나도 없다. 제5·6부는 버전과 주소와 명령까지만 적었다. 게스트 세 대에 메모리 8240MB 와 디스크 40GB 를 선언해 두었는데, 그 선언이 11,648MiB 와 226G 짜리 호스트 한 대에서 실제로 얼마를 먹는지는 어디에도 없었다. 「5GB 를 줬으니 5GB 를 쓴다」와 「20GB 두 장이면 40GB 를 쓴다」가 맞는지 모르는 채로 게스트를 더 띄울지 정해야 했다. ## 결론 선언한 양은 상한이고 점유가 아니다. k3s 만 떠 있고 Keycloak 은 아직 안 올린 상태에서 넷을 쟀다. 메모리 : `kc-lab-1` 은 할당 5120MB 에 실사용 353MB, `kc-lab-2` 는 할당 3120MB 에 실사용 301MB 메모리 합계 : 8240MB 를 할당했고 실제 점유는 654MB 디스크 : `kc-lab-1.qcow2` 1.4GiB, `kc-lab-2.qcow2` 665MiB, 바닥 `base.qcow2` 는 `virtual size` 3 GiB 에 `disk size` 335MiB 디스크 합계 : 20GB 를 두 장 선언했고 실제로 쓴 것은 2.1GB 철거 : 게스트 셋을 지우자 `df -h /` 가 11G 에서 7.9G 로 내려 3.1GB 가 회수됐다 `virt-install --memory 4096` 으로 만든 `kc-lab-2` 의 할당이 3120 으로 보인다. `dommemstat` 의 `actual` 은 현재 할당이지 선언한 상한이 아니고, 상한은 `virsh dominfo` 의 `Max memory` 에 있다. 줄어든 까닭은 virtio-balloon 회수로 보이는데, 두 값을 나란히 찍어 보지는 않았다. ## 검증 환경 측정일 : 2026-09-10 호스트 : `test-server`, Arch Linux CPU : `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz`, 논리 코어 8 RAM : 11,648MiB 루트 파일시스템 : 226G 가운데 9.9G 사용 QEMU : 11.1.1 libvirt : 12.7.0 커널 : `7.2.2-arch1-1` 중첩 가상화 : `nested` 가 `Y` 지만 이 실험대는 쓰지 않는다 게스트 : Debian 12 genericcloud 3대 — 엣지 1대, k3s 2노드 워크로드 : k3s 만 떠 있고 Keycloak · PostgreSQL · Redis · Prometheus 는 올리기 전 ## 재현 조건 1. k3s 두 노드만 띄우고 Keycloak · PostgreSQL · Redis · Prometheus 는 올리지 않는다. 2. 게스트마다 `virsh dommemstat` 을 돌려 `actual` 과 `unused` 를 읽고, 그 차이를 실사용으로 잡는다. 3. `qemu-img info` 로 `base.qcow2` 의 `virtual size` 와 `disk size` 를 읽고, `ls -l /var/lib/libvirt/images/` 로 오버레이와 시드 파일의 바이트 수를 읽는다. 4. 철거하기 전에 `df -h /` 를 읽어 둔다. 5. `virsh destroy` 와 `virsh undefine --remove-all-storage` 로 게스트 셋을 지우고 `df -h /` 를 다시 읽는다. ## 본문 ## 이 호스트에서 처음으로 양을 쟀다 이 실험대의 문서는 제5·6부까지 버전과 주소와 명령을 적었고 자원의 양은 적지 않았다. 제7부가 그 양과 시간을 처음 쟀고, 원본이 표기 규약을 스스로 밝혀 두었다. > 여기 적힌 숫자는 전부 2026-09-10 에 `test-server` 에서 실제로 돌려 받은 출력이다. 추정값·예상값은 없다. 없는 값은 「미측정」이라고 쓴다. 측정 환경부터 읽어 둔다. 논리 코어가 8 이고 게스트 셋에 vCPU 를 2 + 2 + 1 로 잡아 여유를 뒀다. ```text label="측정 환경 — free -m 의 앞 두 줄" total used free shared buff/cache available Mem: 11648 5642 2599 4 3776 6005 ``` `available` 이 6005 로 `free` 2599 보다 훨씬 큰데, `buff/cache` 3776 이 필요해지면 회수되기 때문이다. 게스트를 몇 대 더 띄울 수 있는지는 `free` 가 아니라 `available` 로 읽는다. ## 메모리 — 할당 5120MB 에 실사용 353MB 게스트마다 `dommemstat` 의 `actual` 에서 `unused` 를 뺀 값이 실사용이다. ```text label="k3s 만 떠 있고 Keycloak 은 아직 안 올린 상태" kc-lab-1 할당 5120MB 실사용 353MB kc-lab-2 할당 3120MB 실사용 301MB ``` k3s server 한 대가 353MB 를 쓰니 할당의 7% 다. 둘을 합치면 8240MB 를 할당했고 실제 점유는 654MB 여서, 11,648MiB 짜리 호스트 한 대에서 게스트 세 대가 무리 없이 돈다. ## `kc-lab-2` 의 할당이 4096 이 아니라 3120 이다 `kc-lab-2` 는 `virt-install --memory 4096` 으로 만들었는데 `dommemstat` 이 3120 을 낸다. `dommemstat` 의 `actual` 은 현재 할당이지 선언한 상한이 아니라서, 상한을 보려면 `virsh dominfo` 의 `Max memory` 를 읽어야 한다. 둘을 같은 값으로 읽으면 「메모리가 왜 줄었지」가 된다. 줄어든 까닭은 virtio-balloon 회수로 보인다. 게스트가 안 쓰는 만큼 balloon 드라이버가 호스트에 돌려주고, 돌려준 만큼 현재 할당이 내려간다. 다만 이 실험대에서 `dommemstat` 의 `actual` 과 `dominfo` 의 `Max memory` 를 나란히 찍어 대조한 기록이 없어서, 3120 이 balloon 회수의 결과라는 것은 관측이 아니라 추론이다. ## 디스크 — 40GB 를 선언해 2.1GB 게스트 디스크는 `base.qcow2` 위의 오버레이다. 20GB 짜리를 두 장 만들어도 바닥은 한 벌이고 변경분만 쌓인다. ```text label="qemu-img info 가 읽은 바닥 이미지" image: /var/lib/libvirt/images/base.qcow2 file format: qcow2 virtual size: 3 GiB (3221225472 bytes) disk size: 335 MiB ``` ```text label="엣지를 만들기 전, k3s 2 노드만 있던 시점의 ls -l" -rw-r--r-- base.qcow2 351404032 (335 MiB) -rw------- kc-lab-1.qcow2 1521025024 (1.4 GiB) ← 선언 20GB -rw------- kc-lab-2.qcow2 697499648 (665 MiB) ← 선언 20GB -rw------- seed-kc-lab-1.iso 378880 (370 KiB) -rw------- seed-kc-lab-2.iso 378880 (370 KiB) ``` 바닥은 게스트가 3 GiB 로 보는데 파일은 335MiB 이고, 20GB 로 선언한 오버레이 둘도 실제로는 1.4GiB 와 665MiB 다. 합쳐 40GB 를 선언하고 2.1GB 를 썼다. `kc-lab-1` 이 `kc-lab-2` 의 두 배 이상을 쓰는 것은 k3s server 가 컨트롤 플레인 바이너리와 SQLite 를 들고 있기 때문이다. ## `virsh pool-info` 의 `Allocation` 은 VM 사용량이 아니다 같은 날 `virsh pool-info default` 도 읽었다. ```text label="스토리지 풀 default" Name: default State: running Persistent: yes Autostart: yes Capacity: 225.31 GiB Allocation: 7.84 GiB Available: 217.46 GiB ``` `Allocation` 7.84 GiB 는 풀이 얹힌 호스트 루트 파일시스템 전체의 사용량이다. VM 이 얼마를 쓰는지는 위의 `ls -l` 이 말한다. 두 수를 같은 것으로 읽으면 게스트 둘이 7.84 GiB 를 먹은 것이 된다. ## 철거 — `df -h /` 가 11G 에서 7.9G 로 게스트 셋을 `virsh destroy` 로 내리고 `virsh undefine --remove-all-storage` 로 지웠다. 한 대분 출력은 이렇다. ```text label="kc-lab-edge 한 대를 철거한 출력" Domain 'kc-lab-edge' destroyed Domain 'kc-lab-edge' has been undefined Volume 'vda'(/var/lib/libvirt/images/kc-lab-edge.qcow2) removed. Volume 'vdb'(/var/lib/libvirt/images/seed-kc-lab-edge.iso) removed. ``` `Volume` 줄이 두 개 나오는데, 오버레이 디스크 `vda` 와 시드 ISO `vdb` 다. | 무엇을 읽었나 | 철거 전 | 철거 후 | |---|---|---| | `virsh list --all` | 3 대 running | (없음) | | `virsh vol-list default` | 7 개 | `base.qcow2` 1 개 | | DHCP 예약 | 3 줄 | 0 줄 | | `df -h /` | 11G | 7.9G | | `virbr0` | UP | DOWN | 3.1GB 가 회수됐고 내역은 `kc-lab-1` 1.4GB 와 `kc-lab-2` 665MB 와 시드 ISO 3개(각 370KB)다. `base.qcow2` 335MB 는 다음 재구축의 바닥이라 남긴다. 다시 받아도 몇 분이면 된다. ## 같은 대상의 숫자가 두 벌이다 이 SSOT 안에는 같은 실험대의 스냅샷이 두 벌 있다. §218 은 2026-09-03 값이고 이 기록은 2026-09-10 값이다. | 무엇 | 2026-09-03 | 2026-09-10 | |---|---|---| | 호스트 RAM | `RAM 7.4Gi` | `Mem: 11648` | | `kc-lab-1` | `RAM 3584M · vCPU 2` | 할당 5120MB | | `kc-lab-2` | `RAM 2560M · vCPU 2` | 할당 3120MB (선언 4096) | | 게스트 수 | 2 (엣지 없음) | 3 (엣지 추가) | 그사이에 호스트 RAM 이 8GB 에서 12GB 로 물리 증설됐고 `setmaxmem` 과 `setmem` 으로 게스트 메모리가 재배분됐다. 두 값이 어긋나 보이면 틀린 것이 아니라 다른 날이다. 날짜가 아니라 단위로 갈리는 것도 하나 있다. §198 은 같은 호스트의 RAM 을 `11.6GB` 로도 적는데, 그 표기가 원 가이드에서 온 것이라 고쳐 쓰지 않고 어긋남을 적어 둔다고 스스로 밝힌다. `free -m` 의 `Mem: 11648` 은 MiB 단위이므로 11,648MiB, 약 11.4GiB 다. ## 확인하지 못한 것 이 값은 호스트 한 대의 한 시점이다. Keycloak 2 파드와 PostgreSQL 과 Redis 와 Prometheus 가 올라간 뒤의 메모리는 재지 않았다. 원본도 §198 에서 그 시점의 값을 미측정으로 밝힌다. 디스크 값과 철거 값은 시점이 서로 다르다. `ls -l` 은 엣지를 만들기 전 k3s 2노드만 있던 때의 것이고, 3.1GB 회수는 엣지까지 세 대가 있던 때의 것이다. `kc-lab-edge` 의 디스크 크기는 따로 재 두지 않았고, 회수 합계에서 역산하면 1GB 안팎이다. 게스트 안에서 본 실사용과 QEMU 프로세스가 호스트에서 붙잡고 있는 양은 다른 수인데, 뒤엣것은 이 기록이 재지 않았다. 여기 옮긴 출력은 전부 SSOT 본문의 코드 블록에서 왔고, 이 저장소의 `final/evidence/` 에는 그 명령들의 출력 원문이 파일로 없다. 같은 측정을 다시 돌려 `final/evidence/raw/` 에 남기면 그때 원문을 댈 수 있다.