kubernetes之定義容器和Pod的內存資源


簡介

此文主要講述如何定以容器的內存請求數和內存限制數。一個容器的運行必須保證內存大於容器請求的內存數,但是不能超過容器的限制數。

備注:此文檔參考官方文檔,並加以自己的理解。如有誤導性的內容,請批評指正。

創建命名空間

# kubectl create namespace mem-example

定義內存請求數和內存限制數

創建一個Pod,其中args塊中的--vm-bytes參數請求150MiB的內存。文件名:memory-request-limit.yaml

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-ctr
    image: polinux/stress
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
# kubectl apply -f /root/k8s-example/pods/memory-request-limit.yaml --namespace=mem-example

確認Pod 容器正在運行

# kubectl get pod memory-demo --output=yaml --namespace=mem-example

查看Pod詳情

# kubectl get pod memory-demo --output=yaml --namespace=mem-example

從結果可以看出,改Pod內存請求數200Mi,限制數100Mi

...
resources:
  limits:
    memory: 200Mi
  requests:
    memory: 100Mi
...

執行kubectl top命令,查看當前Pod好用了CPU和內存

# kubectl top pod memory-demo --namespace=mem-example

備注:執行kubectl top首先確保安裝metrics server,若沒有安裝可參考如下,需保證能下載k8s.gcr.io/metrics-server-amd64:v0.3.1鏡像:

# git clone https://github.com/kodekloudhub/kubernetes-metrics-server.git
# kubectl create -f kubernetes-metrics-server/

kubectl top結果可以看出,當前Pod使用了150Mi字節內存,大於該Pod的請求值100MiB,小於該Pod的限制值200MiB

NAME          CPU(cores)   MEMORY(bytes)
memory-demo   138m         150Mi

刪除該Pod

# kubectl delete pod memory-demo --namespace=mem-example

超過容器的內存限制

如果容器有更多的內存可以分配,則容器可以超過自定義的請求內存。如果容器需要的內存超過自定義的內存限制,則容器將會成為被終止的候選對象。如果容器持續消耗的內存大於自定義的內存限制,則容器被強制停止運行。容器被終止運行后,kubelet會重新啟動改容器。

創建一個分配的內存超過內存限制的Pod,如下配置,請求內存50MiB,限制內存100MiB。文件名:memory-request-limit-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-2
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-2-ctr
    image: polinux/stress
    resources:
      requests:
        memory: "50Mi"
      limits:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
# kubectl apply -f /root/k8s-example/pods/memory-request-limit-2.yaml --namespace=mem-example
# kubectl get pod memory-demo-2 --namespace=mem-example

從結果可以看出,由於內存溢出,導致Pod直接被kill掉了。

# kubectl get pod memory-demo-2 --namespace=mem-example                                 NAME            READY   STATUS      RESTARTS   AGE
memory-demo-2   0/1     OOMKilled   1          4s

查看Pod詳情

# kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example

從結果可以看出,最后的狀態由於OOMKilledOut Of Memory導致容器被kill

lastState:
  terminated:
    containerID: docker://0d4d5580e28df2a936f28cbef8580ac21c1014e1fad2814e28cfa28417bd3bb0
    exitCode: 1
    finishedAt: "2020-01-10T00:39:55Z"
    reason: OOMKilled
    startedAt: "2020-01-10T00:39:55Z"

刪除Pod

# kubectl delete pod memory-demo-2 --namespace=mem-example

定義內存請求大於節點內存的容器

內存請求數、內存限制數和容器相關聯,因此,對於Pod來說,設置合適的內存請求和限制非常有必要。Pod的內存請求數等於Pod內所有容器的內存請求數總和。Pod的內存限制數就是Pod內所有容器內存限制數總和。

Pod的調度是基於請求調度的。一個Pod運行於哪個Pod上取決於改Node是否能滿足該Pod的存請求。

在下面的聯系中,創建一個內存請求遠大於節點內存總數的Pod,下面的實例中定義的Pod內存請求數為1000GiB。文件名:memory-request-limit-3.yaml

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo-3
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-3-ctr
    image: polinux/stress
    resources:
      limits:
        memory: "1000Gi"
      requests:
        memory: "1000Gi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
# kubectl apply -f /root/k8s-example/pods/memory-request-limit-3.yaml --namespace=mem-example 

查看容Pod狀態

# kubectl get pod memory-demo-3 --namespace=mem-example
NAME            READY   STATUS    RESTARTS   AGE
memory-demo-3   0/1     Pending   0          15s

查看Pod資源詳情

# kubectl describe pod memory-demo-3 --namespace=mem-example

從結果看,7個node節點沒有足夠的內存,由於我的是3個master節點高可用、4個node節點的k8s集群

Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/7 nodes are available: 7 Insufficient memory.

刪除名稱空間


內存單位

內存資源用bytes字節衡量。單位有EPTGMKEiPiTiGiMiKi。例如如下表達式均為同一個值

128974848, 129e6, 129M , 123Mi

刪除Pod資源

# kubectl delete pod memory-demo-3 --namespace=mem-example

沒有定義內存限制

如果沒有定義容器的內存限制,則適用以下情況之一:

  • 容器對其使用的內存量沒有上限。容器可以使用其正在運行的節點上的所有可用內存,進而可以調用OOM Killer。此外,如果發生OOM Kill,則沒有資源限制的容器將有更大的機會被殺死。
  • 運行在有默認內存限制的namespace中的容器,系統會自動為容器分配默認限制。集群管理員可以通過LimitRange定義內存限制的值。

內存請求限制的原因

通過在集群中配置容器的內存請求和內存限制,可以合理的使用集群中node節點的內存資源。如果保證Pod的內存請求在合理值范圍內,則該Pod可以在集群中被合理的調度到合適的node節點上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM