Persistant storage with localstorage and longhorn
See k3s storage docs for more documentation.
Below we will show two options. Local storage and distributed storage. That just means using the local storage on the node where it is running. On a single machine this is of course not a problem, but it can cause problems if you have a permanent failure of a node in a cluster, where you of course will suffer data loss. On a distributed storage on the other hand, you can make sure that the data is replicated on multiple nodes, and in that case a single node failure would be no problem.
Local storage
Local storage PVC
cat pvc-ghost-localstorage.yaml | envsubst | kubectl apply -f -
pvc-ghost-localstorage.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ghost-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 2Gi
Ghost with persistant local storage
cat ghost-localstorage.yaml | envsubst | kubectl apply -f -
ghost-localstorage.yaml
apiVersion: v1
kind: Service
metadata:
name: ghost
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 2368
selector:
app: ghost
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ghost
spec:
selector:
matchLabels:
app: ghost
replicas: 1
template:
metadata:
labels:
app: ghost
spec:
containers:
- name: ghost
image: ghost:5.32.0
# prettier-ignore
env:
- name: database__client
value: sqlite3
- name: database__connection__filename
value: content/data/ghost.db
- name: database__useNullAsDefault
value: "true"
- name: database__debug
value: "false"
ports:
- containerPort: 2368
volumeMounts:
- name: my-ghost-volume
mountPath: /var/lib/ghost/content
volumes:
- name: my-ghost-volume
persistentVolumeClaim:
claimName: ghost-pvc
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ghost-ingress
annotations:
spec.ingressClassName: traefik
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- host: ghost.${DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ghost
port:
number: 80
tls:
- secretName: ghost-tls
hosts:
- ghost.${DOMAIN}
Distributed storage (Longhorn)
Setting up Longhorn
Apply the longhorn.yaml
to install Longhorn
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.0/deploy/longhorn.yaml
Longhorn will be installed in the namespace longhorn-system
.
Longhorn PVC
cat pvc-ghost-longhorn.yaml | envsubst | kubectl apply -f -
pvc-ghost-longhorn.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ghost-longhorn-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 2Gi
Ghost with Longhorn distributed storage
- first delete ghost
cat ghost-localstorage.yaml | envsubst | kubectl delete -f -
- And then recreate it with longhorn
cat ghost-longhorn.yaml | envsubst | kubectl apply -f -
Longhorn UI
cat longhorn-ui-ingress.yaml | envsubst | kubectl apply -f -
longhorn-ui-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: longhorn-ingress
namespace: longhorn-system
annotations:
spec.ingressClassName: traefik
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.middlewares: default-my-basic-auth@kubernetescrd
spec:
rules:
- host: longhorn.${DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: longhorn-frontend
port:
number: 80
tls:
- secretName: longhorn-tls
hosts:
- longhorn.${DOMAIN}
Your longhorn UI should now be accessible at https://longhorn.dog.example.com