chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Kubernetes Pod調度策略原理與落地指南

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 2026-02-27 11:08 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

Pod調度是Kubernetes的核心機制之一,決定了Pod最終運行在哪個節(jié)點上。默認調度器kube-scheduler通過一系列預選(Filtering)和優(yōu)選(Scoring)算法完成調度決策,但默認行為在生產環(huán)境中往往不夠用。

實際場景中經常遇到的問題:數據庫Pod被調度到了沒有SSD的節(jié)點上,導致IO性能差;兩個高負載服務的Pod被調度到同一個節(jié)點,互相搶資源;GPU節(jié)點上跑了一堆普通業(yè)務Pod,真正需要GPU的任務反而調度不上去。

這些問題都需要通過調度策略來解決。Kubernetes提供了nodeSelector、nodeAffinity、podAffinity/podAntiAffinity、taints/tolerations、topologySpreadConstraints等多種調度機制,本文逐一講解并給出生產環(huán)境的配置方案。

1.2 技術特點

多層調度控制:從簡單的nodeSelector到復雜的自定義調度器,提供不同粒度的調度控制能力

軟硬約束結合:requiredDuringScheduling是硬約束(不滿足就不調度),preferredDuringScheduling是軟約束(盡量滿足,不滿足也能調度)

拓撲感知:topologySpreadConstraints支持按zone、node、rack等拓撲域分散Pod,實現跨故障域部署

搶占機制:PriorityClass支持高優(yōu)先級Pod搶占低優(yōu)先級Pod的資源

1.3 適用場景

場景一:將數據庫、緩存等IO密集型Pod調度到SSD節(jié)點,計算密集型Pod調度到高CPU節(jié)點

場景二:同一服務的多個副本分散到不同節(jié)點/可用區(qū),避免單點故障導致服務全部不可用

場景三:GPU、FPGA等特殊硬件資源的獨占調度,防止普通Pod占用專用資源

場景四:多租戶集群中,不同團隊的Pod隔離到各自的節(jié)點池

1.4 環(huán)境要求

組件 版本要求 說明
Kubernetes 1.24+ topologySpreadConstraints在1.19 GA,PodSecurity在1.25 GA
kube-scheduler 與集群版本一致 自定義調度器需要單獨部署
節(jié)點標簽 提前規(guī)劃 調度策略依賴節(jié)點標簽,需要統一標簽規(guī)范
metrics-server 0.6+ 資源感知調度需要metrics數據

二、詳細步驟

2.1 準備工作

2.1.1 節(jié)點標簽規(guī)劃

調度策略的基礎是節(jié)點標簽,先把標簽體系規(guī)劃好:

# 查看現有節(jié)點標簽
kubectl get nodes --show-labels

# 按硬件類型打標簽
kubectl label node k8s-worker-01 disktype=ssd
kubectl label node k8s-worker-02 disktype=ssd
kubectl label node k8s-worker-03 disktype=hdd

# 按業(yè)務用途打標簽
kubectl label node k8s-worker-01 workload-type=database
kubectl label node k8s-worker-02 workload-type=application
kubectl label node k8s-worker-03 workload-type=application

# 按可用區(qū)打標簽(如果是多機房部署)
kubectl label node k8s-worker-01 topology.kubernetes.io/zone=zone-a
kubectl label node k8s-worker-02 topology.kubernetes.io/zone=zone-b
kubectl label node k8s-worker-03 topology.kubernetes.io/zone=zone-c

# GPU節(jié)點標簽
kubectl label node k8s-gpu-01 accelerator=nvidia-tesla-v100
kubectl label node k8s-gpu-02 accelerator=nvidia-tesla-a100

# 驗證標簽
kubectl get nodes -L disktype,workload-type,topology.kubernetes.io/zone

注意:標簽key的命名要有規(guī)范,建議用/格式,如company.com/team=backend。Kubernetes內置標簽用kubernetes.io和k8s.io前綴,自定義標簽不要用這兩個前綴。

2.1.2 理解調度流程

kube-scheduler的調度流程分為兩個階段:

預選(Filtering):過濾掉不滿足條件的節(jié)點,比如資源不足、nodeSelector不匹配、taint不容忍等

優(yōu)選(Scoring):對通過預選的節(jié)點打分,選擇得分最高的節(jié)點

# 查看scheduler的調度日志(需要提高日志級別)
# 修改/etc/kubernetes/manifests/kube-scheduler.yaml
# 在command中添加 --v=4
# 然后查看日志
kubectl logs -n kube-system kube-scheduler-k8s-master-01 --tail=50

2.1.3 調度策略優(yōu)先級

多種調度策略同時存在時的生效順序:

nodeName(最高優(yōu)先級):直接指定節(jié)點名,跳過調度器

taints/tolerations:節(jié)點污點過濾,不容忍的Pod直接排除

nodeSelector:簡單的標簽匹配過濾

nodeAffinity:更靈活的節(jié)點親和性規(guī)則

podAffinity/podAntiAffinity:Pod間的親和/反親和

topologySpreadConstraints:拓撲分散約束

資源請求:節(jié)點剩余資源是否滿足Pod的requests

2.2 核心配置

2.2.1 nodeSelector(最簡單的調度約束)

nodeSelector是最基礎的調度方式,通過標簽鍵值對匹配節(jié)點:

# 文件:nginx-nodeselector.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:nginx-ssd
namespace:default
spec:
replicas:3
selector:
 matchLabels:
  app:nginx-ssd
template:
 metadata:
  labels:
   app:nginx-ssd
 spec:
  nodeSelector:
   disktype:ssd
  containers:
   -name:nginx
    image:nginx:1.24
    resources:
     requests:
      cpu:100m
      memory:128Mi
     limits:
      cpu:200m
      memory:256Mi
kubectl apply -f nginx-nodeselector.yaml

# 驗證Pod只調度到了ssd節(jié)點
kubectl get pods -l app=nginx-ssd -o wide

注意:nodeSelector是硬約束,如果沒有節(jié)點匹配標簽,Pod會一直Pending。生產環(huán)境建議配合nodeAffinity的軟約束使用。

