SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-09

VPS CPU steal time 확인 및 noisy neighbor 판별법

vmstat의 st 항목을 통해 CPU steal time을 분석하는 방법을 설명합니다. 서버 부하와 외부 요인인 noisy neighbor를 구분하고, 가상 CPU가 물리 코어를 할당받지 못해 발생하는 성능 저하 원인을 정확히 파악하는 가이드를 제공합니다.

CPU steal time이 실제로 측정하는 것

CPU steal time은 가상 CPU가 실행 준비를 마쳤고 대기 중인 작업이 없음에도 불구하고, 하이퍼바이저가 물리 코어를 다른 게스트에게 할당하여 대기하게 된 시간의 비율입니다. 작업은 큐에 쌓여 있었고, 코어는 다른 곳에서 사용 중이었습니다. Linux는 이러한 사이클을 별도로 집계하여 st로 보고합니다. 이를 통해 "내 서버가 바쁜 상태"인지 "내 서버가 차례를 기다리는 상태"인지 구분할 수 있습니다.

이러한 차이를 구분하는 것이 바로 이 카운터가 존재하는 이유입니다. 자신의 프로세스가 CPU에서 소비한 시간은 us(user) 또는 sy(system)으로 보고됩니다. 작업이 스토리지 때문에 차단된 시간은 wa(I/O wait)로 보고됩니다. 실행 가능 상태(runnable)이고 런큐(run queue)에 머물러 있으며 진행 중인 I/O가 없는데도 실행되지 않는 vCPU(가상 CPU)는 st으로 보고됩니다. 서버 내부의 그 무엇으로도 이 상태를 해결할 수 없습니다. 스케줄링 결정은 사용자보다 한 계층 아래인 호스트에서 이루어지기 때문입니다.

이는 하나의 물리 머신을 여러 게스트가 공유하는 방식에서 직접적으로 기인합니다. 일반적인 원인은 이웃 게스트입니다. 같은 노드에 있는 다른 게스트가 과도하게 자원을 사용하면 호스트가 코어를 나누어 할당하기 때문입니다. 간과하기 쉬운 두 번째 원인도 있습니다. 많은 제공업체가 공유 vCPU의 성능을 물리 코어의 일정 비율로 제한하며, 여러 하이퍼바이저에서는 이 제한된 성능을 게스트 내부에서 steal로 계산합니다. 따라서 st 수치가 높게 나타난다면 코어가 할당되지 않았음을 의미합니다. 하지만 누가 코어를 가져갔는지를 항상 알려주는 것은 아닙니다.

Steal 수치의 출처

커널은 호스트를 직접 볼 수 없으므로 스스로 Steal을 측정할 수 없습니다. 하이퍼바이저가 이를 커널에 알려줍니다. KVM 환경에서 호스트는 vCPU별 카운터를 게스트와 공유하는 페이지에 기록하며, 커널이 CONFIG_PARAVIRT_TIME_ACCOUNTING 옵션으로 빌드된 경우 게스트가 이를 합산합니다. 모든 배포판 커널은 이 옵션을 포함하고 있습니다. Xen 역시 runstate 영역을 통해 동일한 정보를 보고합니다. 이 합계는 정확히 한 곳을 통해 사용자 공간으로 전달됩니다.

head -1 /proc/stat

cpu 라인에는 부팅 이후의 USER_HZ 틱 단위로 user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice 순서로 10개의 카운터가 포함되어 있습니다. Steal은 레이블 뒤의 여덟 번째 값입니다. vmstat, top, mpstat 및 모든 Prometheus exporter를 포함한 아래의 모든 도구는 동일한 필드를 읽어 두 개의 샘플을 백분율로 변환합니다.

이와 관련하여 한 가지 중요한 결과가 있습니다. 하이퍼바이저가 카운터를 내보내지 않으면 해당 필드는 영원히 0으로 유지되며, 호스트가 과부하 상태여도 이를 기반으로 하는 모든 도구는 0.0으로 평온하게 보고합니다. KVM과 Xen은 이를 내보내지만, VMware와 Hyper-V의 게스트는 일반적으로 0을 보고합니다. 0이라는 수치를 신뢰하기 전에 플랫폼을 확인하십시오.

