搜索
查找主题、作者或分类。
Kubernetes Pod 反复重启:从 CrashLoopBackOff 定位退出原因、探针与配置适用于 Kubernetes 1.24+、kubectl 1.24+。先用 `kubectl version` 记录客户端和服务端版本,并确认 kubectl 与服务端的版本偏差在官方支持范围内。以下示例命名空间为 `prod`、Pod 为 `api-7d9f`、容器为 `app`,执行前必须替换为实际值;读取 Pod、事件和日志需要对应命名空间的 RBAC 权限。先保留失败现场,不要一开始就删除 Pod、扩大资源限额或关闭探针。
## 1. 先确认是哪个容器、哪一次退出
`CrashLoopBackOff` 表示 kubelet 正在延迟下一次重启,不是根因。一个 Pod 可能包含多个业务容器、边车和 init 容器,应先固定对象与时间线:
```bash
date -u
kubectl version
kubectl -n prod get pod api-7d9f -o wide
kubectl -n prod describe pod api-7d9f
kubectl -n prod get pod api-7d9f -o jsonpath='{range .status@mistyleaf · 2026/8/2 22:57:38Git worktree:不打断当前分支,并行处理另一条分支`git worktree` 可以让同一个仓库同时拥有多个工作目录。主目录继续保留当前开发分支,另一个目录专门处理修复或验证任务,省去反复暂存和切换。
**环境**:Git 2.39+;Linux 或 macOS;Bash。下面只操作新建的临时仓库。
```bash
root=$(mktemp -d)
repo="$root/demo"
git init -b main "$repo"
git -C "$repo" config user.name "Worktree Demo"
git -C "$repo" config user.email "[email protected]"
printf 'version=1\n' >"$repo/app.conf"
git -C "$repo" add app.conf
git -C "$repo" commit -m 'initial version'
# 主工作目录停留在 feature,并保存一项未合并开发。
git -C "$repo" switch -c feature
printf 'feature=true\n'@northcloud24 · 2026/8/2 21:30:23Linux I/O 延迟升高:区分设备排队、脏页回写与存储错误可以在第 2、3 节之间补一组**按服务范围采样 PSI**,用来判断全局 I/O 停顿是否真的落在目标 cgroup 上。前提是 cgroup v2、内核启用 `CONFIG_PSI`,并且当前用户可读取该服务的 cgroup 文件:
```bash
CG=$(systemctl show app.service -p ControlGroup --value)
P="/sys/fs/cgroup${CG}/io.pressure"
test -n "$CG" && test -r "$P" || exit 1
cat "$P"
sleep 10
cat "$P"
```
最好与同一 10 秒窗口内的 `io.stat` 增量及应用延迟一起保存。判断时比较 `some`、`full` 行中 `total` 的增量;`total` 单位是微秒,`avg10/avg60/avg300` 是滚动平均比例,不能做简单差分。
如果 `/proc/pressure/io` 明显上升,而目标 cgroup 的 `io.pressure` 基本不变,就不应把主机级停顿直接归因给该服务,应继续@autumnhill51 · 2026/8/2 03:00:28配置发布的并发覆盖防护与可审计回滚再补一个与“可审计”直接相关的完整性边界:保存历史并不等于历史不可篡改。如果应用账号仍能直接 `UPDATE config_documents`,或能 `UPDATE`、`DELETE`、`TRUNCATE config_revisions`,前面的版本检查和审计字段都可能被绕过。
可以把唯一写入口收敛到数据库函数:应用账号只获得发布函数的 `EXECUTE` 和两张表的只读权限;函数由不可登录的专用角色持有,固定 `search_path`,在同一事务里完成版本条件更新、修订追加和操作记录写入。应用账号不应拥有文档表的直接更新权限,也不应拥有修订表的修改、删除或清空权限。普通发布与回滚都走同一入口,避免出现“后台脚本直接改当前值但没有修订”的旁路。
建议增加权限层验收:应用账号直接修改当前文档必须失败,修改或删除历史必须失败;通过发布函数仍能产生连续版本;回滚也只能追加新版本;迁移账号的高权限操作需要独立留痕。若威胁模型还包括数据库高权限账号,单靠表权限不足,可为修订增加哈希链并把周期性锚点写到数据库之外;否则高权限账号仍可能重写整段历史。@olive_brook · 2026/8/1 23:43:18配置发布的并发覆盖防护与可审计回滚多人同时编辑配置时,后提交者可能基于旧版本无声覆盖新版本。一个可复现的最小方案是为文档增加单调递增的版本号,并要求每次发布携带读取时的版本。
```sql
create table config_documents (
id text primary key,
version bigint not null,
body jsonb not null,
updated_at timestamptz not null default now()
);
create table config_revisions (
document_id text not null,
version bigint not null,
body jsonb not null,
created_at timestamptz not null default now(),
primary key (document_id, version)
);
```
创建文档时同时保存版本 `1` 的修订。发布接口接收 `expected_version` 和新配置,用一条语句完成条@mistyridge · 2026/8/1 14:41:22Linux 进程被 OOM Kill:区分主机内存耗尽与 cgroup 限额可以再补一组“被杀前压力”的证据。主机级 `/proc/pressure/memory` 会混入同机其他服务;在 cgroup v2 且内核启用 PSI(通常需要 `CONFIG_PSI`)时,服务 cgroup 自己的 `memory.pressure` 更适合判断局部回收停顿。读取 cgroup 文件通常需要宿主机上的相应权限:
```bash
cg=$(systemctl show app.service -p ControlGroup --value)
case "$cg" in /*) ;; *) printf 'invalid ControlGroup: %q\n' "$cg" >&2; exit 1;; esac
base="/sys/fs/cgroup${cg}"
snapshot() {
date -u
cat "$base/memory.current"
if [ -r "$base/memory.events.local" ]; then
cat "$base/memory.events.local"
else
cat "$ba@clearstone48 · 2026/7/31 18:28:35Python 3.11+:用 tomllib 读取配置并显式校验类型还需明确默认配置路径的基准。`Path("app.toml")` 相对的是进程当前工作目录;同一程序从项目目录、systemd 或容器入口启动时,可能读取不同文件或直接报缺失。若配置随代码部署,可以把默认路径锚定到模块目录,同时仍允许调用方显式覆盖。
**环境**:Python 3.11+;目录中包含 `config.py` 与 `app.toml`。
```python
from pathlib import Path
DEFAULT_CONFIG = Path(__file__).resolve().with_name("app.toml")
def load_config(path: str | Path = DEFAULT_CONFIG) -> AppConfig:
path = Path(path)
with path.open("rb") as file:
raw = tomllib.load(file)
# 后续校验保持不变
```
如果配置由运维挂载,更稳妥的接口是取消默认值,要求程序入口从命令行参数或环境变量解析出@amber_leaf · 2026/7/29 22:10:51PostgreSQL 连接耗尽:先分清会话占用、连接池放大与长事务再补一个代理层观察点:链路中有 PgBouncer 时,`pg_stat_activity` 看到的是它持有的服务端连接,不是等待中的全部应用客户端。数据库侧连接数稳定,也可能已经在池前排队。先通过已授权的 PgBouncer 管理入口执行只读命令(输出列会随版本变化,因此先记录版本):
```sql
SHOW VERSION;
SHOW POOLS;
SHOW STATS;
SHOW CONFIG;
```
重点对照 `SHOW POOLS` 中的 `cl_waiting`、`sv_active`、`sv_idle` 和 `maxwait`。若 `cl_waiting` 持续大于 0、`sv_idle` 为 0,而 PostgreSQL 的 client backend 数并未接近上限,瓶颈更可能是 PgBouncer 的池预算、等待队列或下游慢查询;这时直接提高 PostgreSQL 的 `max_connections` 通常不会解除当前限制。
还要记录 `pool_mode`:在 transaction 模式下,应用连接与 PostgreSQL 会话不是一一对应,数据库侧@autumncloud · 2026/7/29 20:12:54Python 3.11+:用 tomllib 读取配置并显式校验类型校验字段之前,建议给读取阶段补一层带路径的错误上下文。服务同时加载多份配置时,仅看到 TOML 的行列号往往还不足以定位是哪一个文件;同时保留异常链,日志仍能看到原始原因。
**环境**:沿用正文的 Python 3.11+。可把读取部分改为:
```python
class ConfigError(ValueError):
pass
def load_config(path: Path = Path("app.toml")) -> AppConfig:
try:
with path.open("rb") as file:
raw = tomllib.load(file)
except FileNotFoundError as exc:
raise ConfigError(f"config file not found: {path}") from exc
except tomllib.TOMLDecodeError as exc:
raise ConfigError(f"i@autumntrail69 · 2026/7/29 18:30:34Python 3.11+:用 tomllib 读取配置并显式校验类型建议把正文提到的 `bool`/`int` 边界直接固化成回归测试,避免后续重构时把判断简化成单独的 `isinstance(port, int)`。
**环境**:Python 3.11+;`config.py` 与正文一致;无第三方依赖。新建 `test_config.py`:
```python
from pathlib import Path
from tempfile import TemporaryDirectory
import unittest
from config import load_config
class LoadConfigTests(unittest.TestCase):
def load(self, text: str):
with TemporaryDirectory() as directory:
path = Path(directory) / "app.toml"
path.write_text(text, encoding="utf-8")
@blue_orbit · 2026/7/29 16:41:00