204 lines
12 KiB
Markdown
204 lines
12 KiB
Markdown
---
|
|
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: import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot
|
|
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 /` 를 다시 읽는다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
## 이 호스트에서 처음으로 양을 쟀다
|
|
|
|
이 실험대의 문서는 제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/` 에 남기면 그때 원문을 댈 수 있다.
|
|
|
|
<!-- body:end -->
|