0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Kubernetes集群运维经验总结

马哥Linux运维 ? 来源:马哥Linux运维 ? 2025-08-18 11:23 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Kubernetes集群运维的10个坑与规避方法:血泪教训总结

作为一名在K8s运维战壕里摸爬滚打3年的工程师,我踩过的坑能绕地球一圈。今天把这些"学费"分享给大家,希望能帮你们少走弯路。

前言:为什么要写这篇文章?

去年双11凌晨2点,我们的K8s集群突然雪崩,200+个Pod全部重启,用户投诉电话打爆了运营的手机。事后复盘发现,这完全是一个可以避免的低级错误。那一刻我意识到,运维不仅是技术活,更是经验活。

本文总结了我和团队在K8s生产环境中遇到的10个最常见且最致命的坑,每个坑都配有真实案例、详细分析和可执行的解决方案。

坑位1:资源配置不当导致的"雪花效应"

真实案例

# 错误配置示例
apiVersion:apps/v1
kind:Deployment
metadata:
name:web-service
spec:
replicas:10
template:
 spec:
  containers:
  -name:web
   image:nginx:latest
   # 没有设置资源限制!

后果:某个Pod内存泄漏,疯狂占用节点资源,导致整个节点上的其他Pod被驱逐,引发连锁反应。

规避方法

1.强制设置资源限制

resources:
requests:
 memory:"256Mi"
 cpu:"250m"
limits:
 memory:"512Mi"
 cpu:"500m"

2.使用LimitRange自动注入

apiVersion:v1
kind:LimitRange
metadata:
name:default-limit-range
spec:
limits:
-default:
  cpu:"500m"
  memory:"512Mi"
 defaultRequest:
  cpu:"100m"
  memory:"128Mi"
 type:Container

运维心得:生产环境必须设置资源限制,这是铁律!建议用Prometheus监控资源使用趋势,动态调整配置。

坑位2:存储卷挂载的"消失魔术"

真实案例

一次升级后,我们发现数据库Pod的数据全部丢失。原因是PVC配置错误,挂载了错误的存储类。

# 危险配置
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:mysql-pvc
spec:
storageClassName:"standard"# 默认存储类,不持久化!
accessModes:
 -ReadWriteOnce
resources:
 requests:
  storage:20Gi

规避方法

1.明确指定存储类

spec:
storageClassName:"ssd-retain"# 明确指定持久化存储类

2.设置PV回收策略

apiVersion:v1
kind:PersistentVolume
metadata:
name:mysql-pv
spec:
persistentVolumeReclaimPolicy:Retain# 保护数据
capacity:
 storage:20Gi
volumeMode:Filesystem
accessModes:
-ReadWriteOnce

3.备份验证脚本

#!/bin/bash
# daily-backup-check.sh
kubectl get pvc -A -o wide | grep -v"Bound"&&echo"警告:存在未绑定的PVC!"
kubectl get pv | grep"Released"&&echo"警告:存在已释放的PV,可能数据丢失!"

坑位3:镜像管理的"薛定谔状态"

真实案例

# 坑爹配置
containers:
-name:app
image:myapp:latest# latest标签,部署时不确定版本
imagePullPolicy:Always# 每次都拉取,网络故障时无法启动

生产环境中,某次网络抖动导致镜像拉取失败,整个服务无法启动,影响了2小时。

规避方法

1.使用具体版本标签

containers:
-name:app
image:myapp:v1.2.3-20231120# 明确版本号
imagePullPolicy:IfNotPresent

2.建立镜像仓库高可用方案

# 配置多个镜像仓库
apiVersion:v1
kind:Secret
metadata:
name:regcred-backup
type:kubernetes.io/dockerconfigjson
data:
.dockerconfigjson:
---
spec:
template:
 spec:
  imagePullSecrets:
  -name:regcred-primary
  -name:regcred-backup

3.镜像预热脚本

#!/bin/bash
# image-preload.sh
NODES=$(kubectl get nodes -o name)
IMAGE_LIST="app:v1.2.3 nginx:1.20 redis:6.2"

