Kubernetes資源請求與限制

ryanlll3發表於2021-01-04

Request/Limit 基本概念。

K8S支援在容器界別設定Request和Limit來約束容器所使用的CPU和Memory。

  • Request表示在應用釋出時,對容器所使用CPU和Memory的預估,提出的申請。K8S會根據當前工作節點的資源情況,進行排程決策,K8S會把POD排程到滿足資源需求的節點上去執行。如果請求的資源不能得到滿足,那釋出的POD會處於Pending狀態。
  • Limit表示容器執行時對資源需求的限制,如果容器的CPU使用量達到或超過限制,K8S會限制容器對CPU資源的額外使用。如果容器的記憶體使用量達到或超過限制,K8S會Kill掉POD。

下圖單位:
m為minicore
cpu: “1000m” = “1core”
在這裡插入圖片描述

QOS/POD Kill 策略

三種QOS設定類別的POD以及相應踢出決策。

  • Guaranteed CPU&Memory 都需要設定,並且request=limit。這類POD只有在記憶體使用量超過限制的時候才會被Kill掉。
  • Burstable 這類POD屬於突發流量型,當節點資源不足的時候,這類POD可能會被Kill掉。
  • Best Effort request和limit都不設定,這類POD屬於盡最大努力型,當節點資源不足時,這類POD首先會被Kill掉。

在這裡插入圖片描述

資源檢視命令

檢視本機節點名稱

kubectl get node

檢視本機節點與執行POD的詳情

kubectl describe node node_name
#找到Capacity, CPU, Memory, PODs數量, 已啟動的POD的資源使用與限制。

POD釋出檔案-資源限制配置樣例

注意:本檔案僅為樣例檔案,如需釋出,需要configmap文章中的所有yml檔案。

petclinic-deployment.yml檔案樣例修改。
注意resources為新增配置。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: petclinic
spec:
  replicas: 1
  selector:
    matchLabels:
      app: petclinic
  template:
    metadata:
      labels:
        app: petclinic
    spec:
      containers:
      - name: petclinic
        # Run this image
        image: spring2go/spring-petclinic:1.0.0.RELEASE
        resources:
          requests:
            memory: "128Mi"
            # 200 minicore, 1000m = 1core
            cpu: "200m"
          limits:
            memory: "512Mi"
        envFrom:
          - configMapRef:
              name: petclinic-config
---
apiVersion: v1
kind: Service
metadata:
  # Unique key of the Service instance
  name: petclinic
spec:
  ports:
    # Accept traffic sent to port 80
    - name: http
      # port為叢集內部服務前通訊的埠
      port: 8080
      targetPort: 8080
      nodePort: 31080
  selector:
    # 下面標籤app: petclinic表示本服務會路由指向所有app標籤為petclinic的pod。
    app: petclinic
  type: NodePort

與其他檔案搭配發布。需要此文件中的YAML檔案一起釋出。

可以再次檢視節點詳情。

檢視本機節點名稱

kubectl get node

檢視本機節點與執行POD的詳情

kubectl describe node node_name
#找到Capacity, CPU, Memory, PODs數量, 已啟動的POD的資源使用與限制。

下面命令用於刪除與當前路徑下yml檔案對應的POD/Service。

kubectl detele -f .

實驗記憶體超限制

petclinic-deployment.yml檔案樣例修改。

修改位置:

  • replicas
  • requests - memory
  • limits -memory

啟動5個POD,每個容器啟動的時候都需要1個G的記憶體。總量接近5個G,實際上本NODE只給了4G記憶體。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: petclinic
spec:
  replicas: 5
  selector:
    matchLabels:
      app: petclinic
  template:
    metadata:
      labels:
        app: petclinic
    spec:
      containers:
      - name: petclinic
        # Run this image
        image: spring2go/spring-petclinic:1.0.0.RELEASE
        resources:
          requests:
            memory: "1024Mi"
            # 200 minicore, 1000m = 1core
            cpu: "200m"
          limits:
            memory: "1024Mi"
        envFrom:
          - configMapRef:
              name: petclinic-config
---
apiVersion: v1
kind: Service
metadata:
  # Unique key of the Service instance
  name: petclinic
spec:
  ports:
    # Accept traffic sent to port 80
    - name: http
      # port為叢集內部服務前通訊的埠
      port: 8080
      targetPort: 8080
      nodePort: 31080
  selector:
    # 下面標籤app: petclinic表示本服務會路由指向所有app標籤為petclinic的pod。
    app: petclinic
  type: NodePort

釋出服務之後,檢視POD。

kubectl get po

發現pending狀態的POD。由於節點記憶體不夠,所以一直pending。

檢視本機節點名稱

kubectl get node

檢視本機節點與執行POD的詳情

kubectl describe node node_name
#找到Capacity, CPU, Memory, PODs數量, 已啟動的POD的資源使用與限制。

下面命令用於刪除與當前路徑下yml檔案對應的POD/Service。

kubectl detele -f .

實驗限制記憶體過小

petclinic-deployment.yml檔案樣例修改。

修改位置:

  • replicas
  • requests - memory
  • limits -memory

啟動5個POD,每個容器啟動的時候都需要1個G的記憶體。總量接近5個G,實際上本NODE只給了4G記憶體。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: petclinic
spec:
  replicas: 1
  selector:
    matchLabels:
      app: petclinic
  template:
    metadata:
      labels:
        app: petclinic
    spec:
      containers:
      - name: petclinic
        # Run this image
        image: spring2go/spring-petclinic:1.0.0.RELEASE
        resources:
          requests:
            memory: "20Mi"
            # 200 minicore, 1000m = 1core
            cpu: "200m"
          limits:
            memory: "20Mi"
        envFrom:
          - configMapRef:
              name: petclinic-config
---
apiVersion: v1
kind: Service
metadata:
  # Unique key of the Service instance
  name: petclinic
spec:
  ports:
    # Accept traffic sent to port 80
    - name: http
      # port為叢集內部服務前通訊的埠
      port: 8080
      targetPort: 8080
      nodePort: 31080
  selector:
    # 下面標籤app: petclinic表示本服務會路由指向所有app標籤為petclinic的pod。
    app: petclinic
  type: NodePort

釋出服務之後,檢視POD。

kubectl get po
#發現CrashLoopBackOff狀態的POD。Restarts次數為1。因為該應用本身需要的執行記憶體大於20兆。

kubectl get po
#發現OOMKilled狀態的POD。Restarts次數為2。K8S Limit生效,將POD Kill掉。

環境清理。
下面命令用於刪除與當前路徑下yml檔案對應的deployment/Service。

kubectl detele -f .

相關文章