91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Kubernetes故障排查手冊(cè)

馬哥Linux運(yùn)維 ? 來源:馬哥Linux運(yùn)維 ? 2026-02-26 09:47 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Kubernetes故障排查手冊(cè)

一、概述

1.1 背景介紹

K8s集群出故障是常態(tài)。Pod起不來、Service訪問不通、節(jié)點(diǎn)NotReady、證書過期、etcd磁盤滿——每一個(gè)問題都可能導(dǎo)致業(yè)務(wù)中斷。和傳統(tǒng)運(yùn)維不同,K8s的故障鏈路更長:一個(gè)請(qǐng)求從Ingress進(jìn)來,經(jīng)過Service、Endpoint、kube-proxy的iptables/IPVS規(guī)則,到達(dá)Pod,中間任何一環(huán)出問題都會(huì)導(dǎo)致故障。

這篇手冊(cè)整理了生產(chǎn)環(huán)境中最常見的K8s故障場(chǎng)景和排查方法,按照"現(xiàn)象→定位→解決"的思路組織。不講理論,直接給排查命令和解決方案。

1.2 技術(shù)特點(diǎn)

分層排查思路:K8s故障排查遵循"節(jié)點(diǎn)層→控制平面層→工作負(fù)載層→網(wǎng)絡(luò)層"的分層模型,從底層往上排查效率最高

聲明式系統(tǒng)的排查特點(diǎn):K8s是聲明式系統(tǒng),故障往往表現(xiàn)為"期望狀態(tài)和實(shí)際狀態(tài)不一致"。排查的核心是找到哪個(gè)控制器沒有正常工作

事件驅(qū)動(dòng)排查:kubectl describe和kubectl get events是最有價(jià)值的排查入口,90%的問題能從Events中找到線索

1.3 適用場(chǎng)景

Pod狀態(tài)異常:CrashLoopBackOff、ImagePullBackOff、Pending、OOMKilled、Evicted

網(wǎng)絡(luò)故障:Service無法訪問、Pod間通信不通、DNS解析失敗、Ingress 502/504

節(jié)點(diǎn)故障:NotReady、磁盤壓力、內(nèi)存壓力、PID壓力

控制平面故障:API Server無響應(yīng)、etcd故障、調(diào)度器異常、證書過期

存儲(chǔ)故障:PVC Pending、掛載失敗、存儲(chǔ)性能問題

1.4 環(huán)境要求

組件 版本要求 說明
kubectl 與集群版本匹配 排查的核心工具,版本差異不超過1個(gè)小版本
crictl 與容器運(yùn)行時(shí)匹配 節(jié)點(diǎn)級(jí)容器排查工具,替代docker命令
nsenter 系統(tǒng)自帶 進(jìn)入容器網(wǎng)絡(luò)命名空間排查網(wǎng)絡(luò)問題
tcpdump 需要安裝 抓包分析網(wǎng)絡(luò)故障
etcdctl 與etcd版本匹配 etcd故障排查和數(shù)據(jù)恢復(fù)

二、詳細(xì)步驟

2.1 準(zhǔn)備工作

2.1.1 排查工具準(zhǔn)備

# 確認(rèn)kubectl版本和集群連接
kubectl version --short
kubectl cluster-info

# 安裝kubectl插件(可選但推薦)
# krew是kubectl插件管理器
kubectl krew install ctx   # 快速切換context
kubectl krew install ns    # 快速切換namespace
kubectl krew install neat   # 清理kubectl輸出中的冗余字段
kubectl krew install tree   # 以樹形展示資源關(guān)系
kubectl krew install node-shell# SSH到節(jié)點(diǎn)

# 準(zhǔn)備debug鏡像(用于網(wǎng)絡(luò)排查)
kubectl run debug-pod --image=nicolaka/netshoot --restart=Never -- sleep 3600

2.1.2 快速定位故障范圍

# 第一步:集群整體健康檢查
kubectl get nodes
kubectl get cs         # 控制平面組件狀態(tài)(1.19+已廢棄,用下面的命令)
kubectl get --raw='/readyz?verbose'

# 第二步:檢查所有namespace中異常的Pod
kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded | head -30

# 第三步:檢查最近的集群事件
kubectl get events -A --sort-by='.lastTimestamp'| tail -30

# 第四步:檢查節(jié)點(diǎn)資源壓力
kubectl describe nodes | grep -A 5"Conditions:"

2.2 核心配置

2.2.1 Pod故障排查

場(chǎng)景一:Pod狀態(tài) CrashLoopBackOff

Pod啟動(dòng)后立即退出,kubelet不斷重啟,重啟間隔指數(shù)增長(10s→20s→40s→...→5min)。

# 查看Pod狀態(tài)和重啟次數(shù)
kubectl get pod  -o wide

# 查看Pod事件
kubectl describe pod 
# 關(guān)注Events部分和容器的Last State

# 查看容器退出日志(最關(guān)鍵的一步)
kubectl logs  --previous
# --previous 查看上一次崩潰的日志,不加只能看到當(dāng)前(可能還沒輸出就崩了)

# 如果容器啟動(dòng)太快來不及看日志,用debug容器
kubectl debug  -it --copy-to=debug-pod --container=app -- sh

常見原因和解決方案

退出碼 含義 常見原因 解決方案
0 正常退出 應(yīng)用執(zhí)行完就退出了,不是常駐進(jìn)程 檢查Dockerfile的CMD/ENTRYPOINT
1 應(yīng)用錯(cuò)誤 配置文件錯(cuò)誤、依賴服務(wù)不可用 查看--previous日志定位具體錯(cuò)誤
137 SIGKILL(OOMKilled) 內(nèi)存超過limits被殺 調(diào)大memory limits或優(yōu)化應(yīng)用內(nèi)存使用
139 SIGSEGV 段錯(cuò)誤,程序bug 檢查應(yīng)用代碼,特別是C/C++/CGO
143 SIGTERM 被正常終止 檢查是否被liveness probe殺掉

# 確認(rèn)是否OOMKilled
kubectl get pod  -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'
# 如果輸出OOMKilled,查看內(nèi)存使用
kubectl top pod 

場(chǎng)景二:Pod狀態(tài) ImagePullBackOff

# 查看具體拉取錯(cuò)誤
kubectl describe pod  | grep -A 10"Events:"
# 常見錯(cuò)誤:
# ErrImagePull: 鏡像不存在或tag錯(cuò)誤
# ImagePullBackOff: 拉取失敗后的退避狀態(tài)
# unauthorized: 需要認(rèn)證但沒配置imagePullSecrets

# 檢查鏡像是否存在
crictl pull 

# 檢查imagePullSecrets配置
kubectl get pod  -o jsonpath='{.spec.imagePullSecrets}'
kubectl get secret  -o jsonpath='{.data..dockerconfigjson}'| base64 -d

解決方案

鏡像名或tag寫錯(cuò) → 修正鏡像地址

私有倉庫未配置認(rèn)證 → 創(chuàng)建docker-registry類型的Secret并關(guān)聯(lián)到Pod

網(wǎng)絡(luò)不通無法拉取 → 檢查節(jié)點(diǎn)到鏡像倉庫的網(wǎng)絡(luò)連通性

鏡像倉庫限流(Docker Hub免費(fèi)賬戶100次/6小時(shí))→ 配置鏡像代理或使用私有倉庫

# 創(chuàng)建鏡像拉取Secret
kubectl create secret docker-registry regcred 
 --docker-server=your-registry.com 
 --docker-username=user 
 --docker-password=pass 
 -n 

場(chǎng)景三:Pod狀態(tài) Pending

