183 lines
6.1 KiB
YAML
183 lines
6.1 KiB
YAML
# =============================================================================
|
||
# 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
|