AI 让漏洞发现变快,响应计划必须跟上
漏洞发现的速度已经超过团队修复能力,CVE 目录也跟不上 AI 的发现量。M-Trends 报告估计平均利用时间已到负七天,意味着利用先于补丁出现。响应和修复时间必须压缩,风险接受也变得更难向董事会和审计解释。
发现已经规模化,响应也必须跟上。
@DevOpsTalkCN
漏洞发现的速度已经超过团队修复能力,CVE 目录也跟不上 AI 的发现量。M-Trends 报告估计平均利用时间已到负七天,意味着利用先于补丁出现。响应和修复时间必须压缩,风险接受也变得更难向董事会和审计解释。
对任何代码库而言,这是激增而非无尽洪流。代码有限,AI 发现的漏洞大多属于已知类别、有已知修复方式。难点不在漏洞有多罕见,而在数量。
四步计划:扫描、排序、修复、兜底
扫描阶段要把所有发现汇入一处管理。CVE 发现是常规部分,新工作在于非 CVE 发现——扫描需纳入 CVE 目录之外的漏洞数据,包括 AI 发现的缺陷,并接入同一套处理和修复流程。只管理 CVE 的工具对这一类新发现是盲的。
排序阶段有三个关键信号:漏洞包是否实际加载进内存运行、能否被网络访问或暴露触达、资产被攻破是否有真实业务影响。前两个只能在线上环境测量。团队应聚焦分析产出的短清单,并信任辅助排序的工具——降级处理是主动决策,只有团队信任过滤器才站得住。
修复阶段不能手工逐个处理。在根上修:补一次基础镜像,而不是修补每个实例。自动化所有权和分派,让发现自动路由到对应团队。能用自动修复就用,生成的 PR 和配置变更能提升修复吞吐。在生产前拦截:不需要上线的就在准入控制器或流水线里挡住。还要熟悉其他杠杆——切断易受攻击工作负载的网络访问也是修复,往往比等补丁快。组织层面需要真正把这件事排上优先级,用业务驱动的指标争取支持。
最后为漏洞被利用做计划。修不完的,运行时是安全网。利用后的行为无论入口多新颖都相似:提权、侦察、取密钥。不必识别利用本身,抓住利用与业务影响之间的窗口就能保护组织。实践中要监控工作负载的失陷指标,测量检测和响应速度并找出瓶颈,用 AI 代理处理过多告警或夜间覆盖不足,把响应推到离数据源更近的位置,提前建好遏制剧本、升级路径和业务通知流程。人手或技能不足时,用服务商或 agentic SOC 工具补充。
发现已经规模化,响应也必须跟上。
@DevOpsTalkCN
IntervalStyle:改的是解析,不只是输出格式
PostgreSQL 的 IntervalStyle 参数常被当成纯输出格式偏好,但它同样改变 interval 的输入解析方式。默认值是
sql_standard 会悄悄翻转数据符号
建议
服务端保持
#DevOps #运维 #PostgreSQL #IntervalStyle #数据库 #参数调优
@DevOpsTalkCN
PostgreSQL 的 IntervalStyle 参数常被当成纯输出格式偏好,但它同样改变 interval 的输入解析方式。默认值是
postgres,上下文为 user,自 8.4 起随 interval 输入输出重构引入。四种风格中,sql_standard 和 iso_8601 各藏一个坑。sql_standard 会悄悄翻转数据符号
SQL 标准要求 interval 每个字段同号,前导负号作用于整个值;而 PostgreSQL 传统上各字段独立符号。IntervalStyle决定歧义字面量按哪套规则解析:
```
SET IntervalStyle = 'postgres';
SELECT extract(epoch from interval '-1 2:03:04');
-- -79016(负一天,加 2:03:04)
SET IntervalStyle = 'sql_standard';
SELECT extract(epoch from interval '-1 2:03:04');
-- -93784(负一天,减 2:03:04)
```
同一字面量,两种结果,相差四小时多。sql_standard是四种风格里唯一改变输入含义的,且恰好命中人们随手写的写法。防御办法:负 interval 的每个字段都显式加符号,'-1 days -2:03:04'在任何设置下含义一致。
iso_8601 的坑在输出端
对混合符号 interval,PostgreSQL 输出负号设计符,如P-1Y-2M3DT-4H-5M-6S。基础 ISO 8601 没有负时长(带符号时长是 8601-2:2019 的扩展),严格解析器会拒绝这种输出。interval 可能为负时,切到iso_8601并不能换来互操作性。
改风格影响所有文本协议客户端
大多数驱动默认走文本格式返回结果,interval 列以字符串到达,驱动用写死的代码解析——几乎都只认postgres风格。node-postgres的解析器只懂postgres风格,文档明确要求改过就改回来。按库或按角色设iso_8601让某个 API 端点好看,其他所有读 interval 的客户端会在没人动过的代码里解析出错。(二进制格式不受影响,风格只存在于文本表示。)
建议
服务端保持
postgres,把它当会话级参数用。导出或 API 需要 ISO 8601 时长时,在产生数据的事务里 SET LOCAL IntervalStyle = 'iso_8601',或在应用层格式化。sql_standard 绝不要设到比会话更广的范围——它改的是输入含义,不只是输出长相。负 interval 每个字段都写符号,不发送歧义数据,任何设置都无法曲解它。#DevOps #运维 #PostgreSQL #IntervalStyle #数据库 #参数调优
@DevOpsTalkCN
独立部署让测试失真,开源工具如何用观测替代手工维护
微服务独立部署让集成测试的 mock 数据快速过期,测试可能通过,但验证的却是几个月前的旧行为。这不是代码质量问题,而是覆盖时效性问题——测试写得好,但测错了对象。
20 个服务、每个每周部署两次,生产环境每周产生 40 次潜在的 mock 失效事件。上游加个字段、改个错误码、调整认证头,下游 mock 就悄悄失真,没有任何可见信号。靠平台团队手工追踪每个上游部署并更新 mock,在交付压力下必然失效。这是结构性问题,需要结构性解法。
传统工具如 Testcontainers、WireMock、Pact 都很有价值,但共同局限是:行为假设在某个时间点编码后就开始老化。观测式工具则从实时行为中推导假设,跑一次捕获会话就能同时刷新所有集成测试假设,维护成本不再与上游部署频率成正比。
对线上环境的意义:如果你们正被"测试全绿但上线就炸"困扰,且服务数量已多到手工维护 mock 跟不上节奏,观测式测试值得试点。从两三个关键依赖边界开始,用真实流量替代手工假设,能显著减少因 mock 过期导致的线上事故。
#DevOps #运维 #云原生 #微服务 #集成测试 #Keploy #Microcks #Pact #WireMock #Testcontainers #eBPF #CICD
@DevOpsTalkCN
微服务独立部署让集成测试的 mock 数据快速过期,测试可能通过,但验证的却是几个月前的旧行为。这不是代码质量问题,而是覆盖时效性问题——测试写得好,但测错了对象。
20 个服务、每个每周部署两次,生产环境每周产生 40 次潜在的 mock 失效事件。上游加个字段、改个错误码、调整认证头,下游 mock 就悄悄失真,没有任何可见信号。靠平台团队手工追踪每个上游部署并更新 mock,在交付压力下必然失效。这是结构性问题,需要结构性解法。
传统工具如 Testcontainers、WireMock、Pact 都很有价值,但共同局限是:行为假设在某个时间点编码后就开始老化。观测式工具则从实时行为中推导假设,跑一次捕获会话就能同时刷新所有集成测试假设,维护成本不再与上游部署频率成正比。
三种开源工具的实现路径差异明显:
Keploy 用 eBPF 捕获真实流量,直接解决独立部署的时效问题,最贴近生产行为。
Microcks 可导入真实 API 流量,适合已有流量记录的团队。
VCR 系(go-vcr、VCR.py)录制真实 HTTP 响应供回放,实现简单但需注意录制内容的时效管理。
在 CI/CD 中定时刷新 fixture,能让集成测试跟上频繁变更的微服务。建议平台团队先从少数高风险集成边界试点,再逐步推广到全架构。
对线上环境的意义:如果你们正被"测试全绿但上线就炸"困扰,且服务数量已多到手工维护 mock 跟不上节奏,观测式测试值得试点。从两三个关键依赖边界开始,用真实流量替代手工假设,能显著减少因 mock 过期导致的线上事故。
#DevOps #运维 #云原生 #微服务 #集成测试 #Keploy #Microcks #Pact #WireMock #Testcontainers #eBPF #CICD
@DevOpsTalkCN
别把 GPU 当 Web Pod 调度
Kubernetes 默认把 GPU 当成不透明的整数资源来调度,一个 Pod 独占整卡,但推理负载往往只用掉十几到三十几个百分点的算力。集群看起来排满了,账单却按整卡在涨——"已调度"和"已利用"之间的落差,就是云原生 AI 预算悄悄漏掉的地方。问题不在 GPU 贵,而在拿无状态 Web 服务的默认模式去套最贵、最不可替代的计算单元。
共享一张卡,有三种不同工具
- 时间切片(time-slicing):纯软件方案,驱动按毫秒级轮转上下文,几乎支持所有 NVIDIA 卡,ConfigMap 即可开启。但没有内存、故障隔离,也没有算力保证,适合开发、笔记本和低优先级突发推理。
- MPS:多进程上下文复用,内核在不同 SM 上并发执行,吞吐和延迟优于时间切片,但同样无内存隔离,故障隔离弱,一个客户端崩溃可能拖垮邻居。
- MIG:硬件级分区,单卡最多 7 个隔离实例,各自独立内存、算力和故障域。需要 Ampere 或更新架构(A100/H100 等),T4/V100 不支持。配置静态、需提前规划,适合不可信租户或需要可预测 QoS 的场景。
配置 MIG 切片后,调度器终于能按资源属性而非整数计数来分配,例如
按因果信号扩缩容,别盯 CPU
GPU 推理 Pod 里 CPU 是去相关代理——加速器干重活,CPU 只做 tokenize、HTTP 和批处理。CPU 30% 时 GPU 可能已 100%、KV cache 打满、请求在队列堆积,HPA 却读着"健康"无动于衷。应改用因果信号:队列深度是领先指标,GPU 利用率(DCGM exporter 采集到 Prometheus)是同步护栏。KEDA 是标准机制,因为信号在 Pod cgroup 之外、HPA 够不着,且它能缩到零。用 backlog 决定副本数,用 GPU 百分比做上限。教程里抄来的 5% 阈值只是演示值,真实 serving 应看 70–80%。
冷启动税,没人提前算
共享和 scale-to-zero 的代价是冷启动——LLM 冷启动不是容器重启,多 GB 权重要加载进 VRAM,从本地 NVMe 读大模型可能耗时数十秒,还没算 CUDA graph capture。此时别急着上 lazy-pull 镜像快照:推理负载启动几秒内就要读几乎整个镜像(CUDA 库和权重),按需拉取只是把卡顿从拉取挪到首次推理。AWS 给 EKS 推的"并行"拉取模式就是承认这点——更快的全量下载,而非懒加载。结构性解法是停止把模型权重塞进容器镜像,并维持一个小的热基线,减少启动延迟和 GPU 浪费。
#DevOps #运维 #Kubernetes #GPU #NVIDIA #MIG #DRA #KEDA #LLM #云原生
@DevOpsTalkCN
Kubernetes 默认把 GPU 当成不透明的整数资源来调度,一个 Pod 独占整卡,但推理负载往往只用掉十几到三十几个百分点的算力。集群看起来排满了,账单却按整卡在涨——"已调度"和"已利用"之间的落差,就是云原生 AI 预算悄悄漏掉的地方。问题不在 GPU 贵,而在拿无状态 Web 服务的默认模式去套最贵、最不可替代的计算单元。
共享一张卡,有三种不同工具
- 时间切片(time-slicing):纯软件方案,驱动按毫秒级轮转上下文,几乎支持所有 NVIDIA 卡,ConfigMap 即可开启。但没有内存、故障隔离,也没有算力保证,适合开发、笔记本和低优先级突发推理。
- MPS:多进程上下文复用,内核在不同 SM 上并发执行,吞吐和延迟优于时间切片,但同样无内存隔离,故障隔离弱,一个客户端崩溃可能拖垮邻居。
- MIG:硬件级分区,单卡最多 7 个隔离实例,各自独立内存、算力和故障域。需要 Ampere 或更新架构(A100/H100 等),T4/V100 不支持。配置静态、需提前规划,适合不可信租户或需要可预测 QoS 的场景。
配置 MIG 切片后,调度器终于能按资源属性而非整数计数来分配,例如
nvidia.com/mig-1g.5gb: "1" 表示申请一个 5GB 的 MIG 切片而非整卡,四副本可共享一张物理卡。更长期的方案是动态资源分配(DRA)。Kubernetes v1.34(2025 年 9 月发布)中 DRA 核心框架 GA,调度器首次能原生表达"要一个具备这些属性的设备"而非整数。但注意:框架虽稳定,细粒度共享能力(可消费容量、扩展资源映射)在该版本仍是 alpha 或 beta,DRA 方向正确,但还不能完全替代 device plugin。
按因果信号扩缩容,别盯 CPU
GPU 推理 Pod 里 CPU 是去相关代理——加速器干重活,CPU 只做 tokenize、HTTP 和批处理。CPU 30% 时 GPU 可能已 100%、KV cache 打满、请求在队列堆积,HPA 却读着"健康"无动于衷。应改用因果信号:队列深度是领先指标,GPU 利用率(DCGM exporter 采集到 Prometheus)是同步护栏。KEDA 是标准机制,因为信号在 Pod cgroup 之外、HPA 够不着,且它能缩到零。用 backlog 决定副本数,用 GPU 百分比做上限。教程里抄来的 5% 阈值只是演示值,真实 serving 应看 70–80%。
冷启动税,没人提前算
共享和 scale-to-zero 的代价是冷启动——LLM 冷启动不是容器重启,多 GB 权重要加载进 VRAM,从本地 NVMe 读大模型可能耗时数十秒,还没算 CUDA graph capture。此时别急着上 lazy-pull 镜像快照:推理负载启动几秒内就要读几乎整个镜像(CUDA 库和权重),按需拉取只是把卡顿从拉取挪到首次推理。AWS 给 EKS 推的"并行"拉取模式就是承认这点——更快的全量下载,而非懒加载。结构性解法是停止把模型权重塞进容器镜像,并维持一个小的热基线,减少启动延迟和 GPU 浪费。
#DevOps #运维 #Kubernetes #GPU #NVIDIA #MIG #DRA #KEDA #LLM #云原生
@DevOpsTalkCN
Kubernetes 按整卡调度 GPU,LLM 推理吃大亏
Kubernetes 默认把 GPU 当整数资源调度:Pod 申请
核心教训:别再把整张昂贵 GPU 自动分配给只需要一小块的负载。Kubernetes 的 Dynamic Resource Allocation(DRA)提供了更细粒度的设备感知调度方式,值得关注。
#DevOps #运维 #Kubernetes #GPU #NVIDIA #MIG #MPS #LLM #KServe #DRA
@DevOpsTalkCN
Kubernetes 默认把 GPU 当整数资源调度:Pod 申请
nvidia.com/gpu: 1 就独占整卡,哪怕模型只用了一小块显存。实测中八卡节点每张卡都显示 Allocated 1/1,利用率却只有 10% 左右——7B 模型在 80GB 显存里只用了约六分之一。这不是调参问题,是资源模型的问题:调度器只数卡,不知道你的模型需要 14GB 而卡有 80GB,也不知道两个 Pod 本可共存。单纯开自动扩缩容只会把浪费线性放大。HPA 能拉起更多整卡 Pod,Karpenter 能拉起更多整卡节点,但装箱的容器形状就是错的。
三种共享单卡的方式,差别很大
NVIDIA GPU Operator 提供三种机制,选错要么损失吞吐、要么让租户互相影响:
• 时间切片(time-slicing):纯软件,驱动按毫秒级轮转上下文切换。几乎支持所有 NVIDIA GPU(T4/V100/L40S/A100/H100),用 ConfigMap 配replicas: N即可让一张卡变成四张。代价:无内存隔离、无故障隔离、无算力保证,一个 Pod OOM 可能拖垮整卡。适合笔记本、开发环境、低优先级突发推理。
• MPS:CUDA MPS 服务端多路复用进程上下文,内核在不同 SM 上"并发"跑,延迟更低、利用率更高。但依然没有内存隔离,故障隔离较弱,且是三者中在 Kubernetes 里最不成熟的。适合你掌控所有租户、追求吞吐的场景。
• MIG:唯一硬件级分区,把一张卡切成最多 7 个隔离实例,各自有独立显存、SM 和故障域。真正的隔离——租户在自己的切片里崩溃不影响整卡。代价:仅 Ampere 及更新架构(A100/H100/H200/B 系列,T4/V100 不行),且 profile 是静态的,重配置要排空 GPU。GPU Operator 配mig.strategy=mixed后,MIG 实例以nvidia.com/mig-1g.5gb这类完整资源名暴露,Pod 可以直接按名申请切片。
LLM 推理 Pod 应按有状态对待
权重加载是没人预算的隐性成本:典型冷启动要 60–120 秒,140GB BF16 模型从本地 NVMe 加载到 H100 约 40–50 秒,再加 25–30 秒 CUDA graph 捕获——本地盘加载就超一分钟,还没算拉镜像。所以minReplicas: 0意味着每次流量恢复都要付这笔延迟。
KServe 的 InferenceService 可以同时解决两件事:用 MIG 切片共享硅片,把权重加载当状态水合而非廉价重启。把nvidia.com/gpu: "1"换成nvidia.com/mig-1g.5gb: "1"就能从独占 80GB H100 变成让六个租户共享同一张卡;storageUri: "pvc://model-cache/..."用节点本地缓存缩短权重加载,initialDelaySeconds: 60避免权重没加载完就被标记 Ready。
核心教训:别再把整张昂贵 GPU 自动分配给只需要一小块的负载。Kubernetes 的 Dynamic Resource Allocation(DRA)提供了更细粒度的设备感知调度方式,值得关注。
#DevOps #运维 #Kubernetes #GPU #NVIDIA #MIG #MPS #LLM #KServe #DRA
@DevOpsTalkCN
Dragonfly 轻量部署:去掉 Manager 和数据库,一条 Helm 命令搞定镜像分发
Dragonfly 用 P2P 加速文件与容器镜像分发,但标准安装要部署 Scheduler、Seed Client、Client 之外,还得有 Manager 做动态配置,背后挂 MySQL 和 Redis。对单集群、只想解决镜像拉取时 registry 过载的场景,这套太重了。
轻量部署模式去掉了 Manager、MySQL 和 Redis,Scheduler 作为唯一协调组件,整个安装用一条 Helm 命令完成。本文讲清轻量架构怎么运作,并在本地 kind 集群里跑通。
三种部署模式对比:轻量部署只装 Scheduler、Seed Client、Client,适合单集群、边缘或 CI/CD 管道;轻量 + Redis(scheduler.database.redis.addrs)支持持久化任务和缓存元数据保留;带 Manager 的完整部署提供 Web 控制台、OpenAPI、多集群管理和 API 触发的预热。功能差异上,黑名单、任务分发、dfctl 预热三种模式都支持;持久化任务和持久化缓存任务需要 Redis;OpenAPI 预热、Web 控制台、OpenAPI 集成、个人访问令牌只有 Manager 模式才有。Helm chart 默认禁用 Manager、MySQL 和 Redis,轻量部署就是默认基线。
kind 集群跑通步骤:先建多节点集群(一个 control-plane 加两个 worker),预拉 dragonflyoss/scheduler、client、dfinit 三个镜像并 load 进 kind 节点,再写 charts-config.yaml 配置镜像和 metrics,dfinit 开启并指向 containerd 配置路径、proxyAllRegistries 设为 true,最后 helm repo add dragonfly 后 helm install 部署,验证四个 Pod 启动成功(每 worker 节点一个 Client、一个 Scheduler、一个 Seed Client)。
对单集群或边缘场景,这套轻量部署把组件砍到最少,升级不用管数据库,配置走 ConfigMap 热更新,值得一试。
#DevOps #运维 #Dragonfly #P2P #Kubernetes #Helm #镜像分发 #CNCF #containerd
@DevOpsTalkCN
Dragonfly 用 P2P 加速文件与容器镜像分发,但标准安装要部署 Scheduler、Seed Client、Client 之外,还得有 Manager 做动态配置,背后挂 MySQL 和 Redis。对单集群、只想解决镜像拉取时 registry 过载的场景,这套太重了。
轻量部署模式去掉了 Manager、MySQL 和 Redis,Scheduler 作为唯一协调组件,整个安装用一条 Helm 命令完成。本文讲清轻量架构怎么运作,并在本地 kind 集群里跑通。
传统部署里 Manager 是控制面,提供 Web 控制台、OpenAPI 集成(如 registry 触发的预热)、多 P2P 集群管理,并把动态配置分发给 Scheduler 和 Client,状态存 MySQL,Redis 做缓存和异步任务分发。单集群只做 P2P 分发时,真正需要的其实只有动态配置——也就是 YAML 里的调度限制、黑名单、Client 发现 Scheduler 的端点。去掉 Manager 地址后,Scheduler 和 Client 可以脱离数据库后端独立运行。
轻量部署用两个原生 Kubernetes 原语替代 Manager:ConfigMap 和 headless Service。manager.addr 未设置时,Scheduler 和 Client 从本地 /etc/dragonfly/dynconfig.yaml 加载动态配置,该文件由 Helm chart 通过 ConfigMap 挂载;文件不存在则启动时生成默认值。Scheduler 的 dynconfig.yaml 定义集群级调度参数,比如 seed peer 并发上传上限 loadLimit: 2000、候选父节点数 candidateParentLimit: 3、过滤父节点数 filterParentLimit: 15、peer 并发上传上限 loadLimit: 200。配置按 refreshInterval(默认一分钟)周期性重载,ConfigMap 更新后无需重启 Pod 即可生效,这些参数也暴露为 Helm values(scheduler.dynconfig、seedClient.dynconfig、client.dynconfig),保持声明式、GitOps 对齐。
Client 发现 Scheduler 的方式也变了:Manager 模式下 Client 查 Manager 找 Scheduler,轻量模式下 Client 的 dynconfig.yaml 直接指向 Scheduler 的 headless Service 地址(dragonfly-scheduler.dragonfly-system.svc.cluster.local:8002),dfdaemon 进程通过 DNS 解析出所有 Scheduler Pod IP,逐个健康检查并过滤不健康实例。Scheduler StatefulSet 扩缩容后,Client 自动通过 DNS 发现新端点。Scheduler 跑在静态 IP(如集群外)时,可用 scheduler.addrs 显式定义列表,非空时优先于 addr。
集群内落地三个工作负载:Scheduler(StatefulSet)协调跨 peer 的任务调度和分片分发;Seed Client(StatefulSet)作为 P2P 网络根 peer,直接从源仓库下载内容;Client(DaemonSet)跑在每个节点,dfinit 配置 containerd 把镜像拉取路由到本地 peer client。这套架构升级时无需数据库备份或迁移脚本,状态存在本地磁盘缓存,可按需从源重建。
三种部署模式对比:轻量部署只装 Scheduler、Seed Client、Client,适合单集群、边缘或 CI/CD 管道;轻量 + Redis(scheduler.database.redis.addrs)支持持久化任务和缓存元数据保留;带 Manager 的完整部署提供 Web 控制台、OpenAPI、多集群管理和 API 触发的预热。功能差异上,黑名单、任务分发、dfctl 预热三种模式都支持;持久化任务和持久化缓存任务需要 Redis;OpenAPI 预热、Web 控制台、OpenAPI 集成、个人访问令牌只有 Manager 模式才有。Helm chart 默认禁用 Manager、MySQL 和 Redis,轻量部署就是默认基线。
kind 集群跑通步骤:先建多节点集群(一个 control-plane 加两个 worker),预拉 dragonflyoss/scheduler、client、dfinit 三个镜像并 load 进 kind 节点,再写 charts-config.yaml 配置镜像和 metrics,dfinit 开启并指向 containerd 配置路径、proxyAllRegistries 设为 true,最后 helm repo add dragonfly 后 helm install 部署,验证四个 Pod 启动成功(每 worker 节点一个 Client、一个 Scheduler、一个 Seed Client)。
对单集群或边缘场景,这套轻量部署把组件砍到最少,升级不用管数据库,配置走 ConfigMap 热更新,值得一试。
#DevOps #运维 #Dragonfly #P2P #Kubernetes #Helm #镜像分发 #CNCF #containerd
@DevOpsTalkCN
把 K8s 发布校验从 45 分钟压到 2 分钟
发布流水线变绿,不代表应用真的健康。部署完成只是交付信号,应用健康是运行时信号,两者在 Kubernetes 里经常脱节:Pod 可能没 Ready、卡在 Pending、CrashLoopBackOff,或镜像拉取失败。流水线视角里部署已完成,用户视角里服务可能已降级。
我们团队在大型支付环境管理 K8s 负载,过去每次发布靠工程师手动校验:登录集群、逐命名空间缩容、查 Pod 状态、发布新版本、扩容、再查状态、翻日志。小发布还能扛,大生产发布跨多集群、多命名空间、数百个工作负载,一次校验约 45 分钟。更糟的是不一致——发布压力下容易漏查命名空间,Pod 可能 Running 但没 Ready,发布结论过度依赖执行校验的人。
我们没建新平台、没写 Operator、没换部署系统,直接复用现有 CI/CD 流水线和内部部署平台。流水线自动执行完整发布流:缩容目标负载、确认 Pod 下线、部署新版本、扩容、跨命名空间检查 Pod 健康。健康则通过,不健康则上报失败 Pod 及原因,始终不健康可触发回滚。每个校验阶段调用内部部署 API,传入集群、命名空间、发布名和操作,平台执行后返回状态,流水线据此决定继续、等待、通过、失败或回滚——本质是个小型发布控制循环。
时间节省是次要的,真正的收益是一致性和信心:发布结论不再取决于执行校验的人,而是来自流程本身。发布校验从约 45 分钟降到约 2 分钟,同时消除了发布焦虑和重复手工操作。
#DevOps #运维 #Kubernetes #CICD #SRE #发布管理 #Helm #Pod健康检查
@DevOpsTalkCN
发布流水线变绿,不代表应用真的健康。部署完成只是交付信号,应用健康是运行时信号,两者在 Kubernetes 里经常脱节:Pod 可能没 Ready、卡在 Pending、CrashLoopBackOff,或镜像拉取失败。流水线视角里部署已完成,用户视角里服务可能已降级。
我们团队在大型支付环境管理 K8s 负载,过去每次发布靠工程师手动校验:登录集群、逐命名空间缩容、查 Pod 状态、发布新版本、扩容、再查状态、翻日志。小发布还能扛,大生产发布跨多集群、多命名空间、数百个工作负载,一次校验约 45 分钟。更糟的是不一致——发布压力下容易漏查命名空间,Pod 可能 Running 但没 Ready,发布结论过度依赖执行校验的人。
我们没建新平台、没写 Operator、没换部署系统,直接复用现有 CI/CD 流水线和内部部署平台。流水线自动执行完整发布流:缩容目标负载、确认 Pod 下线、部署新版本、扩容、跨命名空间检查 Pod 健康。健康则通过,不健康则上报失败 Pod 及原因,始终不健康可触发回滚。每个校验阶段调用内部部署 API,传入集群、命名空间、发布名和操作,平台执行后返回状态,流水线据此决定继续、等待、通过、失败或回滚——本质是个小型发布控制循环。
最关键的检查是 Pod 就绪状态。Running 和 Ready 不是一回事:Running 只代表容器进程启动了,Ready 才代表 K8s 认为 Pod 可以接收流量。五个副本全 Running 但只有三个 Ready,应用就没完全健康。失败原因同样重要:Pending 指向调度或资源问题,CrashLoopBackOff 通常指向启动失败、缺配置或依赖问题,ImagePullBackOff 指向镜像标签、仓库或认证问题。流水线不只报"不健康",而是报哪个 Pod 失败、为什么,省去工程师从零排查。
另一个关键设计是 60 秒稳定窗口。Pod 刚变 Ready 就立刻判定成功会制造假信心——Pod 可能 Ready 几秒后又崩溃,或依赖问题在开始处理流量后才暴露。流水线要求 Pod 保持 Ready 满 60 秒才通过,避免在第一个绿灯瞬间误判发布成功。
时间节省是次要的,真正的收益是一致性和信心:发布结论不再取决于执行校验的人,而是来自流程本身。发布校验从约 45 分钟降到约 2 分钟,同时消除了发布焦虑和重复手工操作。
#DevOps #运维 #Kubernetes #CICD #SRE #发布管理 #Helm #Pod健康检查
@DevOpsTalkCN
Postgres 时间表结构迁移实战
PDXPUG 九月聚会将聚焦 Postgres 时间表(Temporal Schema)迁移。Postgres v18 已支持时间主键、唯一约束和外键(
活动于 9 月 8 日 18:30-20:30 在 UpStart Collective(U.S. Bancorp Tower)举行,与 devopsdays Portland 同期。若你在考虑引入时间表,这场分享能帮你了解整体方案与代价。
#DevOps #运维 #Postgres #TemporalSchema #SQL2011 #数据库 #PDXPUG
@DevOpsTalkCN
PDXPUG 九月聚会将聚焦 Postgres 时间表(Temporal Schema)迁移。Postgres v18 已支持时间主键、唯一约束和外键(
NO ACTION),v19 有望加入 UPDATE/DELETE FOR PORTION OF,现在正是评估迁移的时机。时间表结构的优势在于:简化历史数据重建的查询与连接、以保留引用完整性的方式实现软删除、避免外键引用已更新数据带来的 bug,以及用更规范的方式表达历史数据。
演讲者 Paul Jungwirth 将用一个运行超 12 年的计时与开票应用为例,展示旧结构痛点,并演示如何迁移到包含应用时间daterange和tstzrange列的结构。他也会讨论时间表使用中仍存的痛点及缓解建议。
Paul 是波特兰自由开发者,自 2010 年起构建 Postgres 应用,贡献涉及 GiST 索引、multiranges 及 SQL:2011 应用时间特性。
活动于 9 月 8 日 18:30-20:30 在 UpStart Collective(U.S. Bancorp Tower)举行,与 devopsdays Portland 同期。若你在考虑引入时间表,这场分享能帮你了解整体方案与代价。
#DevOps #运维 #Postgres #TemporalSchema #SQL2011 #数据库 #PDXPUG
@DevOpsTalkCN
用 Postgres 扩展估算查询内存占用
手写一个 Postgres 扩展,在语句执行前估算其最坏情况下的 work_mem 占用,并可选记录或阻止超限查询。作者以 Postgres 18 为目标,完整走了一遍从环境搭建、解析查询、生成执行计划到遍历计划节点的过程。
核心算法很直白:遍历执行计划,普通节点计 1.0,hash 节点按 hash_mem_multiplier(默认 2.0)计,累加后乘以 work_mem 得出估算值。实测一个带两个 hash join 和 sort 的查询,估算 28MB,与实际计划算出的 7 个 work_mem 单位(28672KB)吻合。
作者实测了一个看似无害的物化 CTE 查询,估算内存高达 57MB——这正是这类工具的价值所在。完整源码在 GitHub 的 querymem 仓库。
#DevOps #运维 #Postgres #扩展开发 #性能调优 #work_mem #querymem
@DevOpsTalkCN
手写一个 Postgres 扩展,在语句执行前估算其最坏情况下的 work_mem 占用,并可选记录或阻止超限查询。作者以 Postgres 18 为目标,完整走了一遍从环境搭建、解析查询、生成执行计划到遍历计划节点的过程。
核心算法很直白:遍历执行计划,普通节点计 1.0,hash 节点按 hash_mem_multiplier(默认 2.0)计,累加后乘以 work_mem 得出估算值。实测一个带两个 hash join 和 sort 的查询,估算 28MB,与实际计划算出的 7 个 work_mem 单位(28672KB)吻合。
扩展通过 PGXS 构建,用官方 postgres:18 镜像做 Docker 开发环境,避免本地源码安装的麻烦。关键步骤包括用 raw_parser 解析查询、通过 pg_analyze_and_rewrite 做语义分析、直接调用 planner 拿到真实执行计划,再递归遍历节点累加内存系数。子计划(如物化 CTE)需要单独遍历,否则会漏算。
进阶功能通过 GUC 和 ExecutorStart hook 实现:定义 log 阈值和 block 阈值两个配置项,hook 在每条语句执行前自动估算,超阈值就记录或直接 abort。hook 必须保存并链式调用上一个 hook,否则会静默禁用其他扩展的钩子。
作者实测了一个看似无害的物化 CTE 查询,估算内存高达 57MB——这正是这类工具的价值所在。完整源码在 GitHub 的 querymem 仓库。
#DevOps #运维 #Postgres #扩展开发 #性能调优 #work_mem #querymem
@DevOpsTalkCN
多AZ集群里,服务网格的“默认负载均衡”正在悄悄收税
Kubernetes Service 和 Istio Envoy sidecar 默认在所有健康端点间随机分发流量,完全不感知 Pod 所在可用区。单 AZ 部署没问题,但一旦为容灾把 Pod 铺到三个 AZ,这个默认行为就成了隐患:us-east-1a 的 Pod 调用下游服务,约三分之二概率打到别的 AZ。一条请求路径经过三四个内部服务和数据库副本,跨 AZ 跳转次数会迅速累积。AWS NLB 默认也开启跨区负载均衡,入口流量同样会被随机分发到任意 AZ。
具体代价有两块。延迟:一个约 3500 RPS 的中型生产集群中,同 AZ 请求 p50 为 15-18ms,跨 AZ 则到 25-30ms,慢 40%-65%。约三分之二请求跨 AZ,加权后 p50 约 24ms,而本可做到约 17ms。钱:AWS 对区域内跨 AZ 流量收取 $0.01/GB,服务间流量通常是外部流量的 5-10 倍。该环境保守估算,入口、服务间、数据库和 Kafka 的跨 AZ 流量每月约 $600,还没算 Aurora 自动跨 AZ 复制和日志传输。具体数字取决于流量构成,建议用 AWS Cost Explorer 的 DataTransfer-Regional-Bytes 自己核对。
收益不仅是延迟改善,更重要的是故障爆炸半径变小。随机分发下,失去一个 AZ 会让剩余两个 AZ 瞬间多扛 50% 负载,容易级联饱和。80/10/10 策略下,失去一个 AZ 只重新分配它原本承担的 80% 流量,其他 AZ 相对增量小得多,outlier detection 会自动绕开故障。代价是运维复杂度:流量分布不再是直观的 33/33/33,排查“为什么这个 AZ 流量多”时需要知道 locality 策略的存在,上线前务必文档化。
先在低环境用 k6 或 Locust 做真实负载验证,再在生产最低流量服务上金丝雀发布,观察错误率和 p95 延迟。Locality-aware 负载均衡是 Istio 存在多年的功能,被跳过只因默认行为“能用”。等对账 AWS 数据传输账单或 AZ 故障被 paged 时,就晚了。
#DevOps #运维 #Istio #Kubernetes #AWS #负载均衡 #服务网格 #多AZ #SRE
@DevOpsTalkCN
Kubernetes Service 和 Istio Envoy sidecar 默认在所有健康端点间随机分发流量,完全不感知 Pod 所在可用区。单 AZ 部署没问题,但一旦为容灾把 Pod 铺到三个 AZ,这个默认行为就成了隐患:us-east-1a 的 Pod 调用下游服务,约三分之二概率打到别的 AZ。一条请求路径经过三四个内部服务和数据库副本,跨 AZ 跳转次数会迅速累积。AWS NLB 默认也开启跨区负载均衡,入口流量同样会被随机分发到任意 AZ。
具体代价有两块。延迟:一个约 3500 RPS 的中型生产集群中,同 AZ 请求 p50 为 15-18ms,跨 AZ 则到 25-30ms,慢 40%-65%。约三分之二请求跨 AZ,加权后 p50 约 24ms,而本可做到约 17ms。钱:AWS 对区域内跨 AZ 流量收取 $0.01/GB,服务间流量通常是外部流量的 5-10 倍。该环境保守估算,入口、服务间、数据库和 Kafka 的跨 AZ 流量每月约 $600,还没算 Aurora 自动跨 AZ 复制和日志传输。具体数字取决于流量构成,建议用 AWS Cost Explorer 的 DataTransfer-Regional-Bytes 自己核对。
修复方案是 Istio 的 locality-aware 负载均衡,通过 DestinationRule 配置。不要用 100% 本地 AZ 的极端策略,那会丧失吸收故障的能力。推荐加权分布:80% 同 AZ,另外两个 AZ 各 10%,配合 outlier detection 自动剔除不健康端点。配置示例:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: checkout-service-locality-lb
spec:
host: checkout-service.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true
distribute:
- from: us-east-1a/*
to:
"us-east-1a/*": 80
"us-east-1b/*": 10
"us-east-1c/*": 10
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
生效有三个前提:Pod 需均匀分布,用 topologySpreadConstraints 的 maxSkew: 1 保证;ingress gateway Pod 也要铺满所有 AZ;NLB 需通过 service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "false" 注解关闭跨区负载均衡,否则 LB 会重新引入随机性。
收益不仅是延迟改善,更重要的是故障爆炸半径变小。随机分发下,失去一个 AZ 会让剩余两个 AZ 瞬间多扛 50% 负载,容易级联饱和。80/10/10 策略下,失去一个 AZ 只重新分配它原本承担的 80% 流量,其他 AZ 相对增量小得多,outlier detection 会自动绕开故障。代价是运维复杂度:流量分布不再是直观的 33/33/33,排查“为什么这个 AZ 流量多”时需要知道 locality 策略的存在,上线前务必文档化。
先在低环境用 k6 或 Locust 做真实负载验证,再在生产最低流量服务上金丝雀发布,观察错误率和 p95 延迟。Locality-aware 负载均衡是 Istio 存在多年的功能,被跳过只因默认行为“能用”。等对账 AWS 数据传输账单或 AZ 故障被 paged 时,就晚了。
#DevOps #运维 #Istio #Kubernetes #AWS #负载均衡 #服务网格 #多AZ #SRE
@DevOpsTalkCN
PostgreSQL 的 JIT 开关:开了不等于在用
库缺失时,
#DevOps #运维 #PostgreSQL #JIT #LLVM #数据库 #性能调优
@DevOpsTalkCN
jit 参数控制 PostgreSQL 是否用 LLVM 将查询编译为原生代码,默认开启。它用编译时间换长查询的执行速度,对 CPU 密集的分析型查询划算,短查询则纯亏。是否生效及耗时,会显示在 EXPLAIN ANALYZE 底部的 JIT 段。一个观测陷阱:EXPLAIN (ANALYZE, COSTS OFF)会连 JIT 段一起隐藏,看不到不代表没跑。TIMING OFF则只去掉耗时行,JIT 段保留。jit_provider指定执行编译的共享库,默认llvmjit,基本不用改。但它指向的库不一定装了:PGDG 的 Debian/Ubuntu 包把llvmjit.so放在单独的postgresql-18-jit包里,服务器包只是推荐安装;RPM 系更是完全不拉取。用--no-install-recommends装的 Docker 镜像大多没有。
库缺失时,
jit 显示 on,查询正常跑,日志无任何报错——配置和实际行为脱节,唯一能发现的是 pg_jit_available() 返回 false。建议在所有服务器上跑一下这个函数确认,不少集群“启用”JIT 多年,实际从未编译过一条指令。#DevOps #运维 #PostgreSQL #JIT #LLVM #数据库 #性能调优
@DevOpsTalkCN
AlloyDB 深度评测:兼容性真相与 HTAP 实战
Google 的 AlloyDB 声称与 PostgreSQL 完全兼容,分析查询性能最高可达原生 Postgres 的 100 倍。作者用一年时间实测后得出结论:兼容性仅停留在 wire protocol 层,底层存储引擎与社区版分道扬镳。本文是这份评测的核心发现。
结论:AlloyDB 是披着 PostgreSQL 协议外衣的企业级 HTAP 引擎,适合已在 GCP 上、需要免运维故障切换和实时分析的大数据量团队。依赖 timescaledb、plv8 等扩展、需要深度调优或物理格式可见性的团队应谨慎。迁移前务必验证扩展白名单、列式存储驻留状态和写竞争表现。
完整基准数据与 EXPLAIN ANALYZE 输出:GitHub
#DevOps #运维 #PostgreSQL #AlloyDB #HTAP #列式存储 #ScaNN #GCP #数据库评测
@DevOpsTalkCN
Google 的 AlloyDB 声称与 PostgreSQL 完全兼容,分析查询性能最高可达原生 Postgres 的 100 倍。作者用一年时间实测后得出结论:兼容性仅停留在 wire protocol 层,底层存储引擎与社区版分道扬镳。本文是这份评测的核心发现。
存储架构上,AlloyDB 将 WAL 视为数据库本身,计算节点不再写完整数据页,而是把日志记录发送到基于 Colossus 的分布式存储层,由 Log Processing Service 异步物化数据页。这带来四个好处:故障切换无需回放 WAL、读副本不再是数据拷贝、存储扩容自动化、写路径省去 full_page_writes 开销。代价是存储格式专有,pageinspect 这类工具彻底失效,你无法再逐字节检查 MVCC 头来排查 bloat 问题。
VACUUM 并未像宣传那样被存储层吸收。死元组清理、可见性映射维护、事务 ID 回卷冻结仍跑在计算节点上,Google 只是用自适应调度器替换了社区版的固定阈值。实测中 n_dead_tup 依然呈锯齿状波动,autovacuum_count 照常递增。监控告警阈值若按社区版 autovacuum 调参,将失去意义。
列式存储是性能核心。TPC-H Q6 在 SF100 下从 182 秒降到 0.6 秒,311 倍加速,但这是最佳场景。Q5 加速 9.8 倍,Q12 4.8 倍,Q1 仅 2 倍,点查无提升。列式引擎对写热点表有代价,SF100 下并发扫描使写吞吐下降 29%,比行存的 16% 更糟。自动填充可能静默失败,必须用 google_columnar_engine_add 显式固定列并验证数据驻留。
AlloyDB Omni 是另一款产品:跑在标准 PostgreSQL 存储上,无共享存储、无托管故障切换,但内置列式引擎和 ScaNN 向量索引。ScaNN 的 sq8 量化索引比 ivfflat 小约 30 倍,构建快 7-9 倍,但查询参数 scann.num_leaves_to_search 必须先 LOAD 'alloydb_scann' 才生效,否则静默使用浅层搜索,作者因此跑出过 0.15 的召回率。
读池经济性取决于负载形态。AlloyDB 节点单价约为 Cloud SQL 两倍,但共享一份存储。全天候平稳读负载下,约 5TB 数据才打平;若读负载集中在业务时段,打平点降至约 765GB。跨区域仅支持主备模式,无 active-active。
结论:AlloyDB 是披着 PostgreSQL 协议外衣的企业级 HTAP 引擎,适合已在 GCP 上、需要免运维故障切换和实时分析的大数据量团队。依赖 timescaledb、plv8 等扩展、需要深度调优或物理格式可见性的团队应谨慎。迁移前务必验证扩展白名单、列式存储驻留状态和写竞争表现。
完整基准数据与 EXPLAIN ANALYZE 输出:GitHub
#DevOps #运维 #PostgreSQL #AlloyDB #HTAP #列式存储 #ScaNN #GCP #数据库评测
@DevOpsTalkCN
PostgreSQL JIT 排障:两个开关定位编译 bug
PostgreSQL 的 JIT 编译器承担两项工作:编译表达式和元组变形(tuple deforming)。
注意这不是调优旋钮。若 JIT 编译开销大于收益,应调整成本阈值或直接关闭 JIT,而不是逐个关功能。日常保持两者开启,排障时用 SET 临时切换即可。
#DevOps #运维 #PostgreSQL #JIT #数据库 #性能调优 #故障排查
@DevOpsTalkCN
PostgreSQL 的 JIT 编译器承担两项工作:编译表达式和元组变形(tuple deforming)。
jit_expressions 和 jit_tuple_deforming 这两个布尔参数分别控制这两项功能,默认开启,属于 Developer Options 类别,官方文档明确警告不建议在生产库上修改。表达式编译把执行器对 WHERE 子句、目标列表、聚合转换的解释执行替换为针对具体表达式生成的原生代码。元组变形则是在此之前,把存储元组的压缩字节转换为执行器所需的 datum 和 null 数组。JIT 会为特定元组描述符生成专用变形函数,省去通用逻辑。
这两个参数看似对称,实则不然。关闭jit_tuple_deforming后,JIT 块中只是少了变形函数;但关闭jit_expressions后,整个 JIT 块完全消失——因为变形代码只在编译消费它的表达式过程中生成,没有表达式编译就无处挂载变形器。
这正是它们作为排障工具的价值:怀疑 JIT 导致崩溃或结果错误时,先SET jit = off确认问题是否消失;再开启 JIT 并关闭jit_tuple_deforming,若问题解决则变形编译器是元凶,否则就是表达式编译器。两个开关、三种结果、一个嫌疑对象,全程无需重启。
注意这不是调优旋钮。若 JIT 编译开销大于收益,应调整成本阈值或直接关闭 JIT,而不是逐个关功能。日常保持两者开启,排障时用 SET 临时切换即可。
#DevOps #运维 #PostgreSQL #JIT #数据库 #性能调优 #故障排查
@DevOpsTalkCN
pgsonify:把 PostgreSQL 健康状态变成大象叫声
一个实验性的 MIT 许可开源工具,用真实大象录音来“播放” PostgreSQL 的健康状态。它监控实例,将指标实时映射为声音:一切正常时是低沉的隆隆声,出问题时则是喇叭声。作者明确表示,这是面向本地、开发与 QA 环境的实验,用于培养对数据库负载行为的直觉,而非替代正式监控。
工具用 Go 编写,声音来自已发表的生物声学研究录音。它通过一个 [0, 1] 区间的连续压力分数驱动三种状态:平静(深沉缓慢的隆隆声)、警报(音调与脉冲率上升,伴随短促喇叭声)、恐慌(快速混乱的喇叭声)。每种具体问题都有独立声音:锁等待与长事务是咕噜声,临时文件溢出是喷鼻声,复制延迟与 XID 回卷是联络叫声,WAL 压力导致的检查点是沉重脚步声,死锁与连接饱和则是恐慌喇叭声。控制台会同步打印触发声音的指标与阈值。
映射逻辑基于标准统计视图,无需扩展或超级用户权限。启动时读取
作为监控工具它替代不了 Prometheus 和告警系统,但作为理解数据库负载响应(锁队列如何堆积、检查点风暴如何跟随 WAL 突发、部署出错时回滚率如何飙升)的辅助手段,它能让数据库行为变得可感知,适合演示与教学场景。
GitHub
#DevOps #运维 #PostgreSQL #pgsonify #可观测性 #数据库运维 #开源工具 #声音监控
@DevOpsTalkCN
一个实验性的 MIT 许可开源工具,用真实大象录音来“播放” PostgreSQL 的健康状态。它监控实例,将指标实时映射为声音:一切正常时是低沉的隆隆声,出问题时则是喇叭声。作者明确表示,这是面向本地、开发与 QA 环境的实验,用于培养对数据库负载行为的直觉,而非替代正式监控。
工具用 Go 编写,声音来自已发表的生物声学研究录音。它通过一个 [0, 1] 区间的连续压力分数驱动三种状态:平静(深沉缓慢的隆隆声)、警报(音调与脉冲率上升,伴随短促喇叭声)、恐慌(快速混乱的喇叭声)。每种具体问题都有独立声音:锁等待与长事务是咕噜声,临时文件溢出是喷鼻声,复制延迟与 XID 回卷是联络叫声,WAL 压力导致的检查点是沉重脚步声,死锁与连接饱和则是恐慌喇叭声。控制台会同步打印触发声音的指标与阈值。
映射逻辑基于标准统计视图,无需扩展或超级用户权限。启动时读取
pg_settings 建立声音基线(如 shared_buffers 越大,隆隆声越低),默认每 5 秒采样 pg_stat_activity、pg_locks、pg_stat_database 等视图。检查点计数器按版本区分:PG 17+ 用 pg_stat_checkpointer,更早版本用 pg_stat_bgwriter。复制状态在主库读 pg_stat_replication,在备库读 pg_last_wal_replay_timestamp(),角色由 pg_is_in_recovery() 判断。早期版本用合成大象叫声,效果很差。当前版本使用开放许可的真实野外录音:警报声来自 King et al. 2010(PLOS ONE, CC BY 2.5),喇叭声来自 Fuchs et al. 2021(PLOS ONE, CC BY 4.0),另有 Wikimedia Commons 与 Freesound 的 CC0 录音。一个诚实的例外:真实大象的隆隆声多为次声波(约 20-30 Hz),笔记本扬声器无法还原,因此连续背景隆隆声是在可听频段合成的,事件叫声则全部为真实录音。
仓库附带pgchaos负载生成器,可故意触发连接激增、锁队列、死锁、临时文件溢出、回滚风暴、idle-in-transaction 等场景,几分钟内听完全部声音。make demo可用 Docker 一键启动 postgres + pgchaos。Herd 模式支持通过多个-dsn参数连接主库与备库,每个实例有独立音高与立体声位置,可听出是哪台服务器在报警。兼容性经过实测:PG 10 到 18 每个版本线均通过端到端冒烟测试。
作为监控工具它替代不了 Prometheus 和告警系统,但作为理解数据库负载响应(锁队列如何堆积、检查点风暴如何跟随 WAL 突发、部署出错时回滚率如何飙升)的辅助手段,它能让数据库行为变得可感知,适合演示与教学场景。
GitHub
#DevOps #运维 #PostgreSQL #pgsonify #可观测性 #数据库运维 #开源工具 #声音监控
@DevOpsTalkCN
PostgreSQL JIT 阈值:按成本触发,但成本衡量的不是表达式复杂度
PostgreSQL 的 JIT 编译是否触发,取决于规划器对查询的估算成本,而这个成本衡量的是数据量,不是表达式复杂度。
这个设计有三个叠加后果:决策基于估算成本,误估可能让一个 2 毫秒的查询也触发编译;编译结果不缓存,每次执行、每个进程、每个并行 worker 都各自编译一份;成本单位衡量的是页数和行数,而 JIT 的收益取决于表达式执行次数和复杂度——两者只在 JIT 设计目标场景(大扫描 + 重谓词)下相关,其他场景基本无关。
结论不是调阈值——阈值衡量的东西本身就不对,移动它们只是挪动错误生效的位置。应在工作负载层面决策:事务库
#DevOps #运维 #PostgreSQL #JIT #性能调优 #数据库 #LLVM #pgstatstatements
@DevOpsTalkCN
PostgreSQL 的 JIT 编译是否触发,取决于规划器对查询的估算成本,而这个成本衡量的是数据量,不是表达式复杂度。
jit_above_cost(默认 100000)、jit_inline_above_cost(默认 500000)和 jit_optimize_above_cost(默认 500000)三个 GUC 决定 JIT 何时启动,全部以规划器成本单位计价(seq_page_cost = 1.0 为锚)。成本超过 jit_above_cost 就编译表达式和元组反序列化;超过 jit_inline_above_cost 还内联内置函数和操作符;超过 jit_optimize_above_cost 再跑 LLVM 优化。任一设为 -1 即禁用该层,jit_above_cost = -1 直接关掉整个 JIT。这个设计有三个叠加后果:决策基于估算成本,误估可能让一个 2 毫秒的查询也触发编译;编译结果不缓存,每次执行、每个进程、每个并行 worker 都各自编译一份;成本单位衡量的是页数和行数,而 JIT 的收益取决于表达式执行次数和复杂度——两者只在 JIT 设计目标场景(大扫描 + 重谓词)下相关,其他场景基本无关。
实测演示(默认配置,未调任何参数):550MB 表分 64 个 hash 分区,跑最简单的SELECT sum(id),估算成本 112620 超过阈值,JIT 触发。64 个扫描节点导致编译了 130 个函数(未分区版本只需 5 个),每次执行都付编译费。同一查询jit = off时热执行 844–878ms,开 JIT 后 871–938ms 外加 36–49ms 编译——JIT 收了入场费但没加速任何东西,因为sum(id)几乎没有表达式工作可加速。分区是典型放大器,同时抬高估算成本和函数数量;任何成本来自数据量而非表达式复杂度的查询都吃同样的亏。阈值全设为零强制触发时,编译耗时 2.8 秒内联 + 0.25 秒优化(并行 leader 加两个 worker 合计),只为加速一个执行仅 1.3 秒的查询。
是否受影响一条 SQL 就能查:PostgreSQL 15 起pg_stat_statements带每条语句的 JIT 计数器,对比jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time与total_exec_time,若事务型负载中 JIT 耗时占比明显,就是在为不需要的查询付编译费。
结论不是调阈值——阈值衡量的东西本身就不对,移动它们只是挪动错误生效的位置。应在工作负载层面决策:事务库
ALTER DATABASE oltp_db SET jit = off,数仓库 jit = on,两边都不用重启。单库混合负载时把 jit_above_cost 提高一个数量级是可行的粗暴方案;把两个 500000 阈值拆开几乎不值得。唯一绝对不该做的是调低任何阈值——默认值已经会让分区 sum(id) 触发 JIT,不需要再鼓励。#DevOps #运维 #PostgreSQL #JIT #性能调优 #数据库 #LLVM #pgstatstatements
@DevOpsTalkCN
OpenBao 跑在 CNPG 上:全开源、无密码的密钥管理栈
这套方案把 OpenBao(Linux 基金会维护的 HashiCorp Vault 开源分支)的 PostgreSQL 存储后端,接到 CloudNativePG 管理的三节点集群上。整条链路全是开源组件:Kubernetes 和 CloudNativePG 都是 CNCF 项目,认证完全走 TLS 客户端证书,通过 1.30 的 DatabaseRole CRD 签发,栈里没有任何密码。
证书续期是这套方案最需要盯的点:DatabaseRole 签发的客户端证书到期后,OpenBao 的连接会直接失败,需要提前规划轮换流程。备份和容灾没在这篇展开,但 CNPG 的 Barman Cloud 插件已经装好,可以按官方文档补上。
@DevOpsTalkCN
这套方案把 OpenBao(Linux 基金会维护的 HashiCorp Vault 开源分支)的 PostgreSQL 存储后端,接到 CloudNativePG 管理的三节点集群上。整条链路全是开源组件:Kubernetes 和 CloudNativePG 都是 CNCF 项目,认证完全走 TLS 客户端证书,通过 1.30 的 DatabaseRole CRD 签发,栈里没有任何密码。
对线上环境的意义:密钥管理后端不再依赖云厂商数据库,PostgreSQL 集群由 CNPG 自动运维,同步复制保证 RPO=0。OpenBao 的 HA 锁表也启用,故障切换时不会丢数据。
部署要点:
• 三实例 CNPG 集群,quorum 同步复制(method: any, number: 1),配合节点选择器和强制 zonal pod 反亲和,PostgreSQL 跑在专用节点上
• 两个 DatabaseRole:role-openbao 只跑一次性 DDL,role-openbao-rw 是运行时连接角色,都通过 clientCertificate 认证
• pg_hba 显式写 cert 规则,hostnossl 直接 reject——没有密码可绕,证书失效连接就断
• 镜像用 ClusterImageCatalog 追踪,kubectl apply 同一份 manifest 就能吃到新补丁版本
本地复现:cnpg-playground 仓库的 setup.sh 起一个六节点 Kind 集群,三个节点带 postgres taint,正好给 CNPG 用。REQUIREMENTS_ONLY=true 跳过 demo 数据库,只装 operator、cert-manager 和镜像目录。
证书续期是这套方案最需要盯的点:DatabaseRole 签发的客户端证书到期后,OpenBao 的连接会直接失败,需要提前规划轮换流程。备份和容灾没在这篇展开,但 CNPG 的 Barman Cloud 插件已经装好,可以按官方文档补上。
@DevOpsTalkCN
CNCF 治理指南:按项目规模与阶段选对治理结构
CNCF 技术监督委员会基于 72 个毕业、孵化及归档项目的治理审查,总结出不同成熟度阶段的结构选择规律。数据显示,进入沙箱时维护者来自多个组织的项目,毕业率是单一组织项目的 2.07 倍(59.1% 对 28.6%)。仅有书面治理文档而缺乏结构性机制,往往挡不住权力集中——多个治理文档写得不错的项目,最终仍因缺少组织平衡投票或指导委员会限制而出现维护者集中。
组织投票是可与任何模型配合的结构性机制:按组织而非个人分配治理投票权,通常每组织限 1-2 票,防止单一公司靠维护者人数主导治理。它保护治理决策,但不保证维护者构成平衡——多数维护者仍可来自一家公司,只是这种多数不会转化为相应的治理控制权。实践中该机制适用于指导委员会选举、治理变更和战略方向,技术决策(代码审查、合并权限、发布)仍由维护者在懒共识下处理。超过两票的上限已被证明无效。
对正在选型或演进治理结构的项目,核心判断是:结构要与当前规模匹配,文档之外要有硬性机制兜底,且治理结构要能随项目收缩而简化。
#DevOps #运维 #CNCF #开源治理 #Kubernetes #云原生 #社区管理
@DevOpsTalkCN
CNCF 技术监督委员会基于 72 个毕业、孵化及归档项目的治理审查,总结出不同成熟度阶段的结构选择规律。数据显示,进入沙箱时维护者来自多个组织的项目,毕业率是单一组织项目的 2.07 倍(59.1% 对 28.6%)。仅有书面治理文档而缺乏结构性机制,往往挡不住权力集中——多个治理文档写得不错的项目,最终仍因缺少组织平衡投票或指导委员会限制而出现维护者集中。
数据还显示,20% 的毕业项目在毕业后出现治理集中,且这些项目在孵化期都缺少组织平衡机制。一个已归档的孵化项目在治理委员会设了组织多样性规则,维护者层面却没有。组织平衡机制要覆盖实际干活的地方,而不只是治理层。贡献者数量本身不能预测项目健康度,治理结构、组织多样性和贡献者路径更重要。
项目模板仓库提供三种治理模型:
1. 维护者委员会:适合范围聚焦、单一仓库或小规模紧密协作的项目。3-10 名活跃维护者直接沟通,默认懒共识决策,分歧或治理变更时正式投票。关键要素包括 MAINTAINERS 文件、维护者增删流程、荣休状态、安全响应团队。当单一组织通过招聘、收购或外部贡献者流失主导维护者名单时,应考虑引入组织平衡投票或转向选举制指导委员会。
2. 选举制指导委员会:适合贡献者社区成熟、领导层需对社区负责的大型项目。委员会由合格贡献者选举产生,负责战略方向,技术工作下放给工作组或 SIG。任期限制(通常 1-2 年)和公司代表上限(每组织不超过 1-2 人)保障视角多样性。将治理与执行分离的项目能更长久维持组织多样性,因为委员会的组织限制独立于代码贡献者构成。项目收缩或委员会职责重叠、协调成本高于决策收益时,合并冗余机构、减少席位是正当的治理转型。
3. 联邦式子项目治理:适合由多个半独立子项目组成的伞形项目。各子项目有自己的维护者和发布节奏,指导机构负责共享基础设施、品牌、安全响应和子项目间冲突解决。需要明确的子项目增删流程、健康标准和生命周期(活跃/维护/归档)。失去活跃贡献者或已完成使命的子项目应归档或合并,空壳 SIG 会造成治理广泛的假象,实际工作却集中在少数群体。
组织投票是可与任何模型配合的结构性机制:按组织而非个人分配治理投票权,通常每组织限 1-2 票,防止单一公司靠维护者人数主导治理。它保护治理决策,但不保证维护者构成平衡——多数维护者仍可来自一家公司,只是这种多数不会转化为相应的治理控制权。实践中该机制适用于指导委员会选举、治理变更和战略方向,技术决策(代码审查、合并权限、发布)仍由维护者在懒共识下处理。超过两票的上限已被证明无效。
对正在选型或演进治理结构的项目,核心判断是:结构要与当前规模匹配,文档之外要有硬性机制兜底,且治理结构要能随项目收缩而简化。
#DevOps #运维 #CNCF #开源治理 #Kubernetes #云原生 #社区管理
@DevOpsTalkCN
Kubeflow 正式毕业,成 CNCF 首个 AI 原生毕业项目
CNCF 宣布 Kubeflow 从孵化项目正式毕业,成为云原生 AI/ML 平台在 Kubernetes 上的事实标准。该项目覆盖数据预处理、交互式开发、分布式训练、微调、推理与模型服务全生命周期,支持公有云、私有云与混合云环境。
Kubeflow 于 2017 年在 Google 诞生,2023 年进入 CNCF 孵化。目前拥有超过 6600 名贡献者、来自 1000 多家组织,GitHub 累计星标超 33000,Python 包在 PyPI 下载量近 2.6 亿次。Bloomberg、NVIDIA、Red Hat、LinkedIn、Spotify 等企业均在其上标准化 AI 工作负载。
对平台团队而言,Kubeflow 毕业意味着 AI 基础设施选型有了一个经过 CNCF 治理体系验证的 Kubernetes 原生底座——跨云可移植、厂商中立,适合需要把 AI 工作负载从实验推向生产的组织。
@DevOpsTalkCN
CNCF 宣布 Kubeflow 从孵化项目正式毕业,成为云原生 AI/ML 平台在 Kubernetes 上的事实标准。该项目覆盖数据预处理、交互式开发、分布式训练、微调、推理与模型服务全生命周期,支持公有云、私有云与混合云环境。
Kubeflow 于 2017 年在 Google 诞生,2023 年进入 CNCF 孵化。目前拥有超过 6600 名贡献者、来自 1000 多家组织,GitHub 累计星标超 33000,Python 包在 PyPI 下载量近 2.6 亿次。Bloomberg、NVIDIA、Red Hat、LinkedIn、Spotify 等企业均在其上标准化 AI 工作负载。
毕业前,Kubeflow 完成了第三方安全审计,成立了正式指导委员会,并采用 CNCF 行为准则,同时持有 CII 最佳实践徽章。
项目与 CNCF 生态深度集成:Prometheus 负责监控,KServe 处理模型服务,Feast 管理特征存储,Kueue 做任务排队,Istio 保障服务间安全通信。
后续路线图聚焦扩展 LLM 编排、增强微调等后训练能力、大规模数据工程,以及面向 Data & AI 生命周期的 agentic 工作负载。
对平台团队而言,Kubeflow 毕业意味着 AI 基础设施选型有了一个经过 CNCF 治理体系验证的 Kubernetes 原生底座——跨云可移植、厂商中立,适合需要把 AI 工作负载从实验推向生产的组织。
@DevOpsTalkCN
AWS DevOps Agent 接入 GitHub,自动定位 CI/CD 失败根因
当 GitHub 托管的应用在 CI/CD 部署中失败时,工程师通常要在多个 AWS 服务、日志和流水线阶段之间手动排查,耗时从几分钟到几小时不等。AWS DevOps Agent 能自动将流水线失败与具体代码变更关联,直接指出是哪个 commit 或 PR 导致问题,并给出修复建议,减少跨 GitHub、CodePipeline、CloudWatch 之间的上下文切换。
这套方案把故障排查从被动救火转为自动化诊断,缩短 MTTR,同时保留完整的审计轨迹。适合多服务架构下频繁因代码变更引发部署失败的团队,减少人工跨系统追踪日志的时间。
@DevOpsTalkCN
当 GitHub 托管的应用在 CI/CD 部署中失败时,工程师通常要在多个 AWS 服务、日志和流水线阶段之间手动排查,耗时从几分钟到几小时不等。AWS DevOps Agent 能自动将流水线失败与具体代码变更关联,直接指出是哪个 commit 或 PR 导致问题,并给出修复建议,减少跨 GitHub、CodePipeline、CloudWatch 之间的上下文切换。
架构上,CloudWatch 持续监控 CodePipeline 执行指标和日志,检测到构建失败、部署回滚或下游健康指标异常时生成错误指标并触发告警。告警进入 ALARM 状态后直接调用 WebHook Executor Lambda,该函数解析告警负载、提取上下文元数据,再向 DevOps Agent 发送结构化调查请求,自动开始根因分析。
前置条件包括:AWS 账号及创建 IAM 角色的权限(Agent Space 角色、Web app 角色,多账号监控需额外源账号角色);GitHub 账号需对目标仓库有管理员权限,且仓库代码部署到待监控的 AWS 资源;应用需启用 CloudWatch 监控。
实施时先创建 Agent Space(如 myhotelapp),选择自动创建 IAM 角色并命名,在 Capabilities 页生成 webhook 凭据存入 Secrets Manager,再用 AWS CLI 创建 secret。随后在 Agent Space 的 GitHub Configuration 中注册并连接目标仓库,状态变为 Connected 即完成。CloudWatch 告警触发 Agent 调查的参考实现见 sample-aws-devops-agent-cloudwatch。
这套方案把故障排查从被动救火转为自动化诊断,缩短 MTTR,同时保留完整的审计轨迹。适合多服务架构下频繁因代码变更引发部署失败的团队,减少人工跨系统追踪日志的时间。
@DevOpsTalkCN