Skip to main content

Kubernetes Installation

This guide covers deploying Grafana on Kubernetes using Kubernetes manifests or Helm charts.

Before You Begin

Ensure you have:
  • A Kubernetes cluster (local or cloud-based)
    • Local: minikube, kind, or Docker Desktop
    • Cloud: GKE, EKS, or AKS
  • kubectl CLI configured to access your cluster
  • For Helm installation: Helm 3.x installed

System Requirements

Minimum hardware requirements per pod:
  • CPU: 250m (0.25 cores)
  • Memory: 750 MiB
  • Disk: 1 GB persistent storage
Ensure port 3000 is accessible in your network environment.

Installation with Kubernetes Manifests

Deploy Grafana using native Kubernetes manifests for full control over the deployment.
1
Create a namespace
2
kubectl create namespace my-grafana
3
Create the manifest file
4
Create a file named grafana.yaml with the following contents:
5
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      securityContext:
        fsGroup: 472
        supplementalGroups:
          - 0
      containers:
        - name: grafana
          image: grafana/grafana:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
              name: http-grafana
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /robots.txt
              port: 3000
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 30
            successThreshold: 1
            timeoutSeconds: 2
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 3000
            timeoutSeconds: 1
          resources:
            requests:
              cpu: 250m
              memory: 750Mi
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: grafana-pv
      volumes:
        - name: grafana-pv
          persistentVolumeClaim:
            claimName: grafana-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
spec:
  ports:
    - port: 3000
      protocol: TCP
      targetPort: http-grafana
  selector:
    app: grafana
  sessionAffinity: None
  type: LoadBalancer
6
Deploy the manifest
7
kubectl apply -f grafana.yaml --namespace=my-grafana
8
Verify the deployment
9
Check the PersistentVolumeClaim:
10
kubectl get pvc --namespace=my-grafana -o wide
11
Check the Deployment:
12
kubectl get deployments --namespace=my-grafana -o wide
13
Check the Service:
14
kubectl get svc --namespace=my-grafana -o wide
15
Access Grafana
16
Get all resources:
17
kubectl get all --namespace=my-grafana
18
For cloud providers with LoadBalancer support, find the EXTERNAL-IP and access Grafana at http://<EXTERNAL-IP>:3000.
19
For local clusters or if no external IP is available, use port forwarding:
20
kubectl port-forward service/grafana 3000:3000 --namespace=my-grafana
21
Then access Grafana at http://localhost:3000.
22
Sign in
23
Default credentials:
24
  • Username: admin
  • Password: admin
  • Installation with Helm

    Helm simplifies Kubernetes deployments using packaged charts.
    1
    Add the Helm repository
    2
    helm repo add grafana-community https://grafana-community.github.io/helm-charts
    
    3
    Update the repository
    4
    helm repo update
    
    5
    Create a namespace
    6
    kubectl create namespace monitoring
    
    7
    Install Grafana
    8
    helm install my-grafana grafana-community/grafana --namespace monitoring
    
    9
    Get admin password
    10
    The Helm chart generates a random admin password stored in a Kubernetes secret:
    11
    kubectl get secret --namespace monitoring my-grafana \
      -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
    
    12
    Access Grafana
    13
    Use port forwarding:
    14
    export POD_NAME=$(kubectl get pods --namespace monitoring \
      -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=my-grafana" \
      -o jsonpath="{.items[0].metadata.name}")
    
    kubectl --namespace monitoring port-forward $POD_NAME 3000
    
    15
    Access Grafana at http://localhost:3000.

    Helm Configuration

    Enable Persistent Storage

    Create or download the values.yaml file from the Grafana Helm Charts repository. Edit values.yaml to enable persistence:
    persistence:
      type: pvc
      enabled: true
      storageClassName: default
    
    Apply the configuration:
    helm upgrade my-grafana grafana-community/grafana -f values.yaml -n monitoring
    

    Install Plugins

    Add plugins to values.yaml:
    plugins:
      - grafana-clock-panel
      - grafana-simple-json-datasource
    
    Apply the configuration:
    helm upgrade my-grafana grafana-community/grafana -f values.yaml -n monitoring
    

    Custom Admin Password

    Set a custom admin password in values.yaml:
    adminUser: admin
    adminPassword: your-secure-password
    
    Apply the configuration:
    helm upgrade my-grafana grafana-community/grafana -f values.yaml -n monitoring
    

    Deploy Grafana Enterprise

    To deploy Grafana Enterprise on Kubernetes:
    1
    Create a license secret
    2
    kubectl create secret generic ge-license \
      --from-file=/path/to/your/license.jwt \
      --namespace=my-grafana
    
    3
    Create Grafana configuration
    4
    Create grafana.ini:
    5
    [enterprise]
    license_path = /etc/grafana/license/license.jwt
    
    [server]
    root_url = /your/license/root/url
    
    6
    Create ConfigMap
    7
    kubectl create configmap ge-config \
      --from-file=/path/to/your/grafana.ini \
      --namespace=my-grafana
    
    8
    Update deployment manifest
    9
    Modify the Deployment section to use the Enterprise image and mount the license:
    10
    containers:
      - image: grafana/grafana-enterprise:latest
        name: grafana
        volumeMounts:
          - mountPath: /var/lib/grafana
            name: grafana-pv
          - mountPath: /etc/grafana
            name: ge-config
          - mountPath: /etc/grafana/license
            name: ge-license
    volumes:
      - name: grafana-pv
        persistentVolumeClaim:
          claimName: grafana-pvc
      - name: ge-config
        configMap:
          name: ge-config
      - name: ge-license
        secret:
          secretName: ge-license
    
    11
    Deploy
    12
    kubectl apply -f grafana.yaml --namespace=my-grafana
    

    Update Deployment

    Perform rolling updates to change the Grafana version:
    kubectl edit deployment grafana --namespace=my-grafana
    
    Change the image version:
    image: grafana/grafana:12.1.0
    
    Verify the rollout:
    kubectl rollout status deployment grafana --namespace=my-grafana
    

    Rollback Deployment

    View rollout history:
    kubectl rollout history deployment grafana --namespace=my-grafana
    
    Rollback to a previous revision:
    kubectl rollout undo deployment grafana --to-revision=1 --namespace=my-grafana
    

    Troubleshooting

    View logs

    kubectl logs --namespace=my-grafana deploy/grafana
    
    For multi-container pods:
    kubectl logs --namespace=my-grafana deploy/grafana -c grafana
    

    Enable debug logging

    Create a ConfigMap with custom configuration:
    echo '[log]
    level = debug' > grafana.ini
    
    kubectl create configmap grafana-config \
      --from-file=grafana.ini \
      --namespace=my-grafana
    

    Cleanup

    Remove the Grafana deployment:
    kubectl delete -f grafana.yaml --namespace=my-grafana
    
    For Helm installations:
    helm uninstall my-grafana -n monitoring
    
    Delete the namespace:
    kubectl delete namespace my-grafana
    

    Next Steps

    • Configure data sources using provisioning
    • Set up persistent storage for production
    • Configure high availability with multiple replicas
    • Integrate with ingress controllers for external access