feat: add Grafana Alloy log collection manifests for K8s
- add alloy-daemonset to run Alloy on every node via DaemonSet
- add alloy-configmap to scrape Pod logs through the K8s API and parse
zap JSON fields (level, traceID, pod, namespace) into Loki labels
- add alloy-rbac granting pods/log read access for log collection
- forward parsed logs to loki-service for Grafana querying
This commit is contained in:
parent
ca68cf6c18
commit
98a28b62eb
|
|
@ -0,0 +1,81 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: alloy-config
|
||||||
|
namespace: default
|
||||||
|
data:
|
||||||
|
config.alloy: |
|
||||||
|
// 发现集群内所有 Pod
|
||||||
|
discovery.kubernetes "pods" {
|
||||||
|
role = "pod"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重写元数据标签,并只保留带 app label 的 Pod
|
||||||
|
discovery.relabel "pods" {
|
||||||
|
targets = discovery.kubernetes.pods.targets
|
||||||
|
|
||||||
|
rule {
|
||||||
|
source_labels = ["__meta_kubernetes_namespace"]
|
||||||
|
target_label = "namespace"
|
||||||
|
}
|
||||||
|
rule {
|
||||||
|
source_labels = ["__meta_kubernetes_pod_name"]
|
||||||
|
target_label = "pod"
|
||||||
|
}
|
||||||
|
rule {
|
||||||
|
source_labels = ["__meta_kubernetes_pod_container_name"]
|
||||||
|
target_label = "container"
|
||||||
|
}
|
||||||
|
rule {
|
||||||
|
source_labels = ["__meta_kubernetes_pod_label_app"]
|
||||||
|
target_label = "app"
|
||||||
|
}
|
||||||
|
// 只采集有 app label 的 Pod
|
||||||
|
rule {
|
||||||
|
source_labels = ["__meta_kubernetes_pod_label_app"]
|
||||||
|
action = "keep"
|
||||||
|
regex = ".+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过 Kubernetes API 抓取容器日志(无需挂载宿主机日志目录)
|
||||||
|
loki.source.kubernetes "pods" {
|
||||||
|
targets = discovery.relabel.pods.output
|
||||||
|
forward_to = [loki.process.parse.receiver]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析 zap 输出的 JSON 日志,并将关键字段提升为 Loki Label
|
||||||
|
loki.process "parse" {
|
||||||
|
forward_to = [loki.write.default.receiver]
|
||||||
|
|
||||||
|
// 解析结构化字段
|
||||||
|
stage.json {
|
||||||
|
expressions = {
|
||||||
|
level = "level",
|
||||||
|
traceID = "traceID",
|
||||||
|
spanID = "spanID",
|
||||||
|
caller = "caller",
|
||||||
|
pod = "pod",
|
||||||
|
namespace = "namespace",
|
||||||
|
node = "node",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提升为 Label,支持在 Grafana 中按实例/Trace 过滤
|
||||||
|
stage.labels {
|
||||||
|
values = {
|
||||||
|
level = "",
|
||||||
|
traceID = "",
|
||||||
|
pod = "",
|
||||||
|
namespace = "",
|
||||||
|
node = "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 推送到 Loki
|
||||||
|
loki.write "default" {
|
||||||
|
endpoint {
|
||||||
|
url = "http://loki-service:3100/loki/api/v1/push"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: alloy
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: alloy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: alloy
|
||||||
|
spec:
|
||||||
|
serviceAccountName: alloy
|
||||||
|
tolerations:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
effect: NoSchedule
|
||||||
|
containers:
|
||||||
|
- name: alloy
|
||||||
|
image: grafana/alloy:v1.16.3
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
args:
|
||||||
|
- run
|
||||||
|
- /etc/alloy/config.alloy
|
||||||
|
- --storage.path=/var/lib/alloy/data
|
||||||
|
- --server.http.listen-addr=0.0.0.0:12345
|
||||||
|
ports:
|
||||||
|
- containerPort: 12345
|
||||||
|
name: http
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/alloy
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/alloy/data
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 128Mi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: alloy-config
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: alloy
|
||||||
|
namespace: default
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: alloy
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods/log"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: alloy
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: alloy
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: alloy
|
||||||
|
namespace: default
|
||||||
Loading…
Reference in New Issue