2.2.2 nodeAffinity(節(jié)點親和性)

nodeAffinity比nodeSelector更靈活,支持多種操作符和軟硬約束:

# 文件:app-node-affinity.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:app-with-affinity
namespace:default
spec:
replicas:6
selector:
 matchLabels:
  app:app-affinity
template:
 metadata:
  labels:
   app:app-affinity
 spec:
  affinity:
   nodeAffinity:
    # 硬約束:必須調度到zone-a或zone-b
    requiredDuringSchedulingIgnoredDuringExecution:
     nodeSelectorTerms:
      -matchExpressions:
        -key:topology.kubernetes.io/zone
         operator:In
         values:
          -zone-a
          -zone-b
    # 軟約束:優(yōu)先調度到ssd節(jié)點,權重1-100
    preferredDuringSchedulingIgnoredDuringExecution:
     -weight:80
      preference:
       matchExpressions:
        -key:disktype
         operator:In
         values:
          -ssd
     -weight:20
      preference:
       matchExpressions:
        -key:workload-type
         operator:In
         values:
          -application
  containers:
   -name:app
    image:nginx:1.24
    resources:
     requests:
      cpu:200m
      memory:256Mi

操作符說明

In:標簽值在列表中

NotIn:標簽值不在列表中

Exists:標簽存在(不關心值)

DoesNotExist:標簽不存在

Gt:標簽值大于指定值(僅限數字)

Lt:標簽值小于指定值(僅限數字)

注意:requiredDuringSchedulingIgnoredDuringExecution中的IgnoredDuringExecution表示Pod已經運行后,即使節(jié)點標簽變了也不會驅逐Pod。Kubernetes計劃實現RequiredDuringExecution但目前還沒有。

2.2.3 podAffinity和podAntiAffinity(Pod間親和/反親和)

控制Pod之間的調度關系,典型場景:Web應用和緩存部署在同一節(jié)點減少網絡延遲,同一服務的多個副本分散到不同節(jié)點。

# 文件:web-cache-affinity.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:web-frontend
namespace:default
spec:
replicas:3
selector:
 matchLabels:
  app:web-frontend
template:
 metadata:
  labels:
   app:web-frontend
 spec:
  affinity:
   # Pod親和:和redis-cache部署在同一節(jié)點
   podAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
     -weight:100
      podAffinityTerm:
       labelSelector:
        matchExpressions:
         -key:app
          operator:In
          values:
           -redis-cache
       topologyKey:kubernetes.io/hostname
   # Pod反親和:同一服務的副本分散到不同節(jié)點
   podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     -labelSelector:
       matchExpressions:
        -key:app
         operator:In
         values:
          -web-frontend
      topologyKey:kubernetes.io/hostname
  containers:
   -name:web
    image:nginx:1.24
    resources:
     requests:
      cpu:200m
      memory:256Mi

說明

topologyKey: kubernetes.io/hostname表示以節(jié)點為拓撲域,同一節(jié)點上的Pod視為同一拓撲域

topologyKey: topology.kubernetes.io/zone表示以可用區(qū)為拓撲域

podAntiAffinity的硬約束會限制副本數不能超過節(jié)點數,3個副本至少需要3個節(jié)點

警告:podAffinity/podAntiAffinity的計算復雜度是O(N^2),N是集群中的Pod數量。在Pod數量超過5000的大集群中,大量使用podAffinity會導致調度延遲從毫秒級上升到秒級。

2.2.4 Taints和Tolerations(污點和容忍)

Taints從節(jié)點角度排斥Pod,Tolerations從Pod角度容忍污點。兩者配合實現節(jié)點專用化。

# 給GPU節(jié)點添加污點,只允許GPU任務調度
kubectl taint nodes k8s-gpu-01 gpu=true:NoSchedule
kubectl taint nodes k8s-gpu-02 gpu=true:NoSchedule

# 給維護中的節(jié)點添加NoExecute污點,驅逐現有Pod
kubectl taint nodes k8s-worker-03 maintenance=true:NoExecute

# 查看節(jié)點污點
kubectl describe node k8s-gpu-01 | grep -A 5 Taints

# 刪除污點
kubectl taint nodes k8s-worker-03 maintenance=true:NoExecute-

Pod中配置Tolerations:

# 文件:gpu-job.yaml
apiVersion:batch/v1
kind:Job
metadata:
name:gpu-training-job
namespace:ml-training
spec:
template:
 spec:
  tolerations:
   # 容忍gpu污點
   -key:"gpu"
    operator:"Equal"
    value:"true"
    effect:"NoSchedule"
  nodeSelector:
   accelerator:nvidia-tesla-v100
  containers:
   -name:training
    image:pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
    resources:
     limits:
      nvidia.com/gpu:1
     requests:
      cpu:"4"
      memory:"16Gi"
  restartPolicy:Never

Taint Effect說明

NoSchedule:新Pod不會調度到該節(jié)點,已有Pod不受影響

PreferNoSchedule:盡量不調度,但資源不足時仍可調度

NoExecute:新Pod不調度,已有Pod如果不容忍會被驅逐??梢栽O置tolerationSeconds指定驅逐前的等待時間

# 容忍NoExecute污點,但最多等待300秒后被驅逐
tolerations:
-key:"maintenance"
 operator:"Equal"
 value:"true"
 effect:"NoExecute"
 tolerationSeconds:300

2.2.5 topologySpreadConstraints(拓撲分散約束)

1.19版本GA的功能,比podAntiAffinity更精細地控制Pod在拓撲域間的分布:

# 文件:app-topology-spread.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:app-spread
namespace:default
spec:
replicas:9
selector:
 matchLabels:
  app:app-spread
template:
 metadata:
  labels:
   app:app-spread
 spec:
  topologySpreadConstraints:
   # 跨可用區(qū)均勻分布,最大偏差1
   -maxSkew:1
    topologyKey:topology.kubernetes.io/zone
    whenUnsatisfiable:DoNotSchedule
    labelSelector:
     matchLabels:
      app:app-spread
   # 跨節(jié)點均勻分布,最大偏差1,軟約束
   -maxSkew:1
    topologyKey:kubernetes.io/hostname
    whenUnsatisfiable:ScheduleAnyway
    labelSelector:
     matchLabels:
      app:app-spread
  containers:
   -name:app
    image:nginx:1.24
    resources:
     requests:
      cpu:100m
      memory:128Mi