systemd-detect-virt

이 명령은 kvm, xen, vmware, microsoft와 같은 플랫폼 이름을 출력하며, 베어메탈 환경에서는 none를 출력합니다. 컨테이너 내부에서는 lxc, docker, podman과 같은 런타임 정보를 출력하는데, 이는 기계 자체가 아닌 컨테이너에 대한 정보를 알려줍니다. kvm 환경에서 0이 출력된다면 호스트가 자원을 잘 할당하고 있다는 확실한 증거입니다. 하지만 해당 필드를 채우지 않는 플랫폼에서 0이 출력된다면 이는 아무런 증거가 되지 않으며, 이 경우 실제 작업 시간을 측정하여 경합 여부를 판단해야 합니다.

VPS에서 CPU steal time을 확인하는 방법

vmstatprocps 패키지에 포함되어 있습니다. 거의 모든 Ubuntu 및 Debian VPS 이미지에 기본으로 설치되어 있지만, 일부 최소형 컨테이너 이미지에는 없을 수 있으므로 사용하기 전에 설치하십시오.

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

vmstat --version를 실행하면 vmstat from procps-ng 4.0.4과 같은 줄이 출력됩니다. 이 내용이 출력된다면 도구가 설치된 것이며 커널 카운터 값을 정상적으로 읽어오고 있는 상태입니다. vmstat 1 5는 1초에 한 번씩, 총 5번 샘플을 수집합니다.

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

오른쪽 cpu 블록에서 st 열을 찾으십시오. 최신 procps-ng 빌드에서는 KVM 게스트 시간을 나타내는 gu 열이 그 뒤에 추가되므로, st은 마지막이 아닌 오른쪽에서 두 번째에 위치합니다. 릴리스마다 위치가 변경될 수 있으므로 반드시 헤더 이름을 기준으로 열을 확인하십시오.

정확한 측정을 위해 두 가지 습관을 권장합니다. 첫 번째 데이터 줄은 부팅 이후의 평균값이므로 무시하고 그 이후의 줄을 읽으십시오. 또한 steal time은 간헐적으로 발생하므로 단 한 번의 샘플로는 측정할 수 없습니다. vmstat 1 60를 실행하고 1분 동안 지켜본 뒤 결론을 내리십시오.

top%Cpu(s) 요약 줄의 st로 표시된 필드에서 동일한 수치를 보고합니다.

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

코어별 상세 정보를 보려면 sysstat 옵션을 추가하십시오.

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

mpstat는 CPU당 한 줄씩 %steal 열을 포함하여 출력하며, 이를 통해 모든 vCPU가 영향을 받는지 아니면 특정 vCPU만 영향을 받는지 확인할 수 있습니다. 기술 지원 티켓에 필요한 기록을 남기려면 화면으로만 보지 말고 샘플을 파일로 저장하십시오.

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

문제가 의심되는 시간 동안 cron을 통해 해당 명령을 실행하십시오. 그러면 단순히 공급자에게 "어젯밤에 느렸다"고 말하는 것과, 정확히 10분간의 데이터를 제시하는 것 사이의 큰 차이를 만들 수 있습니다.

Steal 수치는 무엇을 의미합니까?

  • 0.0가 일정하게 유지됨. 정상 상태이거나, 플랫폼에서 Steal 수치를 보고하지 않는 경우입니다. 안심하기 전에 systemd-detect-virt 명령어로 확인하십시오.
  • 수 초간 몇 퍼센트 정도의 스파이크 발생. 공유 노드에서는 정상입니다. 이웃한 사용자의 빌드가 시작되었거나 호스트가 백업을 수행 중일 수 있습니다.
  • 공유 플랜에서 1~5퍼센트가 지속됨. 예상 가능한 범위입니다. 공유 CPU는 가격에 그 성능이 반영되어 있습니다.
  • 5~10퍼센트가 지속됨. 체감할 수 있는 속도 저하가 발생합니다. 기록을 시작하고 며칠 동안 같은 시간대의 수치를 비교하십시오.
  • 시간 단위로 10퍼센트 이상 지속됨. 현재 워크로드에 비해 노드가 과도하게 할당(oversubscribed)된 상태입니다. 이 수준이라면 기술 지원 티켓을 생성하거나 서버 이전을 고려해야 합니다.

