1. 说明

此项目使用镜像 docker.io/grafana/grafana-oss:9.1.0 ,离线环境请在部署前将其导入至 containerd 或私有镜像源地址中。

2. 创建持久卷

使用以下配置创建对应的持久卷:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-grafana
  namespace: monitor-app
  labels:
    app: grafana
spec:
  storageClassName: 'sc-nfs-share'
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

3. 创建用户分组

Grafana 使用 LDAP 统一管理用户,需登陆 LDAP 管理控制台,添加如下用户:

1
cn=monitor,ou=groups,dc=cluster,dc=local

4. 创建配置

使用以下配置创建 Grafana 需要的相关的配置

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
apiVersion: v1
kind: ConfigMap
metadata:
  name: conf-grafana
  namespace: monitor-app
  labels:
    app: grafana
data:
  ADMIN_USER: 'admin'
  LDAP_ADMIN_GROUP_DN: 'cn=admin,ou=groups,dc=cluster,dc=local'
  LDAP_EDITOR_GROUP_DN: 'cn=monitor,ou=groups,dc=cluster,dc=local'

---
apiVersion: v1
kind: Secret
metadata:
  name: secret-grafana
  namespace: monitor-app
  labels:
    app: grafana
stringData:
  ADMIN_PASSWORD: 'grafana-admin-password'
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: conf-grafana-data
  namespace: monitor-app
  labels:
    app: grafana
data:
  grafana.ini: |
    app_mode = production
    [server]
    http_port = 3000
    serve_from_sub_path = true
    [database]
    type = sqlite3
    path = grafana.db
    [security]
    admin_user = ${ADMIN_USER}
    admin_password = ${ADMIN_PASSWORD}
    
    [users]
    allow_sign_up = false
    default_theme = dark
    default_locale = zh-CN
    
    [auth.anonymous]
    enabled = false
    hide_version = false
    
    [auth.basic]
    enabled = false
    
    [auth.ldap]
    enabled = true
    config_file = /etc/grafana/ldap.toml
    allow_sign_up = true
    sync_cron = "0 1 * * *"
    active_sync_enabled = true
    
    [log]
    mode = console
    level = warn
    
    [help]
    enabled = false
  ldap.toml: |
    [[servers]]
    host = "${LDAP_HOST}"
    port = ${LDAP_PORT}
    use_ssl = false
    start_tls = false
    ssl_skip_verify = false
    
    bind_dn = "${LDAP_BIND_DN}"
    bind_password = "${LDAP_BIND_PASSWORD}"
    timeout = 10
    search_filter = "(uid=%s)"
    search_base_dns = ["${LDAP_USER_BASE_DN}"]
    
    ## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
    ## Please check grafana LDAP docs for examples
    # group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
    # group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
    # group_search_filter_user_attribute = "uid"
    
    # Specify names of the ldap attributes your ldap uses
    [servers.attributes]
    name = "givenName"
    surname = "sn"
    username = "cn"
    member_of = "memberOf"
    email = "mail"
    
    # Map ldap groups to grafana org roles
    [[servers.group_mappings]]
    group_dn = "${LDAP_ADMIN_GROUP_DN}"
    org_role = "Admin"
    grafana_admin = true
    
    [[servers.group_mappings]]
    group_dn = "${LDAP_EDITOR_GROUP_DN}"
    org_role = "Editor"

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: conf-grafana-sources
  namespace: monitor-app
  labels:
    app: grafana
data:
  prometheus.yml: |
    apiVersion: 1
    deleteDatasources:
      - name: prometheus
        orgId: 1
    datasources:
      - id: 1
        orgId: 1
        name: prometheus
        type: prometheus
        url: http://svc-prometheus.monitor-app.svc.cluster.local:9090

5. 导入启动配置

使用以下配置创建 Grafana 启动配置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sts-grafana
  namespace: monitor-app
  labels:
    app: grafana
spec:
  serviceName: svc-grafana
  selector:
    matchLabels:
      app: grafana
  replicas: 1
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - name: grafana
          image: docker.io/grafana/grafana-oss:9.1.0
          envFrom:
            - configMapRef:
                name: conf-grafana
            - secretRef:
                name: secret-grafana
          env:
            - name: LDAP_HOST
              valueFrom:
                configMapKeyRef:
                  key: LDAP_HOST
                  name: conf-ldap
            - name: LDAP_PORT
              value: "389"
            - name: LDAP_BIND_DN
              valueFrom:
                configMapKeyRef:
                  key: LDAP_BIND_DN
                  name: conf-ldap
            - name: LDAP_BIND_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: LDAP_BIND_DN_PASSWORD
                  name: secret-ldap-service
            - name: LDAP_USER_BASE_DN
              valueFrom:
                configMapKeyRef:
                  key: LDAP_USERS_DN
                  name: conf-ldap
          volumeMounts:
            - name: grafana-conf
              mountPath: /etc/grafana/
            - name: grafana-data
              mountPath: /var/lib/grafana
            - name: grafana-datasource
              mountPath: '/etc/grafana/provisioning/datasources'
      volumes:
        - name: grafana-datasource
          configMap:
            name: conf-grafana-sources
        - name: grafana-conf
          configMap:
            name: conf-grafana-data
        - name: grafana-data
          persistentVolumeClaim:
            claimName: pvc-grafana

6. 创建 Service

使用以下配置,创建对应的 Service 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: svc-grafana
  namespace: monitor-app
spec:
  ports:
    - port: 3000
      name: grafana
  selector:
    app: grafana

7. 创建 Ingress

Service 创建完成后,使用以下配置将对应的 Service 暴露到 Ingress 中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-grafana
  namespace: monitor-app
  labels:
    app: grafana
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
  ingressClassName: nginx-private
  tls:
    - hosts:
        - grafana.internal.d7z.net
      secretName: tls-pri-d7z
  rules:
    - host: grafana.internal.d7z.net
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: svc-grafana
                port:
                  name: grafana

8. 测试

配置导入完成后,使用如下命令查看结果:

1
kubectl get pods,svc,ingress,configmaps -n monitor-app -l app=grafana

待一切完成后,访问 https://grafana.internal.d7z.net 查看 web 页面。