參數說明

maxSkew:拓撲域間Pod數量的最大差值。設為1表示任意兩個域的Pod數量差不超過1

topologyKey:拓撲域的標簽key

whenUnsatisfiable:不滿足約束時的行為,DoNotSchedule(硬約束)或ScheduleAnyway(軟約束)

9個副本在3個zone中的分布結果:zone-a=3, zone-b=3, zone-c=3。如果zone-c只有1個節(jié)點且資源不足,DoNotSchedule會導致部分Pod Pending,ScheduleAnyway則會盡量均勻但允許偏差。

2.2.6 PriorityClass(優(yōu)先級和搶占)

高優(yōu)先級Pod可以搶占低優(yōu)先級Pod的資源:

# 定義優(yōu)先級類
apiVersion:scheduling.k8s.io/v1
kind:PriorityClass
metadata:
name:critical-production
value:1000000
globalDefault:false
preemptionPolicy:PreemptLowerPriority
description:"生產核心服務,可搶占低優(yōu)先級Pod"
---
apiVersion:scheduling.k8s.io/v1
kind:PriorityClass
metadata:
name:normal-production
value:500000
globalDefault:true
preemptionPolicy:PreemptLowerPriority
description:"普通生產服務"
---
apiVersion:scheduling.k8s.io/v1
kind:PriorityClass
metadata:
name:batch-job
value:100000
globalDefault:false
preemptionPolicy:Never
description:"批處理任務,不搶占其他Pod"

在Pod中引用:

apiVersion:apps/v1
kind:Deployment
metadata:
name:core-api
spec:
replicas:3
selector:
 matchLabels:
  app:core-api
template:
 metadata:
  labels:
   app:core-api
 spec:
  priorityClassName:critical-production
  containers:
   -name:api
    image:myapp:v1.0
    resources:
     requests:
      cpu:"1"
      memory:"2Gi"

警告:preemptionPolicy: PreemptLowerPriority會驅逐低優(yōu)先級Pod來騰出資源,被驅逐的Pod會收到SIGTERM信號。確保應用能正確處理優(yōu)雅關閉,否則會丟數據。生產環(huán)境建議批處理任務設置preemptionPolicy: Never。

2.3 啟動和驗證

2.3.1 驗證調度結果

# 查看Pod調度到了哪個節(jié)點
kubectl get pods -o wide -l app=app-spread

# 查看Pod的調度事件
kubectl describe pod  | grep -A 10 Events

# 查看調度失敗的原因
kubectl get events --field-selector reason=FailedScheduling -A

# 查看節(jié)點資源分配情況
kubectl describe node k8s-worker-01 | grep -A 20"Allocated resources"

2.3.2 調度模擬測試

# 使用kubectl創(chuàng)建一個dry-run的Pod,查看是否能調度成功
kubectl runtest-schedule --image=nginx:1.24 --dry-run=server -o yaml 
 --overrides='{
  "spec": {
   "nodeSelector": {"disktype": "ssd"},
   "containers": [{"name": "test", "image": "nginx:1.24", "resources": {"requests": {"cpu": "100m", "memory": "128Mi"}}}]
  }
 }'

# 查看各節(jié)點的可分配資源
kubectl get nodes -o custom-columns=
NAME:.metadata.name,
CPU_ALLOC:.status.allocatable.cpu,
MEM_ALLOC:.status.allocatable.memory,
PODS_ALLOC:.status.allocatable.pods

2.3.3 驗證拓撲分散

# 查看Pod在各zone的分布
kubectl get pods -l app=app-spread -o custom-columns=
NAME:.metadata.name,
NODE:.spec.nodeName,
ZONE:.spec.nodeName

# 更精確的方式:通過節(jié)點標簽查看
forpodin$(kubectl get pods -l app=app-spread -o jsonpath='{.items[*].spec.nodeName}');do
 zone=$(kubectl get node$pod-o jsonpath='{.metadata.labels.topology.kubernetes.io/zone}')
echo"Node:$pod, Zone:$zone"
done

三、示例代碼和配置

3.1 完整配置示例

3.1.1 多租戶節(jié)點池隔離方案

生產環(huán)境中不同團隊共用一個集群,通過taint+nodeAffinity實現節(jié)點池隔離:

# 文件:namespace-resource-setup.yaml
# 第一步:創(chuàng)建團隊namespace
apiVersion:v1
kind:Namespace
metadata:
name:team-backend
labels:
 team:backend
---
apiVersion:v1
kind:Namespace
metadata:
name:team-data
labels:
 team:data
---
# 第二步:為每個團隊設置ResourceQuota
apiVersion:v1
kind:ResourceQuota
metadata:
name:backend-quota
namespace:team-backend
spec:
hard:
 requests.cpu:"20"
 requests.memory:40Gi
 limits.cpu:"40"
 limits.memory:80Gi
 pods:"100"
---
apiVersion:v1
kind:ResourceQuota
metadata:
name:data-quota
namespace:team-data
spec:
hard:
 requests.cpu:"40"
 requests.memory:80Gi
 limits.cpu:"80"
 limits.memory:160Gi
 pods:"200"

節(jié)點打標簽和污點:

# backend團隊節(jié)點池
kubectl label node k8s-worker-{01..05} node-pool=backend
kubectl taint nodes k8s-worker-{01..05} node-pool=backend:NoSchedule

# data團隊節(jié)點池
kubectl label node k8s-worker-{06..10} node-pool=data
kubectl taint nodes k8s-worker-{06..10} node-pool=data:NoSchedule

# 公共節(jié)點池(不加污點,所有Pod都能調度)
kubectl label node k8s-worker-{11..15} node-pool=shared

團隊Deployment模板:

# 文件:backend-app-template.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:backend-api
namespace:team-backend
spec:
replicas:5
selector:
 matchLabels:
  app:backend-api
