본문 바로가기

Compute

How ballooning driver works (2)

지난 글에서 VMKernel이 Memory Pressure 환경에서 Memory Reclamation 기능을 활용하는데 어떠한 기능을 사용하는지를 결정하기 위해서 Memory State 값을 활용한다고 말씀드렸습니다. 또한, Memory State 값은 사전에 계산된 minFree 값을 이용하는 것도 정리해봤습니다.

 

지난 번에 보여드렸던 표를 다시 한 번 가져와봤습니다. 아래 표를 보시면 이번에 살펴볼 Ballooning은 Memory State가 Soft까지 변경된 경우에 사용되게 됩니다.

 

다른 Memory Reclamation 기능과 달리 Ballooning의 특징은 Guest OS와 같이 연계하면서 성능 영향은 최소화 하면서 가장 많은 Memory 양을 회수할 수 있습니다.

 

구현 목적

Hypervisor의 유형과 상관없이 기본적으로 Hypervisor는 Guest OS의 Memory Manager가 어떻게 Guest OS 내부의 Memory를 관리하고 있는지 알 수가 없습니다.

 

Guest OS의 Memory Manager는 프로세스에 Memory를 할당하고 해제할 때마다 각 Memory 상태에 맞게 List로 관리합니다.

예를 들어, Guest OS 내에서 어떤 프로세스에 Memory를 할당하고자 하여 특정 Page를 요청할 때, VMKernel은 Physical Memory의 Page를 Mapping 시켜줍니다.

반대로 Guest OS 내에서 프로세스가 종료되거나, 사용했던 Memory를 반환하는 경우에는 어떻게 될까요?

Guest OS의 Memory Manager는 이를 바로 반환하지 않고 Free List에 보관하게 됩니다.

이렇게 되기 때문에 VMKernel 입장에서는 Physcial Memory로부터 할당해줬던 Page가 여전히 사용 중이라고 인식하게 되는 것입니다.

 

이러한 Guest OS의 Memory Manager와 VMKernel의 Memory Manager 사이에 정보를 교환할 수 있도록 Balloon Driver를 구현하게 되었습니다. Balloon Driver는 Guest OS 내에 위치하게 되며, VMware Tools를 설치할 때 같이 설치됩니다.

Guest OS 종류로는 Windows, Linux, FreeBSD, Solaris를 지원하고 있습니다.

만약, VMware Tools가 설치되어 있지 않다면 VMKernel은 Ballooning 기능을 이용할 수 없기 때문에 대신 Compression과 Swapping 기능을 이용하게 됩니다.

 

구현 방식

VMKernel이 Ballooning 기능을 이용하기 시작하면, Guest OS 내부에서 동작 중인 Balloon Driver는 특정 갯수의 Page를 요청하게 됩니다. 이 때 Guest OS의 Memory Manager는 현재 할당되어 사용 중인 Page를 주는 것이 아니라, Free Page List에 있는 Page들을 주는 것입니다. 

Free Page List로부터 Page를 할당받은 Balloon Driver는 VMKernel에게 다른 VM에게 할당 가능한 Page를 알려줍니다.

Balloon Driver가 요청해서 할당받은 Page는 Guest OS 내부의 Memory Manager가 다른 프로세스를 위해서 할당할 수는 없습니다. 즉, Balloon Driver가 할당받은 Page는 고정된 것입니다.

 

반대로 VMKernel에서 Memory Pressure가 없어진 경우에는 VMKernel이 Balloon Driver에게 할당되었던 Page들을 다시 Guest OS에 반환하도록 요청합니다.

 

이를 간단하게 도식화 해보면 다음과 같습니다. 아래 그림은 Guest OS가 Windows인 경우입니다.

 

Ballooning 확인 방법

Balloon 관련된 값은 esxtop과 memstats 명령어로 확인 가능합니다.

esxtop의 경우에는 memory display를 이용해야 하며, MCTL field를 추가해야 합니다.

 4:01:28am up 13 days  3:55, 1472 worlds, 14 VMs, 64 vCPUs; MEM overcommit avg: 0.00, 0.00, 0.00
