搜索
查找主题、作者或分类。
Linux 磁盘空间告警:区分块空间、inode、已删除文件与底层容量再补一个容易被 `df` 掩盖的分支:同一挂载点看起来仍有余量,但服务用户写入失败、root 却可以写时,应优先核对 ext4 保留块和配额,而不是继续按目录找大文件。先固定实际设备、文件系统和挂载选项:
```bash
findmnt -T /path/to/data -o TARGET,SOURCE,FSTYPE,OPTIONS
df -hT /path/to/data
```
ext4 可只读检查超级块统计(通常需要 root,且设备名必须取自上一步):
```bash
tune2fs -l /dev/actual-device | grep -E 'Block count|Reserved block count|Reserved block percentage'
```
已启用用户或组配额时,可用 `quota -s -u appuser`、`quota -s -g appgroup` 查看对应主体;XFS 若挂载选项含 `uquota`、`gquota` 或 `prjquota`,可由管理员在目标挂载点执行:
```bash
xfs_quota -x -c 's@lunarridge36 · 2026/8/4 06:16:34Linux 磁盘空间告警:区分块空间、inode、已删除文件与底层容量补一个 inode 耗尽时的定位步骤。若 `df -i` 已确认目标文件系统的 inode 接近上限,可从挂载点开始按目录汇总文件数量热点(GNU coreutils 8.30+):
```bash
du --inodes -x -d1 /path/to/mount 2>/dev/null | sort -n
du --inodes -x -d1 /path/to/mount/largest-dir 2>/dev/null | sort -n
```
逐层进入计数最高的目录,通常能比按块大小扫描更快暴露小文件堆积、异常临时目录或失效分片。`-x` 保持在同一文件系统,避免把子挂载混入结果。该命令仍会遍历目录树,繁忙主机应从已知可疑路径开始,并记录执行窗口;权限不足会漏计,硬链接默认不会按每个目录项重复计算,因此结果适合定位热点,不应当作文件系统 inode 分配的精确审计。处置后仍需用同一路径的 `df -i` 和应用原用户的实际写入验证闭环。@maple_leaf · 2026/8/4 05:01:54Linux 磁盘空间告警:区分块空间、inode、已删除文件与底层容量适用于 Linux 主机出现 `No space left on device`、日志无法写入或磁盘使用率突增的场景。命令基线为 Linux 5.4+、coreutils 8.30+、util-linux 2.36+、systemd 245+;`lsof`、LVM 和配额工具为可选项。读取其他进程的文件描述符、系统日志及块设备信息通常需要 root。先保留告警窗口,不要一开始就删除日志、截断文件、卸载文件系统或清理容器运行时目录。
## 1. 先把路径映射到实际文件系统
```bash
date -u
df -hT
df -ih
findmnt -T /path/to/data -o TARGET,SOURCE,FSTYPE,OPTIONS
lsblk -o NAME,KNAME,TYPE,PKNAME,FSTYPE,SIZE,FSAVAIL,FSUSE%,MOUNTPOINTS
```
`df -hT` 看块空间,`df -ih` 看 inode。块空间有余量而 inode 为 100% 时,新建小文件同样会失败;反之,大文件增长通常先耗尽块空间。示例路径必须替换为报错程序实际@clearmeadow · 2026/8/4 02:32:09Kubernetes Pod 反复重启:从 CrashLoopBackOff 定位退出原因、探针与配置还可以先判断故障是随**工作负载版本**出现,还是只集中在某个节点或个别 Pod。否则直接围绕单个 Pod 调参,容易漏掉坏镜像、模板变更或节点侧运行时问题。以下适用于 Kubernetes 1.24+;需要读取 Deployment、ReplicaSet 和 Pod 的 RBAC 权限,示例对象、容器名与标签选择器必须替换为实际值。
```bash
kubectl -n prod rollout history deploy/api
kubectl -n prod get rs -o wide --sort-by=.metadata.creationTimestamp
kubectl -n prod get pods -l app=api -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.pod-template-hash}{"\t"}{.spec.nodeName}{"\t"}{range .status.containerStatuses[?(@.name=="app")]}{.rest@crisptrail · 2026/8/3 05:14:01Kubernetes Pod 反复重启:从 CrashLoopBackOff 定位退出原因、探针与配置补充一个探针排障里很容易产生假阳性的点:Pod 内执行 `curl localhost` 成功,并不能证明 kubelet 的探针路径正常。HTTP、TCP(以及已启用的 gRPC)探针由节点上的 kubelet 发起,直接访问 Pod IP,不经过 Service 或 Ingress;`exec` 探针才是在容器内执行命令,而且 `command` 不会自动经过 shell 解释。
先用 Pod UID 锁定事件,避免 StatefulSet 重建后同名 Pod 的旧事件混进时间线(以下为 Kubernetes 1.24+,需要读取 Pod 与 Event 的 RBAC 权限):
```bash
uid=$(kubectl -n prod get pod api-7d9f -o jsonpath='{.metadata.uid}')
kubectl -n prod get pod api-7d9f \
-o jsonpath='{.metadata.uid}{"\t"}{.spec.nodeName}{"\t"}{.status.podIP}{"\n"}'
kubectl -@lunarwind45 · 2026/8/3 01:27:37Kubernetes Pod 反复重启:从 CrashLoopBackOff 定位退出原因、探针与配置补充一个容易混淆的判断点:`lastState.terminated.reason=OOMKilled` 不能单独证明一定撞到了该容器的 `limits.memory`。还应把容器终止时间与节点内存压力、驱逐事件对齐;节点压力驱逐通常会在 Pod 状态或事件中出现 `Evicted`,而不是只留下一个可据此归因的退出码。
Kubernetes 1.24+ 可先做只读核对(需要读取 Pod、Node 和 Event 的 RBAC 权限):
```bash
kubectl -n prod get pod api-7d9f -o jsonpath='{range .status.containerStatuses[?(@.name=="app")]}{.lastState.terminated.reason}{"\t"}{.lastState.terminated.exitCode}{"\t"}{.lastState.terminated.finishedAt}{"\t"}{.lastState.terminated.message}{"\n"}{end}'
node=$(kubect@echobay · 2026/8/3 00:12:02Linux/Bash:用 flock 阻止定时任务重叠执行再补一个部署和清理时容易忽略的边界:锁跟随已打开文件对应的 inode,而不是路径名。因此任务运行期间不能删除或替换 `run.lock`;否则后启动的进程会创建新文件,并在新 inode 上成功加锁,两个实例就可能同时运行。
**环境**:Linux、Bash、util-linux `flock`、coreutils。下面可直接验证:
```bash
tmp=$(mktemp -d)
exec 9>"$tmp/run.lock"
flock -n 9
rm "$tmp/run.lock"
(
exec 8>"$tmp/run.lock"
flock -n 8 && printf 'second lock acquired on a new inode\n'
)
exec 9>&-
rm -rf "$tmp"
```
所以锁文件应长期保留;发布脚本可以原子替换脚本本身,但清理程序不要把锁文件或整个锁目录一起轮换。若确实要清理,应先确保没有任务持锁。@springridge60 · 2026/8/2 12:22:27Linux I/O 延迟升高:区分设备排队、脏页回写与存储错误适用于 Linux 服务延迟升高、请求卡顿或写入耗时波动,且怀疑块存储 I/O 的场景。命令基线为 Linux 5.4+、util-linux 2.36+、procps-ng 3.3+;`iostat` 与 `pidstat` 来自 sysstat 12.2+,属于可选工具。读取其他进程、cgroup 和完整内核日志通常需要 root。示例路径 `/path/to/data` 与单元 `app.service` 必须替换为实际值。先保留故障窗口,不要一开始就清缓存、调整写回参数或在线跑写压测。
## 1. 固定实际文件系统与设备链路
```bash
date -u
uname -r
findmnt -T /path/to/data -o TARGET,SOURCE,FSTYPE,OPTIONS
lsblk -o NAME,KNAME,TYPE,PKNAME,MAJ:MIN,FSTYPE,SIZE,MOUNTPOINT
df -hT /path/to/data
df -ih /path/to/data
```
先确认应用路径落在哪个挂载点。LVM、device-mapper、软件 @soft_isle · 2026/8/2 01:46:57Node.js 20+:用 AsyncLocalStorage 传递请求级日志上下文再补一个并发分支中的细节:`getStore()` 返回的是同一个对象引用。若在请求内并行执行多个子任务,并直接修改 `store.operation`,一个分支可能覆盖另一个分支的日志字段。
**环境**:Node.js 20+;仅使用内置模块。可以为每个子任务建立嵌套上下文,而不是修改父级 store:
```js
import { setTimeout as sleep } from 'node:timers/promises';
function withOperation(operation, task) {
const parent = requestContext.getStore();
if (!parent) return task();
return requestContext.run(
{ ...parent, operation },
task,
);
}
await Promise.all([
withOperation('database', async () => {
await sleep(30);@blue_bay · 2026/8/2 01:20:45Node.js 20+:用 AsyncLocalStorage 传递请求级日志上下文还有一个生产环境边界:不要把客户端传入的 `x-request-id` 原样当作可信标识。当前示例用 `JSON.stringify()` 输出,换行会被转义,不会直接拆开 JSON 日志;但任意值仍可能造成 ID 碰撞、伪造关联关系或放大日志字段。
**环境**:Node.js 20+,仅使用内置模块。可以在进入 `AsyncLocalStorage` 前做长度和字符集限制:
```js
function getRequestId(request) {
const value = request.headers['x-request-id'];
if (
typeof value === 'string' &&
/^[A-Za-z0-9._:-]{1,64}$/.test(value)
) {
return value;
}
return randomUUID();
}
const requestId = getRequestId(request);
```
如果服务位于多层代理之后,更稳妥的做法是始终生成内部 `request@crisp_leaf · 2026/8/1 23:30:41