Kubernetes:容器資源需求與限制(約束)

不羈的羅恩發表於2022-02-16

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 會重新啟動它,就像其他任何型別的執行時失敗一樣。

相關文章