在云原生与微服务架构日益普及的今天,对于运行在 Kubernetes 集群中应用的监控和日志记录变得至关重要。集群本身和应用会产生海量日志,如何高效地收集、存储和查询这些日志,是保障系统可观测性与稳定运行的关键一环。Grafana Loki 作为一款设计灵巧的日志聚合系统,因其与 Grafana 无缝集成的特性和较低的资源消耗,成为了许多团队的选择。它允许您在一个统一的界面中,像查询指标一样查询日志。
本文将手把手带你完成在 Kubernetes 集群中使用 Helm 一键部署完整的 Loki 日志收集套件,并通过 Grafana 进行可视化查询。
整体架构
下图清晰地展示了基于 Grafana Loki 的 Kubernetes 日志收集与监控架构:

核心流程如下:
- 日志采集:每个 Kubernetes 工作节点(Worker Node)上运行的 Promtail 代理,负责收集节点上所有 Pod 的应用程序日志。
- 日志汇聚:Promtail 将收集到的日志发送至中央的 Loki 服务。
- 查询与展示:用户通过 Grafana 界面(默认端口 3000)连接到 Loki 数据源,对日志进行检索和监控。
前提条件
本教程采用 Helm Chart 进行一键式部署,因此你需要准备以下环境:
-
一个可用的 Kubernetes 集群
确保你的 kubectl 可以正常连接集群。例如:
[root@k8smaster ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8smaster Ready control-plane 10d v1.35.2
k8sworker Ready <none> 10d v1.35.2
-
安装 Helm 工具
如果你的环境尚未安装 Helm,可以通过官方脚本快速安装:
[root@k8smaster ~]# curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11929 100 11929 0 0 2825 0 0:00:04 0:00:04 --:--:-- 2968
[WARNING] Could not find git. It is required for plugin installation.
Downloading https://get.helm.sh/helm-v3.20.1-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
安装后验证版本:
[root@k8smaster ~]# helm version
version.BuildInfo{Version:"v3.20.1", GitCommit:"a2369ca71c0ef633bf6e4fccd66d634eb379b371", GitTreeState:"clean", GoVersion:"go1.25.8"}
部署步骤
1. 添加 Grafana Helm 仓库
首先,将 Grafana 官方的 Helm 仓库添加到本地。
[root@k8smaster ~]# helm repo add grafana https://grafana.github.io/helm-charts
"grafana" has been added to your repositories
添加成功后,更新仓库以获取最新的 Chart 信息。
[root@k8smaster ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "grafana" chart repository
Update Complete. ⎈Happy Helming!⎈
接下来,搜索与 Loki 相关的 Chart。我们会发现一个名为 grafana/loki-stack 的 Chart,它集成了 Loki、Promtail 和 Grafana 等组件,非常适合一键部署。
[root@k8smaster ~]# helm search repo loki
NAME CHART VERSION APP VERSION DESCRIPTION
grafana/loki 6.55.0 3.6.7 Helm chart for Grafana Loki and Grafana Enterpr...
grafana/loki-canary 0.14.1 2.9.1 Helm chart for Grafana Loki Canary
grafana/loki-distributed 0.80.6 2.9.13 Helm chart for Grafana Loki in microservices mode
grafana/loki-simple-scalable 1.8.11 2.6.1 Helm chart for Grafana Loki in simple, scalable...
grafana/loki-stack 2.10.3 v2.9.3 Loki: like Prometheus, but for logs.
grafana/fluent-bit 2.6.0 v2.1.0 Uses fluent-bit Loki go plugin for gathering lo...
grafana/lgtm-distributed 3.0.1 ^12.1.1 Umbrella chart for a distributed Loki, Grafana,...
grafana/meta-monitoring 1.3.0 0.0.1 A Helm chart for meta monitoring Grafana Loki, ...
grafana/promtail 6.17.1 3.5.1 Promtail is an agent which ships the contents o...
本教程将使用 grafana/loki-stack 这个一体化 Chart。
2. 自定义 Helm Chart 配置值
默认配置可能不完全符合需求,例如 Grafana 组件默认是关闭的。我们可以通过自定义 Values 文件来启用所需组件并调整配置。
首先,将默认的配置值导出到一个 YAML 文件中:
[root@k8smaster ~]# helm show values grafana/loki-stack > loki-custom-values.yaml
然后,编辑这个文件。我们需要关注几个关键部分,确保以下组件被正确启用:
# 查看配置文件的关键部分
[root@k8smaster ~]# cat loki-custom-values.yaml
test_pod:
enabled: true
image: bats/bats:1.8.2
pullPolicy: IfNotPresent
loki:
enabled: true
isDefault: true
url: http://{{(include "loki.serviceName" .)}}:{{ .Values.loki.service.port }}
readinessProbe:
httpGet:
path: /ready
port: http-metrics
initialDelaySeconds: 45
livenessProbe:
httpGet:
path: /ready
port: http-metrics
initialDelaySeconds: 45
datasource:
jsonData: "{}"
uid: ""
promtail:
enabled: true
config:
logLevel: info
serverPort: 3101
clients:
- url: http://{{ .Release.Name }}:3100/loki/api/v1/push
fluent-bit:
enabled: false
grafana:
enabled: true
sidecar:
datasources:
label: ""
labelValue: ""
enabled: true
maxLines: 1000
image:
tag: 10.3.3
service:
type: NodePort
prometheus:
enabled: false
isDefault: false
url: http://{{ include "prometheus.fullname" .}}:{{ .Values.prometheus.server.service.servicePort }}{{ .Values.prometheus.server.prefixURL }}
datasource:
jsonData: "{}"
filebeat:
enabled: false
filebeatConfig:
filebeat.yml: |
# logging.level: debug
filebeat.inputs:
- type: container
paths:
- /var/log/containers/*.log
processors:
- add_kubernetes_metadata:
host: ${NODE_NAME}
matchers:
- logs_path:
logs_path: "/var/log/containers/"
output.logstash:
hosts: ["logstash-loki:5044"]
logstash:
enabled: false
image: grafana/logstash-output-loki
imageTag: 1.0.1
filters:
main: |-
filter {
if [kubernetes] {
mutate {
add_field => {
"container_name" => "%{[kubernetes][container][name]}"
"namespace" => "%{[kubernetes][namespace]}"
"pod" => "%{[kubernetes][pod][name]}"
}
replace => { "host" => "%{[kubernetes][node][name]}"}
}
}
mutate {
remove_field => ["tags"]
}
}
outputs:
main: |-
output {
loki {
url => "http://loki:3100/loki/api/v1/push"
#username => "test"
#password => "test"
}
# stdout { codec => rubydebug }
}
# proxy is currently only used by loki test pod
# Note: If http_proxy/https_proxy are set, then no_proxy should include the
# loki service name, so that tests are able to communicate with the loki
# service.
proxy:
http_proxy: ""
https_proxy: ""
no_proxy: ""
配置要点说明:
loki.enabled: true: 启用 Loki 主服务。
promtail.enabled: true: 启用 Promtail 日志收集代理,它以 DaemonSet 形式运行在每个节点上。
grafana.enabled: true 和 grafana.service.type: NodePort: 关键! 启用 Grafana 并将其服务类型设置为 NodePort,以便从集群外部访问。这是默认配置中需要修改的核心部分。
prometheus, filebeat, logstash, fluent-bit 均设为 false: 本教程聚焦于 Loki+Promtail 方案,故禁用其他可选的日志收集器。
3. 使用 Helm 部署 Loki Stack
配置好 Values 文件后,就可以开始部署了。我们将在名为 grafana-loki 的命名空间中安装所有组件。
[root@k8smaster ~]# helm upgrade --install --values loki-custom-values.yaml loki grafana/loki-stack -n grafana-loki --create-namespace
Release "loki" does not exist. Installing it now.
WARNING: This chart is deprecated
NAME: loki
LAST DEPLOYED: Sun Mar 22 15:21:26 2026
NAMESPACE: grafana-loki
STATUS: deployed
REVISION: 1
NOTES:
The Loki stack has been deployed to your cluster. Loki can now be added as a datasource in Grafana.
See http://docs.grafana.org/features/datasources/loki/ for more detail
部署成功后,查看相关 Pod 和 Service 的状态,确认所有组件运行正常。
[root@k8smaster ~]# kubectl get pods -n grafana-loki
NAME READY STATUS RESTARTS AGE
loki-0 1/1 Running 0 26m
loki-grafana-6bb45f476b-xxqgk 2/2 Running 0 26m
loki-promtail-cp24p 1/1 Running 0 26m
loki-promtail-d95c2 1/1 Running 0 26m
[root@k8smaster ~]# kubectl get svc -n grafana-loki
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
loki ClusterIP 10.96.74.47 <none> 3100/TCP 26m
loki-grafana NodePort 10.96.51.130 <none> 80:32650/TCP 26m
loki-headless ClusterIP None <none> 3100/TCP 26m
loki-memberlist ClusterIP None <none> 7946/TCP 26m
可以看到 loki-grafana 服务已分配了一个 NodePort 32650。
4. 访问 Grafana 并配置 Loki 数据源
首先,获取访问 Grafana 所需的端口和凭据。
- 获取 NodePort:
[root@k8smaster ~]# kubectl get svc loki-grafana -n grafana-loki -o jsonpath="{.spec.ports[0].nodePort}"
32650
- 获取管理员用户名 (默认为
admin):
[root@k8smaster ~]# kubectl get secret loki-grafana -n grafana-loki -o jsonpath="{.data.admin-user}" | base64 --decode
admin
- 获取管理员密码:
[root@k8smaster ~]# kubectl get secret loki-grafana -n grafana-loki -o jsonpath="{.data.admin-password}" | base64 --decode
3exqqaQhlQoi9xpfoC8TObCYmIasokKKcR4wcnFZ
现在,通过浏览器访问 http://<你的K8s节点IP>:32650,使用上面获取的用户名和密码登录。

登录成功后,你会看到 Grafana 的主页。

接下来,需要将 Loki 添加为数据源。点击左侧导航栏的 Connections -> Data sources。

在搜索框输入 “loki”,然后选择 Loki 数据源。由于我们在 Helm 配置中已经通过 Sidecar 自动完成了数据源配置,这里应该能看到一个名为 “Loki” 的已连接数据源,其地址指向了集群内的 Loki 服务 (http://loki:3100)。

5. 探索与查询日志
点击数据源列表右侧的 “Explore” 按钮,进入 Loki 的日志查询界面。

在 “Label filters” 区域,你可以通过添加标签对日志进行筛选。这是 Loki 强大的地方,它使用与 Prometheus 类似的标签系统来索引日志。
例如,我们可以选择 namespace 标签,其值为 grafana-loki,来查看我们刚部署的这套系统自身产生的日志。点击 “Run query”。

查询结果会显示在下方。你还可以进一步细化查询,例如,增加一个 pod 标签过滤器,只查看某个特定 Pod(如 loki-promtail-d95c2)的日志。

总结与后续
至此,我们成功在 Kubernetes 集群中使用 Helm 部署了 Grafana Loki 日志收集栈。通过自定义 Values 文件,我们启用了核心的 Loki、Promtail 和 Grafana 组件,并配置 Grafana 以 NodePort 方式对外暴露,方便访问。
本文重点在于快速搭建和验证基础日志流水线,因此并未涉及持久化存储配置、日志保留策略、资源配额限制等生产环境需要考虑的高级话题。在实际生产部署前,请务必根据业务需求规划存储方案并调整资源限制。
Grafana Loki 以其简洁的架构和与 Grafana 生态的深度整合,为 Kubernetes 环境下的日志管理提供了一个高效且低成本的选项。希望这篇实战指南能帮助你快速上手。如果你在部署过程中遇到问题,或想探讨更多关于云原生可观测性的实践,欢迎到云栈社区的相关板块交流讨论。