PMEM  /MB: 261765   total: 3508     vmk,107095 other, 151161 free
VMKMEM/MB: 261379 managed:  3228 minfree, 22071 rsvd, 239308 ursvd,  high state
NUMA  /MB: 130691 (62886), 131072 (87891)
PSHARE/MB:      41  shared,      39  common:       2 saving
SWAP  /MB:       0    curr,       0 rclmtgt:                 0.00 r/s,   0.00 w/s
ZIP   /MB:       0  zipped,       0   saved
MEMCTL/MB:       0    curr,       0  target,   45476 max

       GID NAME            MCTL?   MCTLSZ  MCTLTGT  MCTLMAX
     86410 esxi672             N     0.00     0.00     0.00
     14589 hostd.2099977       N     0.00     0.00     0.00
     71785 vsanmgmtd.21084     N     0.00     0.00     0.00
     86428 esxi673             N     0.00     0.00     0.00
    666904 vcsa01              Y     0.00     0.00  7797.00
     52236 vcsa67              Y     0.00     0.00  6493.88
    226810 esxi701             N     0.00     0.00     0.00
    226819 esxi702             N     0.00     0.00     0.00
    687514 redhat              Y     0.00     0.00  5084.32
    266761 windowskor          Y     0.00     0.00  2661.77
    781330 windowseng          Y     0.00     0.00  2661.77
    573283 centos              Y     0.00     0.00  5083.80
     20852 vpxa.2100722        N     0.00     0.00     0.00
    251245 vropscp01           Y     0.00     0.00  5184.77
     85015 ad01                Y     0.00     0.00  5324.80
    246529 vrops01             Y     0.00     0.00  5184.76

 

esxtop에서 조회되는 field 중 balloon 관련된 field에 대한 정의는 다음과 같습니다.

 

memstats 명령어로도 개별 VM들의 Balloon 관련 값을 조회할 수 있습니다.

# memstats -r vm-stats -s name:memSize:max:ballooned:balloonTgt

 VIRTUAL MACHINE STATS: Sun Dec 25 03:57:32 2022
 -----------------------------------------------
   Start Group ID   : 0
   No. of levels    : 12
   Unit             : KB
   Selected columns : name:memSize:max:balloonTgt:ballooned

-----------------------------------------------------------
           name    memSize        max balloonTgt  ballooned
-----------------------------------------------------------
     vm.2105445   10485760         -1          0          0
     vm.2110136    8388608         -1          0          0
     vm.2110333   16777216         -1          0          0
     vm.2110334   16777216         -1          0          0
     vm.2110335   16777216         -1          0          0
     vm.2130072   16777216         -1          0          0
     vm.2130073   16777216         -1          0          0
     vm.2133990    8388608         -1          0          0
     vm.2135166    8388608         -1          0          0
     vm.2138552    4194304         -1          0          0
     vm.2194103    8388608         -1          0          0
     vm.2207918   12582912         -1          0          0
     vm.2211041    8388608         -1          0          0
     vm.2231122    4194304         -1          0          0
-----------------------------------------------------------
          Total  157286400                     0          0
-----------------------------------------------------------

 

놓칠 수 있는 한 가지

지금까지 Memory Reclamation을 얘기할 때 한 가지 가정은 Memory Consumption이 높은 경우 였습니다.

즉, VMKernel에서 Memory Pressure를 감지하는 경우에 각각의 Memory State에 맞게 적합한 Memory Reclamation 기능을 활용합니다.

Memory State가 Soft로 변경되면, Ballooning을 사용하기 시작하고 이는 Guest OS 내에 설치된 Balloon Driver와 같이 연계하여 동작한다고 했습니다.

문제는 Memory Pressure가 아닌 다른 경우에도 Ballooning이 사용되는 경우가 있다는 것입니다.

그 경우는 바로 VM의 Memory 설정에서 Limit을 사용하는 경우입니다.

아래 캡쳐 화면을 보시면 VM에서 Memory 설정을 할 때 Reservation, Limit, Shares 항목을 보실 수 있습니다.

자세한 내용은 별도로 다뤄야 하나 간단히 보면,

Reservation은 무슨 일이 있더라도 설정된 Memory양만큼은 무조건 VM이 사용할 수 있다는 의미이고,

Limit은 Hypervisor가 Memory 사용을 허용할 수 있는 최대량입니다.

Shares는 여러 VM이 기동 중일 때, 해당 값에 따라 Memory 할당의 Priority를 조절하기 위해서 사용되는 값입니다.

위 화면을 예로 들면, 기본적으로 Guest OS 입장에서는 설정한 Memory 용량인 4GB를 모두 바라보도록 되어 있습니다.

그리고 Limit 값은 Default로 Unlimited로 되어 있습니다. 이러한 경우에는 Limit 값으로 인해 Ballooning이 동작할 여지가 없습니다. 아래 memstat 결과를 보시면, ballooned 값이 0으로 되어 있는 것을 알 수 있습니다.

# memstats -r vm-stats -s name:memSize:max:ballooned:balloonTgt

 VIRTUAL MACHINE STATS: Sun Dec 25 07:58:01 2022
 -----------------------------------------------
   Start Group ID   : 0
   No. of levels    : 12
   Unit             : KB
   Selected columns : name:memSize:max:balloonTgt:ballooned

