Files
awoooi/k8s/observability/event-exporter.yaml
OG T 41bf0681cf feat(observability): Phase O-2/O-3 OTEL Log管線 + Event Exporter + Remote Write
O-2.1: OTEL Collector DaemonSet (filelog receiver)
  - 收集所有 K3s 節點 Pod stdout/stderr → SigNoz ClickHouse
  - CRI log parser (Go time layout for +08:00 timezone)
  - filter processor 排除 kube-system debug noise
  - observability namespace PSA privileged (log 目錄需 root)
  - 資源限制: 50m-200m CPU / 64-128Mi Memory

O-2.2: kubernetes-event-exporter
  - K8s Event → 結構化 JSON Log → SigNoz
  - Warning/Error 全量保留, Normal 過濾高頻事件
  - 解決: Event 預設僅保留 ~1hr 的致命盲區

O-3: Prometheus remote_write 配置模板
  - 白名單: ~50 關鍵 metric series (node/container/kube/api/db)
  - 目標: 90 天長期儲存於 SigNoz ClickHouse

已部署驗證: 3 Pod Running, 0 error, filelog 正常監控所有 namespace

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:01:42 +08:00

158 lines
4.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# Kubernetes Event Exporter - Phase O-2.2
# =============================================================================
# 建立者: Claude Code (首席架構師)
# 日期: 2026-04-02 (台北時間)
# 用途: 將 K8s Event 轉為結構化 Log 送往 SigNoz保留 30 天
# 解決: K8s Event 預設僅保留 ~1 小時的致命盲區
# =============================================================================
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: event-exporter
namespace: observability
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: event-exporter
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: event-exporter
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: event-exporter
subjects:
- kind: ServiceAccount
name: event-exporter
namespace: observability
---
apiVersion: v1
kind: ConfigMap
metadata:
name: event-exporter-config
namespace: observability
data:
config.yaml: |
# Phase O-2.2: K8s Event → SigNoz (OTLP HTTP)
logLevel: info
logFormat: json
route:
routes:
# Warning 和 Error 事件: 全量保留 (RCA 關鍵資料)
- match:
- receiver: signoz-warning
drop:
- type: "Normal"
reason: "Scheduled"
- type: "Normal"
reason: "Pulling"
- type: "Normal"
reason: "Pulled"
- type: "Normal"
reason: "Created"
- type: "Normal"
reason: "Started"
# Normal 事件中的關鍵類型: 選擇性保留
- match:
- receiver: signoz-normal
drop:
- type: "Warning"
receivers:
- name: signoz-warning
webhook:
endpoint: http://192.168.0.188:24318/v1/logs
headers:
Content-Type: application/json
layout:
severity: "{{ .Type }}"
body: "{{ .Message }}"
attributes:
k8s.event.reason: "{{ .Reason }}"
k8s.event.type: "{{ .Type }}"
k8s.event.action: "{{ .Action }}"
k8s.event.count: "{{ .Count }}"
k8s.namespace.name: "{{ .InvolvedObject.Namespace }}"
k8s.object.kind: "{{ .InvolvedObject.Kind }}"
k8s.object.name: "{{ .InvolvedObject.Name }}"
k8s.event.source.component: "{{ .Source.Component }}"
k8s.event.source.host: "{{ .Source.Host }}"
k8s.event.first_timestamp: "{{ .FirstTimestamp }}"
k8s.event.last_timestamp: "{{ .LastTimestamp }}"
- name: signoz-normal
webhook:
endpoint: http://192.168.0.188:24318/v1/logs
headers:
Content-Type: application/json
layout:
severity: "Normal"
body: "{{ .Message }}"
attributes:
k8s.event.reason: "{{ .Reason }}"
k8s.event.type: "{{ .Type }}"
k8s.namespace.name: "{{ .InvolvedObject.Namespace }}"
k8s.object.kind: "{{ .InvolvedObject.Kind }}"
k8s.object.name: "{{ .InvolvedObject.Name }}"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: event-exporter
namespace: observability
labels:
app.kubernetes.io/name: event-exporter
phase: o-2
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: event-exporter
template:
metadata:
labels:
app.kubernetes.io/name: event-exporter
spec:
serviceAccountName: event-exporter
# PSA restricted 合規
securityContext:
runAsNonRoot: true
runAsUser: 65534
seccompProfile:
type: RuntimeDefault
containers:
- name: event-exporter
image: ghcr.io/resmoio/kubernetes-event-exporter:v1.7
args:
- -conf=/etc/event-exporter/config.yaml
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: 20m
memory: 32Mi
limits:
cpu: 100m
memory: 64Mi
volumeMounts:
- name: config
mountPath: /etc/event-exporter
readOnly: true
volumes:
- name: config
configMap:
name: event-exporter-config