1. Answers
  2. Implementing persistent storage for Grafana dashboards on Kubernetes

How do I implement persistent storage for Grafana dashboards on Kubernetes?

In this guide, we will set up persistent storage for Grafana dashboards on Kubernetes using Pulumi. This ensures that your Grafana data is not lost when the Grafana pod is restarted or rescheduled. We will achieve this by creating a PersistentVolume (PV) and a PersistentVolumeClaim (PVC) in Kubernetes, and then deploying Grafana with this persistent storage.

Key Points

  • PersistentVolume (PV): A storage resource in a Kubernetes cluster.
  • PersistentVolumeClaim (PVC): A request for storage by a user.
  • Grafana Deployment: Deploy Grafana with a volume mount that uses the PVC.
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

// Define the PersistentVolume (PV)
const pv = new k8s.core.v1.PersistentVolume("grafana-pv", {
    spec: {
        capacity: {
            storage: "10Gi",
        },
        accessModes: ["ReadWriteOnce"],
        persistentVolumeReclaimPolicy: "Retain",
        storageClassName: "manual",
        hostPath: {
            path: "/mnt/data",
        },
    },
});

// Define the PersistentVolumeClaim (PVC)
const pvc = new k8s.core.v1.PersistentVolumeClaim("grafana-pvc", {
    spec: {
        accessModes: ["ReadWriteOnce"],
        resources: {
            requests: {
                storage: "10Gi",
            },
        },
        storageClassName: "manual",
    },
});

// Deploy Grafana with the persistent storage
const grafanaDeployment = new k8s.apps.v1.Deployment("grafana-deployment", {
    spec: {
        selector: { matchLabels: { app: "grafana" } },
        replicas: 1,
        template: {
            metadata: { labels: { app: "grafana" } },
            spec: {
                containers: [
                    {
                        name: "grafana",
                        image: "grafana/grafana:latest",
                        ports: [{ containerPort: 3000 }],
                        volumeMounts: [
                            {
                                name: "grafana-storage",
                                mountPath: "/var/lib/grafana",
                            },
                        ],
                    },
                ],
                volumes: [
                    {
                        name: "grafana-storage",
                        persistentVolumeClaim: {
                            claimName: pvc.metadata.name,
                        },
                    },
                ],
            },
        },
    },
});

// Expose Grafana using a Service
const grafanaService = new k8s.core.v1.Service("grafana-service", {
    spec: {
        selector: { app: "grafana" },
        ports: [
            {
                port: 80,
                targetPort: 3000,
            },
        ],
        type: "LoadBalancer",
    },
});

export const grafanaServiceName = grafanaService.metadata.name;

Conclusion

In this guide, we have created a PersistentVolume and a PersistentVolumeClaim to provide persistent storage for Grafana dashboards on Kubernetes. We then deployed Grafana with this persistent storage and exposed it using a Kubernetes Service. This setup ensures that your Grafana data persists across pod restarts and rescheduling.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up