# Pending說明Pod還沒被調(diào)度到節(jié)點(diǎn)上
kubectl describe pod 
# 關(guān)注Events中的調(diào)度失敗原因

# 常見調(diào)度失敗原因:
# 0/3 nodes are available: 3 Insufficient cpu
# → 所有節(jié)點(diǎn)CPU不夠
# 0/3 nodes are available: 3 node(s) had taint {key: NoSchedule}
# → 所有節(jié)點(diǎn)有污點(diǎn),Pod沒配置容忍
# 0/3 nodes are available: 1 node(s) didn't match Pod's node affinity
# → 節(jié)點(diǎn)親和性不匹配
# 檢查集群可用資源
kubectl describe nodes | grep -A 8"Allocated resources:"

# 檢查節(jié)點(diǎn)污點(diǎn)
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

# 檢查PVC是否綁定(如果Pod掛載了PVC)
kubectl get pvc -n 
# Pending的PVC會(huì)導(dǎo)致Pod也Pending

2.2.2 網(wǎng)絡(luò)故障排查

場(chǎng)景一:Service無法訪問

# 第一步:確認(rèn)Service和Endpoint存在
kubectl get svc  -n 
kubectl get endpoints  -n 
# 如果Endpoints為空(),說明沒有Pod匹配Service的selector

# 第二步:確認(rèn)Service selector和Pod label匹配
kubectl get svc  -o jsonpath='{.spec.selector}'
kubectl get pods -l = -n 

# 第三步:確認(rèn)Pod端口和Service targetPort一致
kubectl get svc  -o jsonpath='{.spec.ports}'
kubectl get pod  -o jsonpath='{.spec.containers[0].ports}'

# 第四步:從集群內(nèi)部測(cè)試連通性
kubectl runtest-curl --rm -it --image=curlimages/curl -- 
 curl -v http://..svc:port/path

場(chǎng)景二:DNS解析失敗

# 測(cè)試DNS解析
kubectl run dns-test --rm -it --image=busybox:1.36 -- nslookup kubernetes.default
kubectl run dns-test --rm -it --image=busybox:1.36 -- nslookup ..svc.cluster.local

# 檢查CoreDNS是否正常運(yùn)行
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=30

# 檢查CoreDNS的ConfigMap
kubectl get configmap coredns -n kube-system -o yaml

# 檢查Pod的DNS配置
kubectlexec -- cat /etc/resolv.conf
# nameserver應(yīng)該指向CoreDNS的ClusterIP(通常是10.96.0.10)

常見DNS問題

CoreDNS Pod掛了 → 重啟CoreDNS:kubectl rollout restart deployment coredns -n kube-system

節(jié)點(diǎn)上的resolv.conf有問題導(dǎo)致CoreDNS上游解析失敗 → 檢查CoreDNS的forward配置

ndots配置導(dǎo)致解析慢 → Pod的resolv.conf默認(rèn)ndots:5,短域名會(huì)嘗試5次搜索域拼接后才查外部DNS??梢栽赑od spec中設(shè)置dnsConfig減小ndots

場(chǎng)景三:Pod間通信不通

# 從源Pod ping目標(biāo)Pod IP
kubectlexec -- ping -c 3 

# 如果ping不通,檢查CNI插件狀態(tài)
kubectl get pods -n kube-system | grep -E"calico|flannel|cilium|weave"

# 檢查節(jié)點(diǎn)間網(wǎng)絡(luò)
# 在源Pod所在節(jié)點(diǎn)上抓包
kubectl debug node/ -it --image=nicolaka/netshoot -- 
 tcpdump -i any host  -c 10

# 檢查NetworkPolicy是否阻止了通信
kubectl get networkpolicy -n 
kubectl describe networkpolicy  -n 

場(chǎng)景四:Ingress返回502/504

# 502通常是后端Pod不健康或不存在
# 504通常是后端Pod響應(yīng)超時(shí)

# 檢查Ingress配置
kubectl describe ingress  -n 

# 檢查Ingress Controller日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50

# 檢查后端Service的Endpoints
kubectl get endpoints  -n 

# 檢查后端Pod是否Ready
kubectl get pods -l  -n 
# 如果Pod Running但不Ready,說明readinessProbe失敗
kubectl describe pod  | grep -A 5"Readiness"

2.2.3 節(jié)點(diǎn)故障排查

場(chǎng)景一:節(jié)點(diǎn)狀態(tài)NotReady

# 查看節(jié)點(diǎn)狀態(tài)和條件
kubectl describe node  | grep -A 20"Conditions:"

# 常見Condition:
# Ready=False: kubelet停止上報(bào)心跳
# MemoryPressure=True: 內(nèi)存不足
# DiskPressure=True: 磁盤不足
# PIDPressure=True: PID耗盡
# NetworkUnavailable=True: 網(wǎng)絡(luò)插件未就緒

# SSH到節(jié)點(diǎn)檢查kubelet狀態(tài)
ssh 
systemctl status kubelet
journalctl -u kubelet --since"10 minutes ago"| tail -50

# 檢查節(jié)點(diǎn)資源
free -h
df -h
ps aux | wc -l

常見原因和解決方案

原因 排查命令 解決方案
kubelet進(jìn)程掛了 systemctl status kubelet systemctl restart kubelet
證書過期 openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates kubeadm certs renew all
磁盤滿 df -h 清理docker/containerd鏡像緩存:crictl rmi --prune
內(nèi)存不足 free -h 驅(qū)逐低優(yōu)先級(jí)Pod或擴(kuò)容節(jié)點(diǎn)
容器運(yùn)行時(shí)掛了 systemctl status containerd systemctl restart containerd

場(chǎng)景二:節(jié)點(diǎn)磁盤壓力(DiskPressure)

# 檢查磁盤使用
df -h /var/lib/kubelet
df -h /var/lib/containerd