-----------------------------------------------------------
           name    memSize        max balloonTgt  ballooned
-----------------------------------------------------------
     vm.2105445   10485760         -1          0          0
     vm.2110136    8388608         -1          0          0
     vm.2110333   16777216         -1          0          0
     vm.2110334   16777216         -1          0          0
     vm.2110335   16777216         -1          0          0
     vm.2130072   16777216         -1          0          0
     vm.2130073   16777216         -1          0          0
     vm.2133990    8388608         -1          0          0
     vm.2135166    8388608         -1          0          0
     vm.2138552    4194304         -1          0          0
     vm.2194103    8388608         -1          0          0
     vm.2207918   12582912         -1          0          0
     vm.2211041    8388608         -1          0          0
     vm.2233511    2097152         -1          0          0 
-----------------------------------------------------------
          Total  155189248                     0          0
-----------------------------------------------------------

 

실제로 Guest OS 내부에서도 확인해보면, Driver에 의해서 점유된 메모리 용량이 약 7MB 정도밖에 안되는 것을 알 수 있습니다. 아래는 Guest OS가 Windwos인 경우에 Sysinternals에서 제공하는 RAMMAP 도구를 이용한 화면입니다.

 

하지만, 설정된 Memory 크기인 2GB 보다, Limit 값을 더 작게 하는 경우가 문제가 됩니다.

아래 화면처럼 Memory 크기가 2GB인 상태에서 Limit 값을 1500MB로 변경하여 VM을 시작해보겠습니다.

 

이번에는 memstats 결과를 보면, 이전과 상황이 달라진 것을 볼 수 있습니다.

Ballooning 기능이 사용되어, Ballooned 값이 1043520MB로 되어 있습니다. 

즉, 설정한 Memory 용량인 2GB에서 Limit으로 지정한 1500MB를 제외한 용량만큼을 Ballooning 기능을 이용하고 있는 것을 알 수 있습니다.

# memstats -r vm-stats -s name:memSize:max:ballooned:balloonTgt

 VIRTUAL MACHINE STATS: Sun Dec 25 08:12:38 2022
 -----------------------------------------------
   Start Group ID   : 0
   No. of levels    : 12
   Unit             : KB
   Selected columns : name:memSize:max:balloonTgt:ballooned

-----------------------------------------------------------
           name    memSize        max balloonTgt  ballooned
-----------------------------------------------------------
     vm.2105445   10485760         -1          0          0
     vm.2110136    8388608         -1          0          0
     vm.2110333   16777216         -1          0          0
     vm.2110334   16777216         -1          0          0
     vm.2110335   16777216         -1          0          0
     vm.2130072   16777216         -1          0          0
     vm.2130073   16777216         -1          0          0
     vm.2133990    8388608         -1          0          0
     vm.2135166    8388608         -1          0          0
     vm.2138552    4194304         -1          0          0
     vm.2194103    8388608         -1          0          0
     vm.2207918   12582912         -1          0          0
     vm.2211041    8388608         -1          0          0
     vm.2234441    2097152    1536000     560440     557248
-----------------------------------------------------------
          Total  155189248                560440     557248
-----------------------------------------------------------

 

정상적인 경우와 비교를 위해 동일하게 RAMMP 도구를 이용하여, Guest OS에서 Driver가 얼마나 많은 Memory를 점유하고 있는지 보면, 다음과 같이 memstats로 조회한 결과와 유사한 용량이 확인됩니다.

 

이는 Guest OS 입장에서는 설정해준 Memory 크기인 2GB가 자신에게 할당된 용량으로 인식하는데 VMKernel은 Limit 설정으로 인해 설정 Memory 크기에서 Limit 값으로 설정한 만큼을 제외한 용량을 Memory Manager가 할당해주지 않기 때문에 발생합니다.

 

따라서 (Configured Memory Size - Limit Size) 만큼의 용량을 Guest OS의 Balloon Driver가 점유하는 현상이 발생합니다.

 

Ballooning은 VMKernel이 제공하는 여러 가지 Memory Reclalamtion 기능 중 하나입니다.

다른 여느 Memory Reclamation 기능 보다 Guest OS의 성능에 영향을 최소한으로 미치면서 가장 효율적으로 Memory를 Reclaim 할 수 있습니다.

 

 

'Compute' 카테고리의 다른 글

vCenter failover happened due to time sync  (0) 2023.01.06
Overview of Replication with vCenter(embedded PSC)  (0) 2023.01.04
How ballooning driver works (1)  (2) 2022.12.23
Overview of SNMP  (0) 2022.12.22
How to retrieve information using SNMP  (0) 2022.12.21