template:
 metadata:
  labels:
   app:backend-api
 spec:
  tolerations:
   -key:"node-pool"
    operator:"Equal"
    value:"backend"
    effect:"NoSchedule"
  affinity:
   nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     nodeSelectorTerms:
      -matchExpressions:
        -key:node-pool
         operator:In
         values:
          -backend
          -shared
   podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
     -weight:100
      podAffinityTerm:
       labelSelector:
        matchExpressions:
         -key:app
          operator:In
          values:
           -backend-api
       topologyKey:kubernetes.io/hostname
  containers:
   -name:api
    image:backend-api:v2.1.0
    ports:
     -containerPort:8080
    resources:
     requests:
      cpu:500m
      memory:512Mi
     limits:
      cpu:"1"
      memory:1Gi
    readinessProbe:
     httpGet:
      path:/health
      port:8080
     initialDelaySeconds:10
     periodSeconds:5
    livenessProbe:
     httpGet:
      path:/health
      port:8080
     initialDelaySeconds:30
     periodSeconds:10

3.1.2 調度策略自動注入腳本

通過Kyverno策略自動為特定namespace的Pod注入調度規(guī)則,避免每個Deployment都手動配置:

# 文件:kyverno-scheduling-policy.yaml
apiVersion:kyverno.io/v1
kind:ClusterPolicy
metadata:
name:inject-node-affinity-backend
spec:
rules:
 -name:add-backend-scheduling
  match:
   any:
    -resources:
      kinds:
       -Pod
      namespaces:
       -team-backend
  mutate:
   patchStrategicMerge:
    spec:
     tolerations:
      -key:"node-pool"
       operator:"Equal"
       value:"backend"
       effect:"NoSchedule"
     affinity:
      nodeAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
         -matchExpressions:
           -key:node-pool
            operator:In
            values:
             -backend
             -shared

注意:Kyverno需要單獨安裝(helm install kyverno kyverno/kyverno -n kyverno --create-namespace)。這種方式比在每個Deployment里寫調度規(guī)則更易維護,團隊只需要關注業(yè)務配置,調度策略由平臺團隊統一管理。

3.2 實際應用案例

案例一:數據庫Pod的調度策略

場景描述:MySQL主從集群部署在K8s中,主庫需要SSD+高內存節(jié)點,從庫可以用普通節(jié)點。主從Pod不能在同一節(jié)點上,避免節(jié)點故障導致主從同時不可用。

實現代碼

# 文件:mysql-master-statefulset.yaml
apiVersion:apps/v1
kind:StatefulSet
metadata:
name:mysql-master
namespace:database
spec:
serviceName:mysql-master
replicas:1
selector:
 matchLabels:
  app:mysql
  role:master
template:
 metadata:
  labels:
   app:mysql
   role:master
 spec:
  priorityClassName:critical-production
  affinity:
   nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     nodeSelectorTerms:
      -matchExpressions:
        -key:disktype
         operator:In
         values:
          -ssd
        -key:workload-type
         operator:In
         values:
          -database
   podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     -labelSelector:
       matchExpressions:
        -key:app
         operator:In
         values:
          -mysql
      topologyKey:kubernetes.io/hostname
  containers:
   -name:mysql
    image:mysql:8.0.35
    ports:
     -containerPort:3306
    env:
     -name:MYSQL_ROOT_PASSWORD
      valueFrom:
       secretKeyRef:
        name:mysql-secret
        key:root-password
    resources:
     requests:
      cpu:"2"
      memory:4Gi
     limits:
      cpu:"4"
      memory:8Gi
    volumeMounts:
     -name:mysql-data
      mountPath:/var/lib/mysql
volumeClaimTemplates:
 -metadata:
   name:mysql-data
  spec:
   accessModes:["ReadWriteOnce"]
   storageClassName:local-ssd
   resources:
    requests:
     storage:100Gi
---
# MySQL從庫
apiVersion:apps/v1
kind:StatefulSet
metadata:
name:mysql-slave
namespace:database
spec:
serviceName:mysql-slave
replicas:2
selector:
 matchLabels:
  app:mysql
  role:slave
template:
 metadata:
  labels:
   app:mysql
   role:slave
 spec:
  priorityClassName:normal-production
  affinity:
   podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     -labelSelector:
       matchExpressions:
        -key:app
         operator:In
         values:
          -mysql
      topologyKey:kubernetes.io/hostname
  topologySpreadConstraints:
   -maxSkew:1
    topologyKey:topology.kubernetes.io/zone
    whenUnsatisfiable:DoNotSchedule
    labelSelector:
     matchLabels:
      app:mysql
      role:slave
  containers:
   -name:mysql
    image:mysql:8.0.35
    ports:
     -containerPort:3306
    resources:
     requests:
      cpu:"1"
      memory:2Gi
     limits:
      cpu:"2"
      memory:4Gi
    volumeMounts:
     -name:mysql-data
      mountPath:/var/lib/mysql
volumeClaimTemplates:
 -metadata:
   name:mysql-data
  spec:
   accessModes:["ReadWriteOnce"]
   storageClassName:standard
   resources:
    requests:
     storage:100Gi

運行結果

NAME       READY  STATUS  NODE      ZONE
mysql-master-0  1/1   Running  k8s-worker-01  zone-a  (SSD+database節(jié)點)
mysql-slave-0  1/1   Running  k8s-worker-02  zone-b  (不同節(jié)點不同zone)
mysql-slave-1  1/1   Running  k8s-worker-03  zone-c  (不同節(jié)點不同zone)

案例二:混合調度策略實現灰度發(fā)布

場景描述:灰度發(fā)布時,新版本Pod先調度到特定的灰度節(jié)點,驗證通過后再擴展到所有節(jié)點。通過標簽和調度策略控制灰度范圍。

實現步驟

給灰度節(jié)點打標簽:

kubectl label node k8s-worker-01 canary=true

灰度版本Deployment:

# 文件:app-canary.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:myapp-canary
namespace:production
spec:
replicas:2
selector:
 matchLabels:
  app:myapp
  version:canary
