這篇教程指導如何給容器分配申請的內存和內存限制。咱們保證讓容器得到足夠的內存 資源,可是不容許它使用超過限制的資源。node
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube.git
你的集羣裏每一個節點至少必須擁有300M的內存。github
這個教程裏有幾個步驟要求Heapster , 可是若是你沒有Heapster的話,也能夠完成大部分的實驗,就算跳過這些Heapster 步驟,也不會有什麼問題。docker
檢查看Heapster服務是否運行,執行命令:api
kubectl get services --namespace=kube-system
若是Heapster服務正在運行,會有以下輸出:curl
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-system heapster 10.11.240.9 <none> 80/TCP 6d
建立命名空間,以便你在實驗中建立的資源能夠從集羣的資源中隔離出來。ide
kubectl create namespace mem-example
給容器配置內存申請,只要在容器的配置文件裏添加resources:requests就能夠了。配置限制的話, 則是添加resources:limits。ui
本實驗,咱們建立包含一個容器的Pod,這個容器申請100M的內存,而且內存限制設置爲200M,下面 是配置文件:url
memory-request-limit.yaml |
---|
apiVersion: v1 kind: Pod metadata: name: memory-demo spec: containers: - name: memory-demo-ctr image: vish/stress resources: limits: memory: "200Mi" requests: memory: "100Mi" args: - -mem-total - 150Mi - -mem-alloc-size - 10Mi - -mem-alloc-sleep - 1s |
在這個配置文件裏,args代碼段提供了容器所需的參數。-mem-total 150Mi告訴容器嘗試申請150M 的內存。spa
建立Pod:
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/memory-request-limit.yaml --namespace=mem-example
驗證Pod的容器是否正常運行:
kubectl get pod memory-demo --namespace=mem-example
查看Pod的詳細信息:
kubectl get pod memory-demo --output=yaml --namespace=mem-example
這個輸出顯示了Pod裏的容器申請了100M的內存和200M的內存限制。
... resources: limits: memory: 200Mi requests: memory: 100Mi ...
啓動proxy以便咱們能夠訪問Heapster服務:
kubectl proxy
在另一個命令行窗口,從Heapster服務獲取內存使用狀況:
curl http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/heapster/api/v1/model/namespaces/mem-example/pods/memory-demo/metrics/memory/usage
這個輸出顯示了Pod正在使用162,900,000字節的內存,大概就是150M。這很明顯超過了申請 的100M,可是還沒達到200M的限制。
{ "timestamp": "2017-06-20T18:54:00Z", "value": 162856960 }
刪除Pod:
kubectl delete pod memory-demo --namespace=mem-example
只要節點有足夠的內存資源,那容器就能夠使用超過其申請的內存,可是不容許容器使用超過其限制的 資源。若是容器分配了超過限制的內存,這個容器將會被優先結束。若是容器持續使用超過限制的內存, 這個容器就會被終結。若是一個結束的容器容許重啓,kubelet就會重啓他,可是會出現其餘類型的運行錯誤。
本實驗,咱們建立一個Pod嘗試分配超過其限制的內存,下面的這個Pod的配置文檔,它申請50M的內存, 內存限制設置爲100M。
memory-request-limit-2.yaml |
---|
apiVersion: v1 kind: Pod metadata: name: memory-demo-2 spec: containers: - name: memory-demo-2-ctr image: vish/stress resources: requests: memory: 50Mi limits: memory: "100Mi" args: - -mem-total - 250Mi - -mem-alloc-size - 10Mi - -mem-alloc-sleep - 1s |
在配置文件裏的args段裏,能夠看到容器嘗試分配250M的內存,超過了限制的100M。
建立Pod:
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/memory-request-limit-2.yaml --namespace=mem-example
查看Pod的詳細信息:
kubectl get pod memory-demo-2 --namespace=mem-example
這時候,容器可能會運行,也可能會被殺掉。若是容器還沒被殺掉,重複以前的命令直至 你看到這個容器被殺掉:
NAME READY STATUS RESTARTS AGE memory-demo-2 0/1 OOMKilled 1 24s
查看容器更詳細的信息:
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
這個輸出顯示了容器被殺掉由於超出了內存限制。
lastState: terminated: containerID: docker://65183c1877aaec2e8427bc95609cc52677a454b56fcb24340dbd22917c23b10f exitCode: 137 finishedAt: 2017-06-20T20:52:19Z reason: OOMKilled startedAt: null
本實驗裏的容器能夠自動重啓,所以kubelet會再去啓動它。輸入多幾回這個命令看看它是怎麼 被殺掉又被啓動的:
kubectl get pod memory-demo-2 --namespace=mem-example
這個輸出顯示了容器被殺掉,被啓動,又被殺掉,又被啓動的過程:
stevepe@sperry-1:~/steveperry-53.github.io$ kubectl get pod memory-demo-2 --namespace=mem-example NAME READY STATUS RESTARTS AGE memory-demo-2 0/1 OOMKilled 1 37s stevepe@sperry-1:~/steveperry-53.github.io$ kubectl get pod memory-demo-2 --namespace=mem-example NAME READY STATUS RESTARTS AGE memory-demo-2 1/1 Running 2 40s
查看Pod的歷史詳細信息:
kubectl describe pod memory-demo-2 --namespace=mem-example
這個輸出顯示了Pod一直重複着被殺掉又被啓動的過程:
... Normal Created Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511 ... Warning BackOff Back-off restarting failed container
查看集羣裏節點的詳細信息:
kubectl describe nodes
輸出裏面記錄了容器被殺掉是由於一個超出內存的情況出現:
Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child
刪除Pod:
kubectl delete pod memory-demo-2 --namespace=mem-example
內存的申請和限制是針對容器自己的,可是認爲Pod也有容器的申請和限制是一個頗有幫助的想法。 Pod申請的內存就是Pod裏容器申請的內存總和,相似的,Pod的內存限制就是Pod裏全部容器的 內存限制的總和。
Pod的調度策略是基於請求的,只有當節點知足Pod的內存申請時,纔會將Pod調度到合適的節點上。
在這個實驗裏,咱們建立一個申請超大內存的Pod,超過了集羣裏任何一個節點的可用內存資源。 這個容器申請了1000G的內存,這個應該會超過你集羣裏能提供的數量。
memory-request-limit-3.yaml |
---|
apiVersion: v1 kind: Pod metadata: name: memory-demo-3 spec: containers: - name: memory-demo-3-ctr image: vish/stress resources: limits: memory: "1000Gi" requests: memory: "1000Gi" args: - -mem-total - 150Mi - -mem-alloc-size - 10Mi - -mem-alloc-sleep - 1s |
建立Pod:
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/memory-request-limit-3.yaml --namespace=mem-example
查看Pod的狀態:
kubectl get pod memory-demo-3 --namespace=mem-example
輸出顯示Pod的狀態是Pending,由於Pod不會被調度到任何節點,全部它會一直保持在Pending狀態下。
kubectl get pod memory-demo-3 --namespace=mem-example NAME READY STATUS RESTARTS AGE memory-demo-3 0/1 Pending 0 25s
查看Pod的詳細信息包括事件記錄
kubectl describe pod memory-demo-3 --namespace=mem-example
這個輸出顯示容器不會被調度由於節點上沒有足夠的內存:
Events: ... Reason Message ------ ------- ... FailedScheduling No nodes are available that match all of the following predicates:: Insufficient memory (3).
內存資源是以字節爲單位的,能夠表示爲純整數或者固定的十進制數字,後綴能夠是E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki.好比,下面幾種寫法表示相同的數值:alue:
128974848, 129e6, 129M , 123Mi
刪除Pod:
kubectl delete pod memory-demo-3 --namespace=mem-example
若是不給容器配置內存限制,那下面的任意一種狀況可能會出現:
經過配置容器的內存申請和限制,你能夠更加有效充分的使用集羣裏內存資源。配置較少的內存申請, 可讓Pod跟任意被調度。設置超過內存申請的限制,能夠達到如下效果:
刪除命名空間,這會順便刪除命名空間裏的Pod。
kubectl delete namespace mem-example