공유 플랜에서 Steal 수치를 보장하는 제공업체는 없으므로, 이 수치들을 절대적인 사양보다는 참고 지표로 활용하십시오. 운영 중인 서비스의 성격에 따라 판단해야 합니다. 야간 배치 작업은 15퍼센트의 Steal이 발생해도 아무도 눈치채지 못할 수 있습니다. 반면 지연 시간에 민감한 서비스는 평균 수치가 위험해 보이기 훨씬 전부터 p99 지연 시간에서 문제가 드러나므로, 트레이딩 봇과 같이 지연 시간에 민감한 워크로드는 전용 코어에서 운영해야 합니다.

Steal time은 얼마나 큰 비용을 발생시키는가?

계산은 간단합니다. CPU 시간의 s만큼을 빼앗기면, 고정된 양의 CPU가 필요한 작업은 완료까지 1 / (1 - s)배의 시간이 더 걸립니다. 60초의 CPU 시간이 필요한 작업을 예로 들겠습니다.

ChartWall clock time for a job needing 60 seconds of CPU
The data behind this chart
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

공유 플랜에서 흔히 볼 수 있는 3 퍼센트의 steal time이 발생하면, 해당 작업은 60.0초 대신 61.9초가 소요됩니다. 이 정도 차이로 문의 티켓을 발행하는 사람은 없습니다. 8 퍼센트가 되면 65.2초가 걸립니다. 40 퍼센트가 되면 동일한 작업에 100.0초가 필요하며, 평소에 처리되던 작업 대기열이 오히려 쌓이기 시작합니다.

이 값들은 측정값이 아니라 계산된 수치입니다. 이 모델은 실행 가능한 스레드가 하나뿐이며, steal time이 해당 구간에 균등하게 분산된다고 가정합니다. 실제 서비스는 이 곡선보다 더 나쁘게 느껴지는 경우가 많습니다. CPU 슬라이스를 빼앗기는 시점이 요청 처리 중간일 수 있고, 그로 인한 지연 시간이 해당 요청을 기다리는 모든 작업에 전가되기 때문입니다. 공식에 의존하지 않고 실제 수치를 얻으려면, VPS 벤치마크를 수행하십시오. 서버가 한가할 때와 바쁠 때 각각 측정하여 두 구간의 st 값을 기록하면 됩니다.

Steal인가, 아니면 다른 문제인가?

Steal은 다른 증상과 혼동하기 쉽습니다. vmstat 라인에서 카운터들을 함께 확인하십시오.

  • st가 높지만 rus가 낮게 유지되는 경우: 호스트가 코어를 할당하지 않는 상태입니다. 이것이 Steal입니다.
  • r가 vCPU 개수를 훨씬 상회하고 us이 높으며 st이 0에 가까운 경우: 할당된 CPU가 처리할 수 있는 양보다 많은 작업을 수행 중입니다. rnproc의 출력 결과를 비교하십시오. 이는 이웃의 영향이 아니라 사용자의 오버커밋(oversubscription) 문제입니다.
  • wa이 높고 st이 0에 가까운 경우: 작업이 스토리지 I/O에서 차단된 상태이며, 이는 해결 방법이 다른 별개의 문제입니다.
  • Load average는 높지만 stus이 모두 낮은 경우: Load 수치는 인터럽트 불가능한 작업(uninterruptible tasks)도 포함하므로, 보통 CPU 문제가 아니라 장치 오류나 네트워크 마운트가 멈춘 상황을 나타냅니다.

Burstable 플랜은 별도로 고려해야 합니다. 유휴 상태일 때 크레딧 잔액이 쌓이고 작업 중일 때 소모되는 방식이며, 잔액이 소진되면 제공업체는 기준 속도로 제한을 겁니다. 일부 플랫폼에서는 이 스로틀링이 Steal로 보고되기도 합니다. 반면 내부에서 보이지 않는 플랫폼도 있으며, 이 경우 단순히 초당 처리 가능한 사이클 수가 줄어듭니다. 이웃의 문제라고 단정 짓기 전에 플랜 설명을 먼저 확인하십시오.

