表裡不一--限制容器記憶體4G,free還是32G

it排球君發表於2024-12-02

前言

最近有個新同事問了我一個問題,明明透過limit給容器記憶體限制了4G,為什麼進容器看到的還是宿主機的記憶體32G

▶ docker run -it --rm -m 512m ubuntu:18.04 bash
root@ae00bec75ad7:/# free -m 
              total        used        free      shared  buff/cache   available
Mem:          31954       11482        8487        1708       11983       18305
Swap:          2047           0        2047

這個提問不禁勾起了我的一泡回憶,那是之前在學習《深入剖析kubernetes》的時候提到的知識細節

環境準備

元件 版本
作業系統 Ubuntu 22.04.4 LTS
lxcfs 4.0.3
k8s v1.26.3

lxcfs原理介紹

  • free是從/proc檔案系統獲取的資料,但是容器啟動的時候/proc還是對映的宿主機,所以free顯示的資訊肯定是宿主機的
  • 使用lxcfs可以解決這個問題,本質就是透過docker啟動對於cpu、memory施加的限制行為,手動的掛載proc(修改過的)檔案系統進入容器內
  • 目前專案依然在更新: lxcfs,從文件看,支援的檔案系統有這些:
/proc/cpuinfo
/proc/diskstats
/proc/meminfo
/proc/stat
/proc/swaps
/proc/uptime
/proc/slabinfo
/sys/devices/system/cpu/online

安裝lxcfs

1)直接使用apt安裝lxcfs工具

▶ sudo apt install lxcfs

2)部署到對應的目錄

sudo mkdir -p /var/lib/lxcfs
sudo lxcfs /var/lib/lxcfs &

部署完成之後,lxcfs是以一個後臺程序的方式工作

docker 使用

1. 常規啟動

▶ docker run -it --rm -m 512m ubuntu:18.04 bash
root@ae00bec75ad7:/# free -m 
              total        used        free      shared  buff/cache   available
Mem:          31954       11482        8487        1708       11983       18305
Swap:          2047           0        2047

2. docker使用lxcfs

先安裝lxcfs

▶ sudo apt install lxcfs
▶ docker run -it --rm -m 512m \
      -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
      ubuntu:18.04 bash
root@56e3c146ba4e:/# free -m
              total        used        free      shared  buff/cache   available
Mem:            512           1         510           0           0         510
Swap:             0           0           0

透過lxcfs,讓docker正確的識別了限制的記憶體

k8s 使用

1. 常規啟動

▶ echo '          
apiVersion: v1
kind: Pod
metadata:
  name: wilson-test
spec:
  containers:
  - image: ubuntu:18.04
    imagePullPolicy: IfNotPresent
    command: ["sleep", "33333"]
    name: wilson-test
    resources:
      limits:
        memory: 128Mi
      requests:
        memory: 64Mi
' | kubectl apply -f -
pod/wilson-test created

▶ kubectl get pod 
NAME          READY   STATUS    RESTARTS   AGE
wilson-test   1/1     Running   0          3s

▶ kubectl exec -it wilson-test -- free -m
              total        used        free      shared  buff/cache   available
Mem:          31954       11034        6384        1568       14534       18893
Swap:          2047           0        2047

使用lxcfs

▶ echo '                                                                                                                                                                                                                             
apiVersion: v1                                                                                                                                                                                                                       
kind: Pod
metadata:
  name: wilson-test
spec:
  containers:
  - image: ubuntu:18.04
    imagePullPolicy: IfNotPresent
    command: ["sleep", "33333"]
    name: wilson-test
    resources:
      limits:
        memory: 128Mi
      requests:
        memory: 64Mi
    volumeMounts:
    - mountPath: /proc/meminfo
      name: lxcfs-proc-meminfo
      readOnly: true
  volumes:
  - hostPath:
      path: /var/lib/lxcfs/proc/meminfo
      type: ""
    name: lxcfs-proc-meminfo
' | kubectl apply -f -

pod/wilson-test created

▶ kubectl get pod 
NAME          READY   STATUS    RESTARTS   AGE
wilson-test   1/1     Running   0          2s

▶ kubectl exec -it wilson-test -- free -m
              total        used        free      shared  buff/cache   available
Mem:            128           0         127           0           0         127
Swap:          2047           0        2047

記憶體限制128m已經生效

k8s自動注入lxcfs preset

1. 使用k8s preset

  • kubernetes v1.20 把 preset給移除了
  • github上有大佬用CRD給做了回來 podpreset,但是3年沒更新過了

2. 使用k8s Admission Controller

在github也可以找到大佬現成 lxcfs-admission-webhook,但是貌似也很久沒更新了

小結

  • 本文只演示了記憶體,關於其他的指標,只需要依葫蘆畫瓢即可
  • 關於自動掛載,現成的專案都已經很久沒有更新過了,後面可以嘗試手搓一個admission-hook,敬請期待

聯絡我

聯絡我,做深入的交流


至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...

相關文章