Files
awoooi/k8s/observability/event-exporter.yaml

183 lines
6.1 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
# P0-OBS-001: deploy bursts can reach the watcher 5-15 seconds late.
# Preserve them for RCA and avoid one API GET per involved object; the OTLP
# layout below only consumes fields already present on the Event itself.
maxEventAgeSeconds: 120
omitLookup: true
route:
routes:
# Warning/Error 全量保留;只排除已知高頻、低診斷價值的 Normal 事件。
# 單一 receiver 避免未列出的 Normal 事件被兩條 route 重複送出。
- match:
- receiver: signoz-otlp
drop:
- type: "Normal"
reason: "Scheduled"
- type: "Normal"
reason: "Pulling"
- type: "Normal"
reason: "Pulled"
- type: "Normal"
reason: "Created"
- type: "Normal"
reason: "Started"
receivers:
- name: signoz-otlp
webhook:
endpoint: http://192.168.0.188:24318/v1/logs
headers:
Content-Type: application/json
# OTLP/HTTP JSON envelope。舊版的平面 JSON 雖會得到 HTTP 200
# 但 collector 會把它當成空請求,無任何 durable log write。
layout:
resourceLogs:
- resource:
attributes:
- key: service.name
value:
stringValue: kubernetes-event-exporter
- key: k8s.cluster.name
value:
stringValue: awoooi-k3s
scopeLogs:
- scope:
name: awoooi.k8s.events
logRecords:
- severityText: "{{ .Type }}"
body:
stringValue: "{{ .Message }}"
attributes:
- key: k8s.event.reason
value:
stringValue: "{{ .Reason }}"
- key: k8s.event.type
value:
stringValue: "{{ .Type }}"
- key: k8s.event.action
value:
stringValue: "{{ .Action }}"
- key: k8s.event.count
value:
stringValue: "{{ .Count }}"
- key: k8s.namespace.name
value:
stringValue: "{{ .InvolvedObject.Namespace }}"
- key: k8s.object.kind
value:
stringValue: "{{ .InvolvedObject.Kind }}"
- key: k8s.object.name
value:
stringValue: "{{ .InvolvedObject.Name }}"
- key: k8s.event.source.component
value:
stringValue: "{{ .Source.Component }}"
- key: k8s.event.source.host
value:
stringValue: "{{ .Source.Host }}"
- key: k8s.event.first_timestamp
value:
stringValue: "{{ .FirstTimestamp }}"
- key: k8s.event.last_timestamp
value:
stringValue: "{{ .LastTimestamp }}"
---
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: 192.168.0.110:5000/awoooi/runtime-mirror/event-exporter@sha256:d90516e5a8277a725867df3e1d084fe6533c63c49bc527696f45dc2e6d7d7ddb
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