LXC 虛擬電腦的記憶體管理

對虛擬系統、虛擬電腦來說,除了 CPU 運算資源的需求之外,另外一個重要的資源,就是記憶體的分配與使用,而對 LXC 虛擬系統來說,若沒有特別設定,實體系統有多少記憶體,LXC 虛擬電腦就可以使用多少記憶體。

這樣聽起來似乎不錯,實體電腦有多少記憶體,LXC 虛擬電腦就可以使用多少記憶體,若是在一般狀況下,這樣的設計的確可以大大提升 LXC 虛擬電腦執行的效能,不過,若是實體電腦的環境較為複雜,虛擬電腦數量較多,或者有電腦(不管實體或虛擬電腦)在提供應用服務(如網站,或是資料庫),這樣任意取用記憶體的設計,反而容易形成資源的濫用與分配不均,嚴重的話,還可能會造成系統的不穩定。

利用設定檔指定(限制)LXC 虛擬電腦記憶體大小

對 LXC 虛擬電腦而言,還是可以透過設定檔來設定(限制)虛擬電腦可使用的記憶體大小,不過,再修改設定檔之前,在 LXC 虛擬電腦的終端機內,先利用以下指令來查看 LXC 虛擬電腦的記憶體大小(實際上也是實體電腦的記憶體大小):

$ free -m

由圖中可以清楚看到,系統整體的記憶體可以區分為兩大塊,一塊就是大家比較熟悉的記憶體(Mem),另一塊則是 Swap,其實也就是硬碟的空間,一般來說,在系統最初建置的時候,若沒有特別指定 Swap 的空間大小,則系統會自行調整設定。

接下來,先將 LXC 虛擬電腦關機,並在實體電腦的終端機用任一編器開啟 LXC 虛擬電腦的設定檔:

$ sudo vim /vat/lib/lxc/myUS1204/config

檔案開啟之後,在適當的位置(如下圖,不可寫錯位置)填入以下資訊:

lxc.cgroup.memory.limit_in_bytes = 300000000
lxc.cgroup.memory.memsw.limit_in_bytes = 300000000

其中,〝lxc.cgroup.memory.limit_in_bytes = 300000000〞表示的是限制 LXC 虛擬電腦可以使用的記憶體大小(單位是 byte),而〝lxc.cgroup.memory.memsw.limit_in_bytes = 300000000〞的值一樣為 300000000,這表示 Swap 被關閉(禁止)。

設定檔修改完成之後,就可以直接存檔退出,接著再執行 LXC 虛擬電腦,並在實體電腦的終端機利用以下指令來查看異動是設定檔之後, LXC 虛擬電腦的記憶體狀態:

$ cat /sys/fs/cgroup/memory/lxc/myUS1204/memory.stat

檢測 LXC 虛擬電腦記憶體配置成效

雖然我們可以利用 LXC 虛擬電腦組態檔來設定(限制)記憶體使用的大小,不過,現階段卻沒有合適的指令,或是套件,可以檢測設定之後的成效,因此,這邊我們還是利用撰寫程式的方式,來驗證 LXC 虛擬系統對於記憶體配置的效果。

一樣,在 LXC 虛擬電腦的終端機內,以任一編輯器開啟一個附檔名為〝.c〞的空檔,這邊疆檔案命名為〝allocmem.c〞,沒看錯,這是一個 C 的程式,接著輸入以下內容:

$ vim allocmen.c

#include <stdio.h>
#include <sys/mman.h>
#include <sys/poll.h>

int main() {
  char *addr;
 
  addr = mmap(NULL, 350000000 , PROT_READ | PROT_WRITE,
              MAP_PRIVATE | MAP_POPULATE | MAP_ANONYMOUS, -1, 0);

  printf("alloc 350000000 bytes ok\n");
  return 0;
}

輸入完成,就可存檔退出。

接著,利用以下指定來編譯程式:

$ sudo gcc allocmem.c -o allocmem

不過,大家有很大的機會會看到以下的錯誤(警示)訊息:

很明顯的,就是 LXC 虛擬電腦的系統內缺乏 gcc 的套件,這只需要利用以下的方式就可以安裝了:

$ sudo apt-get install gcc

gcc 安裝完成,再執行一次〝gcc allocmem.c -o allocmem〞,就可以將進行程式的編譯,而編譯完成,就會在當前目錄下產生一個可執行的程式(allocmem)。

此程式主要是檢測系統內可用的記憶體(含 Swap)大小是否超過 350000000 bytes,而在前面的步驟中,我們在 LXC 虛擬電腦的組態檔內,設定(限制)記憶體大小為 300000000 bytes,且 Swap 也被關閉,所以此時若執行此程式,就會看到如下圖的訊息:

$ ./allocmem

這表示目前 LXC 虛擬電腦可用的記憶體不足 350000000 bytes。

而回到組態檔內(LXC 虛擬電腦記得要先關機),並將剛剛寫入的設定值給標註起來,如下圖:

修改完成,並存檔退出之後,並將 LXC 虛擬電腦開機。

LXC 虛擬電腦開機之後,回到實體電腦的終端機,並輸入以下指令來限制記憶體的大小:

$ sudo lxc-cgroup -n myUS1204 memory.limit_in_bytes 300000000

按下 Enter 鍵之後,設定值馬上套用,而這表示我們已經針對 LXC 虛擬電腦的記憶體進行限制,此時再執行 allocmen 的程式,其結果如下:

其結果回應目前 LXC 虛擬電腦的記憶體足夠 350000000 bytes,但是我們剛剛不是已經限制了 LXC 虛擬電腦的記憶體大小了嗎?這表示什麼,這表示 Swap 發揮了公用,彌補了 LXC 虛擬電腦記憶體的不足。

那我們在實體電腦內,再用以下指令來關閉  LXC 虛擬電腦使用 Swap :

$ sudo lxc-cgroup -n myUS1204_bak memory.memsw.limit_in_bytes 300000000

此時再執行一次 allocmen 的程式,就無法通過程式的檢測了:

以上就是 LXC 虛擬系統針對虛擬電腦記憶體資源控制的部份。