컨테이너에서 steal time이 0으로 표시되는 이유

Steal은 컨테이너 내부가 아닌 가상 머신(VM)의 속성입니다. 사용자의 VPS에서 실행되는 Docker 컨테이너는 호스트의 /proc를 공유하므로, 컨테이너 내부에서 읽은 st 값은 VPS의 steal 값을 나타내며 이는 의도한 결과입니다. VPS로 판매되는 컨테이너 기반 가상화는 다르게 동작합니다. lxcfs이 적용된 환경에서는 컨테이너 내부의 /proc/stat이 cgroup 계정을 기반으로 합성되므로, steal 값은 구조적으로 0이 됩니다. 컨테이너 내부에서만 데이터를 수집하는 모니터링 스택은 하부 물리 머신이 자원 부족에 시달리는 상황에서도 steal 값이 0으로 평탄하게 유지되는 것처럼 보일 수 있습니다.

컨테이너 내부에서 동일한 의미를 갖는 지표는 CPU 쿼터 스로틀링(throttling)입니다. cgroup v2에서는 다음과 같습니다.

cat /sys/fs/cgroup/cpu.stat

nr_throttled은 그룹이 CPU 쿼터 제한에 도달한 강제 적용 주기를 계산하며, throttled_usec는 프로세스가 정지된 총 시간을 나타냅니다. nr_throttled 값이 상승한다는 것은 프로세스가 실행 가능한 상태였음에도 실행되지 못했음을 의미합니다. 이는 steal과 동일한 경험이지만, 사용자가 직접 설정한 제한으로 인해 발생합니다. 호스트를 탓하기 전에 먼저 자신의 제한 설정을 확인하십시오. 특히 Docker compose 파일에 CPU 제한을 설정하여 VPS에서 서비스를 운영하는 경우라면 더욱 그렇습니다. 계층화된 가상화는 시간이 사라지는 지점을 하나 더 추가합니다. VPS 내부의 VM은 호스트의 steal과 VM 자체의 스케줄링 지연을 모두 겪기 때문입니다. VPS에서 중첩 가상화를 사용하는 경우 이 점을 유념하십시오.

지속적인 steal 발생 시 대처 방법

게스트 내부의 설정으로는 steal 문제를 해결할 수 없습니다. 스케줄러가 결정을 내리는 주체는 게스트 외부이기 때문입니다. 실질적인 해결책은 네 가지입니다.

먼저 증거를 수집하십시오. UTC 기준 타임스탬프, 각 에피소드의 지속 시간, 반복 빈도, 그리고 mpstat 명령 실행 시 특정 vCPU만 영향을 받는지 아니면 전체가 영향을 받는지 기록하십시오. 일주일간 기록된 샘플 데이터가 스크린샷 한 장보다 훨씬 가치 있습니다.

해당 데이터를 첨부하여 티켓을 발행하십시오. 두 가지를 직접 질문하십시오. 해당 시간대에 노드가 오버서브스크립션(oversubscription) 상태인지, 그리고 인스턴스를 다른 노드로 이동할 수 있는지 확인하십시오. vmstat 출력 결과와 정확한 시간을 붙여넣으십시오. 제공업체는 재현 가능한 시간대가 있을 때 조치를 취합니다. 단순히 서버가 느리다고만 적힌 티켓에는 다시 정보를 요구하는 답변만 돌아올 뿐입니다. 이 작업을 얼마나 위임할 수 있는지가 관리형 VPS와 비관리형 VPS의 실질적인 차이 중 하나입니다.

마이그레이션을 요청하십시오. 게스트를 부하가 적은 노드로 옮기는 것은 제공업체 입장에서 일상적인 작업이며, 보통 짧은 재부팅으로 완료됩니다. 이는 비용이 들지 않는 해결책이며, 한 노드에 여러 부하가 큰 이웃 인스턴스가 동시에 몰려 있는 일반적인 상황을 해결해 줍니다.

