Linux 内核崩溃与 kdump:给服务器装上飞行记录仪
概述 凌晨三点,你被告警吵醒,登录服务器发现屏幕上只有一行 Kernel panic - not syncing: Fatal exception,然后系统就重启了。等你好不容易连上去,崩溃现场什么都没留下——没有日志,没有 core dump,没有调用栈。你只能对着一句 systemd-logind: System is going down 发呆。 这种场景,每个干过几年运维的人都遇到过。内核崩溃本身已经够头疼了,但更头疼的是崩溃后什么都抓不到,问题根本没法定位。 kdump 就是解决这个问题的。它相当于给 Linux 服务器装了一台飞行记录仪——飞机坠毁时,黑匣子能告诉你最后几秒发生了什么;内核崩溃时,kdump 能把崩溃瞬间的完整内存状态保存下来,让你事后用 crash 工具逐帧分析。 这篇文章不讲虚的,从 kdump 的工作原理到生产环境的完整配置流程,再到 crash 工具的实际分析操作,全部覆盖。读完之后,你应该能在自己的服务器上搭一套可靠的崩溃捕获系统。 kdump 是怎么工作的 双内核机制 要理解 kdump,先搞懂一个关键概念:崩溃时主内核已经不可信了。你不能指望一个已经 panic 的内核去把自己的内存好好保存下来——它连正常执行代码都做不到。 kdump 的思路很巧妙:系统启动时,提前预留一块物理内存,在里面加载一个精简的"捕获内核"(capture kernel,也叫第二内核)。主内核正常运行时,这块内存被隔离,谁都不许动。一旦主内核崩溃,kexec 机制会直接把 CPU 控制权交给捕获内核——不走 BIOS,不重启硬件,直接在预留内存里启动。捕获内核接管后,主内核的内存内容还完好无损地躺在那里,捕获内核把它打包成 vmcore 文件,写到磁盘上。 整个过程像这样: ┌──────────────────────────────────────────────┐ │ 物理内存布局 │ │ │ │ ┌────────────────┐ ┌───────────────────┐ │ │ │ 主内核区域 │ │ 预留内存区域 │ │ │ │ (正常运行) │ │ (crashkernel) │ │ │ │ │ │ │ │ │ │ 用户进程 │ │ 捕获内核 + │ │ │ │ 内核模块 │ │ initramfs │ │ │ │ 页缓存....
数据库监控体系搭建:从 Exporter 到告警规则的全链路实战
概述 数据库慢了,业务就慢了。这句话每个运维都听过,但真正把数据库监控做到位的团队,说实话不多。 我见过太多团队的数据库监控长这样:Zabbix 模板跑着十年前的指标,告警只有"CPU 超过 90%“和"磁盘满了"两条,数据库内部的连接数、锁等待、缓存命中率、复制延迟——这些真正能提前预警的指标,压根没采。等业务方跑来说"接口好慢”,你才发现数据库连接池早就满了,慢查询堆积了几百条。 数据库监控的核心难点不在于"装个 exporter",而在于你知道该看哪些指标、怎么设阈值、怎么从指标变化中读出数据库的健康状况。这篇文章就把这些讲透。 覆盖 MySQL 和 PostgreSQL 两大主流数据库,从 exporter 部署、核心指标解读、告警规则设计到 Grafana 仪表盘配置,全链路打通。技术栈基于 Prometheus + Grafana,这是目前开源数据库监控的事实标准。 数据库监控的三层架构 在动手之前,先理清监控的层次。数据库监控不是一股脑把所有指标都采上来就完了,得分层: ┌──────────────────────────────────────────────────┐ │ 业务应用层 │ │ 核心接口响应时间 | 业务操作成功率 | 业务吞吐量 │ │ → 这些指标直接关联用户体验 │ ├──────────────────────────────────────────────────┤ │ 数据库内核层 │ │ 连接数 | QPS/TPS | 慢查询 | 锁等待 | 缓存命中率 │ │ 复制延迟 | 死锁 | WAL写入 | 事务回滚率 │ │ → 这些指标反映数据库内部运行状态 │ ├──────────────────────────────────────────────────┤ │ 服务器资源层 │ │ CPU | 内存 | 磁盘IO | 网络 | 文件系统 │ │ → 这些指标是数据库运行的物理基础 │ └──────────────────────────────────────────────────┘ 参考 数据库性能监控体系构建 的三层架构设计,每一层关注的问题不同:...
K3s 边缘计算实战:轻量级 Kubernetes 在资源受限场景下的部署与运维
概述 你在一家智能制造公司干运维。工厂车间里有 200 台边缘网关,每台跑着数据采集和实时质检的服务。之前用裸 Docker 部署,每次更新都得写脚本逐台 SSH 上去拉镜像、重启容器。200 台机器跑一轮,半小时过去了,中间还经常有几台网络抖动导致更新失败。 你心想:这不就是 Kubernetes 要解决的问题吗?编排、调度、滚动更新、自愈——全都有了。但真去装 K8s 的时候傻眼了:车间网关用的是 ARM 架构的工控机,2 核 CPU、2G 内存,光 etcd 就吃掉 500M,kube-apiserver、kube-scheduler、kube-controller-manager 一堆组件跑起来,系统资源所剩无几。 这时候 K3s 登场了。它是 Rancher 开发的轻量级 Kubernetes 发行版,把所有控制面组件打包成一个 50MB 的二进制文件,内存占用不到 512M,支持 ARM64/x86_64,自带 containerd 运行时、Flannel 网络、CoreDNS、Traefik Ingress——开箱即用。在树莓派上都能跑起来,工控机更不在话下。 这篇文章聊聊 K3s 在边缘计算场景下的实战:从架构原理到集群搭建,从网络方案到边缘自治,从监控告警到故障排查。不是入门教程的复述,而是生产环境踩坑后的经验总结。 K3s 架构:为什么它能在 512M 内存上跑起来 和 K8s 的关键差异 K3s 不是 K8s 的阉割版——这个说法太粗暴了。它是一个为资源受限环境重新设计的 Kubernetes 发行版。核心区别在以下几方面: 特性 K8s K3s 二进制大小 ~300MB(多组件) ~50MB(单二进制) 最低内存 2GB 512MB 存储后端 etcd(必须) SQLite(默认)/ etcd / MySQL / PostgreSQL 运行时 需单独安装 containerd/Docker 内置 containerd 网络 CNI 需手动安装 内置 Flannel Ingress 需手动安装 内置 Traefik DNS 需手动安装 内置 CoreDNS Alpha/Beta 特性 全部包含 剔除 云厂商专用代码 全部包含 剔除 架构支持 x86_64 / ARM64 x86_64 / ARM64 / ARMv7 K3s 的核心设计哲学是:在边缘场景下,你需要的是 K8s 的编排能力,而不是它的全部复杂性。去掉 alpha/beta 特性和云厂商专用代码后,K3s 保留了 K8s 的核心 API 和功能——Pod、Deployment、Service、ConfigMap、HPA、CronJob 这些你日常用的资源全都在,kubectl 命令完全兼容。...
SRE 故障预案与演练:从纸上谈兵到肌肉记忆的工程实践
概述 凌晨两点,你被电话吵醒。监控大屏一片红,核心交易链路 P99 延迟飙到 8 秒,上游服务开始超时熔断,客服群里用户截图已经刷屏了。你一边远程连 VPN,一边脑子里飞速转——这场景上次演练时见过吗?预案里有没有覆盖?切换步骤还记得吗? 如果你这时候还在翻 wiki 找文档,那说明一件事:你的预案只是写了,没练过。 故障预案不是写完就完事的文档。它是一套需要反复演练、不断修正的应急肌肉记忆。就像消防队不会只在纸上画逃生路线——他们会点真火,拉真警报,让人在浓烟里跑。SRE 的故障演练也是同一个道理:不逼团队在接近真实的故障场景里做决策,到了真正出事的时候,你永远不知道谁会卡壳。 这篇文聊聊怎么把故障预案从"写给别人看的文档"变成"团队真正能执行的作战手册",以及怎么设计演练体系让团队保持手感。 故障预案的本质:不是文档,是决策树 预案要解决什么问题 很多人把故障预案理解成一份操作手册——“如果 A 挂了,执行步骤 1-2-3”。这没错,但太浅了。真正有用的预案是一棵决策树,帮值班人员在高压环境下快速做对三件事: 判断故障等级——这事值不值得半夜叫人?叫到哪一级? 选择止损路径——先切流量、先回滚、还是先扩容? 确定沟通节奏——谁对外发声、多久同步一次、什么时候升级 我见过太多预案写得像产品说明书,事无巨细地列了 50 个步骤,值班同学在故障现场根本来不及看。好的预案应该短、狠、准——能在 30 秒内定位到对应的处置方案,3 分钟内开始执行止损。 预案体系的三层结构 层级 内容 目标读者 更新频率 L1 应急卡片 单服务故障的快速处置步骤(≤10 步) 值班 On-Call 每次演练后 L2 灾备预案 跨服务故障的切换方案与回滚流程 SRE 团队 每季度 L3 业务连续性预案 机房级故障的全面接管方案 SRE + 业务方 每半年 L1 应急卡片是日常用得最多的。它不是 wiki 上的长文,而是一张可以打印出来贴在工位上的卡片。格式很简单: # [服务名] 应急卡片 ## 故障特征 - 核心指标:P99 延迟 > 500ms 或 错误率 > 1% - 典型告警:service_latency_p99_critical / service_error_rate_high ## 快速止血(按优先级) 1....
APM 工具选型:从开源到商业的全维度实战指南
概述 你有没有遇到过这种情况:用户反馈"系统好卡",你打开 Grafana 看了一堆面板,CPU 正常、内存正常、网络也正常,但用户就是说慢。这时候你需要的不是更多的指标面板,而是一条完整的请求链路——从用户点下按钮到数据库返回结果,每一跳花了多少时间,卡在哪一步。 这就是 APM(Application Performance Monitoring,应用性能监控)干的事。 简单说:日志告诉你发生了什么,指标告诉你系统是否健康,APM 告诉你为什么慢、慢在哪里、影响了谁。三者各管一摊,缺一不可。 本文从实际选型角度出发,拆解主流开源和商业 APM 工具的架构差异、适用场景和坑点。不吹不黑,每家都有适合的场景,关键看你的团队规模、技术栈和预算。 APM 要解决什么问题 先说清楚为什么需要 APM,而不是直接跳到工具对比。 微服务架构下的"链路黑盒" 单体应用时代,一个请求从入口到数据库都在一个进程里完成,打个断点就能调试。微服务拆分后,一个用户请求可能经过 API 网关 → 认证服务 → 订单服务 → 支付服务 → 消息队列 → 库存服务 → 数据库,中间还穿插着 Redis 缓存和第三方 API 调用。 任何一个环节变慢,整体就慢。但你看日志只能看到单个服务的视角,没法把整条链路串起来。这就像你在医院看病,内科查完说没问题让你去外科,外科查完说没问题让你去骨科——每个科室都说自己没问题,但你就是难受。APM 就是那个能把你所有科室检查结果串起来看的"全科医生"。 APM 的三个核心能力 能力 解决什么问题 类比 分布式追踪(Distributed Tracing) 一个请求经过哪些服务、每跳花了多久 快递物流追踪,每个中转站都有时间戳 性能剖析(Profiling) 某个函数执行慢,CPU 花在哪了 体检报告,精确到每个器官的指标 错误追踪(Error Tracking) 异常发生在哪个服务的哪行代码 车辆故障码,直接定位到故障部件 分布式追踪是 APM 最核心的能力。它通过在请求入口生成一个唯一的 Trace ID,然后通过 HTTP Header 或 RPC 上下文传递到下游服务,每个服务在自己的处理过程中记录一个 Span(你可以理解为链路上的一个节点),最终拼出完整的调用树。 关键概念速览 术语 含义 说明 Trace 一次完整的请求链路 由多个 Span 组成的有向无环图(DAG) Span 链路上的一个操作节点 包含操作名、起止时间、标签、日志 Context Propagation 上下文传递 Trace ID 通过 HTTP Header 在服务间传递 Sampling 采样 不可能记录所有请求,按策略采样部分 Instrumentation 探针/埋点 代码层面自动或手动注入追踪逻辑 采样策略很关键。线上流量大的时候,全量记录 Trace 会把存储和 CPU 吃干。常见做法是头部采样(Head-based Sampling)——在请求入口决定是否记录,要么整条链路全记,要么全不记。尾部采样(Tail-based Sampling)更精细——在链路结束时根据条件(比如耗时超过阈值、出现错误)决定是否保留,但实现复杂度高,需要中间层缓存完整链路。...
系统安全审计:auditd 规则配置与日志分析实战
概述 凌晨三点,你被告警吵醒。登录服务器一看,某个关键配置文件被改了,但 last 命令显示那个时间段没有人登录,bash_history 也没记录。你知道出事了,但不知道是谁干的、怎么干的。 这时候你需要的是 auditd——Linux 内核自带的审计系统。它就像飞机的黑匣子,记录系统上发生的每一个关键动作:谁执行了什么命令、访问了哪些文件、改了什么配置、什么时候提的权。而且这些记录在内核层面生成,不依赖 shell history 或应用日志——攻击者就算删了 ~/.bash_history,也删不掉 auditd 的日志。 本文从安装部署讲到规则编写、日志分析和生产调优。不是手册翻译,是踩过坑后的实战经验。 auditd 是什么,和 syslog 有什么区别 先说清楚一个常见的混淆。很多人觉得"我有 syslog/journald 了,还要 auditd 干嘛?" 两者记录的东西完全不同: 对比项 syslog/journald auditd 记录层级 应用层 内核层 记录内容 服务启动/停止、应用日志、登录记录 系统调用、文件访问、权限变更 粒度 粗(按事件) 细(按系统调用) 防篡改 无(root 可随意修改) 有(日志写入前加密校验) 性能影响 极低 有,取决于规则数量和复杂度 典型用途 日常运维日志 安全审计、合规检查、应急响应 打个比方:syslog 像小区门口的保安登记簿,谁进谁出记一笔。auditd 像每户人家的门禁记录加室内监控——什么时候开了哪个门、谁开的、开了多久,精确到秒。 auditd 最初源自 Solaris 的审计子系统,Linux 内核 2.6(2004 年)开始引入,由 Red Hat 和 IBM 主导开发。现在已经是 CIS Benchmark、PCI-DSS、HIPAA 等安全合规标准的必备组件。 auditd 已成为 Linux 安全标准(如 CIS Benchmark、PCI-DSS、HIPAA)的重要组成部分。参考来源:Demystifying Auditd: A Complete Guide for Linux Security Monitoring...
Jenkins 自由风格与流水线:两种项目配置的实战对比与选型
概述 用 Jenkins 的人分两派:一派在网页上填表单配任务,点几下就跑起来了,简单粗暴;另一派在代码仓库里写 Jenkinsfile,把构建流程变成代码,版本控制、评审、回滚一条龙。 前者叫 Freestyle Project(自由风格项目),后者叫 Pipeline Project(流水线项目)。 这两种风格不是"谁取代谁"的关系。很多团队两个都在用——简单的脚本任务用 Freestyle,复杂的多阶段发布用 Pipeline。但如果你刚开始搞 CI/CD,或者在犹豫要不要从 Freestyle 迁到 Pipeline,这篇文章帮你把两种风格的配置流程、核心差异、选型策略一次性捋清楚。 我先说结论:能用 Pipeline 就用 Pipeline。但别急着全盘迁移,得看场景。下面从零开始配。 Jenkins 项目到底是个什么东西 Jenkins 本身是个任务执行引擎。你给它一组指令——去哪拉代码、怎么编译、往哪部署——它照着干。这组指令的载体就是 Jenkins 项目(Jenkins 内部叫 Job)。 打个比方,Jenkins 是厨师,项目就是菜谱。菜谱写了先切菜、再炒、最后装盘,厨师按步骤做。Freestyle 和 Pipeline 就是两种不同格式的菜谱——一个是填表式,一个是代码式。 Jenkins 原生支持好几种项目类型,实际干活最常用的就两种: 项目类型 怎么配 适合谁 Freestyle Project 在网页上填表单 刚接触 Jenkins 的团队,简单构建场景 Pipeline Project 写 Jenkinsfile 代码 需要多阶段编排、长期维护的团队 还有 Maven 项目(Java Maven 专用的 Freestyle 特化版)和多配置项目(同一任务跑多套参数),用得越来越少,这里不展开。 两种风格的本质区别 先看一个直观的例子。假设要配一个"拉代码 → 编译 → 部署"的任务。 Freestyle 版本:打开 Jenkins 网页,在源码管理填 Git 地址,构建步骤填 mvn clean package,构建后操作填部署脚本。保存,点构建,跑起来了。...
Linux 网络抓包与协议分析:从 tcpdump 到 Wireshark 的实战排障指南
概述 凌晨两点,你被电话吵醒。订单系统大面积超时,但 CPU 正常、内存正常、磁盘 IO 正常。重启服务没用,回滚也没用。你盯着监控大盘,一切指标都是绿的,唯独用户在骂。 十有八九,是网络层面的问题。这时候你需要的是一双能看见数据包的眼睛。 tcpdump 就是这双眼睛。它不是什么新工具——1990 年代就有了——但到今天仍然是 Linux 上最硬核的网络诊断手段。说直白点:如果你只会看监控图表、不会抓包,那遇到网络层问题时你就是个瞎子。 这篇文章不讲花哨的概念,就讲实战:tcpdump 怎么抓、BPF 过滤器怎么写、pcap 文件怎么用 Wireshark 分析、TCP 三次握手和 TLS 握手在抓包里长什么样、以及那些我踩过坑才学会的技巧。 tcpdump 基础:先搞懂你在抓什么 什么是抓包 网卡收到的每一个数据帧,正常情况下只有操作系统内核会处理,用户态程序看不到原始内容。抓包就是把网卡的混杂模式(promiscuous mode)打开,让内核把所有流经网卡的数据包副本都交给抓包工具。 打个比方:正常情况下网卡像个只读收件箱的快递员,只把发给你的包裹送上门。开了混杂模式后,它变成监控摄像头,把整条街上经过的所有包裹都拍下来——不管是不是给你的。 tcpdump vs Wireshark:分工不同 对比维度 tcpdump Wireshark 运行环境 服务器命令行,SSH 即可 需要图形界面 资源占用 极低(几 MB 内存) 较高(GUI 程序) 核心能力 捕获+保存 pcap 深度协议解析+交互式分析 过滤语法 BPF(Berkeley Packet Filter) 显示过滤器(Display Filter) 适用场景 生产服务器实时抓包、长期后台捕获 本地分析 pcap 文件、协议细节排查 自动化 可写成脚本、对接告警 不适合自动化 实际工作中的标准流程:服务器上用 tcpdump 抓包保存成 pcap 文件,scp 下载到本地,用 Wireshark 打开分析。这个组合我在过去七年里用了不下五百次。 安装与权限 大多数 Linux 发行版预装了 tcpdump。检查一下:...
自动化巡检平台从零搭建:插件化架构设计与 Go 实现全攻略
概述 运维团队三个人,管着 200 台服务器。每天上班第一件事:挨个 SSH 登录,检查磁盘、内存、CPU、连接数、证书过期时间……一上午就过去了。遇到突发故障,根本来不及巡检,问题已经在用户投诉里炸了。 这不是个别现象。很多中小团队的运维巡检还停留在"人肉+脚本"的阶段——有几个 Shell 脚本,但散落在各个机器上,没人维护,没人知道上次跑是什么时候,输出也没人看。 自动化巡检平台解决的就是这个问题。不是简单的"把脚本集中起来跑",而是一套完整的体系:插件化的检查项、并发的执行引擎、灵活的告警策略、可读的巡检报告。这篇文章从架构设计到代码实现,讲清楚怎么用 Go 搭一个生产可用的巡检平台。 为什么选 Go 而不是 Python?三个原因:单二进制部署、协程并发模型天然适合巡检场景、交叉编译方便分发到不同架构的服务器。Python 也能做,但在 200 台机器上分发 Python 环境和依赖的痛苦,经历过的人都懂。 巡检平台要解决什么问题 传统巡检的痛点 先看看"人肉巡检"到底有多痛: 痛点 具体表现 影响 覆盖不全 200 台机器只检查了 50 台常用的,剩下的"反正没出过事" 隐患积累,暴雷时措手不及 标准不统一 A 用 df -h,B 用 df -hT,C 写了个 Python 脚本但只有自己看得懂 换人就抓瞎,结果无法横向对比 无历史记录 巡检结果写在个人笔记里,离职后带走了 无法追溯趋势变化,“上周还好的怎么突然满了” 告警滞后 巡检发现磁盘 95%,但没人及时看到 从发现到处置间隔几小时甚至几天 人力浪费 3 个人每天花 2-3 小时巡检,月度耗时约 200 工时 相当于 1.25 个全职人力纯粹在做人肉检查 平台化巡检的核心能力 一个合格的巡检平台需要具备以下能力: ┌─────────────────────────────────────────────────────┐ │ 巡检平台核心能力 │ ├──────────┬──────────┬──────────┬──────────┬─────────┤ │ 检查引擎 │ 调度系统 │ 告警联动 │ 报告生成 │ 资产管理 │ │ │ │ │ │ │ │ 插件化 │ 定时触发 │ 多级阈值 │ HTML报告 │ 主机清单 │ │ 并发执行 │ 手动触发 │ 告警去重 │ 趋势图表 │ 分组管理 │ │ 超时控制 │ 补偿执行 │ 通知渠道 │ 差异对比 │ 标签体系 │ └──────────┴──────────┴──────────┴──────────┴─────────┘ 简单说:配置好检查项和阈值,平台自动在指定时间执行,发现问题立即告警,每次结果都存档可追溯。...
Linux CPU 隔离与 NUMA 调优:给关键业务独占算力的实战指南
概述 线上跑着一个高频交易系统,P99 延迟平时 2ms,但偶尔飙到 20ms。CPU 使用率不高,内存充足,网络正常。查了一圈,发现是 CPU 调度器把关键线程踢到了另一个核上,L3 缓存全部 miss,延迟直接翻了 10 倍。 这种问题不是靠加资源能解决的。问题出在"共享"——所有进程共享 CPU 核心,调度器自由分配,谁也不知道哪个线程是延迟敏感的。 解决办法就是 CPU 隔离:把关键业务绑到专属核心上,不让别的进程碰。同时做 NUMA 调优,让 CPU 和内存在物理上"就近",避免跨节点访问带来的延迟翻倍。 这篇笔记覆盖从基础概念到生产实操的完整链路:isolcpus 内核参数、cpuset cgroup、taskset 绑核、NUMA 亲和性、中断绑核、以及组合使用的最佳实践。所有命令都在 Ubuntu 22.04(内核 5.15)和 CentOS 8 上实测过。 基础概念:为什么要隔离 CPU CPU 调度器是怎么工作的 Linux 默认使用 CFS(Completely Fair Scheduler,完全公平调度器)分配 CPU 时间。CFS 的设计目标是"公平"——每个进程根据权重获得 CPU 时间片,调度器在所有可用核心之间自由迁移进程。 听起来没问题,但对延迟敏感的场景是个灾难: 上下文切换开销:线程从 CPU A 迁移到 CPU B,L1/L2 缓存全部失效,需要重新从内存加载数据。一次迁移的代价是微秒级的延迟抖动。 缓存污染:其他进程跑在你的目标核上,把你之前缓存的数据挤出去,下次你的线程回来时全是 cache miss。 中断干扰:网卡中断、定时器中断随时打断你的线程。对于要求微秒级响应的系统,一次中断就是一次延迟尖峰。 NUMA 架构是什么 NUMA(Non-Uniform Memory Access,非统一内存访问)是多路服务器的标配架构。简单说就是:每个 CPU 插槽有自己的本地内存,访问自己的内存很快,访问别的 CPU 的内存要跨 QPI/UPI 总线,延迟翻倍。...