居中
居右
颜色大小K8s不是"黑盒子" 一张图看懂核心架构
先说个残酷真相:90%的K8s运维问题,根源在于不了解控制平面。就像修车只懂换轮胎,却不懂发动机原理。

K8s架构全景图(简化实用版)
💡 核心认知:
K8s不是一组独立组件,而是一个精密协作的有机体。
一个Pod的创建流程:用户指令 → API Server验证 → etcd持久化 → Controller创建资源 → Scheduler分配节点 → Kubelet启动容器
五大核心组件:从"知道名字"到"摸透脾性"
1. API Server:集群的"咽喉要道"
真实痛点:
"为什么执行kubectl命令时卡住不动?为什么集群突然无法创建新资源?"
工作原理(运维视角):
• 所有操作的唯一入口(包括kubectl、控制器、调度器)
• 不是简单的代理,而是认证/授权/准入控制的三重门神
• 与etcd的交互是性能瓶颈
关键关键参数(生产环境亲测):
# kube-apiserver.yaml
command:
- kube-apiserver
- --max-requests-inflight=1500 # 默认400,高负载集群必调
- --max-mutating-requests-inflight=500 # 写操作队列
- --etcd-servers=https://etcd1:2379,https://etcd2:2379 # etcd集群
- --request-timeout=1m # 防止客户端长时间占用故障排查锦囊:
当API响应变慢时,先看这些指标:
# 1. 查看API Server请求延迟
kubectl get --raw /metrics | grep apiserver_request_duration_seconds_bucket
# 2. 检查活跃连接数
netstat -ant | grep ':6443' | wc -l # 6443是API Server端口
# 3. 紧急情况:重启API Server(需谨慎)
systemctl restart kube-apiserver📌 血泪教训:
曾因某次发布,一个错误的CRD定义导致API Server CPU 100%。
根源:CRD验证逻辑过于复杂,每个请求都执行全量校验。
解决:使用--runtime-config=api/all=false临时禁用问题API组。
2. etcd:集群的"心脏起搏器"
真实痛点:
"集群操作突然变卡,但节点和Pod看起来正常"
"etcd数据目录突然暴涨,磁盘空间告急"
工作原理(运维视角):
• 不只是KV存储,更是整个集群状态的唯一真相源
• 使用Raft协议保证数据一致性(奇数节点,3/5/7)
• 写操作必须经过Leader,读操作可从Follower获取
etcd性能调优关键:
# 1. 必须使用SSD磁盘!机械盘是性能杀手
mount -t xfs -o noatime,nodiratime,logbsize=256k /dev/sdb1 /var/lib/etcd
# 2. 定期碎片整理(每月一次)
etcdctl defrag --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
# 3. 关键监控指标
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.01"} # 99%请求应在10ms内完成
etcd_mvcc_db_total_size_in_bytes # 数据库大小灾难恢复实战:
# 1. 备份(每天凌晨执行)
ETCDCTL_API=3 etcdctl --endpoints=$ENDPOINTS snapshot save snapshot.db
# 2. 恢复(灾难场景)
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--name etcd1 \
--initial-cluster "etcd1=http://10.0.0.1:2380,etcd2=http://10.0.0.2:2380" \
--initial-cluster-token my-etcd-token \
--initial-advertise-peer-urls http://10.0.0.1:2380
# 3. 重启etcd服务
systemctl restart etcd
💡 我们的真实案例:
一次大促前,etcd磁盘IO延迟从2ms飙升到200ms。
排查过程:
1.iostat -dx 1 发现%util=100%
2.etcd_disk_backend_commit_duration_seconds 指标异常
3.分析发现某团队在频繁更新ConfigMap(每秒50次)
解决:限制客户端QPS + 合并ConfigMap更新
3. Controller Manager:集群的"自动驾驶仪"
真实痛点:
"Deployment配置了3副本,但只运行了2个Pod"
"节点宕机后,Pod没有自动迁移到其他节点"
核心机制(运维视角):
• 不是单个组件,而是多个控制器的集合(Deployment、Node、Endpoint等)
• 工作模式:Informer Loop(List-Watch-Process)
• 每个控制器独立工作,但共享API Server连接
关键控制器职责:
| 控制器 | 职责 | 常见问题 |
|---|---|---|
| Deployment Controller | 管理ReplicaSet和Pod | 无法扩缩容 |
| Node Controller | 监控节点状态,标记NotReady | 节点状态异常 |
| Endpoint Controller | 同步Service和Pod端点 | Service无法访问 |
| PodNamespace Controller | 清理已删除命名空间的资源 | 命名空间卡在Terminating |
性能优化实战:
# kube-controller-manager.yaml
command:
- kube-controller-manager
- --concurrent-deployment-syncs=20 # 默认5,并行处理Deployment
- --node-monitor-grace-period=40s # 节点失联容忍时间
- --pod-eviction-timeout=5m0s # 节点NotReady后驱逐Pod等待时间故障排查命令:
# 1. 查看控制器工作队列
kubectl get --raw /metrics | grep workqueue_queue_duration_seconds
# 2. 诊断Node Controller问题
kubectl get events --sort-by=.metadata.creationTimestamp | grep -i node
# 3. 强制同步资源(紧急恢复)
# 注意:需在master节点执行
curl -k -v -XPATCH \
-H "Accept: application/json, */*" \
-H "Content-Type: application/strategic-merge-patch+json" \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces/default/deployments/my-app/status \
--data '{"status":{"observedGeneration":0}}'📌 踩坑实录:
一次版本升级后,所有Deployment无法扩缩容。
现象:kubectl describe deployment显示"Progressing"但无变化
真相:Controller Manager与API Server版本不兼容
教训:永远先升级控制平面,再升级节点;永远不要跳过次要版本
4. Scheduler:集群的"资源分配大师"
真实痛点:
"新Pod一直卡在Pending状态"
"节点资源明明充足,但Scheduler不调度"
调度过程揭秘(运维视角):
1. 过滤阶段(Filtering):排除不满足条件的节点(资源不足、污点不匹配等)
2. 打分阶段(Scoring):为剩余节点打分(资源均衡、亲和性等)
3. 绑定阶段(Binding):选择最高分节点,通知API Server
调度器性能调优:
# kube-scheduler.yaml
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
disabled:
- name: NodeResourcesLeastAllocated # 禁用低效插件
enabled:
- name: NodeResourcesBalancedAllocation
weight: 2
filter:
enabled:
- name: PodTopologySpread诊断Pending Pod的终极命令:
# 1. 查看调度失败原因
kubectl get events --field-selector involvedObject.name=my-pod -n my-namespace
# 2. 详细诊断(关键!)
kubectl describe pod my-pod | grep -A 10 "Events:"
# 3. 模拟调度过程
kubectl get --raw "/apis/scheduling.k8s.io/v1/priorityclasses"💡 实战案例:
我们曾遇到Pod卡在Pending,但节点资源充足。
排查:
• kubectl describe pod显示"Tolerates: node.kubernetes.io/not-ready:NoExecute"
• 发现节点有临时污点
解决:
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300 # 等待300秒后驱逐5. 工作节点组件:集群的"一线工人"
三剑客职责:
• Kubelet:节点的"管家",管理Pod生命周期
• Kube-Proxy:节点的"交通警察",维护Service网络规则
• Containerd:节点的"发动机",运行容器
Kubelet关键优化:
# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
maxPods: 110 # 默认110,根据节点规格调整
imageGCHighThresholdPercent: 85 # 磁盘使用超过85%清理镜像
imageGCLowThresholdPercent: 80
serializeImagePulls: false # 并行拉取镜像Kube-Proxy模式选择:
| 模式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| iptables | 稳定,兼容性好 | 规则复杂时性能下降 | 小规模集群(<100节点) |
| ipvs | 高性能,连接复用 | 需要内核支持 | 大规模集群(>100节点) |
切换到ipvs模式:
# 1. 检查内核支持
grep -e ipvs /lib/modules/$(uname -r)/modules.builtin
# 2. 修改kube-proxy配置
kubectl edit configmap kube-proxy -n kube-system
# mode: ipvs
# 3. 重启kube-proxy
kubectl delete pod -l k8s-app=kube-proxy -n kube-system📌 血泪教训:
一次大促,Node节点突然NotReady。
监控发现:Kubelet PLEG(Pod Lifecycle Event Generator)延迟>10s(正常<100ms)
根因:某应用频繁创建/销毁临时容器(每秒20+)
解决:
- 临时:增加Kubelet资源限制--kube-reserved=cpu=500m,memory=1Gi
- 长期:重构应用,避免高频创建Pod
集群监控:给每个组件装上"心电图"
核心监控指标清单(运维必备)
| 组件 | 关键指标 | 告警阈值 | 诊断命令 |
|---|---|---|---|
| API Server | request_duration_seconds | P99> 1s | kubectl get --raw /metrics |
| etcd | wal_fsync_duration_seconds | > 100ms | etcdctl endpoint status |
| Scheduler | scheduling_duration_seconds | > 10s | kubectl logs -l component=kube-scheduler |
| Kubelet | pleg_relist_interval_seconds | > 10s | journalctl -u kubelet |
| Node | memory.available | < 10% | kubectl describe node |
快速诊断脚本(保存为check-cluster.sh):
#!/bin/bash
echo "=== 集群健康检查报告 ($(date)) ==="
# 1. 节点状态
echo -e "\n[1] 节点状态:"
kubectl get nodes -o wide
# 2. Pending的Pod
echo -e "\n[2] Pending状态的Pod:"
kubectl get pods --all-namespaces --field-selector=status.phase=Pending
# 3. API Server延迟
echo -e "\n[3] API Server关键指标:"
kubectl get --raw /metrics | grep -E "apiserver_request_duration_seconds|apiserver_current_inflight_requests"
# 4. etcd健康状态
echo -e "\n[4] etcd健康检查 (需要在master节点执行):"
if [ -x "$(command -v etcdctl)" ]; then
ETCDCTL_API=3 etcdctl endpoint health --cluster
fi
echo -e "\n=== 诊断完成 ==="💡 专业建议:
为每个组件设置黄金指标告警:
• API Server: 5xx错误率 > 1%
• etcd: 写入延迟 > 100ms
• Scheduler: 调度队列深度 > 100
这些告警比"节点宕机"提前30分钟发现问题!
血泪教训:我们踩过的5个致命陷阱陷阱
1:etcd版本与K8s不匹配
• 现象:集群随机出现资源创建失败
• 根因:K8s 1.22要求etcd 3.5+,但我们用了3.4
• 解决:严格遵循版本兼容矩阵陷阱
2:Controller Manager未配置leader选举
• 现象:Controller Manager重启后,所有Deployment卡住
• 解决:
--leader-elect=true
--leader-elect-lease-duration=15s
陷阱3:Kubelet证书未自动轮换
• 现象:节点突然NotReady,日志报"x509证书过期"
• 预防:
--rotate-certificates=true
--feature-gates=RotateKubeletServerCertificate=true
陷阱4:Scheduler资源不足
• 现象:高负载时Pod调度延迟从1s飙升到60s+
• 优化:
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1
memory: 1Gi陷阱5:忽略组件间网络QoS
• 现象:API Server与etcd通信偶尔超时
• 解决:为关键组件配置网络优先级
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 2379 0xffff flowid 1:1从"救火队员"到"集群医生":我们的蜕变
| 能力 | 优化前 | 优化后 |
|---|---|---|
| 故障定位时间 | 2-4小时 | 5-15分钟 |
| 集群稳定性 | 每月3-5次严重故障 | 连续180天无P0事故 |
| 运维信心 | "重启试试" | "我知道问题在哪" |
"以前看到Pending Pod就紧张,现在先看kubectl get events,基本5分钟定位问题。"
行动指南:今晚就能做的3件事
1. 今晚:在你的集群执行
kubectl get --raw /metrics | grep apiserver_request_duration_seconds
如果P99 > 500ms,说明API Server需要优化
2. 明天:检查etcd磁盘IO性能
iostat -dx 1 | grep etcd_device
确保%util < 70%,await < 10ms
3. 本周:为你的测试集群模拟一次etcd故障
# 警告:仅在测试环境执行!
systemctl stop etcd
watch kubectl get nodes # 观察节点状态变化
systemctl start etcd # 恢复记住:真正的K8s高手,不是从不遇到问题,而是知道问题出在哪一层。
从今天起,当集群异常时,先问自己:
"这是API Server的问题?etcd的问题?控制器的问题?调度器的问题?还是节点的问题?"
评论 (0)