template:
 metadata:
  labels:
   app:myapp
   version:canary
 spec:
  affinity:
   nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
     nodeSelectorTerms:
      -matchExpressions:
        -key:canary
         operator:In
         values:
          -"true"
  containers:
   -name:myapp
    image:myapp:v2.0.0-rc1
    ports:
     -containerPort:8080
    resources:
     requests:
      cpu:200m
      memory:256Mi

灰度驗證通過后,全量發(fā)布:

# 移除灰度節(jié)點約束,更新穩(wěn)定版Deployment的鏡像
kubectlsetimage deployment/myapp-stable myapp=myapp:v2.0.0 -n production

# 縮容灰度Deployment
kubectl scale deployment/myapp-canary --replicas=0 -n production

# 清理灰度標簽
kubectl label node k8s-worker-01 canary-

四、最佳實踐和注意事項

4.1 最佳實踐

4.1.1 性能優(yōu)化

減少podAffinity的使用范圍:podAffinity/podAntiAffinity的調度計算復雜度高,在500+節(jié)點集群中,一個帶podAffinity的Pod調度耗時從5ms增加到200ms。能用topologySpreadConstraints替代的場景優(yōu)先用topologySpreadConstraints。

# 不推薦:用podAntiAffinity實現分散
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
 -labelSelector:
   matchLabels:
    app:myapp
  topologyKey:kubernetes.io/hostname

# 推薦:用topologySpreadConstraints替代
topologySpreadConstraints:
-maxSkew:1
 topologyKey:kubernetes.io/hostname
 whenUnsatisfiable:DoNotSchedule
 labelSelector:
  matchLabels:
   app:myapp

合理設置resource requests:調度器根據requests而非limits做調度決策。requests設太高導致節(jié)點利用率低(實測平均CPU利用率只有15%),設太低導致節(jié)點超賣嚴重,Pod被OOMKill。建議requests設為實際使用量的P95值。

# 查看Pod實際資源使用,作為requests設置參考
kubectl top pods -n production --sort-by=cpu
kubectl top pods -n production --sort-by=memory

使用Descheduler重平衡:節(jié)點擴容或Pod漂移后,集群負載可能不均衡。Descheduler可以驅逐不符合當前調度策略的Pod,讓調度器重新調度。

# 安裝Descheduler
helm repo add descheduler https://kubernetes-sigs.github.io/descheduler/
helm install descheduler descheduler/descheduler -n kube-system 
 --setschedule="*/5 * * * *"

4.1.2 安全加固

限制nodeName直接指定:nodeName會跳過調度器的所有檢查(包括資源檢查),生產環(huán)境通過RBAC限制普通用戶使用nodeName字段。

# OPA/Gatekeeper策略:禁止使用nodeName
apiVersion:constraints.gatekeeper.sh/v1beta1
kind:K8sDenyNodeName
metadata:
name:deny-nodename
spec:
match:
 kinds:
  -apiGroups:[""]
   kinds:["Pod"]
 excludedNamespaces:["kube-system"]

PriorityClass權限控制:高優(yōu)先級PriorityClass的創(chuàng)建和使用需要限制,防止普通用戶創(chuàng)建高優(yōu)先級Pod搶占核心服務資源。

# RBAC:只允許admin使用critical-production優(yōu)先級
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
name:use-critical-priority
rules:
-apiGroups:["scheduling.k8s.io"]
 resources:["priorityclasses"]
 resourceNames:["critical-production"]
 verbs:["get","list"]

節(jié)點污點防篡改:關鍵節(jié)點(如GPU節(jié)點)的污點被誤刪會導致普通Pod涌入。通過準入控制webhook攔截對特定節(jié)點taint的修改操作。

4.1.3 高可用配置

HA方案一:核心服務至少3副本,配合podAntiAffinity硬約束分散到不同節(jié)點,再用topologySpreadConstraints分散到不同可用區(qū)

HA方案二:使用PodDisruptionBudget(PDB)限制同時不可用的Pod數量,防止節(jié)點維護時服務中斷

apiVersion:policy/v1
kind:PodDisruptionBudget
metadata:
name:myapp-pdb
spec:
minAvailable:2
selector:
 matchLabels:
  app:myapp

備份策略:調度策略配置(PriorityClass、節(jié)點標簽、污點)納入GitOps管理,用ArgoCD或FluxCD同步

4.2 注意事項

4.2.1 配置注意事項

警告:調度策略配置錯誤可能導致Pod無法調度或調度到錯誤節(jié)點,修改前在測試環(huán)境驗證。

注意nodeAffinity的requiredDuringSchedulingIgnoredDuringExecution中,多個nodeSelectorTerms之間是OR關系,同一個nodeSelectorTerm中的多個matchExpressions之間是AND關系。搞混了會導致調度結果不符合預期。

注意podAntiAffinity硬約束會限制副本數上限。如果topologyKey是kubernetes.io/hostname,副本數不能超過可用節(jié)點數,否則多出來的Pod永遠Pending。

注意topologySpreadConstraints的labelSelector必須和Pod自身的標簽匹配,否則約束不生效。這個錯誤很隱蔽,Pod能正常調度但分布不均勻。

4.2.2 常見錯誤

錯誤現象 原因分析 解決方案
Pod一直Pending,事件顯示0/6 nodes are available nodeSelector或nodeAffinity沒有匹配的節(jié)點 檢查節(jié)點標簽是否正確:kubectl get nodes --show-labels
Pod調度成功但分布不均勻 topologySpreadConstraints的labelSelector寫錯 確認labelSelector和Pod的labels完全一致
高優(yōu)先級Pod搶占后,被搶占的Pod無法重新調度 集群資源不足,被搶占的Pod也找不到合適節(jié)點 擴容節(jié)點或降低resource requests
taint添加后已有Pod沒被驅逐 使用了NoSchedule而非NoExecute NoSchedule只影響新Pod,要驅逐已有Pod用NoExecute
節(jié)點維護drain失敗 Pod有PDB限制,minAvailable不滿足 先擴容副本數,或臨時調整PDB的minAvailable

4.2.3 兼容性問題

版本兼容:topologySpreadConstraints在1.18 Beta、1.19 GA;minDomains字段在1.25 Beta,使用前確認集群版本

