Blog:部落格園 個人
A Container is guaranteed to have as much memory as it requests, but is not allowed to use more memory than its limit.
概念
資源需求:定義需要系統預留給該容器使用的資源最小可用值,容器執行時可能用不到這些額度的資源,但用到時必須確保有相應數量的資源可用。
資源限制(約束):定義該容器可以申請使用的資源最大可用值,超出該額度的資源使用請求將被拒絕;顯然,該限制需要大於等於requests的值,但系統在某項資源緊張時,會從容器回收超出request值的那部分。
一般來講,資源需求 <= 資源限制。
?Tips:如果某 Container 設定了自己的記憶體限制但未設定記憶體請求,Kubernetes 自動為其設定與記憶體限制相匹配的請求值。
單位
在Kubernetes上,可由容器或Pod請求與消費的資源主要是指CPU和記憶體(RAM),它可統稱為計算資源。 計算資源的數量是可測量的,可以被請求、被分配、被消耗。
CPU屬於可壓縮型資源,即資源額度可按需彈性變化,而記憶體(當前)則是不可壓縮型資源,對其執行壓縮操作可能會導致某種程度的問題,例如程式崩潰等。
在Kubernetes系統上,1個單位的CPU相當於虛擬機器上的1顆虛擬CPU(vCPU)或物理機上的一個超執行緒(Hyperthread,或稱為一個邏輯CPU),它支援分數計量方式,一個核心(1 core)相當於1000個微核心(millicores,以下簡稱為m),因此500m相當於是0.5個核心,即1/2個核心。
CPU 總是按絕對數量來請求的,不可以使用相對數量; 0.1 的 CPU 在單核、雙核、48 核的機器上的意義是一樣的。
記憶體的計量方式與日常使用方式相同,預設單位是位元組,也可以使用E、P、T、G、M和K為單位字尾,或Ei、Pi、Ti、Gi、Mi和Ki形式的單位字尾。
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
k8s.kuboard.cn/name: nginx-test
name: nginx-test
namespace: test-web
resourceVersion: '648123'
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
k8s.kuboard.cn/name: nginx-test
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
k8s.kuboard.cn/name: nginx-test
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
k8s.kuboard.cn/name: nginx-test
namespaces:
- test-web
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- image: 'nginx:latest'
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: '1'
memory: 256Mi
requests:
cpu: 100m
memory: 64Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
observedGeneration: 2
readyReplicas: 2
replicas: 2
unavailableReplicas: 1
updatedReplicas: 2
檢視:
[root@master ~]# kubectl describe pod nginx-test-994c44d5f-mlfnt -n test-web
Name: nginx-test-994c44d5f-mlfnt
...
Limits:
cpu: 1
memory: 256Mi
Requests:
cpu: 100m
memory: 64Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-wrl2l (ro)
...
容器CPU資源需求為100m,記憶體資源需求為64Mi,CPU限制為1,記憶體限制為256Mi。
metrics-server
從 v1.8 開始,資源使用情況的監控可以通過 Metrics API的形式獲取,具體的元件為Metrics Server,用來替換之前的heapster,heapster從1.11開始逐漸被廢棄。
安裝完Metrics Server,即可用kubectl top
命令檢視節點和Pod的CPU和記憶體使用情況。
檢視Pod的CPU和記憶體使用情況:
[root@master ~]# kubectl top pods -n test-web --use-protocol-buffers
NAME CPU(cores) MEMORY(bytes)
nginx-test-994c44d5f-mlfnt 0m 3Mi
nginx-test-994c44d5f-t7fvk 0m 3Mi
總結
對於壓縮型的資源CPU來說,若未定義容器的資源請求用量,以確保其最小可用資源量,該Pod佔用的CPU資源可能會被其他Pod物件壓縮至極低的水平,甚至到該Pod物件無法被排程執行的境地。而對於非壓縮型記憶體資源來說,資源緊缺情形下可能導致相關的容器程式被殺死。因此,在Kubernetes系統上執行關鍵型業務相關的Pod時,必須要使用requests屬性為容器明確定義資源需求。當然,我們也可以為Pod物件定義較高的優先順序來改變這種局面。
當節點擁有足夠的可用記憶體時,容器可以使用其請求的記憶體。 但是,容器不允許使用超過其限制的記憶體。 如果容器分配的記憶體超過其限制,該容器會成為被終止的候選容器。 如果容器繼續消耗超出其限制的記憶體,則終止容器(OOMKilled)。 如果終止的容器可以被重啟,則 kubelet 會重新啟動它,就像其他任何型別的執行時失敗一樣。