运维常见故障排查
# kubernetes应用资源竞争问题
# 问题描述:
当我担任高级运维工程师时,我曾经遇到一个复杂的Kubernetes问题,涉及到应用部署和资源调度。
在我们的生产环境中,我们有一个大规模的Kubernetes集群,其中运行着多个应用。我们收到了用户的反馈,称他们的应用在高峰期间遇到了性能下降和请求延迟的问题。我们立即开始调查,并发现以下一系列问题和挑战。
首先,我们检查了应用的资源配置。我们发现有一些应用的资源请求和限制设置不合理,导致它们无法获得足够的CPU和内存资源。我们调整了这些应用的资源配置,并重新部署了它们,但问题仍然存在。
接下来,我们开始分析集群中的节点负载。我们发现一些节点的负载非常高,而其他节点的负载相对较低。这表明资源调度可能存在问题,导致一些节点过载而无法处理足够的请求。我们检查了Kubernetes的调度器配置,并发现一些默认设置不适用于我们的环境。我们对调度器进行了一些调整,以改善资源的均衡分配和负载情况。
然而,问题仍然没有解决。我们开始分析应用之间的互相影响。我们发现一些应用之间存在竞争资源的情况,导致它们相互干扰并影响性能。为了解决这个问题,我们对这些应用进行了重新调度和隔离,确保它们能够独立运行,而不会相互干扰。
最后,我们进行了一些压力测试和性能优化。我们使用工具模拟了高负载的场景,并进行了一系列的性能测试和调优。通过对应用的代码、数据库查询和网络通信进行优化,我们成功地提高了应用的性能和响应速度。
这个复杂的Kubernetes问题涉及到应用部署、资源调度和性能优化等方面。通过仔细的分析和多方面的优化,我们最终成功解决了这个问题,提高了应用的稳定性和性能。这个经历让我更加熟悉了Kubernetes的应用管理和资源调度机制,并提升了我的故障排查和性能优化能力。
# 排查步骤:
首先通过 kubectl top node/pod 确认是否 CPU、内存异常。
找出资源占用最高的 Pod。
检查 Pod 是否缺少 requests/limits。
查看是否存在 JVM、缓存、日志等异常占用。
临时通过驱逐 Pod、扩容节点止血。
后续通过:
requests/limits
taint/toleration
节点亲和性
ResourceQuota
HPA/VPA 做长期治理。
对核心业务进行节点池隔离,避免低优先级任务抢占资源。
# 简短描述
有一次线上订单服务在业务高峰期出现响应变慢,影响了大概30%的用户。
我接到告警后,第一步先看监控,发现有一台节点 CPU 持续打满,初步判断是资源层面的问题。
然后查了昨晚的发布记录,发现有新应用上线并调度到了这台节点。进一步对比各 Pod 的实际资源占用,发现虽然每个应用都设置了 resource limit,但高峰期多个应用同时到达资源上限,叠加之后超过了这台节点的实际资源瓶颈,导致节点整体过载。
处理上分两步:先回滚新应用,让节点资源恢复正常,服务响应恢复;再重新规划调度策略,给核心服务的节点打上污点,配置节点亲和性,确保核心服务独占资源,避免其他应用调度进来叠加负载。
最后做了复盘,整理成内部文档,并排查了其他节点是否存在类似的资源叠加风险。
2
3
4
5
6
7
8
9
具体操作示例
# 下面给出完整的配置示例。
# 场景说明
order-node-1、order-node-2是核心订单服务专用节点- 订单服务 Pod 需要调度到这些节点,其他应用不得进入
# 第一步:给核心节点打污点
# 给节点打污点,效果 NoSchedule(不容忍的 Pod 不会调度进来)
kubectl taint nodes order-node-1 dedicated=order:NoSchedule
kubectl taint nodes order-node-2 dedicated=order:NoSchedule
# 验证
kubectl describe node order-node-1 | grep Taint
# 输出:Taints: dedicated=order:NoSchedule
2
3
4
5
6
7
# 第二步:给核心节点打标签(供亲和性使用)
kubectl label nodes order-node-1 node-role=order
kubectl label nodes order-node-2 node-role=order
# 验证
kubectl get nodes --show-labels | grep order
2
3
4
5
# 第三步:订单服务 Deployment 配置
order-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
# ① 容忍核心节点的污点,允许调度进去
tolerations:
- key: "dedicated"
operator: "Equal"
value: "order"
effect: "NoSchedule"
# ② 节点亲和性,硬性要求只调度到 order 节点
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role
operator: In
values:
- order
containers:
- name: order-service
image: your-registry/order-service:v1.2.0
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 第四步:其他应用确保不调度到核心节点
其他应用的 Deployment 不加 toleration,污点会自动阻止它们进入核心节点,无需额外配置。
但如果其他应用需要明确声明不去 order 节点(双重保险),可加反亲和:
other-app-deployment.yaml 片段
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role
operator: NotIn # 明确排除 order 节点
values:
- order
2
3
4
5
6
7
8
9
# 完整逻辑示意
order-node-1/2
污点: dedicated=order:NoSchedule
标签: node-role=order
↑ ↑
| toleration | nodeAffinity
| (允许进入) | (必须调度到这里)
order-service Pod 其他 Pod
× 无 toleration,被污点拒绝
2
3
4
5
6
7
8
# 验证调度结果
# 确认订单服务 Pod 都落在核心节点
kubectl get pods -n production -o wide | grep order-service
# 确认其他应用没有调度到核心节点
kubectl get pods -n production -o wide | grep -v order-service
2
3
4
5
# 关键点总结
| 配置项 | 作用 | 缺少会怎样 |
|---|---|---|
| Node 污点 | 阻止无容忍的 Pod 进入 | 其他应用仍可调度进来 |
| Pod toleration | 允许订单服务进入有污点的节点 | 订单服务自己也进不去 |
| nodeAffinity required | 强制订单服务只去核心节点 | 订单服务可能散落到普通节点 |
污点负责"拒外",toleration + nodeAffinity 负责"引导自己人进来",两者配合才能实现真正的节点独占。
# 文本机器人接口超时
问题描述:
我曾处理过一次智能客服平台生产故障,当时用户反馈机器人无法正常回答问题,部分请求超时。通过查看应用日志,发现大量数据库请求超时,随后联合DBA排查数据库会话和连接情况。最初通过重启服务临时恢复业务,但故障再次出现。进一步分析发现是MySQL集群HAProxy存在Bug,导致请求被错误转发到主从节点,引发数据库全局锁和连接池耗尽,最终造成应用服务异常。随后DBA清理异常会话并修复代理进程,业务恢复正常。事后我们增加了数据库代理层监控、连接池监控和关键日志告警,避免类似问题再次发生。
排查步骤:
第一阶段:快速止血
运维和开发发现异常后:
- 第一时间重启问答核心服务
- 临时释放积压连接
- 服务短暂恢复
但因为数据库问题没有真正解决,所以后面故障再次出现。
第二阶段:数据库恢复
DBA 介入后:
- 检查数据库会话
- 发现主从库都存在异常连接
- 手动清理主从数据库锁和会话
- 解除全局锁
10:30 后业务恢复正常。
第三阶段:根因修复
持续排查后发现:
- HAProxy 存在异常子进程
- 导致流量错误转发
最终 DBA:
- 删除异常 HAProxy 进程
- 恢复正常主从流量转发
# mysql主从延迟怎么解决
# 1. 诊断:先确定为什么慢
在优化前,必须明确瓶颈在哪里。通过 SHOW SLAVE STATUS\G 查看 Seconds_Behind_Master。
- 网络延迟: 主从服务器跨机房,网络带宽或抖动。
- 主库压力: 主库写入大批量数据(DDL、大事务),导致从库同步不过来。
- 从库单线程: 这是最常见的原因。MySQL 5.6 之前是完全单线程同步,即便从库配置很高也只能利用一个核。
- 锁竞争: 从库上存在长查询,阻塞了 SQL 线程的执行。
# 2. 参数优化(“对症下药”)
- 开启多线程复制(最有效):
- MySQL 5.6+ 支持
slave_parallel_type = LOGICAL_CLOCK(基于组提交的并行复制)。 - MySQL 5.7+ 引入了
slave_parallel_workers,确保主库开启了binlog_group_commit。 - 这是解决从库跟不上主库写入速度的最直接手段。
- MySQL 5.6+ 支持
- 降低从库负载:
sync_binlog = 0和innodb_flush_log_at_trx_commit = 0:在从库允许一定数据丢失风险的前提下,提高磁盘 IO 效率。- 关闭不必要的 Binlog: 从库如果只负责读,可以关掉
log_slave_updates。
- 硬件升级: 将从库的磁盘换成性能更好的 SSD,提升随机 IO 能力。
# 3. 架构调整(“釜底抽薪”)
如果参数调优后依然无法解决,说明架构到了瓶颈,需要重构:
- 拆分大事务: 避免在主库执行长事务(如删除千万级数据),改为分批执行。
- 读写分离的降级处理: * 当延迟超过阈值(如 5s),业务逻辑自动将该用户的读请求暂时切回主库(需评估主库承受能力)。
- 升级数据库版本: 越高版本的 MySQL,在并行复制的粒度(如
WRITESET模式)上优化得越好。 - 缓存策略: 对于实时性要求极高的数据(如余额、订单状态),直接读主库或使用 Redis,减轻从库压力。
|