fornodein$NODES;do
 forimagein$IMAGE_LIST;do
   echo"预加载镜像$image到节点$node"
    kubectl debug$node-it --image=$image-- /bin/true
 done
done

坑位4:网络策略配置的"黑洞现象"

真实案例

开启了网络策略后,服务间无法通信,排查了一整夜才发现是NetworkPolicy配置错误。

# 过度严格的网络策略
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:deny-all
spec:
podSelector:{}
policyTypes:
-Ingress
-Egress
# 没有配置任何允许规则,所有流量被阻断!

规避方法

1.渐进式网络策略部署

# 第一步:只监控,不阻断
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:web-netpol
annotations:
 net.example.com/policy-mode:"monitor"# 先监控模式
spec:
podSelector:
 matchLabels:
  app:web
policyTypes:
-Ingress
ingress:
-from:
 -podSelector:
   matchLabels:
    app:api
 ports:
 -protocol:TCP
  port:80

2.网络策略测试工具

#!/bin/bash
# netpol-test.sh
echo"测试网络连通性..."
kubectl run test-pod --image=nicolaka/netshoot --rm-it -- /bin/bash
# 在Pod内测试:
# nc -zv  

运维技巧:使用Calico或Cilium的可视化工具,图形化查看网络策略效果。

坑位5:探针配置不合理导致的"误杀"

真实案例

# 激进的探针配置
livenessProbe:
httpGet:
 path:/health
 port:8080
initialDelaySeconds:5 # 启动延迟太短
periodSeconds:5    # 检查间隔太短
failureThreshold:1   # 失败一次就重启
timeoutSeconds:1    # 超时时间太短

结果:应用启动需要30秒,但探针5秒后就开始检查,导致Pod不断重启。

规避方法

1.合理配置探针参数

# 温和的探针配置
livenessProbe:
httpGet:
 path:/health
 port:8080
initialDelaySeconds:60 # 给足启动时间
periodSeconds:30    # 适中的检查间隔
failureThreshold:3   # 多次失败才重启
timeoutSeconds:10   # 合理的超时时间
readinessProbe:
httpGet:
 path:/ready
 port:8080
initialDelaySeconds:30
periodSeconds:10
failureThreshold:3

2.探针测试脚本

#!/bin/bash
# probe-test.sh
POD_NAME=$1
echo"测试Pod探针响应时间..."
kubectlexec$POD_NAME--timewget -qO- localhost:8080/health
kubectlexec$POD_NAME--timewget -qO- localhost:8080/ready

坑位6:滚动更新策略的"服务中断"

真实案例

# 危险的更新策略
spec:
strategy:
 type:RollingUpdate
 rollingUpdate:
  maxUnavailable:50% # 一半Pod同时更新
  maxSurge:0     # 不允许超出副本数

结果:更新期间服务能力直接腰斩,用户体验极差。

规避方法

1.保守的滚动更新策略

spec:
strategy:
 type:RollingUpdate
 rollingUpdate:
  maxUnavailable:25% # 最多四分之一不可用
  maxSurge:25%    # 允许临时超出副本数
minReadySeconds:30   # 新Pod稳定30秒后才继续

2.部署前的容量评估

#!/bin/bash
# capacity-check.sh
DEPLOYMENT=$1
CURRENT_REPLICAS=$(kubectl get deployment$DEPLOYMENT-o jsonpath='{.spec.replicas}')
MAX_UNAVAILABLE=$(kubectl get deployment$DEPLOYMENT-o jsonpath='{.spec.strategy.rollingUpdate.maxUnavailable}')
echo"当前副本数:$CURRENT_REPLICAS"
echo"最大不可用:$MAX_UNAVAILABLE"
echo"更新期间最少可用Pod数:$((CURRENT_REPLICAS - MAX_UNAVAILABLE))"

坑位7:日志收集的"磁盘炸弹"

真实案例

某个应用产生大量DEBUG日志,没有配置日志轮转,最终把节点磁盘写满,导致整个节点不可用。

规避方法

1.配置日志轮转