경합을 피하기 위해 비용을 지불하십시오. 전용 vCPU 플랜은 물리적 코어를 귀하의 인스턴스에 할당하므로, steal 카운터는 0으로 유지됩니다. 매달 비용은 더 발생하지만, 변동성을 감당할 수 없는 워크로드에 대한 확실한 해결책입니다. 만약 이것으로도 부족하거나 메모리 대역폭까지 독점하고 싶다면, 다음 단계는 VPS 대신 전용 서버를 사용하는 것입니다.

이러한 조치를 기다리는 동안 steal로 인한 피해를 줄이십시오. vCPU 개수보다 적은 수의 워커 스레드를 실행하십시오. 코어를 할당받지 못한 스레드는 컨텍스트 스위칭만 유발하기 때문입니다. 배치 작업은 직접 기록한 로그를 통해 확인한, 노드가 한가한 시간대로 옮기십시오. 그런 다음 동일한 시간대에 같은 명령으로 다시 측정하십시오. 추측하는 대신 변경 사항이 효과가 있었는지 명확히 판단할 수 있습니다.

FAQ

VPS에서 정상적인 CPU steal time은 어느 정도입니까?

공유 호스팅 플랜에서는 짧은 스파이크나 5퍼센트 미만의 지속적인 값은 일반적입니다. 공유 CPU는 호스트가 물리적 코어를 여러 게스트에게 나누어 할당하기 때문입니다. 수 시간 동안 두 자릿수 이상의 값이 지속되는 것은 일반적이지 않으며, 기술 지원 티켓을 생성할 가치가 있습니다. 전용 vCPU 플랜에서는 0.0이 측정되어야 하며, 이외의 값은 보고해야 할 결함입니다. 수치는 본인의 워크로드에 비추어 판단하십시오. 야간 배치 작업은 감당할 수 있는 steal 수치라도 지연 시간에 민감한 API는 그렇지 못할 수 있습니다.

더 큰 플랜을 사용하면 높은 steal time 문제가 해결됩니까?

그 자체로는 해결되지 않습니다. 동일한 공유 노드에서 vCPU 개수를 늘리면 더 많은 가상 CPU가 동일한 물리적 코어를 두고 경쟁하게 되며, 퍼센트 수치는 그대로 유지될 수 있습니다. steal을 제거하는 방법은 전용 CPU를 할당받거나 부하가 적은 노드로 이동하는 것뿐입니다. 바쁜 장비에서 더 큰 점유율을 갖는다고 해도 여전히 바쁜 장비의 일부일 뿐입니다.

서버가 분명히 느린데 왜 steal time이 0으로 표시됩니까?

두 가지 일반적인 이유가 있습니다. 하이퍼바이저가 카운터를 전혀 내보내지 않는 경우인데, 이는 VMware 및 Hyper-V 플랫폼에서 흔히 발생하며 호스트의 상태와 관계없이 필드값이 0으로 유지됩니다. systemd-detect-virt를 실행하여 사용 중인 플랫폼을 확인하십시오. 그렇지 않다면 병목 현상이 다른 곳에 있는 것입니다. wa를 통해 스토리지 대기 시간을 확인하고, 본인의 과부하 여부를 확인하기 위해 rnproc을 비교하며, 컨테이너 내부의 쿼터 제한을 확인하려면 /sys/fs/cgroup/cpu.stat을 읽어보십시오.

서버 내부에서 steal time을 줄일 수 있습니까?

게스트 내부에서 호스트의 스케줄링 방식을 변경할 수는 없습니다. 다만 그 영향력을 줄일 수는 있습니다. vCPU 개수보다 적은 수의 워커 스레드를 실행하여, 가용 코어를 기다리며 실행 큐에 쌓이는 작업을 줄이십시오. 배치 작업은 노드가 비교적 한가한 시간대로 옮기십시오. 결과를 캐싱하여 CPU를 필요로 하는 요청 자체를 줄이는 것도 방법입니다. steal을 근본적으로 제거하는 변경 사항인 노드 이전이나 전용 코어 할당은 제공업체 측에서 처리해야 할 영역입니다.