Files
document-haness/docs/virtualization/tech-log-studio/cpu-virtualization/question/question-steal-time-increase-under-two-cpu-bound-vms.md
DongHyeonkaandClaude Opus 5 2109f726fe feat(pipeline): keycloak-session-store 25편·virtualization 59편을 S3→S5→S6 으로 돌린다
기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만
있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문
종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다.

SSOT 결함 둘을 고쳤다.

- kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이
  「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽
  `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다.
- virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데
  원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다.

기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은
둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더
든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다).

계약을 셋 고쳤다.

- kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/**
  28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는
  것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온
  것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수
  대조했을 때 가장 가까운 커밋도 28개가 어긋났다).
- virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고
  재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다.
- kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고
  넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다.

style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져
(실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고,
engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고
있었다(Question 기록에서 11.94 → 3.86).

verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 11:01:55 +09:00

123 lines
7.9 KiB
Markdown

---
id: 2d058fb5-01f1-4be8-80bb-0e377868573c
kind: QUESTION
slug: steal-time-increase-under-two-cpu-bound-vms
title: 가상 머신 두 대를 CPU-bound 로 만들면 게스트 steal time 은 얼마나 오르는가
topic: cpu-virtualization
topicName: CPU 가상화
project: virtualization
status: 초안
questionStatus: OPEN
studio: "https://hyeonworks.com/studio/documents/2d058fb5-01f1-4be8-80bb-0e377868573c/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#27-문제-영역에서-파생되는-추가-open-question-oq-7
- final/document.md#13-steal-time
- final/document.md#24-cpu-가상화-계층에서-발생할-수-있는-문제-24-4
---
# 가상 머신 두 대를 CPU-bound 로 만들면 게스트 steal time 은 얼마나 오르는가
이 호스트에서 게스트의 steal time(`%st`)을 잰 값이 없어 부하 전 기준값부터 남겨야 한다.
논리 코어는 8 이고(§197) 두 게스트에 준 vCPU 는 각각 2 다(§218). 둘을 더해도 코어 수를 넘지 않는다. 그런 구성에서도 두 대를 동시에 CPU-bound 로 만들면 `%st` 가 오르는지는 §27 이 든 네 항목을 부하 전후로 찍어야 갈린다.
## 관계
- **KVM 에서 vCPU 가 물리 CPU 에서 실행되기까지**
게스트가 관측하는 steal time 이 호스트에서 무엇 때문에 생기는지를 설명한 기록이다.
- **가상 머신 두 대에 동시에 부하를 주면 이 호스트에서 vCPU 경쟁이 실제로 생기는가**
같은 부하 실행을 쓴다. 경쟁이 있는지를 묻는 쪽과 그것이 `%st` 로 얼마나 보이는지를 묻는 쪽으로 갈린다.
- **vCPU 를 늘릴수록 이 호스트에서 Keycloak 처리량도 계속 오르는가**
총 vCPU 를 늘린 구성에서 `%st` 가 어떻게 달라지는지가 그쪽 실행에서 다시 나온다.
## 사실
§13 은 게스트 Linux 에서 top 등의 CPU 지표를 볼 때 st(steal time)를 확인할 수 있다고 적었다.
§13 이 적은 steal time 은 이런 상황을 가리키는 단서다.
게스트 vCPU 에 실행할 작업이 있고, 호스트에서 vCPU 스레드가 CPU 를 필요로 하는데, 다른 작업 때문에 즉시 실행되지 못한다.
높은 steal time 은 가상화 환경에서 호스트 CPU 경쟁이나 CPU 초과 할당을 의심할 수 있는 지표 중 하나다.
다만 그 값 하나로 원인을 확정해서는 안 되고, 호스트 CPU 포화와 실행 대기열, 친화도, 어떤 작업이 돌고 있었는지를 함께 확인해야 한다고 같은 절이 적었다.
§24.4 는 게스트에 실행할 작업이 있는데 하이퍼바이저나 호스트가 그 vCPU 스레드를 즉시 실행시키지 못한 시간을 게스트가 steal time 으로 관찰한다고 적었다.
그 값은 게스트의 top 등에서 %st 로 본다.
같은 절은 높은 steal time 을 호스트 CPU 경쟁 또는 초과 할당을 조사하라는 단서로 두되, 단독으로 원인을 확정하는 지표는 아니라고 적었다.
§24.3 은 경쟁 대상이 QEMU vCPU 스레드만은 아니라고 적었다.
호스트에 Nginx 를 직접 설치하고 가상 머신 두 대를 실행하는 테스트 환경에서는 가상 머신 밖의 호스트 작업도 CPU 경쟁에 포함된다.
§197 은 2026-09-10 에 이 호스트에서 잰 값을 적었다. Core(s) per socket 4 에 Thread(s) per core 2 라 논리 코어가 8 이다.
같은 절은 VM 에 주는 vCPU 가 논리 코어를 나눠 쓰는 것이고 합이 8 을 넘어도 libvirt 는 막지 않는다고 적으면서, 이 실험대는 2 + 2 + 1 = 5 로 잡아 여유를 뒀다고 덧붙였다.
§218 의 2026-09-03 배치는 kc-lab-1 과 kc-lab-2 에 각각 vCPU 2 를 적었다.
§27 의 OQ-7 은 함께 측정할 항목으로 넷을 들었다.
Host CPU utilization
Host run queue
QEMU vCPU thread
각 Guest 의 %st
이 호스트에서 %st 를 실제로 잰 값은 없다.
## 가정
두 가상 머신을 동시에 CPU-bound 로 만들면 vCPU 스레드끼리 호스트 CPU 시간을 두고 경쟁하게 된다고 전제한다.
두 게스트의 vCPU 합 4 는 논리 코어 8 보다 적어서 §12 가 그린 초과 할당 상태는 아니다. 그래도 경쟁이 생기는지는 같은 코어를 호스트 쪽 작업이 얼마나 쓰는지에 달려 있어 아직 전제로 둔다.
두 게스트에 같은 정도의 부하를 걸 수 있다고 전제한다.
한쪽이 더 세게 걸리면 두 %st 를 나란히 놓고 읽을 수 없다.
부하 전과 부하 중을 각각 한 번씩 찍으면 비교할 수 있다고 전제한다.
값이 흔들리면 한 번씩 찍은 두 값만으로는 증가인지 흔들림인지 갈리지 않는다.
## 미지수
두 가상 머신을 동시에 CPU-bound 로 만들었을 때 각 게스트의 %st 가 부하 전 대비 얼마나 오르는가.
그 증가가 호스트 실행 대기열과 같은 방향으로 움직이는가.
부하 구간에 호스트 쪽 작업이 같은 논리 코어를 얼마나 쓰는가.
## 제약
§13 이 steal time 하나로 원인을 확정하지 않는다고 적었으므로 %st 만 재서는 이 물음이 닫히지 않는다.
부하 전 기준값을 먼저 남기지 않으면 부하 중 값만으로 증가를 적을 수 없다.
네 항목을 같은 시각에 찍어야 서로 견줄 수 있다. 따로 찍은 값을 한 표에 놓으면 부하 구간이 어긋난다.
부하 구간에 호스트에서 Nginx 같은 다른 작업이 함께 돌면 %st 의 증가분을 두 가상 머신 사이의 경쟁으로만 읽을 수 없다.
§24.3 이 그 목록을 그릴 때 둔 환경은 호스트에 Nginx 를 직접 설치하고 가상 머신 두 대를 실행하는 구성이다. §179 는 그 Nginx 를 엣지 게스트로 옮겼고 호스트가 직접 들던 `:443` 에는 지금 리스너가 없다고 적었으므로, 부하 구간에 호스트 쪽에서 무엇이 도는지는 그 목록이 아니라 그때의 호스트에서 받아 적는다.
OQ-1 과 이 물음은 같은 부하 실행에서 값을 얻는다. 그래도 한 물음으로 합치지 않았다.
합치면 경쟁이 있었다는 결론과 그것이 %st 로 얼마나 보였다는 결론 가운데 어느 쪽 기준으로 닫혔는지가 남지 않는다.
## 선택지
### 1. 부하 전후로 네 항목을 같은 실행에서 남긴다
§27 이 든 네 항목을 부하 전에 한 번, 두 가상 머신을 동시에 CPU-bound 로 만든 뒤에 한 번 같은 시각으로 기록한다.
%st 가 올랐을 때 호스트 실행 대기열도 함께 올랐는지를 같은 표에서 읽을 수 있다.
실행이 한 번이라 값이 흔들리는 정도는 알 수 없다. 흔들림이 의심되면 부하 구간을 늘려 여러 번 찍는다.
### 2. 제외 — %st 만 부하 전후로 비교한다
찍을 것이 하나뿐이라 실행은 가볍다.
다만 §13 이 함께 확인하라고 든 호스트 CPU 포화와 실행 대기열이 빠져서, %st 가 올라도 그것이 호스트 경쟁 때문인지 게스트 쪽 작업 때문인지 가를 수 없다.
### 3. 제외 — 가상 머신 한 대만 CPU-bound 로 만들어 비교군을 하나 더 만든다
이 물음이 묻는 것은 두 대를 동시에 부하로 만든 상태이고, 부하 전 값이 이미 비교군이다.
한 대 부하가 필요해지면 1번 실행을 마친 뒤에 따로 더한다.
## 다음 검증
1. 부하 전에 Host CPU utilization 과 run queue, ps -eLo pid,tid,psr,pcpu,comm | grep qemu (§14.7) 의 QEMU vCPU thread 사용량, 각 Guest 의 top (§14.8) %st 를 기준값으로 남긴다.
2. 가상 머신 두 대를 동시에 CPU-bound 로 만든다.
3. 같은 네 항목을 같은 시각에 다시 기록한다.
닫는 조건 : 부하 전후의 %st 와 호스트 실행 대기열을 한 표로 놓을 수 있으면 그 표가 Case 가 되고 닫는다. %st 가 부하 전과 다르지 않으면 이 호스트 구성에서는 두 가상 머신 동시 부하가 steal time 으로 나타나는 경쟁을 만들지 않는다고 적는다. 그 결론은 OQ-1 과 함께 닫는다.