K8s生产环境排错之:那些暗黑操作

举报
超梦 发表于 2025/04/22 09:30:21 2025/04/22
【摘要】 🔥 开篇血泪史:当集群突然"失忆"时凌晨2点收到告警,某个生产环境Pod疯狂重启但毫无日志输出。官方文档的kubectl describe三板斧毫无作用,直到偶然发现… 🕵️♀️ 场景一:Pod卡在Pending状态(你以为只是资源不够?)暗黑手法1️⃣:撕开调度器的伪装面具# 官方解法:看Events事件(但可能被误导!)kubectl describe pod my-pod | g...

🔥 开篇血泪史:当集群突然"失忆"时

凌晨2点收到告警,某个生产环境Pod疯狂重启但毫无日志输出。官方文档的kubectl describe三板斧毫无作用,直到偶然发现…
image.png


🕵️♀️ 场景一:Pod卡在Pending状态(你以为只是资源不够?)

暗黑手法1️⃣:撕开调度器的伪装面具

# 官方解法:看Events事件(但可能被误导!)
kubectl describe pod my-pod | grep Events -A10

# 暗黑指令:直击调度器内心OS(真实过滤逻辑)
kubectl get events --field-selector involvedObject.kind=Pod | jq '.items[] | select(.reason=="FailedScheduling")'

📌 真相清单

表象原因 真实黑幕 必杀指令
节点资源不足 QoS策略暗藏优先级杀招 kubectl get priorityclass
亲和性冲突 污点容忍的隐藏继承规则 kubectl get pod -o custom-columns=TOLERATIONS:.spec.tolerations
PVC绑定失败 StorageClass幽灵回收锁 kubectl get pv -l failure-domain.beta.kubernetes.io/zone

🌪️ 场景二:服务突然"鬼打墙"(间歇性503错误)

暗黑手法2️⃣:抓包不用进容器

# 绕过sidecar直接嗅探(需要hostNetwork权限)
kubectl debug node/<node-name> -it --image=nicolaka/netshoot
tcpdump -i eth0 port 80 -vvv

💡 避坑指南

  1. kubectl logs显示正常时👉立即检查conntrack表溢出
# 节点上执行(这才是真实罪魁祸首!)
sysctl net.netfilter.nf_conntrack_count
  1. 使用IPVS模式时👉必查/proc/net/ip_vs_conn黑洞

推荐我的私藏诊断镜像(非官方!):

FROM alpine:3.14
RUN apk add --no-cache bind-tools tcpdump curl jq
CMD ["sleep", "infinity"]

快速调试命令:kubectl debug -it <pod-name> --image=my-diag-tools -- sh


🌐 场景三:DNS解析离奇失踪案(比nslookup更狠的破案工具)

暗黑手法3️⃣:直击CoreDNS的"记忆错乱"

# 官方解法:检查DNS配置(但可能被缓存欺骗!)
kubectl exec -it busybox -- nslookup kubernetes.default

# 暗黑指令:解剖CoreDNS的"大脑皮层"
kubectl logs -l k8s-app=kube-dns -n kube-system --tail=100 | grep -E 'ERROR|WARN'

🔍 真相流程图

正确
错误
服务无法解析
检查Pod DNS配置
抓包验证DNS请求
修正dnsConfig
CoreDNS收到请求?
检查上游DNS日志
排查NetworkPolicy封锁

📌 幽灵DNS三宗罪

  1. ndots陷阱
# 查看Pod的resolv.conf暗藏杀机(ndots默认5!)
kubectl exec <pod-name> -- cat /etc/resolv.conf
现象 破解方案
内部域名解析超时 添加ndots:2到dnsConfig
外部域名解析失败 检查CoreDNS的forward插件配置
  1. 幽灵缓存污染
# 暴力清除所有CoreDNS缓存(非官方操作!)
kubectl exec -n kube-system <coredns-pod> -- redis-cli flushall
  1. Hosts文件覆盖攻击
# 检测被篡改的hosts文件(警惕某些Sidecar!)
kubectl exec <pod-name> -- grep '10.96.0.1' /etc/hosts

🔒 场景四:ETCD的隐藏日记本——偷看调度器的小秘密

暗黑手法4️⃣:绕过API Server直连ETCD

# 需要SSH到ETCD节点(高风险操作!)
ETCDCTL_API=3 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 \
get / --prefix --keys-only | grep pending

📌 ETCD暗黑档案解密

Key路径模式 隐藏信息 破译工具
/registry/pods/ 查看被调度器"遗忘"的Pod etcdctl get /registry/pods/<namespace>/<pod-name>
/registry/events/ 挖掘被GC清理的远古事件 etcdctl get --prefix /registry/events
/registry/daemonsets/ 检查幽灵DaemonSet残留配置 jq解析JSON数据