apiVersion:v1
kind:ConfigMap
metadata:
name:fluentd-config
data:
fluent.conf:|
  
   @type tail
   path /var/log/containers/*.log
   pos_file /var/log/fluentd-containers.log.pos
   tag kubernetes.*
   read_from_head true
   
    @type json
    time_format %Y-%m-%dT%H:%M:%S.%NZ
   
  
 
 # 日志过滤,减少存储压力
 
  @typegrep
  
   keylog
   pattern/DEBUG|TRACE/
  
 

2.磁盘使用监控

#!/bin/bash
# disk-monitor.sh
THRESHOLD=85
NODES=$(kubectl get nodes -o name)

fornodein$NODES;do
  USAGE=$(kubectl top node$node--no-headers | awk'{print $5}'|tr-d'%')
 if["$USAGE"-gt"$THRESHOLD"];then
   echo"警告:节点$node磁盘使用率${USAGE}%,超过阈值!"
   # 发送告警...
 fi
done

坑位8:RBAC权限的"特权升级"

真实案例

为了图方便,给应用Pod配置了cluster-admin权限,结果被安全部门发现,差点引发安全事故。

# 危险配置
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRoleBinding
metadata:
name:my-app-binding
subjects:
-kind:ServiceAccount
name:my-app
namespace:default
roleRef:
kind:ClusterRole
name:cluster-admin# 过高的权限!

规避方法

1.最小权限原则

# 创建最小权限角色
apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
namespace:default
name:pod-reader
rules:
-apiGroups:[""]
resources:["pods"]
verbs:["get","watch","list"]
-apiGroups:[""]
resources:["configmaps"]
verbs:["get"]

2.权限审计脚本

#!/bin/bash
# rbac-audit.sh
echo"检查危险的ClusterRoleBinding..."
kubectl get clusterrolebinding -o yaml | grep -A 5 -B 5"cluster-admin"

echo"检查ServiceAccount权限..."
kubectl get rolebinding,clusterrolebinding --all-namespaces -o wide

坑位9:节点维护的"单点故障"

真实案例

某天需要重启一个节点进行内核升级,直接执行了重启,结果发现该节点上运行着数据库的Master Pod,导致数据库短暂不可用。

规避方法

1.优雅的节点维护流程

#!/bin/bash
# node-maintenance.sh
NODE_NAME=$1

echo"1. 检查节点上的关键Pod..."
kubectl get pods --all-namespaces --field-selector spec.nodeName=$NODE_NAME-o wide

echo"2. 标记节点不可调度..."
kubectl cordon$NODE_NAME

echo"3. 等待用户确认..."
read-p"确认要驱逐Pod吗?(y/N) "-n 1 -r
if[[$REPLY=~ ^[Yy]$ ]];then
 echo"4. 驱逐Pod..."
  kubectl drain$NODE_NAME--ignore-daemonsets --delete-emptydir-data --grace-period=300
fi

echo"5. 节点已准备好维护"

2.Pod反亲和性配置

# 确保关键应用分散在不同节点
spec:
affinity:
 podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  -labelSelector:
    matchExpressions:
    -key:app
     operator:In
     values:
     -database
   topologyKey:kubernetes.io/hostname

坑位10:监控告警的"狼来了"

真实案例

配置了过于敏感的告警规则,每天收到几百条告警,最后大家都麻木了,真正的故障反而被忽略。

# 过于敏感的告警规则
-alert:HighCPUUsage
expr:cpu_usage>50%# 阈值过低
for:1m       # 持续时间太短
labels:
 severity:critical # 级别过高

规避方法

1.合理的告警分级

# Prometheus告警规则
groups:
-name:kubernetes-apps
rules:
-alert:PodCrashLooping
 expr:rate(kube_pod_container_status_restarts_total[15m])>0
 for:5m
 labels:
  severity:warning
 annotations:
  summary:"Pod{{ $labels.namespace }}/{{ $labels.pod }}重启频繁"
  
-alert:PodNotReady
 expr:kube_pod_status_ready{condition="false"}==1
 for:10m
 labels:
  severity:critical
 annotations:
  summary:"Pod{{ $labels.namespace }}/{{ $labels.pod }}长时间未就绪"

2.告警降噪脚本

#!/bin/bash
# alert-dedup.sh
# 合并相似告警,减少噪音
kubectl get events --sort-by='.lastTimestamp'| 
grep -E"Warning|Error"| 
awk'{print $4, $5, $6}'| 
sort|uniq-c |sort-nr

运维最佳实践总结

经过这些血泪教训,我总结了几条K8s运维的黄金法则:

预防为主

?资源限制是必须的:宁可保守,不可激进

?探针配置要合理:给应用足够的启动和响应时间

?权限最小化原则:能用Role就不用ClusterRole

监控先行

?全面监控:节点、Pod、网络、存储都要覆盖

?合理告警:减少噪音,突出重点

?定期巡检:自动化检查集群健康状态

故障演练

?混沌工程:主动制造故障,测试系统韧性

?备份验证:定期测试备份恢复流程

?应急预案:制定详细的故障处理流程

文档化

?操作记录:每次变更都要有记录

?知识沉淀:把踩坑经验形成文档

?团队培训:定期分享最佳实践

写在最后

K8s运维是一个持续学习的过程,每个坑都是成长的机会。希望这篇文章能帮到正在K8s路上摸索的你。如果你也有类似的踩坑经历,欢迎在评论区分享,让我们一起成长!

记住:在生产环境中,没有小问题,只有大事故。每一个细节都可能决定系统的稳定性。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 集群
    +关注

    关注

    0

    文章

    119

    浏览量

    17485
  • 数据库
    +关注

    关注

    7

    文章

    3950

    浏览量

    66842
  • kubernetes
    +关注

    关注

    0

    文章

    253

    浏览量

    9152

原文标题:Kubernetes集群运维的10个坑与规避方法:血泪教训总结

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Altera SOPC专题竞赛-经验总结

    Altera SOPC专题竞赛-经验总结Altera SOPC专题竞赛-经验总结.docx
    发表于 08-10 18:19

    电源制作高手经验总结

    电源制作高手经验总结电源制作高手经验总结 28页.pdf (2.9 MB )
    发表于 06-05 02:05

    Kubernetes经验总结

    Kubernetes学习笔记——24 允许外部访问
    发表于 06-18 12:10

    SOPC Builder/Nios 学习经验总结

    SOPC Builder/Nios 学习经验总结
    发表于 07-22 15:32 ?0次下载
    SOPC Builder/Nios 学习<b class='flag-5'>经验总结</b>

    线圈天线设计经验总结

    线圈天线设计经验总结
    发表于 09-12 17:21 ?224次下载

    做四轴飞行器的经验总结

    做四轴飞行器的经验总结,请各位大神共同学习,里面是一位大神做四轴飞行器的经验总结
    发表于 11-11 16:52 ?0次下载

    开关电源测量的经验总结

    开关电源测量的经验总结,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 17:34 ?0次下载

    模拟电路设计经验总结

    模拟电子的相关知识学习教材资料——模拟电路设计经验总结
    发表于 09-27 15:19 ?0次下载

    指针经验总结

    指针经验总结
    发表于 10-27 15:44 ?19次下载
    指针<b class='flag-5'>经验总结</b>

    TD-LTE网络优化经验总结解析

    TD-LTE网络优化经验总结解析说明。
    发表于 04-27 10:30 ?23次下载

    电路设计的一些经验总结

    电路设计的一些经验总结
    发表于 12-02 13:57 ?45次下载

    EMI整改经验总结

    EMI整改经验总结
    发表于 12-20 15:55 ?46次下载

    选择烧结银的经验总结

    选择烧结银的经验总结
    的头像 发表于 12-17 15:46 ?1811次阅读
    选择烧结银的<b class='flag-5'>经验总结</b>

    GaN E-HEMTs的PCB布局经验总结

    GaN E-HEMTs的PCB布局经验总结
    的头像 发表于 03-13 15:52 ?669次阅读
    GaN E-HEMTs的PCB布局<b class='flag-5'>经验总结</b>

    高效管理Kubernetes集群的实用技巧

    作为一名经验丰富的工程师,我深知在日常的Kubernetes集群管理中,熟练掌握kubectl命令是提升工作效率的关键。今天,我将分享1
    的头像 发表于 08-13 15:57 ?124次阅读