跳到主要内容

Grafana 在 Kubernetes 平台部署指南

概述

Grafana 是一个开源的度量分析和可视化套件,常用于可视化时间序列数据。它支持多种数据源,包括 Prometheus、InfluxDB、Elasticsearch 等。本文档将详细介绍如何在 Kubernetes 平台中通过 Helm 部署 Grafana。

目录

  1. 环境准备
  2. Helm 部署 Grafana
  3. 网络配置
  4. 部署验证与访问

1. 环境准备

1.1 Kubernetes 平台要求

  • Kubernetes 版本: 1.20+
  • 节点配置: 至少 2 个节点,每个节点最少 2 核 4GB 内存
  • 存储类: 需要配置默认存储类(如 NFS、Local Path 等)

1.2 必需组件启用

确保以下组件已启用:

  • Ingress Controller(如 Nginx Ingress)
  • 默认 StorageClass

2. Helm 部署 Grafana

2.1 添加 Grafana Helm 仓库

# 添加 Grafana Helm 仓库
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

2.2 配置 Grafana 参数

创建 grafana-values.yaml 配置文件:

# Grafana 镜像配置
image:
repository: grafana/grafana
tag: 10.0.0
sha: ""
pullPolicy: IfNotPresent

# Grafana 副本数
replicas: 1

# Grafana 管理员用户配置
admin:
existingSecret: ""
userKey: admin-user
passwordKey: admin-password
user: "admin"
password: "admin123"

# Grafana 环境变量
env:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: admin123
GF_USERS_ALLOW_SIGN_UP: false

# Grafana 资源限制
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi

# Grafana 持久化存储
persistence:
type: pvc
enabled: true
storageClassName: ""
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
finalizers:
- kubernetes.io/pvc-protection

# Grafana 服务配置
service:
type: ClusterIP
port: 80
targetPort: 3000
annotations: {}
labels: {}
portName: service

# Grafana Ingress 配置
ingress:
enabled: false
annotations: {}
labels: {}
hosts:
- grafana.example.com
path: /
pathType: Prefix
tls: []

# Grafana 初始化配置
initChownData:
enabled: true
image:
repository: busybox
tag: "1.31.1"
sha: ""
pullPolicy: IfNotPresent
resources: {}
securityContext:
runAsNonRoot: false
runAsUser: 0
seLinuxOptions:
type: spc_t

# Grafana sidecar 配置
sidecar:
image:
repository: quay.io/kiwigrid/k8s-sidecar
tag: 1.24.4
sha: ""
imagePullPolicy: IfNotPresent
resources: {}

# sidecar 数据源配置
datasources:
enabled: true
label: grafana_datasource
labelValue: "1"
searchNamespace: null
watchMethod: WATCH
resource: both
folder: /etc/grafana/provisioning/datasources
provider:
name: sidecarProvider
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /etc/grafana/provisioning/datasources

# sidecar 仪表板配置
dashboards:
enabled: true
label: grafana_dashboard
labelValue: "1"
searchNamespace: null
watchMethod: WATCH
folder: /tmp/dashboards
provider:
foldersFromFilesStructure: true
name: sidecarProvider
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /tmp/dashboards
foldersFromFilesStructure: true

# Grafana 插件配置
plugins: []
# - grafana-piechart-panel
# - grafana-worldmap-panel

# Grafana 数据源配置
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-kube-prometheus-prometheus.monitoring:9090
access: proxy
isDefault: true
editable: true

# Grafana 仪表板配置
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default

# Grafana 仪表板配置
dashboards:
default:
kubernetes-cluster:
gnetId: 13130
revision: 1
datasource: Prometheus
kubernetes-pods:
gnetId: 13131
revision: 1
datasource: Prometheus
kubernetes-deployments:
gnetId: 13132
revision: 1
datasource: Prometheus
node-exporter-full:
gnetId: 1860
revision: 27
datasource: Prometheus

# Grafana 网络策略
networkPolicy:
enabled: false

# Grafana 安全上下文
securityContext:
runAsNonRoot: true
runAsUser: 472
runAsGroup: 472
fsGroup: 472

# Grafana 容器安全上下文
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

# Grafana 服务账户
serviceAccount:
create: true
name: ""
nameTest: ""
annotations: {}
autoMount: true

# Grafana 配置
grafana.ini:
paths:
data: /var/lib/grafana/
logs: /var/log/grafana
plugins: /var/lib/grafana/plugins
provisioning: /etc/grafana/provisioning
analytics:
check_for_updates: true
log:
mode: console
grafana_net:
url: https://grafana.net
server:
domain: "{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}"
auth:
disable_login_form: false
disable_signout_menu: false
auth.anonymous:
enabled: false

# Grafana LDAP 配置
ldap:
enabled: false
existingSecret: ""
config: ""

# Grafana SMTP 配置
smtp:
existingSecret: ""
userKey: user
passwordKey: password

# Grafana 额外配置
extraConfigmapMounts: []
extraSecretMounts: []
extraVolumeMounts: []
extraContainers: []
extraInitContainers: []
extraEnvVars: []

# Grafana Node 选择器
nodeSelector: {}

# Grafana 容忍度
tolerations: []

# Grafana 亲和性
affinity: {}

2.3 安装 Grafana

# 创建命名空间
kubectl create namespace monitoring

# 安装 Grafana
helm install grafana grafana/grafana \
--namespace monitoring \
--values grafana-values.yaml \
--version 6.56.0

3. 网络配置

3.1 创建 Ingress

创建 grafana-ingress.yaml 文件:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: grafana.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
number: 80

应用 Ingress 配置:

kubectl apply -f grafana-ingress.yaml

4. 部署验证与访问

4.1 检查服务状态

# 检查 Grafana Pod 状态
kubectl get pods -n monitoring

# 检查 Grafana 服务状态
kubectl get svc -n monitoring

# 检查 Ingress 状态
kubectl get ingress -n monitoring

4.2 访问 Grafana Web 界面

  1. 在本地 /etc/hosts 文件中添加域名解析:

    <节点IP> grafana.example.com
  2. 在浏览器中访问:http://grafana.example.com

4.3 功能验证

获取初始管理员密码

# 获取 Grafana 初始管理员密码
kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

登录验证

使用默认用户名 admin 和获取到的密码登录 Grafana。

数据源验证

  1. 登录 Grafana 后,进入 "Configuration" -> "Data Sources"
  2. 验证 Prometheus 数据源是否已正确配置
  3. 点击 "Test" 按钮验证连接

仪表板验证

  1. 进入 "Dashboards" -> "Manage"
  2. 验证预配置的仪表板是否已成功导入
  3. 打开任意仪表板查看监控数据