痛点:传统应用监控的侵入性困境
运维团队在推进可观测性建设时,常遇到这样的尴尬:
- SDK 侵入成本高 — OpenTelemetry SDK 需要改代码,Java Agent 要加 JVM 参数,Go 应用更是得手动埋点。业务团队排期紧,根本不愿配合。
- 多语言栈覆盖难 — 一个集群里跑着 Go、Java、Python、Node.js、Rust 服务,为每种语言维护 instrumentation 方案是运维噩梦。
- Sidecar 方案有开销 — Istio/Envoy sidecar 虽然能采集 L7 指标,但每个 Pod 多一个容器,内存和 CPU 开销在大规模集群中不可忽视。
Grafana Beyla 用 eBPF 从内核层自动捕获 HTTP/gRPC 调用,无需修改应用代码、无需 sidecar、无需重启服务,真正实现零侵入的应用级可观测性。
方案:Beyla 是什么,怎么工作
Grafana Beyla 是 Grafana Labs 开源的 eBPF 自动化 instrumentation 工具,核心原理:
- 通过 eBPF uprobe/kprobe 挂载到内核和用户态函数
- 自动识别 HTTP(Go net/http、Java Servlet、Python WSGI/ASGI、Node.js http 模块)和 gRPC 调用
- 生成符合 OpenTelemetry 语义约定的 Metrics 和 Traces
- 直接推送到 Prometheus(OTLP)或 Grafana Cloud
关键优势对比:
| 方案 | 代码侵入 | 多语言支持 | 资源开销 | 部署复杂度 |
|---|---|---|---|---|
| OTel SDK | 高(需改代码) | 逐个适配 | 低 | 中 |
| Istio Sidecar | 无 | 仅 L7 层 | 高(每 Pod +1 容器) | 高 |
| Beyla eBPF | 无 | 自动识别 | 极低(~30MB 内存) | 低 |
实操步骤
步骤 1:DaemonSet 部署 Beyla
生产环境推荐以 DaemonSet 方式部署,监控节点上所有应用进程:
# beyla-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: beyla
namespace: monitoring
spec:
selector:
matchLabels:
app: beyla
template:
metadata:
labels:
app: beyla
spec:
hostPID: true # 必须:需要访问宿主机进程
serviceAccountName: beyla
containers:
- name: beyla
image: grafana/beyla:1.8
securityContext:
privileged: true # eBPF 需要特权模式
env:
- name: BEYLA_OPEN_PORT
value: "80,443,8080,3000,5000,9090"
- name: BEYLA_OTEL_METRICS_ENDPOINT
value: "http://prometheus-server.monitoring:4318"
- name: BEYLA_OTEL_TRACES_ENDPOINT
value: "http://tempo.monitoring:4318"
- name: BEYLA_SERVICE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "200m"
volumeMounts:
- name: sys-kernel
mountPath: /sys/kernel
readOnly: true
volumes:
- name: sys-kernel
hostPath:
path: /sys/kernel
kubectl apply -f beyla-daemonset.yaml
步骤 2:配置精细化服务发现
通过 ConfigMap 定义更精准的匹配规则,避免监控不必要的进程:
# beyla-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: beyla-config
namespace: monitoring
data:
beyla-config.yml: |
# 按 Kubernetes metadata 匹配目标
discovery:
services:
- k8s_namespace: "production|staging"
k8s_deployment_name: ".*"
- k8s_namespace: "default"
k8s_pod_labels:
app: "api-gateway"
# 路由分组:将 /users/123 归类为 /users/{id}
routes:
patterns:
- /api/v1/users/{id}
- /api/v1/orders/{id}
- /healthz
ignored_patterns:
- /metrics
- /ready
- /live
# 采样策略:生产环境建议 tail-based sampling
attributes:
kubernetes:
enable: true # 自动添加 pod/node/namespace 标签
otel_metrics_export:
endpoint: http://prometheus-server.monitoring:4318
interval: 15s
otel_traces_export:
endpoint: http://tempo.monitoring:4318
sampler:
name: parentbased_traceidratio
arg: "0.1" # 10% 采样率
挂载 ConfigMap 到 DaemonSet:
kubectl create configmap beyla-config --from-file=beyla-config.yml -n monitoring
# 在 DaemonSet 中添加 volume 和 env:
# BEYLA_CONFIG_PATH=/config/beyla-config.yml
步骤 3:Grafana Dashboard 可视化
Beyla 输出的指标遵循 OpenTelemetry 语义约定,核心指标:
# RED 三指标 — Rate
sum(rate(http_server_request_duration_seconds_count{service_namespace="production"}[5m])) by (service_name)
# RED 三指标 — Errors
sum(rate(http_server_request_duration_seconds_count{http_response_status_code=~"5.."}[5m])) by (service_name)
/ sum(rate(http_server_request_duration_seconds_count[5m])) by (service_name)
# RED 三指标 — Duration (P99)
histogram_quantile(0.99,
sum(rate(http_server_request_duration_seconds_bucket{service_namespace="production"}[5m])) by (le, service_name)
)
Grafana Labs 提供了开箱即用的 Dashboard(ID: 19077),直接导入即可:
# 或通过 Grafana API 导入
curl -X POST http://grafana:3000/api/dashboards/import \
-H "Content-Type: application/json" \
-d '{"dashboard": {"id": 19077}, "overwrite": true, "inputs": [{"name": "DS_PROMETHEUS", "value": "Prometheus"}]}'
步骤 4:验证与排查
# 检查 Beyla Pod 是否正常运行
kubectl get pods -n monitoring -l app=beyla
# 查看 Beyla 日志,确认服务发现
kubectl logs -n monitoring -l app=beyla | grep "instrumenting"
# 预期输出类似:
# level=info msg="instrumenting process" pid=12345 service=api-gateway
# 验证指标是否到达 Prometheus
kubectl exec -n monitoring deploy/prometheus-server -- \
wget -qO- 'http://localhost:9090/api/v1/query?query=http_server_request_duration_seconds_count' | python3 -m json.tool | head -20
避坑指南
坑 1:内核版本过低导致 eBPF 功能不可用
Beyla 依赖 eBPF CO-RE(Compile Once, Run Everywhere),最低要求 Linux 5.8+。AWS EKS 使用 Amazon Linux 2023 AMI(内核 6.1+)没问题,但如果还在用老旧的 Amazon Linux 2(内核 5.10)需要确认 BTF 支持:
# 检查节点是否支持 BTF
ls /sys/kernel/btf/vmlinux
# 存在即支持
坑 2:特权容器与安全策略冲突
Beyla 需要 privileged: true 和 hostPID: true,在启用了 Pod Security Admission 的集群中会被拦截。解决方案:
# 为 monitoring namespace 设置 privileged 级别
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/warn: privileged
坑 3:高基数(High Cardinality)指标爆炸
如果不配置路由分组,/users/123、/users/456 会生成独立的指标标签,导致 Prometheus 内存暴涨。务必配置 routes.patterns 将动态路径参数化,并用 ignored_patterns 排除健康检查等高频低价值路径。
总结
Grafana Beyla 解决了可观测性落地的"最后一公里"问题 — 不用求着开发改代码,不用忍受 sidecar 的资源开销,一个 DaemonSet 部署完毕,全集群 HTTP/gRPC 服务的 RED 指标和分布式 Trace 就自动到位。
适用场景: - 多语言微服务集群快速接入可观测性 - 已有 Grafana Stack(Prometheus + Tempo + Grafana)的团队 - 对应用零侵入有硬性要求的合规环境
不适用场景: - 需要业务自定义 Span/指标(如订单金额、用户 ID 维度)— 仍需 SDK - 非 HTTP/gRPC 协议(如自定义 TCP 二进制协议)— Beyla 暂不支持
生产建议: Beyla 作为基线覆盖 + 核心服务追加 OTel SDK 精细埋点,两者互补而非替代。