平臺兼容:云廠商托管K8s通常自動設置topology.kubernetes.io/zone標簽,自建集群需要手動設置

組件依賴:Descheduler版本需要和K8s版本匹配,0.27.x支持K8s 1.25-1.28

五、故障排查和監(jiān)控

5.1 故障排查

5.1.1 日志查看

# 查看kube-scheduler日志
kubectl logs -n kube-system -l component=kube-scheduler --tail=100

# 查看調度事件
kubectl get events -A --field-selector reason=FailedScheduling --sort-by='.lastTimestamp'

# 查看特定Pod的調度事件
kubectl describe pod  -n  | grep -A 20 Events

# 查看節(jié)點資源分配詳情
kubectl describe node  | grep -A 30"Allocated resources"

5.1.2 常見問題排查

問題一:Pod Pending,報Insufficient cpu

# 診斷命令
kubectl describe pod  | grep -A 5"Events"
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU_REQ:.status.allocatable.cpu,MEM_REQ:.status.allocatable.memory

# 查看各節(jié)點已分配資源
fornodein$(kubectl get nodes -o jsonpath='{.items[*].metadata.name}');do
echo"===$node==="
 kubectl describe node$node| grep -A 5"Allocated resources"
done

解決方案

檢查Pod的resource requests是否設置過高

檢查節(jié)點是否有足夠的可分配資源(allocatable - 已分配)

考慮擴容節(jié)點或優(yōu)化現有Pod的資源配置

問題二:調度策略不生效,Pod沒有按預期分布

# 診斷命令
kubectl get pod  -o yaml | grep -A 50"affinity"
kubectl get pod  -o yaml | grep -A 20"topologySpreadConstraints"

# 檢查節(jié)點標簽是否正確
kubectl get nodes --show-labels | grep 

解決方案

確認YAML縮進正確,affinity字段層級關系容易寫錯

確認labelSelector和Pod標簽一致

用kubectl apply --dry-run=server驗證YAML語法

問題三:節(jié)點drain卡住不動

癥狀:kubectl drain命令長時間無響應

排查

# 查看哪些Pod阻止了drain
kubectl drain  --ignore-daemonsets --delete-emptydir-data --dry-run=client

# 檢查PDB
kubectl get pdb -A

解決

DaemonSet的Pod加--ignore-daemonsets跳過

使用emptyDir的Pod加--delete-emptydir-data

PDB限制導致的,先擴容副本再drain

有Pod設置了terminationGracePeriodSeconds很長,加--timeout=300s限制等待時間

5.1.3 調試模式

# 提高scheduler日志級別
# 編輯/etc/kubernetes/manifests/kube-scheduler.yaml
# 在command中添加 --v=10(最詳細,僅調試用)

# 查看scheduler的調度決策過程
kubectl logs -n kube-system kube-scheduler-k8s-master-01 | grep"pod-name"

# 使用kubectl-scheduler-simulator模擬調度(需要單獨安裝)
# https://github.com/kubernetes-sigs/kube-scheduler-simulator

# 查看scheduler的metrics
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes

5.2 性能監(jiān)控

5.2.1 關鍵指標監(jiān)控

# 調度延遲
kubectl get --raw /metrics | grep scheduler_scheduling_algorithm_duration_seconds

# 調度隊列長度
kubectl get --raw /metrics | grep scheduler_pending_pods

# 搶占次數
kubectl get --raw /metrics | grep scheduler_preemption_victims

# 節(jié)點資源使用率
kubectl top nodes

5.2.2 監(jiān)控指標說明

指標名稱 正常范圍 告警閾值 說明
調度延遲(P99) <100ms >500ms 超過500ms說明調度器過載或策略過于復雜
Pending Pod數量 0 >10持續(xù)5分鐘 持續(xù)有Pod無法調度需要排查
調度失敗率 <1% >5% 高失敗率說明資源不足或策略配置有問題
節(jié)點CPU分配率 40%-70% >85% 分配率過高會導致新Pod無法調度
節(jié)點內存分配率 50%-80% >90% 接近100%時需要擴容
搶占事件數 0 >5次/小時 頻繁搶占說明資源規(guī)劃不合理

5.2.3 Prometheus監(jiān)控規(guī)則

# 文件:scheduler-alerts.yaml
apiVersion:monitoring.coreos.com/v1
kind:PrometheusRule
metadata:
name:scheduler-alerts
namespace:monitoring
spec:
groups:
 -name:kube-scheduler
  rules:
   -alert:SchedulerHighLatency
    expr:|
      histogram_quantile(0.99,
       sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket[5m])) by (le)
      ) > 0.5
    for:10m
    labels:
     severity:warning
    annotations:
     summary:"Scheduler P99 latency exceeds 500ms"

   -alert:PodsPendingTooLong
    expr:|
      sum(scheduler_pending_pods{queue="active"}) > 10
    for:5m
    labels:
     severity:warning
    annotations:
     summary:"More than 10 pods pending for over 5 minutes"

   -alert:SchedulerUnhealthy
    expr:absent(up{job="kube-scheduler"}==1)
    for:3m
    labels:
     severity:critical
    annotations:
     summary:"kube-scheduler is not running"

   -alert:NodeHighAllocation
    expr:|
      (1 - sum(kube_node_status_allocatable{resource="cpu"} - kube_pod_container_resource_requests{resource="cpu"}) by (node)
      / sum(kube_node_status_allocatable{resource="cpu"}) by (node)) > 0.85
    for:10m
    labels:
     severity:warning
    annotations:
     summary:"Node{{ $labels.node }}CPU allocation exceeds 85%"

   -alert:FrequentPreemption
    expr:|
      increase(scheduler_preemption_victims[1h]) > 5
    for:5m
    labels:
     severity:warning
    annotations:
     summary:"More than 5 preemption events in the last hour"

5.3 備份與恢復

5.3.1 備份策略

#!/bin/bash
# 調度策略配置備份腳本
# 文件:/opt/scripts/scheduling-config-backup.sh

set-euo pipefail

BACKUP_DIR="/data/scheduling-backup/$(date +%Y%m%d)"
mkdir -p"${BACKUP_DIR}"