# 查看占用空間最大的目錄
du -sh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/* | sort -rh | head -10

# 清理未使用的容器鏡像
crictl rmi --prune

# 清理已退出的容器
crictl rm $(crictl ps -a --state exited -q)

# 清理kubelet日志
journalctl --vacuum-size=500M

2.2.4 控制平面故障排查

場(chǎng)景一:API Server無響應(yīng)

# 檢查API Server Pod狀態(tài)
kubectl get pods -n kube-system -l component=kube-apiserver

# 如果kubectl完全無法連接,直接到Master節(jié)點(diǎn)操作
ssh 
crictl ps | grep kube-apiserver
crictl logs  --tail 50

# 檢查API Server端口是否監(jiān)聽
ss -tlnp | grep 6443

# 檢查etcd連接
etcdctl --endpoints=https://127.0.0.1:2379 
 --cacert=/etc/kubernetes/pki/etcd/ca.crt 
 --cert=/etc/kubernetes/pki/etcd/server.crt 
 --key=/etc/kubernetes/pki/etcd/server.key 
 endpoint health

場(chǎng)景二:證書過期

# 檢查所有證書過期時(shí)間
kubeadm certs check-expiration

# 輸出示例:
# CERTIFICATE        EXPIRES         RESIDUAL TIME
# admin.conf         Feb 08, 2027 00:00 UTC  364d
# apiserver         Feb 08, 2027 00:00 UTC  364d
# apiserver-etcd-client   Feb 08, 2027 00:00 UTC  364d
# ...

# 續(xù)期所有證書
kubeadm certs renew all

# 重啟控制平面組件使新證書生效
# kubeadm部署的集群,靜態(tài)Pod會(huì)自動(dòng)重啟
# 手動(dòng)檢查:
crictl ps | grep -E"kube-apiserver|kube-controller|kube-scheduler"

注意:證書續(xù)期后需要更新kubeconfig文件。kubeadm certs renew all會(huì)自動(dòng)更新/etc/kubernetes/*.conf,但如果你把kubeconfig復(fù)制到了其他地方(比如~/.kube/config),需要手動(dòng)更新。

2.3 啟動(dòng)和驗(yàn)證

2.3.1 故障恢復(fù)后驗(yàn)證清單

# 1. 集群整體狀態(tài)
kubectl get nodes
kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded

# 2. 控制平面組件
kubectl get pods -n kube-system

# 3. 核心服務(wù)可用性
kubectl run verify --rm -it --image=busybox:1.36 -- wget -qO- http://kubernetes.default.svc/healthz

# 4. DNS解析
kubectl run verify --rm -it --image=busybox:1.36 -- nslookup kubernetes.default

# 5. 業(yè)務(wù)服務(wù)健康檢查
kubectl get deployments -A | awk'$3 != $4 {print $0}'
# 輸出READY數(shù)不等于期望數(shù)的Deployment

2.3.2 驗(yàn)證網(wǎng)絡(luò)連通性

# 創(chuàng)建測(cè)試Pod驗(yàn)證跨節(jié)點(diǎn)通信
kubectl run net-test-1 --image=nicolaka/netshoot --restart=Never 
 --overrides='{"spec":{"nodeName":"node-1"}}'-- sleep 3600
kubectl run net-test-2 --image=nicolaka/netshoot --restart=Never 
 --overrides='{"spec":{"nodeName":"node-2"}}'-- sleep 3600

# 獲取Pod IP
POD1_IP=$(kubectl get pod net-test-1 -o jsonpath='{.status.podIP}')
POD2_IP=$(kubectl get pod net-test-2 -o jsonpath='{.status.podIP}')

# 跨節(jié)點(diǎn)ping測(cè)試
kubectlexecnet-test-1 -- ping -c 3$POD2_IP
kubectlexecnet-test-2 -- ping -c 3$POD1_IP

# 清理
kubectl delete pod net-test-1 net-test-2

三、示例代碼和配置

3.1 完整配置示例

3.1.1 一鍵集群健康檢查腳本

#!/bin/bash
# 文件名:k8s-health-check.sh
# 功能:全面檢查K8s集群健康狀態(tài),輸出診斷報(bào)告
# 用法:./k8s-health-check.sh

RED='?33[0;31m'
YELLOW='?33[1;33m'
GREEN='?33[0;32m'
NC='?33[0m'

echo"============================================"
echo" Kubernetes集群健康檢查報(bào)告"
echo" 時(shí)間:$(date '+%Y-%m-%d %H:%M:%S')"
echo"============================================"
echo""

# 1. 節(jié)點(diǎn)狀態(tài)
echo"=== 1. 節(jié)點(diǎn)狀態(tài) ==="
NOT_READY=$(kubectl get nodes --no-headers | grep -v" Ready "| wc -l)
TOTAL_NODES=$(kubectl get nodes --no-headers | wc -l)
if["$NOT_READY"-gt 0 ];then
 echo-e"${RED}[異常]$NOT_READY/$TOTAL_NODES個(gè)節(jié)點(diǎn)不健康${NC}"
  kubectl get nodes | grep -v" Ready "
else
 echo-e"${GREEN}[正常]$TOTAL_NODES/$TOTAL_NODES個(gè)節(jié)點(diǎn)健康${NC}"
fi
echo""

# 2. 節(jié)點(diǎn)資源壓力
echo"=== 2. 節(jié)點(diǎn)資源壓力 ==="
kubectl get nodes -o json | jq -r'
 .items[] |
 .metadata.name as $name |
 .status.conditions[] |
 select(.type != "Ready" and .status == "True") |
 "($name): (.type) = (.status) - (.message)"
'|whileread-r line;do
 echo-e"${RED}[壓力]$line${NC}"
done
echo""

# 3. 異常Pod
echo"=== 3. 異常Pod ==="
ABNORMAL=$(kubectl get pods -A --no-headers --field-selector status.phase!=Running,status.phase!=Succeeded 2>/dev/null | wc -l)
if["$ABNORMAL"-gt 0 ];then
 echo-e"${YELLOW}[警告]$ABNORMAL個(gè)異常Pod${NC}"
  kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded 2>/dev/null | head -20
else
 echo-e"${GREEN}[正常] 無異常Pod${NC}"
fi
echo""

# 4. CrashLoopBackOff的Pod
echo"=== 4. CrashLoopBackOff Pod ==="
kubectl get pods -A -o json | jq -r'
 .items[] |
 select(.status.containerStatuses[]? | select(.state.waiting.reason == "CrashLoopBackOff")) |
 [.metadata.namespace, .metadata.name,
 (.status.containerStatuses[0].restartCount | tostring)] | @tsv
'|whileIFS=$'	'read-r ns name restarts;do
 echo-e"${RED}[崩潰]$ns/$name(重啟${restarts}次)${NC}"
done
echo""

# 5. 高重啟次數(shù)Pod(>10次)
echo"=== 5. 高重啟次數(shù)Pod(>10次)==="
kubectl get pods -A -o json | jq -r'
 .items[] |
 select(.status.containerStatuses[]? | select(.restartCount > 10)) |
 [.metadata.namespace, .metadata.name,
 (.status.containerStatuses[0].restartCount | tostring)] | @tsv
'| sort -t$'	'-k3 -rn | head -10 |whileIFS=$'	'read-r ns name restarts;do
 echo-e"${YELLOW}[警告]$ns/$name:${restarts}次重啟${NC}"
done
echo""

# 6. Deployment副本數(shù)不匹配
echo"=== 6. Deployment副本數(shù)異常 ==="
kubectl get deployments -A -o json | jq -r'
 .items[] |
 select(.status.readyReplicas != .spec.replicas) |
 [.metadata.namespace, .metadata.name,
 (.status.readyReplicas // 0 | tostring),
 (.spec.replicas | tostring)] | @tsv
'|whileIFS=$'	'read-r ns name ready desired;do
 echo-e"${YELLOW}[異常]$ns/$name: Ready$ready/$desired${NC}"
done
echo""

# 7. PVC狀態(tài)
echo"=== 7. 未綁定的PVC ==="
kubectl get pvc -A --no-headers | grep -v"Bound"|whileread-r line;do
 echo-e"${YELLOW}[未綁定]$line${NC}"
done
echo""

# 8. 最近的Warning事件
echo"=== 8. 最近Warning事件(最近30分鐘)==="
kubectl get events -A --field-selectortype=Warning 
 --sort-by='.lastTimestamp'2>/dev/null | tail -10
echo""

echo"============================================"
echo" 檢查完成"
echo"============================================"

3.1.2 etcd健康檢查和備份腳本

#!/bin/bash
# 文件名:etcd-check-backup.sh
# 功能:檢查etcd健康狀態(tài)并執(zhí)行快照備份

ETCD_ENDPOINTS="https://127.0.0.1:2379"
ETCD_CACERT="/etc/kubernetes/pki/etcd/ca.crt"
ETCD_CERT="/etc/kubernetes/pki/etcd/server.crt"
ETCD_KEY="/etc/kubernetes/pki/etcd/server.key"
BACKUP_DIR="/opt/etcd-backup"

ETCDCTL="etcdctl --endpoints=$ETCD_ENDPOINTS
 --cacert=$ETCD_CACERT--cert=$ETCD_CERT--key=$ETCD_KEY"

echo"=== etcd健康檢查 ==="

# 端點(diǎn)健康狀態(tài)
$ETCDCTLendpoint health
echo""

# 端點(diǎn)狀態(tài)(包含數(shù)據(jù)庫大?。?$ETCDCTLendpoint status --write-out=table
echo""

# 成員列表
$ETCDCTLmember list --write-out=table
echo""

# 檢查數(shù)據(jù)庫大?。ǔ^4GB需要告警)
DB_SIZE=$($ETCDCTLendpoint status --write-out=json | jq'.[0].Status.dbSize')
DB_SIZE_MB=$((DB_SIZE / 1024 / 1024))
echo"數(shù)據(jù)庫大小:${DB_SIZE_MB}MB"
if["$DB_SIZE_MB"-gt 4000 ];then
 echo"[警告] etcd數(shù)據(jù)庫超過4GB,需要壓縮和碎片整理"
 # 壓縮歷史版本
  LATEST_REV=$($ETCDCTLendpoint status --write-out=json | jq'.[0].Status.header.revision')
 $ETCDCTLcompact"$LATEST_REV"
 # 碎片整理
 $ETCDCTLdefrag
fi

# 執(zhí)行快照備份
mkdir -p"$BACKUP_DIR"
SNAPSHOT_FILE="$BACKUP_DIR/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db"
$ETCDCTLsnapshot save"$SNAPSHOT_FILE"
$ETCDCTLsnapshot status"$SNAPSHOT_FILE"--write-out=table

echo"備份完成:$SNAPSHOT_FILE"

3.2 輔助腳本

3.2.1 Pod故障快速診斷腳本

#!/bin/bash
# 文件名:pod-diagnose.sh
# 功能:快速診斷指定Pod的問題
# 用法:./pod-diagnose.sh  

NS=${1:?"用法: $0  "}
POD=${2:?"請(qǐng)指定Pod名稱"}

echo"========== Pod診斷:$NS/$POD=========="

# 基本信息
echo"--- 基本狀態(tài) ---"
kubectl get pod"$POD"-n"$NS"-o wide
echo""

# 容器狀態(tài)
echo"--- 容器狀態(tài) ---"
kubectl get pod"$POD"-n"$NS"-o json | jq -r'
 .status.containerStatuses[]? |
 "容器: (.name) | Ready: (.ready) | 重啟: (.restartCount) | 狀態(tài): (.state | keys[0])"
'
echo""

# 事件
echo"--- 相關(guān)事件 ---"
kubectl get events -n"$NS"--field-selector"involvedObject.name=$POD"
 --sort-by='.lastTimestamp'| tail -10
echo""

# 如果有上次崩潰日志
RESTART_COUNT=$(kubectl get pod"$POD"-n"$NS"-o jsonpath='{.status.containerStatuses[0].restartCount}')
if["$RESTART_COUNT"-gt 0 ];then
 echo"--- 上次崩潰日志(最后30行)---"
  kubectl logs"$POD"-n"$NS"--previous --tail=30 2>/dev/null ||echo"無法獲取上次日志"
 echo""
fi

# 資源使用
echo"--- 資源使用 ---"
kubectl top pod"$POD"-n"$NS"2>/dev/null ||echo"Metrics不可用"
echo""

# 資源配置
echo"--- 資源配置 ---"
kubectl get pod"$POD"-n"$NS"-o json | jq'.spec.containers[] | {name, resources}'
echo""

echo"========== 診斷完成 =========="

3.2.2 節(jié)點(diǎn)資源排查腳本

#!/bin/bash
# 文件名:node-resource-check.sh
# 功能:檢查節(jié)點(diǎn)資源分配和使用情況
# 用法:./node-resource-check.sh [node-name]

NODE=${1:-""}

if[ -z"$NODE"];then
  NODES=$(kubectl get nodes -o jsonpath='{.items[*].metadata.name}')
else
  NODES="$NODE"
fi

fornin$NODES;do
 echo"========== 節(jié)點(diǎn):$n=========="

 # 節(jié)點(diǎn)狀態(tài)
  STATUS=$(kubectl get node"$n"-o jsonpath='{.status.conditions[?(@.type=="Ready")].status}')
 echo"狀態(tài): Ready=$STATUS"

 # 資源容量和已分配
 echo""
 echo"--- 資源分配 ---"
  kubectl describe node"$n"| sed -n'/Allocated resources/,/Events/p'| head -15

 # 該節(jié)點(diǎn)上的Pod數(shù)量
  POD_COUNT=$(kubectl get pods -A --field-selector"spec.nodeName=$n"--no-headers | wc -l)
  MAX_PODS=$(kubectl get node"$n"-o jsonpath='{.status.capacity.pods}')
 echo""
 echo"Pod數(shù)量:$POD_COUNT/$MAX_PODS"

 # 該節(jié)點(diǎn)上資源使用Top 5的Pod
 echo""
 echo"--- CPU使用Top 5 ---"
  kubectl top pods -A --sort-by=cpu --no-headers | 
  whileread-r ns name cpu mem;do
    pod_node=$(kubectl get pod"$name"-n"$ns"-o jsonpath='{.spec.nodeName}'2>/dev/null)
   if["$pod_node"="$n"];then
     echo" $ns/$name: CPU=$cpuMEM=$mem"
   fi
  done| head -5

 echo""
done

3.3 實(shí)際應(yīng)用案例

案例一:生產(chǎn)環(huán)境大規(guī)模Pod驅(qū)逐事件排查

場(chǎng)景描述:周一早上收到告警,production namespace中30%的Pod被驅(qū)逐(Evicted),業(yè)務(wù)出現(xiàn)大面積503。

排查過程

# 1. 確認(rèn)驅(qū)逐規(guī)模
kubectl get pods -n production --field-selector status.phase=Failed | grep Evicted | wc -l
# 輸出:47

# 2. 查看驅(qū)逐原因
kubectl get pods -n production --field-selector status.phase=Failed -o json | 
 jq -r'.items[] | select(.status.reason=="Evicted") | .status.message'| sort | uniq -c
# 輸出:47 The node was low on resource: ephemeral-storage.

# 3. 定位問題節(jié)點(diǎn)
kubectl get pods -n production --field-selector status.phase=Failed -o json | 
 jq -r'.items[] | select(.status.reason=="Evicted") | .spec.nodeName'| sort | uniq -c
# 輸出:47 node-3

# 4. 檢查node-3的磁盤
ssh node-3 df -h
# /dev/sda1 100G 97G 3G 97% /

# 5. 找到磁盤占用元兇
ssh node-3 du -sh /var/log/* | sort -rh | head -5
# 78G /var/log/pods/production_data-processor-xxx/app/0.log

根因:data-processor應(yīng)用沒有配置日志輪轉(zhuǎn),單個(gè)容器日志文件漲到78G,撐滿了節(jié)點(diǎn)磁盤。kubelet檢測(cè)到ephemeral-storage壓力,開始驅(qū)逐該節(jié)點(diǎn)上的Pod。

解決方案

# 1. 清理Evicted Pod
kubectl delete pods -n production --field-selector status.phase=Failed

# 2. 配置kubelet日志輪轉(zhuǎn)(在每個(gè)節(jié)點(diǎn)上)
# /var/lib/kubelet/config.yaml 中添加:
# containerLogMaxSize: "100Mi"
# containerLogMaxFiles: 5

# 3. 給應(yīng)用Pod配置ephemeral-storage限制
# 防止單個(gè)Pod占滿節(jié)點(diǎn)磁盤
resources:
requests:
 ephemeral-storage:1Gi
limits:
 ephemeral-storage:5Gi

案例二:間歇性DNS解析失敗排查

場(chǎng)景描述:業(yè)務(wù)反饋部分請(qǐng)求報(bào)"Name or service not known"錯(cuò)誤,但不是每次都失敗,大約5%的請(qǐng)求會(huì)DNS解析失敗。

排查過程

# 1. 確認(rèn)CoreDNS運(yùn)行狀態(tài)
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 2個(gè)Pod都Running

# 2. 檢查CoreDNS日志
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=100 | grep -i"error|fail"
# 沒有明顯錯(cuò)誤

# 3. 檢查CoreDNS的資源使用
kubectl top pods -n kube-system -l k8s-app=kube-dns
# NAME            CPU  MEMORY
# coredns-xxx-aaa      980m  178Mi
# coredns-xxx-bbb      950m  175Mi
# CPU接近limits(1核),說明CoreDNS過載

# 4. 檢查DNS查詢量
kubectlexec-n kube-system coredns-xxx-aaa -- 
 wget -qO- http://localhost:9153/metrics | grep coredns_dns_requests_total
# 每秒超過5000次查詢

根因:集群規(guī)模擴(kuò)大后DNS查詢量超過CoreDNS的處理能力,2個(gè)Pod各1核CPU已經(jīng)跑滿。

解決方案

# 1. 擴(kuò)容CoreDNS
kubectl scale deployment coredns -n kube-system --replicas=5

# 2. 調(diào)大CoreDNS資源
kubectl edit deployment coredns -n kube-system
# 將CPU limits從1調(diào)到2

# 3. 啟用NodeLocal DNSCache減少CoreDNS壓力
kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
# NodeLocal DNSCache在每個(gè)節(jié)點(diǎn)運(yùn)行DNS緩存,大部分查詢?cè)诒镜孛?,不需要走CoreDNS

四、最佳實(shí)踐和注意事項(xiàng)

4.1 最佳實(shí)踐

4.1.1 性能優(yōu)化

配置合理的資源requests和limits:requests設(shè)太低會(huì)導(dǎo)致Pod被調(diào)度到資源不足的節(jié)點(diǎn),運(yùn)行時(shí)性能差;limits設(shè)太低會(huì)導(dǎo)致CPU被throttle或內(nèi)存OOMKill。生產(chǎn)環(huán)境建議requests設(shè)為實(shí)際使用量的80%,limits設(shè)為requests的1.5-2倍。

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

配置PodDisruptionBudget:防止節(jié)點(diǎn)維護(hù)或集群升級(jí)時(shí)同時(shí)驅(qū)逐太多Pod導(dǎo)致服務(wù)中斷。

apiVersion:policy/v1
kind:PodDisruptionBudget
metadata:
name:web-app-pdb
namespace:production
spec:
minAvailable:"60%"
selector:
 matchLabels:
  app:web-app

配置優(yōu)雅終止時(shí)間:默認(rèn)terminationGracePeriodSeconds是30秒。Java應(yīng)用可能需要更長時(shí)間完成請(qǐng)求處理和資源釋放,建議設(shè)為60-120秒。應(yīng)用代碼中要正確處理SIGTERM信號(hào)。

4.1.2 安全加固

定期檢查證書過期時(shí)間:kubeadm簽發(fā)的證書默認(rèn)1年有效期,過期后API Server直接不可用。配置定時(shí)任務(wù)每周檢查一次。

# 加入crontab,每周一檢查證書
0 9 * * 1 kubeadm certs check-expiration | mail -s"K8s證書檢查"sre@company.com

etcd定期備份:etcd存儲(chǔ)了集群所有狀態(tài)數(shù)據(jù),丟了就全完了。每天至少備份一次,保留最近7天的快照。

# crontab每天凌晨2點(diǎn)備份
0 2 * * * /opt/scripts/etcd-check-backup.sh >> /var/log/etcd-backup.log 2>&1
# 清理7天前的備份
0 3 * * * find /opt/etcd-backup -name"*.db"-mtime +7 -delete

限制kubectl權(quán)限:不要給所有人cluster-admin權(quán)限。按團(tuán)隊(duì)和職責(zé)分配RBAC角色,開發(fā)只能查看自己namespace的資源,SRE有更高權(quán)限但也要審計(jì)。

4.1.3 高可用配置

控制平面多節(jié)點(diǎn):生產(chǎn)環(huán)境至少3個(gè)Master節(jié)點(diǎn),API Server、etcd、Controller Manager、Scheduler都是多副本。單Master掛了整個(gè)集群不可管理。

跨可用區(qū)部署:Worker節(jié)點(diǎn)分布在至少2個(gè)可用區(qū),配合Pod Topology Spread Constraints確保Pod分散在不同AZ。

關(guān)鍵組件監(jiān)控:etcd磁盤延遲、API Server請(qǐng)求延遲、Controller Manager隊(duì)列深度——這三個(gè)指標(biāo)異常通常是集群故障的前兆。

4.2 注意事項(xiàng)

4.2.1 配置注意事項(xiàng)

警告:以下操作在生產(chǎn)環(huán)境中執(zhí)行前務(wù)必確認(rèn)影響范圍。

不要隨意刪除kube-system中的Pod:kube-proxy、CoreDNS、CNI插件等核心組件在kube-system中,誤刪會(huì)導(dǎo)致集群網(wǎng)絡(luò)中斷。

不要在高峰期做節(jié)點(diǎn)維護(hù):kubectl drain會(huì)驅(qū)逐節(jié)點(diǎn)上所有Pod,高峰期驅(qū)逐可能導(dǎo)致其他節(jié)點(diǎn)資源不足,引發(fā)連鎖故障。

kubectl delete pod和kubectl delete deployment的區(qū)別:delete pod只刪一個(gè)Pod(Deployment會(huì)自動(dòng)重建),delete deployment會(huì)刪除所有Pod且不會(huì)重建。緊急情況下重啟服務(wù)用kubectl rollout restart deployment,不要delete。

4.2.2 常見錯(cuò)誤

錯(cuò)誤現(xiàn)象 原因分析 解決方案
kubectl超時(shí)無響應(yīng) API Server過載或網(wǎng)絡(luò)不通 檢查API Server Pod狀態(tài)和節(jié)點(diǎn)網(wǎng)絡(luò)
Pod一直Terminating finalizer阻塞或容器進(jìn)程不響應(yīng)SIGTERM kubectl delete pod --force --grace-period=0 強(qiáng)制刪除
節(jié)點(diǎn)NotReady后Pod不遷移 默認(rèn)等待5分鐘(pod-eviction-timeout)才開始遷移 檢查kube-controller-manager的配置
HPA不工作 Metrics Server未安裝或Pod沒設(shè)requests 安裝Metrics Server,配置resources.requests
PVC一直Pending StorageClass不存在或存儲(chǔ)后端故障 kubectl describe pvc 查看事件
Service ClusterIP不通 kube-proxy未運(yùn)行或iptables規(guī)則異常 檢查kube-proxy Pod和iptables規(guī)則

4.2.3 兼容性問題

kubectl版本:kubectl和集群版本差異不能超過1個(gè)小版本。用1.25的kubectl管理1.28的集群可能出現(xiàn)API不兼容。

容器運(yùn)行時(shí):K8s 1.24+移除了dockershim,必須用containerd或CRI-O。升級(jí)到1.24前確認(rèn)運(yùn)行時(shí)已切換。

API廢棄:每個(gè)K8s版本都會(huì)廢棄一些API(如extensions/v1beta1 Ingress)。升級(jí)前用kubectl convert或pluto工具檢查廢棄API。

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

5.1 故障排查

5.1.1 日志查看

# kubelet日志(節(jié)點(diǎn)級(jí)別)
journalctl -u kubelet --since"30 minutes ago"| tail -100

# API Server日志
kubectl logs -n kube-system -l component=kube-apiserver --tail=50

# Controller Manager日志
kubectl logs -n kube-system -l component=kube-controller-manager --tail=50

# Scheduler日志
kubectl logs -n kube-system -l component=kube-scheduler --tail=50

# etcd日志
kubectl logs -n kube-system -l component=etcd --tail=50

# CoreDNS日志
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50

# kube-proxy日志
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=50

5.1.2 常見問題排查

問題一:API Server響應(yīng)慢,kubectl操作延遲高

# 檢查API Server請(qǐng)求延遲
kubectl get --raw /metrics | grep apiserver_request_duration_seconds

# 檢查etcd延遲(API Server依賴etcd)
kubectlexec-n kube-system etcd-master01 -- etcdctl 
 --endpoints=https://127.0.0.1:2379 
 --cacert=/etc/kubernetes/pki/etcd/ca.crt 
 --cert=/etc/kubernetes/pki/etcd/server.crt 
 --key=/etc/kubernetes/pki/etcd/server.key 
 endpoint status --write-out=table

# 檢查API Server審計(jì)日志中的慢請(qǐng)求
grep"AUDIT"/var/log/kubernetes/audit.log | 
 jq'select(.stageTimestamp > .requestReceivedTimestamp + "5s")'

解決方案

etcd磁盤IO慢 → 將etcd數(shù)據(jù)目錄遷移到SSD

API Server過載 → 檢查是否有大量LIST請(qǐng)求(通常是監(jiān)控組件配置不當(dāng))

大量Webhook調(diào)用 → 檢查MutatingWebhookConfiguration和ValidatingWebhookConfiguration

問題二:Pod被OOMKilled反復(fù)重啟

# 確認(rèn)OOMKill
kubectl get pod  -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'

# 查看Pod內(nèi)存使用趨勢(shì)
kubectl top pod  --containers

# 查看節(jié)點(diǎn)上的OOM事件
ssh  dmesg | grep -i"oom|killed"| tail -10

解決方案

調(diào)大memory limits(臨時(shí)方案)

排查內(nèi)存泄漏(根本方案):Java應(yīng)用用jmap dump堆內(nèi)存分析,Go應(yīng)用用pprof

如果是JVM應(yīng)用,確認(rèn)-Xmx設(shè)置小于容器memory limits的80%,留20%給非堆內(nèi)存

問題三:Service的Endpoints頻繁變化導(dǎo)致流量抖動(dòng)

癥狀:服務(wù)間調(diào)用間歇性失敗,Endpoints列表頻繁增減

排查

# 監(jiān)控Endpoints變化
kubectl get endpoints  -w

# 檢查Pod的readinessProbe是否頻繁失敗
kubectl describe pod  | grep -A 10"Readiness"
kubectl get events --field-selector reason=Unhealthy -n 

解決:調(diào)整readinessProbe的參數(shù),增大failureThreshold和periodSeconds,避免短暫的響應(yīng)慢就被摘除

5.1.3 調(diào)試模式

# 使用ephemeral container調(diào)試運(yùn)行中的Pod(不重啟Pod)
kubectl debug  -it --image=nicolaka/netshoot --target=

# 復(fù)制Pod進(jìn)行調(diào)試(不影響原Pod)
kubectl debug  -it --copy-to=debug-copy --container=app -- sh

# 調(diào)試節(jié)點(diǎn)(在節(jié)點(diǎn)上啟動(dòng)特權(quán)Pod)
kubectl debug node/ -it --image=ubuntu

# 查看Pod的完整YAML(包含status)
kubectl get pod  -o yaml

# 查看資源的所有事件
kubectl get events --field-selector involvedObject.name= --sort-by='.lastTimestamp'

5.2 性能監(jiān)控

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

# 集群整體資源使用率
kubectl top nodes

# 各namespace資源使用匯總
kubectl top pods -A --sort-by=cpu | head -20
kubectl top pods -A --sort-by=memory | head -20

# API Server請(qǐng)求延遲
kubectl get --raw /metrics | grep apiserver_request_duration_seconds_bucket

# etcd數(shù)據(jù)庫大小
kubectlexec-n kube-system etcd-master01 -- etcdctl 
 --endpoints=https://127.0.0.1:2379 
 --cacert=/etc/kubernetes/pki/etcd/ca.crt 
 --cert=/etc/kubernetes/pki/etcd/server.crt 
 --key=/etc/kubernetes/pki/etcd/server.key 
 endpoint status --write-out=json | jq'.[0].Status.dbSize / 1024 / 1024'

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

指標(biāo)名稱 正常范圍 告警閾值 說明
節(jié)點(diǎn)CPU使用率 < 70% > 85% 持續(xù)5分鐘 過高會(huì)導(dǎo)致Pod被throttle
節(jié)點(diǎn)內(nèi)存使用率 < 80% > 90% 接近100%會(huì)觸發(fā)OOM Killer
etcd數(shù)據(jù)庫大小 < 2GB > 4GB 超過8GB etcd會(huì)拒絕寫入
etcd磁盤fsync延遲 < 10ms > 25ms 延遲過高影響集群所有寫操作
API Server請(qǐng)求延遲P99 < 1s > 5s 延遲過高kubectl操作會(huì)超時(shí)
Pod重啟次數(shù) 0 > 5次/小時(shí) 頻繁重啟說明應(yīng)用有問題
CoreDNS請(qǐng)求延遲 < 5ms > 50ms DNS慢會(huì)影響所有服務(wù)間調(diào)用

5.2.3 監(jiān)控告警配置

# Prometheus告警規(guī)則:k8s-cluster-alerts.yaml
apiVersion:monitoring.coreos.com/v1
kind:PrometheusRule
metadata:
name:k8s-cluster-alerts
namespace:monitoring
spec:
groups:
-name:k8s-node.rules
 rules:
 -alert:NodeNotReady
  expr:kube_node_status_condition{condition="Ready",status="true"}==0
  for:5m
  labels:
   severity:critical
  annotations:
   summary:"節(jié)點(diǎn){{ $labels.node }}NotReady超過5分鐘"

 -alert:NodeHighCPU
  expr:|
    100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
  for:5m
  labels:
   severity:warning
  annotations:
   summary:"節(jié)點(diǎn){{ $labels.instance }}CPU使用率超過85%"

 -alert:NodeHighMemory
  expr:|
    (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
  for:5m
  labels:
   severity:critical
  annotations:
   summary:"節(jié)點(diǎn){{ $labels.instance }}內(nèi)存使用率超過90%"

 -alert:NodeDiskPressure
  expr:|
    (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 85
  for:5m
  labels:
   severity:warning
  annotations:
   summary:"節(jié)點(diǎn){{ $labels.instance }}磁盤使用率超過85%"

-name:k8s-pod.rules
 rules:
 -alert:PodCrashLooping
  expr:|
    rate(kube_pod_container_status_restarts_total[15m]) * 60 * 15 > 0
  for:5m
  labels:
   severity:critical
  annotations:
   summary:"Pod{{ $labels.namespace }}/{{ $labels.pod }}頻繁重啟"

 -alert:PodOOMKilled
  expr:|
    kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1
  for:0m
  labels:
   severity:warning
  annotations:
   summary:"Pod{{ $labels.namespace }}/{{ $labels.pod }}被OOMKill"

-name:k8s-etcd.rules
 rules:
 -alert:EtcdHighDiskLatency
  expr:|
    histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.025
  for:5m
  labels:
   severity:critical
  annotations:
   summary:"etcd磁盤fsync P99延遲超過25ms,集群寫入性能受影響"

 -alert:EtcdDatabaseSizeLarge
  expr:etcd_mvcc_db_total_size_in_bytes>4294967296
  for:5m
  labels:
   severity:warning
  annotations:
   summary:"etcd數(shù)據(jù)庫大小超過4GB,需要壓縮和碎片整理"

5.3 備份與恢復(fù)

5.3.1 備份策略

#!/bin/bash
# 文件名:etcd-daily-backup.sh
# 功能:etcd每日快照備份,保留7天

BACKUP_DIR="/opt/etcd-backup"
ETCD_ENDPOINTS="https://127.0.0.1:2379"
ETCD_CACERT="/etc/kubernetes/pki/etcd/ca.crt"
ETCD_CERT="/etc/kubernetes/pki/etcd/server.crt"
ETCD_KEY="/etc/kubernetes/pki/etcd/server.key"

mkdir -p"$BACKUP_DIR"

SNAPSHOT="$BACKUP_DIR/etcd-$(date +%Y%m%d-%H%M%S).db"

etcdctl snapshot save"$SNAPSHOT"
 --endpoints="$ETCD_ENDPOINTS"
 --cacert="$ETCD_CACERT"
 --cert="$ETCD_CERT"
 --key="$ETCD_KEY"

if[ $? -eq 0 ];then
 echo"備份成功:$SNAPSHOT($(du -sh "$SNAPSHOT" | awk '{print $1}'))"
 # 清理7天前的備份
  find"$BACKUP_DIR"-name"etcd-*.db"-mtime +7 -delete
else
 echo"備份失敗!">&2
 exit1
fi

5.3.2 恢復(fù)流程

# etcd從快照恢復(fù)(集群完全不可用時(shí)的最后手段)
# 警告:恢復(fù)會(huì)丟失快照之后的所有變更

# 1. 停止所有Master節(jié)點(diǎn)的API Server
# 移走靜態(tài)Pod manifest
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/

# 2. 停止etcd
mv /etc/kubernetes/manifests/etcd.yaml /tmp/

# 3. 備份當(dāng)前etcd數(shù)據(jù)目錄
mv /var/lib/etcd /var/lib/etcd.bak

# 4. 從快照恢復(fù)
etcdctl snapshot restore /opt/etcd-backup/etcd-20260208.db 
 --data-dir=/var/lib/etcd 
 --name=master01 
 --initial-cluster=master01=https://10.0.0.1:2380 
 --initial-advertise-peer-urls=https://10.0.0.1:2380

# 5. 恢復(fù)etcd和API Server
mv /tmp/etcd.yaml /etc/kubernetes/manifests/
mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

# 6. 等待集群恢復(fù)
sleep 30
kubectl get nodes
kubectl get pods -A

六、總結(jié)

6.1 技術(shù)要點(diǎn)回顧

排查思路分層:節(jié)點(diǎn)層(kubelet、磁盤、內(nèi)存)→ 控制平面層(API Server、etcd、Scheduler)→ 工作負(fù)載層(Pod狀態(tài)、容器日志)→ 網(wǎng)絡(luò)層(Service、DNS、CNI),從底層往上排查效率最高

kubectl describe是第一步:90%的問題能從Events中找到線索。kubectl describe pod/node/svc是排查的起點(diǎn)

--previous查看崩潰日志:CrashLoopBackOff的Pod用kubectl logs --previous查看上一次崩潰的日志,不加這個(gè)參數(shù)看到的可能是空的

etcd是集群的命脈:etcd數(shù)據(jù)丟失等于集群報(bào)廢。每天備份,定期驗(yàn)證恢復(fù)流程

6.2 進(jìn)階學(xué)習(xí)方向

kubectl debug深入使用:Ephemeral Container可以在不重啟Pod的情況下注入調(diào)試工具,K8s 1.25+ GA

文檔:https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/

實(shí)踐建議:準(zhǔn)備一個(gè)包含常用排查工具的debug鏡像(netshoot、busybox等)

混沌工程:用Chaos Mesh或Litmus在測(cè)試環(huán)境主動(dòng)注入故障,提前發(fā)現(xiàn)系統(tǒng)弱點(diǎn)

項(xiàng)目地址:https://chaos-mesh.org/

實(shí)踐建議:從簡單的Pod Kill開始,逐步增加網(wǎng)絡(luò)延遲、磁盤故障等場(chǎng)景

可觀測(cè)性體系建設(shè):Prometheus + Grafana + Loki + Tempo,構(gòu)建指標(biāo)、日志、鏈路追蹤三位一體的可觀測(cè)性平臺(tái)

實(shí)踐建議:先搞定指標(biāo)監(jiān)控和告警,再補(bǔ)充日志和鏈路追蹤

6.3 參考資料

Kubernetes官方排查文檔- 官方故障排查指南

kubectl Cheat Sheet- kubectl命令速查

learnk8s故障排查流程圖- 可視化排查決策樹

etcd運(yùn)維文檔- etcd備份恢復(fù)和調(diào)優(yōu)

附錄

A. 命令速查表

# Pod排查
kubectl get pods -A --field-selector status.phase!=Running,status.phase!=Succeeded # 異常Pod
kubectl describe pod           # Pod詳情和事件
kubectl logs  --previous --tail=50   # 上次崩潰日志
kubectl logs  -c       # 指定容器日志
kubectl top pod  --containers      # Pod資源使用
kubectl debug  -it --image=netshoot   # 調(diào)試Pod
kubectl delete pod  --force --grace-period=0 # 強(qiáng)制刪除卡住的Pod

# 節(jié)點(diǎn)排查
kubectl describe node          # 節(jié)點(diǎn)詳情
kubectl top nodes              # 節(jié)點(diǎn)資源使用
kubectl get nodes -o wide          # 節(jié)點(diǎn)IP和版本
kubectl cordon             # 標(biāo)記節(jié)點(diǎn)不可調(diào)度
kubectl drain  --ignore-daemonsets   # 驅(qū)逐節(jié)點(diǎn)上的Pod
kubectl uncordon            # 恢復(fù)節(jié)點(diǎn)調(diào)度

# 網(wǎng)絡(luò)排查
kubectl get svc,endpoints -n       # Service和Endpoint
kubectl runtest--rm -it --image=busybox -- nslookup  # DNS測(cè)試
kubectl runtest--rm -it --image=curlimages/curl -- curl  # HTTP測(cè)試

# 事件和日志
kubectl get events -A --sort-by='.lastTimestamp'| tail -20 # 最近事件
kubectl get events --field-selectortype=Warning -A     # Warning事件
journalctl -u kubelet --since"30m ago"   # kubelet日志

# etcd
etcdctl endpoint health           # 健康檢查
etcdctl endpoint status --write-out=table  # 狀態(tài)詳情
etcdctl snapshot save          # 快照備份
etcdctl snapshot restore        # 快照恢復(fù)

B. 配置參數(shù)詳解

Pod狀態(tài)含義

狀態(tài) 含義 排查方向
Pending 等待調(diào)度 資源不足、污點(diǎn)、親和性、PVC未綁定
ContainerCreating 容器創(chuàng)建中 鏡像拉取、Volume掛載、Init容器
Running 運(yùn)行中 正常狀態(tài),但可能不Ready
CrashLoopBackOff 反復(fù)崩潰 查看--previous日志,檢查退出碼
ImagePullBackOff 鏡像拉取失敗 鏡像地址、認(rèn)證、網(wǎng)絡(luò)
OOMKilled 內(nèi)存超限被殺 調(diào)大limits或排查內(nèi)存泄漏
Evicted 被驅(qū)逐 節(jié)點(diǎn)資源壓力(磁盤、內(nèi)存)
Terminating 終止中 finalizer阻塞或進(jìn)程不響應(yīng)SIGTERM
Unknown 狀態(tài)未知 節(jié)點(diǎn)失聯(lián),kubelet無法上報(bào)

容器退出碼含義

退出碼 信號(hào) 含義
0 - 正常退出
1 - 應(yīng)用錯(cuò)誤
126 - 命令無法執(zhí)行(權(quán)限問題)
127 - 命令未找到
128+N Signal N 被信號(hào)N終止
137 SIGKILL(9) 被強(qiáng)制殺死(OOMKill或kill -9)
139 SIGSEGV(11) 段錯(cuò)誤
143 SIGTERM(15) 被正常終止

C. 術(shù)語表

術(shù)語 英文 解釋
控制平面 Control Plane K8s集群的管理層,包含API Server、etcd、Scheduler、Controller Manager
數(shù)據(jù)平面 Data Plane K8s集群的工作層,即Worker節(jié)點(diǎn)上運(yùn)行的kubelet、kube-proxy和業(yè)務(wù)Pod
驅(qū)逐 Eviction kubelet在節(jié)點(diǎn)資源壓力下主動(dòng)終止Pod的行為
污點(diǎn) Taint 節(jié)點(diǎn)上的標(biāo)記,阻止不容忍該污點(diǎn)的Pod被調(diào)度到該節(jié)點(diǎn)
容忍 Toleration Pod上的配置,允許Pod被調(diào)度到有特定污點(diǎn)的節(jié)點(diǎn)
親和性 Affinity Pod調(diào)度時(shí)對(duì)節(jié)點(diǎn)或其他Pod的偏好或要求
探針 Probe kubelet用于檢測(cè)容器健康狀態(tài)的機(jī)制:liveness、readiness、startup
臨時(shí)容器 Ephemeral Container 用于調(diào)試的臨時(shí)容器,可以注入到運(yùn)行中的Pod而不重啟

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 磁盤
    +關(guān)注

    關(guān)注

    1

    文章

    398

    瀏覽量

    26489
  • kubernetes
    +關(guān)注

    關(guān)注

    0

    文章

    263

    瀏覽量

    9494

原文標(biāo)題:線上 K8s 又炸了?這份故障排查手冊(cè)請(qǐng)收好

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Kubernetes 網(wǎng)絡(luò)模型如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes 網(wǎng)絡(luò)模型可以使你能夠正確運(yùn)行、監(jiān)控和排查
    的頭像 發(fā)表于 10-08 11:32 ?1720次閱讀

    Docker容器和Kubernetes退出碼中文指南

    當(dāng)容器終止時(shí),容器引擎使用退出碼來報(bào)告容器終止的原因。如果您是 Kubernetes 用戶,容器故障是 pod 異常最常見的原因之一,了解容器退出碼可以幫助您在排查時(shí)找到 pod 故障
    發(fā)表于 06-06 10:08 ?1834次閱讀

    電腦故障分析排查

    電腦系統(tǒng)硬件故障分析,排查維護(hù)實(shí)用工具資料
    發(fā)表于 12-30 14:54 ?4次下載

    Kubernetes網(wǎng)絡(luò)模型介紹以及如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes 網(wǎng)絡(luò)模型可以使你能夠正確運(yùn)行、監(jiān)控和排查
    的頭像 發(fā)表于 05-05 20:22 ?2512次閱讀

    Kubernetes網(wǎng)絡(luò)模型的基礎(chǔ)知識(shí)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes 網(wǎng)絡(luò)模型可以使你能夠正確運(yùn)行、監(jiān)控和排查
    的頭像 發(fā)表于 07-20 09:46 ?1930次閱讀

    Kubernetes集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查

    本文將引入一個(gè)思路:“在 Kubernetes 集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查”。文章將引入 Kubernetes 集群中網(wǎng)絡(luò)排查的思路,包含網(wǎng)絡(luò)異常模型,常用工具,并且提出一些案例以供學(xué)
    的頭像 發(fā)表于 09-02 09:45 ?9659次閱讀

    交換機(jī)怎么排查常見的故障

    交換機(jī)怎么排查常見的故障
    發(fā)表于 10-09 14:29 ?6次下載

    如何判斷芯片是否損壞 掌握芯片故障排查技巧

    芯片故障排查是電子設(shè)備維修中一項(xiàng)關(guān)鍵的技術(shù)活動(dòng)。隨著電子設(shè)備的普及和復(fù)雜性的增加,芯片故障成為了常見的問題。因此,掌握一些芯片故障排查技巧是
    的頭像 發(fā)表于 08-08 18:15 ?9041次閱讀

    PLC故障排查步驟

    故障排查對(duì)于PLC非常重要,下面是一般的PLC故障排查步驟: (1)收集信息:首先,收集有關(guān)故障的詳細(xì)信息,包括
    的頭像 發(fā)表于 11-17 09:01 ?3640次閱讀

    DC電源模塊的故障排查與維修技巧

    BOSHIDA ?DC電源模塊的故障排查與維修技巧 故障排查與維修技巧: DC電源模塊的故障排查
    的頭像 發(fā)表于 01-09 15:08 ?2481次閱讀
    DC電源模塊的<b class='flag-5'>故障</b><b class='flag-5'>排查</b>與維修技巧

    電纜故障排查技術(shù)案例筆記

    電纜故障排查技術(shù)案例筆記
    的頭像 發(fā)表于 05-20 17:03 ?1539次閱讀
    電纜<b class='flag-5'>故障</b><b class='flag-5'>排查</b>技術(shù)案例筆記

    光纖故障怎么排查

    光纖故障排查是一個(gè)細(xì)致且系統(tǒng)的過程,涉及多個(gè)方面的檢查和測(cè)試。以下是一系列光纖故障排查的步驟和方法: 一、初步檢查 確認(rèn)物理連接:首先檢查光纖網(wǎng)絡(luò)的物理連接是否正常,包括光纖端口是否
    的頭像 發(fā)表于 08-20 10:25 ?4790次閱讀

    機(jī)房精密空調(diào)故障?排查步驟看這!

    機(jī)房精密空調(diào)作為維持機(jī)房環(huán)境穩(wěn)定的關(guān)鍵設(shè)備,其故障排查工作至關(guān)重要。下面聊一下排查機(jī)房精密空調(diào)故障的詳細(xì)步驟。
    的頭像 發(fā)表于 02-17 15:48 ?1523次閱讀
    機(jī)房精密空調(diào)<b class='flag-5'>故障</b>?<b class='flag-5'>排查</b>步驟看這!

    CD7377CZ/7388工程化調(diào)試故障排查手冊(cè)

    標(biāo)簽:#CD7377CZ故障排查 #7388調(diào)試手冊(cè) #音頻芯片工程調(diào)試 #線性穩(wěn)壓故障解決 #國產(chǎn)芯片應(yīng)用 #電子工程實(shí)操
    的頭像 發(fā)表于 12-11 16:07 ?399次閱讀

    Kubernetes kubectl命令行工具詳解

    kubectl是Kubernetes官方提供的命令行工具,作為與Kubernetes集群交互的主要接口,它通過調(diào)用Kubernetes API Server實(shí)現(xiàn)對(duì)集群資源的全面管理。在生產(chǎn)環(huán)境中,運(yùn)維工程師需要熟練掌握kubec
    的頭像 發(fā)表于 02-02 16:40 ?436次閱讀