系列目錄html
當你編排一個pod的時候,你也能夠可選地指定每一個容器須要多少CPU和多少內存(RAM).當容器請求特定的資源時,調度器能夠更好地根據資源請求來肯定把pod調度到哪一個節點上.當容器請求限制特定資源時,特定節點會以指定方式對容器的資源進行限制.node
對於資源請求和資源限制的區別,能夠查看QoSmysql
CPU和RAM都是資源類型,資源類型有一個基本單位.CPU資源經過單位核數來指定,內存經過單位字節來指定.它們和api資源不一樣.api資源,例如pod和service是kubernetes api server能夠讀取和修改的對象.git
pod裏的每個容器均可以指一個或多個如下內容:sql
spec.containers[].resources.limits.cpudocker
spec.containers[].resources.limits.memoryapi
spec.containers[].resources.requests.cpubash
spec.containers[].resources.requests.memoryapp
儘管請求和限制只能經過單個的容器來指定,可是咱們一般說pod的資源請求和資源限制,這樣更方便.Pod對於某一特定資源的請求(或限制)是pod裏單個容器請求資源的和.frontend
對cpu資源的請求和限制用單位cpu來衡量,一個cpu在kubernetes裏和如下任意一個是等價的:
1 AWS vCPU
1 GCP Core
1 Azure vCore
1 IBM vCPU
在祼機因特爾超線程處理器上一個超線程
帶小數的請求也是容許的.一個指定
spec.containers[].resources.requests.cpu
值爲0.5的容器會被確保分配1個cpu的一半資源.值0.1和100m是等價的,能夠讀做100 millicpu
,也有人讀做100 millicores
,實際上意義是同樣的.請求資源的值爲0.1將會被api轉換爲100m,請求的精度比1m更小是不容許的,所以100m一個較優的選擇.CPU資源的請求老是絕對量,永遠不會是一個相對值,值是0.1時對於單核cpu,雙核cpu或者甚至48核cpu都是同樣的.
對內存資源的請求/限制用字節來衡量.你可使用一個純整數或者定點整數帶上E, P, T, G, M, K這些後綴,你也可使用2的冪次方的:Ei, Pi, Ti, Gi, Mi, Ki來表示,好比如下表示的量相等
128974848, 129e6, 129M, 123Mi
如下定義的pod包含兩個容器,每個都請求0.25cpu和64MiB (226 字節)的內存.每個都限制0.5cpu和128MIB內存.你能夠說pod請求0.5cpu和128MiB內存,限制1cpu和256MiB內存
前面說過,pod的資源請求/限制是pod裏的容器資源請求/限制的和
apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
當你建立一個pod,kubernetes會選擇一個節點來運行.對於每種資源類型,不管是cpu仍是內存,節點能夠提供給pod的都是有上限的.對於每種資源,調度器都會確保被調度的pod的請求的總和小於節點的承載能力.請注意即使節點上的cpu或者內存的使用率很是低,可是若是容量檢測失敗,調度器仍然可能拒絕把某一pod放到指定節點上.這確保後來資源使用增多時不會出現資源短缺的狀況.
當kubelete啓動了pod的容器,它會把cpu和內存的限制傳入到容器的runtime裏
當使用的是docker時:
spec.containers[].resources.requests.cpu
的值被轉換爲核數值,它也多是小數,乘1024.這個值和2二者較大的一個會被做爲--cpu-shares
標識的值傳入docker run
命令
spec.containers[].resources.limits.cpu
被轉換爲millicore
值而且乘以100.結果值是容器每100毫秒可用的cpu時間的總和.
注意默認的時間段配額是100毫秒,最小配額是1毫秒.
spec.containers[].resources.limits.memory
被轉換爲整數,而後做爲--momory
標識的值傳入docker run
命令.若是一個容器超過了它的資源限制,則它可能會被終止.若是它是可重啓的(根據pod編排時重啓策略),則kubelete會重啓它,就像對待其它運行時錯誤同樣.
一個容器可能會被容許或者不被容許超過超過它的cpu限制.可是超過cpu資源限制時它不會被殺掉.
failedScheduling
若是調度器找不到任何能夠放置pod的節點,pod一直是未調度狀態找到一個合適的節點.調度器每當找不到合適節點來放置pod,就會產生一個事件,信息以下
kubectl describe pod frontend | grep -A 3 Events Events: FirstSeen LastSeen Count From Subobject PathReason Message 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
上面的示例中,因爲節點的cpu資源不足,名稱爲frontend
的pod調度失敗.相似的錯誤提示也多是因爲內存資源不足(PodExceedsFreeMemory).通常地,若是相似這樣的消息出現,能夠進行如下嘗試:
集羣中添加更多節點
終止一些非必須進程來爲掛起的pod騰出資源
檢測確保pod小於node,好比節點的容量是cpu:1,若是pod請求的是cpu:1.1將永遠不會被調度.
你能夠經過kubectl describe nodes命令來查看節點的容量以及可分配的量:
kubectl describe nodes e2e-test-minion-group-4lw4
Name: e2e-test-minion-group-4lw4 [ ... lines removed for clarity ...] Capacity: cpu: 2 memory: 7679792Ki pods: 110 Allocatable: cpu: 1800m memory: 7474992Ki pods: 110 [ ... lines removed for clarity ...] Non-terminated Pods: (5 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits --------- ---- ------------ ---------- --------------- ------------- kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%) kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%) kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%) kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%) kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%) Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) CPU Requests CPU Limits Memory Requests Memory Limits ------------ ---------- --------------- ------------- 680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
經過上面的輸出,你能夠看到若是有一個pod請求或者 6.23Gi 內存,則它不適合調度到此節點上.
經過查看pods
部分,你能夠看到你能夠看到哪些pod在本節點上佔用了資源
可供pod使用的資源數量小於節點的實際容量,這是由於系統守護進程按比例使用可用資源.allocatable
字段裏的數量是pod實際可用的資源數量,詳情請查看可用資源
pod可能因爲資源不足被終止,你可使用kubectl describe pod
來檢測pod是否因爲資源達到上限被殺死
kubectl describe pod simmemleak-hra99
Name: simmemleak-hra99 Namespace: default Image(s): saadali/simmemleak Node: kubernetes-node-tf0f/10.240.216.66 Labels: name=simmemleak Status: Running Reason: Message: IP: 10.244.2.75 Replication Controllers: simmemleak (1/1 replicas created) Containers: simmemleak: Image: saadali/simmemleak Limits: cpu: 100m memory: 50Mi State: Running Started: Tue, 07 Jul 2015 12:54:41 -0700 Last Termination State: Terminated Exit Code: 1 Started: Fri, 07 Jul 2015 12:54:30 -0700 Finished: Fri, 07 Jul 2015 12:54:33 -0700 Ready: False Restart Count: 5 Conditions: Type Status Ready False Events: FirstSeen LastSeen Count From SubobjectPath Reason Message Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
上面的例子中,Restart Count:5
表示simmemleak容器停止而且被重啓了五次.
你能夠經過kubectl get pod
加上-o go-template=...
選項來獲取上次終止的容器的狀態
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
Container Name: simmemleak LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
你能夠看到容器因爲reason:OOM Killed
錯誤被停止,OOM表示out of memory(內存溢出)
此功能在1.14版本中爲beta狀態
Kubernetes在1.8的版本中引入了一種相似於CPU,內存的新的資源模式:ephemeral-storage,而且在1.10的版本在kubelet中默認打開了這個特性。ephemeral-storage是爲了管理和調度Kubernetes中運行的應用的短暫存儲。在每一個Kubernetes的節點上,kubelet的根目錄(默認是/var/lib/kubelet)和日誌目錄(/var/log)保存在節點的主分區上,這個分區同時也會被Pod的EmptyDir類型的volume、容器日誌、鏡像的層、容器的可寫層所佔用。ephemeral-storage即是對這塊主分區進行管理,經過應用定義的需求(requests)和約束(limits)來調度和管理節點上的應用對主分區的消耗。
在節點上的kubelet啓動的時候,kubelet會統計當前節點的主分區的可分配的磁盤資源,或者你能夠覆蓋節點上kubelet的配置來自定義可分配的資源。在建立Pod時會根據存儲需求調度到知足存儲的節點,在Pod使用超過限制的存儲時會對其作驅逐的處理來保證不會耗盡節點上的磁盤空間。
若是運行時指定了別的獨立的分區,好比修改了docker的鏡像層和容器可寫層的存儲位置(默認是/var/lib/docker)所在的分區,將再也不將其計入ephemeral-storage的消耗。
全部的container能夠指定如下一個或多個選項
spec.containers[].resources.limits.ephemeral-storage
spec.containers[].resources.requests.ephemeral-storage
對ephemeral-storage
資源的請求/限制經過字節來衡量.同上面內存的請求/限制方式同樣,這裏再也不細述.
好比如下pod包含兩個容器,每個都對Local ephemeral storage的請求爲2GiB,限制爲4GiB.此時,整個pod對資源的請求爲4GiB,對資源的限制爲8GiB
apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: ephemeral-storage: "2Gi" limits: ephemeral-storage: "4Gi" - name: wp image: wordpress resources: requests: ephemeral-storage: "2Gi" limits: ephemeral-storage: "4Gi"
ephemeral-storage
請求的pod如何調度當你建立一個pod,kubernetes調度器選擇一個節點來運行它.每一個節點都有可供pod使用的最大Local ephemeral storage最大量,詳細信息請查看Node Allocatable
調度器保證被調度的容器資源總和小於節點的容量
對於容器級別的隔離,若是容器的可寫層( writable layer)和日誌(log)超出了容量限制,容器所在的pod將會被驅離;對於pod級別的隔離,若是pod裏全部容器使用的總Local ephemeral storage和pod的emptydir存儲卷超過限制,pod將會被驅離.
示例
apiVersion: v1 kind: Pod metadata: name: teststorage labels: app: teststorage spec: containers: - name: busybox image: busybox command: ["bash", "-c", "while true; do dd if=/dev/zero of=$(date '+%s').out count=1 bs=10MB; sleep 1; done"] # 持續寫入文件到容器的rootfs中 resources: limits: ephemeral-storage: 100Mi #定義存儲的限制爲100M requests: ephemeral-storage: 100Mi
測試這個Pod就能發如今容器寫入超過存儲限制時就會被驅逐掉了:
/tmp kubectl apply -f pod.yaml pod "teststorage" created /tmp kubectl get pod -w NAME READY STATUS RESTARTS AGE teststorage 0/1 ContainerCreating 0 3s teststorage 1/1 Running 0 7s teststorage 0/1 Evicted 0 1m
查看kubernetes的pod的事件也能看到它是因爲超過了限制的ephemeral-storage被驅逐掉:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m default-scheduler Successfully assigned teststorage to minikube Normal SuccessfulMountVolume 2m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-l7wp9" Normal Pulling 2m kubelet, minikube pulling image "busybox" Normal Pulled 2m kubelet, minikube Successfully pulled image "busybox" Normal Created 2m kubelet, minikube Created container Normal Started 2m kubelet, minikube Started container Warning Evicted 1m kubelet, minikube pod ephemeral local storage usage exceeds the total limit of containers {{104857600 0} {<nil>} 100Mi BinarySI} Normal Killing 1m kubelet, minikube Killing container with id docker://busybox:Need to kill Pod