# 備份PriorityClass
kubectl get priorityclass -o yaml >"${BACKUP_DIR}/priorityclasses.yaml"

# 備份PDB
kubectl get pdb -A -o yaml >"${BACKUP_DIR}/pdbs.yaml"

# 備份節(jié)點標簽和污點
fornodein$(kubectl get nodes -o jsonpath='{.items[*].metadata.name}');do
 kubectl get node"$node"-o jsonpath='{.metadata.labels}'>"${BACKUP_DIR}/${node}-labels.json"
 kubectl get node"$node"-o jsonpath='{.spec.taints}'>"${BACKUP_DIR}/${node}-taints.json"
done

# 備份Kyverno策略(如果使用)
kubectl get clusterpolicy -o yaml >"${BACKUP_DIR}/kyverno-policies.yaml"2>/dev/null ||true

echo"[$(date)] Scheduling config backup completed:${BACKUP_DIR}"

5.3.2 恢復流程

停止服務:暫停業(yè)務部署,避免恢復過程中的調度沖突

恢復數據:kubectl apply -f ${BACKUP_DIR}/priorityclasses.yaml

驗證完整性:kubectl get priorityclass確認PriorityClass恢復

恢復節(jié)點配置:逐節(jié)點恢復標簽和污點

驗證調度:創(chuàng)建測試Pod驗證調度策略是否生效

六、總結

6.1 技術要點回顧

要點一:nodeSelector適合簡單場景,nodeAffinity適合需要軟硬約束結合的場景,兩者都基于節(jié)點標簽,標簽規(guī)劃是基礎

要點二:podAntiAffinity硬約束會限制副本數不超過節(jié)點數,大規(guī)模集群中計算開銷大,優(yōu)先用topologySpreadConstraints替代

要點三:taints/tolerations從節(jié)點角度控制調度,適合節(jié)點專用化場景(GPU節(jié)點、數據庫節(jié)點),NoExecute會驅逐已有Pod

要點四:PriorityClass的搶占機制要謹慎使用,批處理任務設置preemptionPolicy: Never,核心服務設置高優(yōu)先級

要點五:topologySpreadConstraints是生產環(huán)境跨故障域部署的首選方案,maxSkew: 1配合DoNotSchedule保證嚴格均勻分布

6.2 進階學習方向

自定義調度器:當內置調度策略無法滿足需求時,可以開發(fā)自定義調度器,通過Scheduling Framework擴展點實現

學習資源:Scheduling Framework

實踐建議:先用調度器擴展(Extender)驗證邏輯,再考慮寫Framework插件

Descheduler深度使用:配置LowNodeUtilization、RemoveDuplicates等策略,自動重平衡集群負載

學習資源:Descheduler GitHub

實踐建議:先在非生產環(huán)境測試Descheduler策略,避免誤驅逐核心服務

Volcano批調度器:針對AI/大數據場景的批調度器,支持Gang Scheduling(一組Pod要么全部調度成功,要么全部不調度)

6.3 參考資料

Kubernetes調度官方文檔 - 調度機制全面說明

kube-scheduler源碼 - 理解調度算法實現

Descheduler項目 - Pod重調度工具

Volcano項目 - 批調度器

附錄

A. 命令速查表

# 節(jié)點標簽管理
kubectl label node  key=value       # 添加標簽
kubectl label node  key=value --overwrite # 修改標簽
kubectl label node  key-          # 刪除標簽
kubectl get nodes --show-labels         # 查看所有標簽
kubectl get nodes -L key1,key2          # 查看指定標簽列

# 污點管理
kubectl taint nodes  key=value:NoSchedule # 添加污點
kubectl taint nodes  key=value:NoSchedule- # 刪除污點
kubectl taint nodes  key-         # 刪除指定key的所有污點
kubectl describe node  | grep Taints    # 查看污點

# 調度排查
kubectl get events --field-selector reason=FailedScheduling -A # 調度失敗事件
kubectl describe pod  | grep -A 10 Events  # Pod事件
kubectl get pods -o wide             # 查看Pod所在節(jié)點
kubectl top nodes                # 節(jié)點資源使用
kubectl describe node  | grep -A 20"Allocated resources"# 已分配資源

# 節(jié)點維護
kubectl drain  --ignore-daemonsets --delete-emptydir-data # 騰空節(jié)點
kubectl uncordon              # 恢復調度
kubectl cordon               # 標記不可調度

B. 配置參數詳解

nodeAffinity操作符

操作符 含義 示例
In 值在列表中 values: ["ssd", "nvme"]
NotIn 值不在列表中 values: ["hdd"]
Exists 標簽存在 不需要values字段
DoesNotExist 標簽不存在 不需要values字段
Gt 值大于 values: ["100"] (數字字符串)
Lt 值小于 values: ["50"] (數字字符串)

Taint Effect對比

Effect 對新Pod 對已有Pod 適用場景
NoSchedule 不調度 不影響 節(jié)點專用化
PreferNoSchedule 盡量不調度 不影響 軟限制
NoExecute 不調度 驅逐 節(jié)點維護、故障隔離

topologySpreadConstraints參數

參數 類型 說明
maxSkew int 拓撲域間Pod數量最大差值,1表示嚴格均勻
topologyKey string 拓撲域標簽key
whenUnsatisfiable string DoNotSchedule 硬約束 /ScheduleAnyway軟約束
labelSelector object 匹配Pod的標簽選擇器
minDomains int 最少拓撲域數量(1.25 Beta)
matchLabelKeys []string 用于區(qū)分不同版本的Pod(1.27 Beta)

C. 術語表

