ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Zabbix-Proxy监控K8S集群:从网络隔离到告警配置实践

Zabbix-Proxy监控K8S集群:从网络隔离到告警配置实践 1. 为什么用 Zabbix-Proxy 监控 K8S而不是直连1.1 网络隔离下的监控困局我接手过不少 K8S 集群的监控项目最常见的场景是Zabbix Server 在总部机房K8S 集群在异地机房、云上 VPC 或者某个隔离网段里。K8S 的 API Server 地址往往是内网地址或者有严格的防火墙策略Zabbix Server 想直接访问根本不可能。就算网络能通你也未必想让监控系统把生产集群的核心 API 暴露到核心网段这是安全上最忌讳的事。这时候 Zabbix-Proxy 的价值就体现出来了。Proxy 是一台部署在 K8S 集群网络内部的轻量级采集代理它只需要能访问 K8S 的 API Server并把采集到的数据主动回传给 Zabbix Server。也就是说Zabbix Server 不需要和 K8S 有任何直连所有流量都由 Proxy 单向发出网络策略上只要放行 Proxy 到 Server 的 10051 端口或配置 TLS 后走自定义端口就行。这个模式很像每个分公司先自己做账再把财务报表报给总部总部不需要去翻分公司的每一张发票。1.2 Proxy 模式比直连 Server 更合适的三个理由第一减轻 Zabbix Server 的轮询压力。K8S 集群内部资源数量不小节点、命名空间、Deployment、Pod、Service 到处都是如果 Server 直接去采集每次 HTTP 请求都从总部发起跨机房延迟高不说一旦集群规模上来Server 的 poller 进程会被瞬间打满。Proxy 部署在集群旁边API 延迟通常在几毫秒采集效率高得多而且 Proxy 自己会有缓冲队列就算到 Server 的链路抖动采集数据也不会立刻丢。第二安全边界更清晰。K8S 的 API Server 是集群的控制面入口把这个入口暴露给外部监控系统等于扩大了攻击面。用 Proxy 之后只有 Proxy 和 K8S 内部网络打交道Zabbix Server 完全不接触集群内网。即使 Proxy 被攻破也只是监控代理权限可以收敛到只读的 RBAC 角色风险可控。第三多集群统一纳管。一个 Zabbix Server 可以接入多个 Proxy每个 Proxy 管一个集群。我见过有人用一台 Server 监控二十套集群每个集群一个 Proxy前端页面里按“代理”维度分组网络拓扑、告警收敛、自动化处置都能做得非常清晰。直连模式在多集群场景下基本就是灾难。2. 监控方案整体设计与前置准备2.1 监控架构拓扑我们要做的架构很简单Zabbix Server (前端数据库) ↑ 10051/TCP (被动模式) Zabbix Proxy (proxy-k8s) ↓ HTTPS:6443 Kubernetes API ServerZabbix Proxy 从 K8S API Server 拉取指标通过 HTTP agent 类型的监控项上报告警数据。前端创建主机时把“由哪个代理监控”设为proxy-k8s那么所有 HTTP 类型的采集都会由 Proxy 发起而不是由 Server 发起。这个点很多人容易忽略因为 Zabbix 前端默认显示的数据源来自 Server但实际执行请求的是 Web 前端指定的 Proxy。在模板方面Zabbix 6 自带的官方模板Kubernetes by HTTP已经覆盖了大部分常用采集项不需要从零造轮子。模板里的数据会通过 K8S API 获取节点状态、Pod 状态、集群健康信息还内置了自动发现规则会自动发现命名空间、节点、Pod然后批量创建监控项。我们只需要准备一个能访问 API Server 的只读 ServiceAccount Token把 Token 填进模板宏里就行。2.2 Zabbix 6 环境准备建议部署版本为 Zabbix 6.0 LTS 或 6.4我这边用的是 6.0.26。Zabbix Server 和前端已经提前安装好这里不再赘述。Proxy 的部署机器建议用独立的虚拟机或云主机不要挤在 K8S 节点上跑避免把监控采集和业务资源互相抢。操作系统我用的是 Rocky Linux 9和常见的 CentOS 7 步骤相差不大只是软件源版本不一样。在开始之前确认几件事Zabbix Server 的 IP 和端口默认 10051Proxy 要能访问到。Proxy 机器到 K8S API Server 的 6443 端口网络通不通。可以先手动curl -k https://api-server:6443/version验证。确认 K8S 集群的 API Server 证书是否需要客户端证书。生产环境一般开启 TLS 和 RBAC所以我们要用 Token 认证而不是裸的 HTTPS。2.3 模板选型与数据流理解官方模板Kubernetes by HTTP的内部逻辑是通过 HTTP agent 请求 K8S API 的 RESTful 接口比如/api/v1/nodes、/api/v1/pods、/apis/metrics.k8s.io/v1beta1/nodes。这些接口返回 JSON模板里的预处理规则会把关键字段提取出来转换成监控项。整个数据流大致是Zabbix Proxy 根据模板宏{$KUBE.API.URL}和{$KUBE.API.TOKEN}向 API Server 发送 GET 请求。K8S API 校验 Token 权限返回资源清单或指标数据。Proxy 将响应内容交给预处理使用 JSONPath 或正则提取出字段值。处理好的数据进入 Proxy 的本地缓存队列按批次发给 Server。Server 写入历史数据库前端展示和触发器计算。理解了这个流程后面排查问题就有思路了。数据卡住要么是网络不通要么是 Token 没权限要么是模板宏填错要么是 Proxy 采集队列异常不可能是玄学。3. 核心配置实操代理部署、监控项与自动发现3.1 部署 Zabbix-Proxy 并接入 Server在 Proxy 机器上安装软件包。Zabbix 官方仓库配置好后执行dnf install -y zabbix-proxy zabbix-sql-scripts zabbix-selinux-policyZabbix Proxy 可以用 SQLite 作为本地数据库适合中小规模集群不用单独装 MySQL。先创建数据库文件mkdir -p /var/lib/zabbix touch /var/lib/zabbix/zabbix_proxy.db chown -R zabbix:zabbix /var/lib/zabbix接着修改主配置/etc/zabbix/zabbix_proxy.conf关键几个参数Server10.0.0.10 Hostnameproxy-k8s DBName/var/lib/zabbix/zabbix_proxy.db StartPollers5 StartHTTPAgents8 StartPreprocessors8 LogFile/var/log/zabbix/zabbix_proxy.log这里StartHTTPAgents要稍微给大一点因为 HTTP agent 每发一个请求就会占用一个进程。如果同时监控多个集群这个值建议调成 16 以上。配置文件改完后启动服务systemctl enable --now zabbix-proxy然后到 Zabbix Web 前端进入“管理 → 代理”点击“创建代理”填上名称proxy-k8s模式选择“主动式”这样符合 Proxy 单向上报的设计。保存后等几十秒能看到代理显示为绿色即可。3.2 在 K8S 集群中创建只读监控账号K8S 侧的权限模型比较严格直接给一个管理员 Token 是很危险的做法。我们创建一个独立的 ServiceAccount绑定一个最小权限的 ClusterRole允许它读取集群监控需要的资源。下面是我常用的 YAMLapiVersion: v1 kind: Namespace metadata: name: zabbix-monitor --- apiVersion: v1 kind: ServiceAccount metadata: name: zabbix namespace: zabbix-monitor --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: zabbix-monitor-readonly rules: - apiGroups: [] resources: [nodes, nodes/stats, namespaces, pods, services, endpoints, events] verbs: [get, list, watch] - apiGroups: [apps] resources: [deployments, daemonsets, statefulsets, replicasets] verbs: [get, list, watch] - apiGroups: [metrics.k8s.io] resources: [nodes, pods] verbs: [get, list] - apiGroups: [coordination.k8s.io] resources: [leases] verbs: [get, list] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: zabbix-monitor-binding subjects: - kind: ServiceAccount name: zabbix namespace: zabbix-monitor roleRef: kind: ClusterRole name: zabbix-monitor-readonly apiGroup: rbac.authorization.k8s.io应用这份 YAMLkubectl apply -f zabbix-sa.yaml在 K8S 1.24 之后ServiceAccount 不会自动生成长期 Token需要手动创建 Secret 来绑定cat EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: zabbix-sa-secret namespace: zabbix-monitor annotations: kubernetes.io/service-account.name: zabbix type: kubernetes.io/service-account-token EOF然后取出 Tokenkubectl -n zabbix-monitor get secret zabbix-sa-secret -o jsonpath{.data.token} | base64 -d把这串 Token 保存好后面填到 Zabbix 宏里。注意K8S 的 Secret 默认type: kubernetes.io/service-account-token是可以长期有效的但如果集群开启了 Token 自动轮换那么监控 Token 也需要定时更新。3.3 在 Zabbix 前端创建主机并链接模板回到 Zabbix Web进入“数据采集 → 主机”点击“创建主机”主机名称k8s-prod-cluster可见名称生产K8S集群模板勾选Kubernetes by HTTP由代理监控proxy-k8s然后在“宏”标签里配置模板所需的宏。不同的 Zabbix 6 小版本宏名略有差异但一般会用到以下几个宏名值{$KUBE.API.URL}https://192.168.10.53:6443{$KUBE.API.TOKEN}上面获取到的 Token{$KUBE.API.ENDPOINT}/version宏的取值建议写到主机级别这样将来多个集群直接复制主机再改 URL 和 Token 就行不用动模板。保存后稍等几分钟进入“监测 → 最新数据”筛选主机k8s-prod-cluster看是否开始出现以k8s.cluster、k8s.node、k8s.pod开头的监控项。如果数据一直不出来不要急着找模板问题先去 Proxy 的日志里看有没有报错。/var/log/zabbix/zabbix_proxy.log里最常见的几类错误是连接 API Server 超时、HTTP 400/401/403、JSON 解析失败。后面第 5 章会专门讲排查方法。3.4 核心监控项与自动发现逻辑Kubernetes by HTTP模板里的监控项很多绝大多数是自动发现规则生成的。使用时有几个高频项需要重点关注监控项 key 或描述含义常见用途k8s.cluster.health集群 API Server 可达性集群故障第一告警k8s.node.ready节点就绪状态节点宕机告警k8s.node.cpu.usage节点 CPU 使用率资源水位告警k8s.node.memory.usage节点内存使用率资源水位告警k8s.pod.statusPod 当前状态异常 Pod 告警k8s.deployment.replicas.availableDeployment 可用副本数应用缩容或拉不起副本告警自动发现规则会自动扫描节点、命名空间、Pod并在前端为每个资源生成独立的监控项。以 Pod 为例模板会调用/api/v1/pods然后把返回的 JSON 里的每个 Pod 作为一条发现记录生成对应主机的k8s.pod.status[*]系列监控项。这样就不需要你手工一条条添加省事很多。4. 指标采集与告警规则实战4.1 配置关键告警触发器模板里自带了部分触发器但生产环境通常要自定义几条更贴合业务的告警。比如节点 NotReady 是一个高危事件我通常用主机宏和触发器表达式组合last(/k8s-prod-cluster/k8s.node.ready[{#NODE}])0这里的最终 key 名要以实际最新数据里的 key 为准。更稳妥的做法是在前端“最新数据”里找到节点状态那一条右键“创建触发器”系统会自动带出监控项 key。我的经验是不要靠记忆拼表达式纯靠手写很容易拿错参数。另外Deployment 副本数异常也是必配的last(/k8s-prod-cluster/k8s.deployment.replicas.available[{#NAME}]) last(/k8s-prod-cluster/k8s.deployment.replicas.desired[{#NAME}])这个表达式的意思是“可用副本数少于期望副本数”一旦触发说明应用正在降级。我建议设置成 1 分钟连续触发防止滚动更新时短暂数量不一致导致误报。告警媒介建议用企业微信或钉钉机器人配合 Zabbix 的动作把告警发到运维群。如果要在夜间减少骚扰可以加“时间 Period”条件比如只在工作时间通知紧急级告警非紧急告警汇总成日报。4.2 设计一个清晰的监控 DashboardZabbix 6 的 Dashboard 支持聚合多个集群的数据。我习惯按“集群总览 → 节点列表 → 工作负载”三层来设计。第一层放最核心的四个大数字API Server 可用状态、异常节点数、异常 Pod 数、整体告警数量。这四个数字一眼扫过去就能判断集群有没有大事。第二层放图表比如每台节点的 CPU 使用率按主机筛选Graph 类型选“线图”。节点多的时候建议只展示最近 1 小时避免画面被线搞成一堆乱麻。内存使用率也可以做一张配合 CPU 就能基本判断热点节点。第三层放问题列表组件筛选条件设成“未解告警按严重性排序”这样打开 Dashboard 就能看到当前待处理的问题。如果发现某台节点的问题总是反复出现记得回到底层检查是监控误报还是业务宿主机确实有隐患。4.3 从监控数据反推容量规划有了历史数据之后不要把监控当成“报警工具”用它更应该是容量规划的数据来源。比如通过节点 CPU 和内存的历史趋势图可以看到集群每天的高峰时段。我通常会把 Zabbix 里的图表时间范围拉到 30 天观察平均值和峰值然后按照“峰值不超过 70%”的标准评估是否需要扩容。K8S 集群一旦内存碎片化排障成本很高提前扩容比事后抢救舒服得多。5. 常见问题与排查技巧实录5.1 认证失败与 RBAC 权限不足最常见的问题就是填了 Token 但 API 返回 403 或 401。403 通常不是 Token 坏了而是 RBAC 没有权限。比如我最初只给了get权限没有给list结果有些接口返回 403但另一些接口正常数据呈现“一半有值一半没值”。遇到这种问题先去 K8S 侧用同一个 Token 手动请求接口curl -k -H Authorization: Bearer token https://api-server:6443/apis/apps/v1/deployments如果返回{kind:Status,status:Failure,message:...}那就说明 RBAC 规则没覆盖对应资源。回到我们的ClusterRole把apiGroups和resources补全即可。如果是 401那就是 Token 过期或 Secret 不存在重新生成一个。5.2 监控项无数据或数据不更新这个问题在我刚上手时也踩过坑。数据不更新先看 Proxy 日志有没有 HTTP agent 报错比如“connection refused”或“timeout”。如果日志是空白的大概率是主机代理配错了。创建主机时必须把“由代理监控”选成proxy-k8s但如果你同时在模板里用了 Zabbix agent 类型的监控项Proxy 根本不会执行因为该主机并没有运行 Zabbix agent。建议只保留Kubernetes by HTTP模板不要和其他 agent 模板混在一起。还有一种情况是 K8S API Server 负载过高导致 HTTP 请求响应特别慢Zabbix 默认的超时时间到了就会报“Timeout while connecting to server”。这时候可以调整模板里 HTTP agent 监控项的“超时时间”参数或者降低采集频率避免高频请求压垮 API Server。5.3 Proxy 与 Server 时间不同步Zabbix 对时间同步非常敏感只要 Proxy 和 Server 的系统时间偏差超过几十秒数据上报就会出问题表现为主机变红、历史数据中断。排查时不要只盯着网络先date看看两边时间再检查 NTP/chrony 是否在正常运行。生产环境一定要统一给所有机器配好时间同步这不光影响 Zabbix对 K8S 本身也是核心要求。5.4 监控项过多导致 Proxy 队列堆积规模大的集群自动发现出来的 Pod 可能有上千个每个 Pod 对应十几个监控项一轮采集下来就是上万条数据。如果 Proxy 的队列一直在涨说明处理能力跟不上。我遇到过一上线就队列爆炸的情况。解决办法有几个调大StartPollers和StartPreprocessors让 Proxy 能并行处理更多请求。调整模板自动发现规则的更新间隔比如从 60s 改成 120s减少每次扫描的请求量。在模板里关闭不需要的监控项比如每个 Pod 的请求数、容器的网络流量等保留核心状态即可。如果一套 Proxy 管多集群考虑拆成多个 Proxy一个 Proxy 最多负责两三个中型集群。最后再分享一个小技巧我实际使用中发现监控 K8S 时不要只依赖单台 Proxy。如果条件允许生产集群可以部署两台 Proxy一台主用一台备用前端主机关联主 Proxy当主 Proxy 宕机时手动把主机切到备用 Proxy。因为 K8S 集群本身对可用性要求很高监控反而成了容易被忽视的“单点”。这个方案不需要额外开发成本Zabbix 原生支持建议在重要集群上直接备一份。另外K8S 的 API Server 在滚动升级、证书轮换时会影响短暂访问Zabbix 的告警模板里要加一点延迟时间比如 3 分钟持续后触发避免把计划内变更和真实故障混在一起。我自己就是因为没加持续时间导致每次集群升级都被告警轰炸后来改成持续 3 分钟再触发告警马上干净了很多。Zabbix-Proxy 监控 K8S 这套思路适合大多数企业网络隔离和多集群场景。先把数据采回来再慢慢把告警、趋势、容量规划做细稳定性和效率都会比用一堆“临时脚本”强很多。
返回列表