⚠️ 禁忌操作红名单

diff
- 直接修改ETCD数据(会导致集群精神分裂)
- 非快照情况下执行defrag(可能触发OOM+ 推荐安全操作:定期备份快照
  etcdctl snapshot save /var/lib/etcd/snapshot.db

🛠️ 诊断工具进阶包

# 自制ETCD健康检查脚本(非官方!)
#!/bin/bash
etcdctl endpoint status --write-out=table \
--endpoints=$(grep -h initial-cluster /etc/kubernetes/manifests/etcd.yaml | awk -F= '{print $2}') 
diff
+ 推荐组合技:
  kubectl get pods -o wide + 抓包 + CoreDNS日志三连击

🏴‍☠️ 场景五:镜像拉取的黑暗森林法则

暗黑手法5️⃣:突破DockerHub的限速结界

# 伪装成CI/CD工具获取加速特权(慎用!)
kubectl create secret docker-registry stealth-registry \
--docker-server=docker.io \
--docker-username=gitlab-ci-token \
--docker-password=${CI_JOB_TOKEN}

🔍 镜像拉取四重幻境解密

表象错误 真实博弈场 破解阵法
ImagePullBackOff 镜像仓库鉴权套娃机制 kubectl get secret -o yaml
ErrImagePull 镜像分片哈希校验暗战 crictl inspecti <image-id>
ImageInspectError 节点磁盘inode隐形杀手 df -i /var/lib/docker

💡 江湖生存指南

  1. 镜像预加载邪术
# 在所有节点预埋镜像(绕过kubelet管制)
for node in $(kubectl get nodes -o name); do 
  docker -H ${node#node/} pull my-image:latest
done
  1. 私有仓库的替身攻击
# 在Pod中植入镜像重定向咒语(非官方!)
spec:
  imagePullSecrets:
  - name: stealth-registry
  containers:
  - image: my-registry-proxy/docker.io/library/nginx:alpine

🌀 场景六:APIServer的量子纠缠——让Watch永不掉线

暗黑手法6️⃣:突破Watch连接的心跳诅咒

# 监听APIServer的脑电波(需要审计权限)
kubectl get --raw="/apis/apiregistration.k8s.io/v1/apiservices" \
--watch --v=8 2>&1 | grep -E 'Timeout|Too large'

🌌 量子态故障矩阵

Watch连接断开
资源版本号漂移?
启用书签机制
检查APIServer内存泄漏
添加allowWatchBookmarks=true
监控apiserver_go_goroutines指标

📌 时空穿越秘籍

  1. 压缩历史事件黑洞
# 调整APIServer的时光机参数(影响深远!)
--watch-cache-sizes=leases.coordination.k8s.io#100
  1. 打破List请求的次元壁
// 客户端代码注入分页咒文(Golang示例)
listOptions := metav1.ListOptions{
    Limit: 500,
    Continue: continueToken, 
    AllowWatchBookmarks: true}

☠️ 终极禁忌仪式

# 集群复活术(当所有节点同时宕机时)
etcdctl snapshot restore snapshot.db \
--data-dir /var/lib/etcd-new \
--initial-cluster etcd1=http://ip1:2380 \
--initial-advertise-peer-urls http://ip1:2380

⚠️ 死亡红皮书

diff
- 直接修改kubelet证书过期时间(引发集群身份认知障碍)
- 在滚动更新时强制删除etcd成员(导致时空撕裂)
+ 推荐时空锚点:
  kubectl annotate node <node-name> rescue-timestamp=$(date +%s)

🧰 暗黑军火库

# 镜像拉取时空穿梭器(按时间戳拉取历史镜像)
docker pull nginx@sha256:xxxxxx
# Watch连接量子态检测器
kubectl get --raw=/metrics | grep apiserver_watch_events_total

🌉 场景七:Ingress流量神秘消失(穿越七层协议栈的幽灵)

暗黑手法7️⃣:撕开Ingress控制器的假面舞会

# 官方解法:检查Ingress状态(可能被虚假Ready欺骗!)
kubectl get ingress my-app -o wide

# 暗黑指令:直击控制器内核日志(需SSH到Pod所在节点)
kubectl logs -n ingress-nginx <pod-name> | grep -E 'http2|rewrite' --color=always

🔍 Ingress幻境解密矩阵

表象症状 隐藏维度 破壁指令
返回404但后端存在 Annotation优先级战争 kubectl get ingress -o jsonpath='{.items[*].metadata.annotations}'
HTTPS证书突然失效 证书热重载时间裂缝 openssl s_client -connect <IP>:443 -prexit 2>/dev/null | grep "Verify return code"
长连接秒断 Keepalive_buffer_size黑洞 kubectl exec -n ingress-nginx <pod-name> -- nginx -T 2>&1 | grep keepalive

💡 时空穿越法则

客户端超时
TCP握手成功?
抓取Ingress Pod tcpdump
检查NodePort防火墙规则
发现RST包?
调整nginx.ingress.kubernetes.io/proxy-next-upstream
检查后端Pod的http.Server超时设置

💾 场景八:Persistent Volume的时空悖论(数据在时空中震荡)

暗黑手法8️⃣:突破StorageClass的因果律封锁

# 查看PV的隐藏元数据(官方命令会过滤关键信息!)
kubectl get pv -o json | jq '.items[] | {name: .metadata.name, phase: .status.phase, reclaimPolicy: .spec.persistentVolumeReclaimPolicy, finalizers: .metadata.finalizers}'

📌 存储卷三体问题解密

  1. 删除黑洞
# 强制移除PV的finalizer(可能引发跨维度数据丢失!)
kubectl patch pv pv-name -p '{"metadata":{"finalizers":null}}'
风险等级 症状 逃生方案
★★★☆☆ PV卡在Released状态 检查StorageClass回收策略
★★★★★ 云盘被意外释放 立即创建同名PV绑定残留数据
  1. 容量膨胀幻术
# 绕过k8s直接扩展云盘(需云平台API密钥)
aliyun ecs ResizeDisk --DiskId=xxx --NewSize=100
kubectl edit pv pv-name  # 静默修改capacity字段

☄️ 终极生存工具包

# Ingress时间回溯器(按时间戳查看历史配置)
git -C /etc/nginx/ diff HEAD@{10.minutes.ago}
# 存储卷量子态检测脚本
while true; do kubectl get pv -w; done & \
watch -n 1 "df -h /mnt/data | grep -v Filesystem"

🛑 禁忌终章:当kubelet开始说谎

突破节点维度的真相封锁

# 绕过kubelet直接查询容器运行时(需要root权限!)
crictl ps | grep -v Running
# 检查cgroup的平行宇宙
cgget -g memory:kubepods | grep memory.limit_in_bytes

⚠️ 跨维度操作红皮书

diff
+ 安全操作:通过Node Problem Detector收集线索
- 危险操作:直接修改/var/lib/kubelet/pods目录
+ 进阶操作:对比kubelet日志与containerd日志时间线

🚨 终极暗黑警示录

以下操作可能引发次元裂缝,仅供绝境参考!

☠️ 禁忌操作1:强制解除Pod的"死亡拥抱"

# 直接操作CRI接口驱逐容器(绕过kubelet)
crictl stopp $(crictl pods --name my-pod -q) 

风险矩阵

操作目的 常规方案 暗黑代价
释放被卡死的Pod kubectl delete --force 可能残留幽灵cgroup
清理僵尸容器 重启docker/containerd 触发节点身份认证紊乱

🌌 禁忌操作2:篡改APIServer记忆宫殿

# 暴力清除Watch缓存(可能引发集群癫痫)
echo 3 > /proc/sys/vm/drop_caches

量子态副作用

  1. 已建立的Watch连接可能产生平行宇宙
  2. List请求可能返回来自其他时间线的资源
  3. 控制器陷入观测者悖论循环

🛡️ 重生秘术:集群复活指南

当遭遇降维打击时(如ETCD全盘崩溃)

步骤1:从高维空间提取备份

# 利用Velero进行跨维度快照(需提前布置)
velero restore create --from-backup=pre-disaster-backup

步骤2:重建因果律锚点

# 在Kubelet植入时空坐标(非官方操作!)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
resolvConf: /etc/resolv.conf.backup

步骤3:启动因果律引擎

# 强制同步所有控制器状态(慎用!)
kubectl get deployments -o json | jq '.items[] | selstatus.replicas != .spec.replicas)' | xargs -I{} kubectl rollout restart

📜 暗黑排错法典(精华摘要)

故障现象
是否可观测?
启用常规武器库
启动混沌工程
检查APIServer审计日志
注入故障探针
出现新症状?
建立症状关联矩阵
怀疑量子隧穿效应

🌌 终局宣言

真正的K8s暗黑艺术,是学会:
在官方文档的字里行间读取空白处的真相
从APIServer的沉默中听出故障的弦外之音
让每个排错操作都成为对抗熵增的逆熵行为


🌟 让技术经验流动起来

▌▍▎▏ 你的每个互动都在为技术社区蓄能 ▏▎▍▌
点赞 → 让优质经验被更多人看见
📥 收藏 → 构建你的专属知识库
🔄 转发 → 与技术伙伴共享避坑指南

点赞 ➕ 收藏 ➕ 转发,助力更多小伙伴一起成长!💪

💌 深度连接
点击 「头像」→「+关注」
每周解锁:
🔥 一线架构实录 | 💡 故障排查手册 | 🚀 效能提升秘籍
R-C.gif

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。