術語 英文 解釋
預選 Filtering 調度第一階段,過濾不滿足條件的節(jié)點
優(yōu)選 Scoring 調度第二階段,對候選節(jié)點打分排序
親和性 Affinity Pod傾向于調度到滿足條件的節(jié)點或Pod附近
反親和性 Anti-Affinity Pod傾向于遠離滿足條件的Pod
污點 Taint 節(jié)點上的排斥標記,阻止不容忍的Pod調度
容忍 Toleration Pod上的聲明,表示可以容忍節(jié)點的污點
拓撲域 Topology Domain 按標簽劃分的節(jié)點組,如同一可用區(qū)的節(jié)點
搶占 Preemption 高優(yōu)先級Pod驅逐低優(yōu)先級Pod以獲取資源
PDB PodDisruptionBudget Pod中斷預算,限制同時不可用的Pod數量

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • gpu
    gpu
    +關注

    關注

    28

    文章

    5258

    瀏覽量

    136032
  • 數據庫
    +關注

    關注

    7

    文章

    4078

    瀏覽量

    68519
  • kubernetes
    +關注

    關注

    0

    文章

    273

    瀏覽量

    9528

原文標題:別再讓 Pod “亂跑”:Kubernetes 調度策略原理與落地指南

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Kubernetes的Device Plugin設計解讀

    設計解讀最近在調研Kubernetes的GPU調度和運行機制,發(fā)現傳統的alpha.kubernetes.io/nvidia-gpu即將在1.11版本中下線,和GPU相關的調度和部署的
    發(fā)表于 03-12 16:23

    阿里云容器Kubernetes監(jiān)控(二) - 使用Grafana展現Pod監(jiān)控數據

    kubernetes中承擔的責任遠不止監(jiān)控數據的采集,還包括控制臺的監(jiān)控接口、HPA的POD彈性伸縮等都依賴于Heapster的功能。簡介在kubernetes的監(jiān)控方案中
    發(fā)表于 05-10 15:28

    從零開始入門 K8s| 詳解 Pod 及容器設計模式

    一、為什么需要 Pod容器的基本概念我們知道 PodKubernetes 項目里面一個非常重要的概念,也是非常重要的一個原子調度單位,但是為什么我們會需要這樣一個概念呢?在使用容
    發(fā)表于 09-20 15:12

    不吹不黑,今天我們來聊一聊 Kubernetes 落地的三種方式

    Kubernetes 作為自己的基礎設施重心,"一萬個人眼中就有一萬個哈姆雷特",雖說 Kubernetes 是容器管理領域的事實標準,但實際上在不同背景的企業(yè)中,Kubernetes
    發(fā)表于 10-12 16:07

    Pod資源配置

    Kubernetes進階實戰(zhàn)》第四章《管理Pod資源對象》
    發(fā)表于 10-22 14:39

    深入研究Kubernetes調度

    “本文從 Pod 和節(jié)點的配置開始,介紹了 Kubernetes Scheduler 框架、擴展點、API 以及可能發(fā)生的與資源相關的瓶頸,并展示了性能調整設置,涵蓋了 Kubernetes
    的頭像 發(fā)表于 08-23 10:39 ?2027次閱讀

    Kubernetes組件pod核心原理

    1. 核心組件原理 —— pod 核心原理 1.1 pod 是什么 pod 也可以理解是一個容器,裝的是 docker 創(chuàng)建的容器,也就是用來封裝容器的一個容器; pod 是一個虛擬化
    的頭像 發(fā)表于 09-02 09:27 ?2566次閱讀

    Kubernetes中的Pod簡易理解

    PodKubernetes中非常重要的概念,也是Kubernetes管理的基本單位。正如其名,Pod像一個豌豆莢,可以容納多個container,擁有相同的IP地址。
    的頭像 發(fā)表于 02-15 10:44 ?2199次閱讀

    Kubernetes Pod如何獨立工作

    在學習 Kubernetes 網絡模型的過程中,了解各種網絡組件的作用以及如何交互非常重要。本文就介紹了各種網絡組件在 Kubernetes 集群中是如何交互的,以及如何幫助每個 Pod 都能獲取 IP 地址。
    的頭像 發(fā)表于 05-16 14:29 ?1273次閱讀
    <b class='flag-5'>Kubernetes</b> <b class='flag-5'>Pod</b>如何獨立工作

    Kubernetes Pod如何獲取IP地址呢?

    Kubernetes 網絡模型的核心要求之一是每個 Pod 都擁有自己的 IP 地址并可以使用該 IP 地址進行通信。很多人剛開始使用 Kubernetes 時,還不清楚如何為每個 Pod
    的頭像 發(fā)表于 07-21 10:00 ?1593次閱讀
    <b class='flag-5'>Kubernetes</b> <b class='flag-5'>Pod</b>如何獲取IP地址呢?

    配置KubernetesPod使用代理的兩種常見方式

    在企業(yè)網絡環(huán)境中進行Kubernetes集群的管理時,經常會遇到需要配置Pods通過HTTP代理服務器訪問Internet的情況。這可能是由于各種原因,如安全策略限制、網絡架構要求或者訪問特定資源
    的頭像 發(fā)表于 01-05 11:22 ?2372次閱讀
    配置<b class='flag-5'>Kubernetes</b>中<b class='flag-5'>Pod</b>使用代理的兩種常見方式

    Kubernetes Pod常用管理命令詳解

    Kubernetes Pod常用管理命令詳解
    的頭像 發(fā)表于 02-17 14:06 ?1621次閱讀
    <b class='flag-5'>Kubernetes</b> <b class='flag-5'>Pod</b>常用管理命令詳解

    詳解Kubernetes中的Pod調度親和性

    Kubernetes(K8s)中,Pod 調度親和性(Affinity) 是一種高級調度策略,用于控制
    的頭像 發(fā)表于 06-07 13:56 ?1077次閱讀

    Kubernetes Pod異常問題排查實戰(zhàn)

    集群跑著跑著,Pod 掛了。Slack 告警一刷屏,腦子一片空白。打開終端敲 kubectl get pods,看到一堆 CrashLoopBackOff、ImagePullBackOff、Pending,不知道從哪下手。這是每個剛接觸 Kubernetes 運維的人都會
    的頭像 發(fā)表于 03-18 15:43 ?239次閱讀

    Kubernetes Pod啟動失敗的各種場景及其排障方法

    Kubernetes 日常運維中,Pod 起不來是最常見的故障形態(tài)之一。很多運維工程師看到 Pod 狀態(tài)不是 Running 時,第一反應是盯著 kubectl get pod
    的頭像 發(fā)表于 04-13 13:53 ?72次閱讀