<p>How to setup periodic database backup in kubernetes? I have deployed a postgres database as <code>StatefulSet</code> in kubernetes and mounted a <code>PersistantVolume</code> to store data. Now to get periodic backup for the mounted volume, I found three options,</p>

<ol>
<li>Setup a <code>CronJob</code> in kubernetes and execute pg_dump and upload to the storage location.</li>
<li>I have already using celery in my project. So now add a new task to backup postgres data and upload to the storage location.</li>
<li>VolumeSnapshots. This looks more kubernetes way. But I couldn't find a way to automate this periodically.</li>
</ol>

<p>Which is the recommended way to take periodic volume backup in kubernetes?</p>

<p>[EDIT] I prefer solutions without using operators.</p>

<blockquote>
  <p>Which is the recommended way to take periodic volume backup in kubernetes?</p>
</blockquote>

<p>I would recommend <a href="https://kubernetes.io/docs/concepts/storage/volume-snapshots/" rel="nofollow noreferrer">VolumeSnapshots</a>, but you need to keep in mind that this is not normal backup and you won't be able to revert the data to previous state. </p>

<blockquote>
  <p>Many storage systems (like Google Cloud Persistent Disks, Amazon Elastic Block Storage, and many on-premise storage systems) provide the ability to create a “snapshot” of a persistent volume. A snapshot represents a point-in-time copy of a volume. A snapshot can be used either to provision a new volume (pre-populated with the snapshot data) or to restore an existing volume to a previous state (represented by the snapshot).</p>
</blockquote>

<p>It's easy to use, as of December 2019 it was moved to beta <a href="https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-feature-cis-volume-snapshot-beta/" rel="nofollow noreferrer">Kubernetes 1.17 Feature: Kubernetes Volume Snapshot Moves to Beta</a>.</p>

<p>Once you specify the <code>VolumeSnapshotClass</code></p>

<blockquote>
  <p>The following VolumeSnapshotClass, for example, tells the Kubernetes cluster that a CSI driver,  <code>testdriver.csi.k8s.io</code>, can handle volume snapshots, and that when these snapshots are created, their deletion policy should be to delete.</p>
  
  <pre class="lang-yaml prettyprint-override"><code>apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
 name: test-snapclass
driver: testdriver.csi.k8s.io
deletionPolicy: Delete
parameters:
 csi.storage.k8s.io/snapshotter-secret-name: mysecret
 csi.storage.k8s.io/snapshotter-secret-namespace: mysecretnamespace
</code></pre>
  
  <p>The common snapshot controller reserves the parameter keys  <code>csi.storage.k8s.io/snapshotter-secret-name</code>  and  <code>csi.storage.k8s.io/snapshotter-secret-namespace</code>. If specified, it fetches the referenced Kubernetes secret and sets it as an annotation on the volume snapshot content object. The CSI external-snapshotter sidecar retrieves it from the content annotation and passes it to the CSI driver during snapshot creation.</p>
  
  <p>Creation of a volume snapshot is triggered by the creation of a VolumeSnapshot API object.</p>
  
  <p>The VolumeSnapshot object must specify the following source type:  <code>persistentVolumeClaimName</code>  - The name of the PVC to snapshot. Please note that the source PVC, PV, and VolumeSnapshotClass for a VolumeSnapshot object must point to the same CSI driver.</p>
</blockquote>

<p>You can create <code>VolumeSnapshot</code> which in this example will make s snapshot of PVC called <code>test-pvc</code>:</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: test-snapshot
spec:
  volumeSnapshotClassName: test-snapclass
  source:
    persistentVolumeClaimName: test-pvc
</code></pre>

<blockquote>
  <p>When volume snapshot creation is invoked, the common snapshot controller first creates a VolumeSnapshotContent object with the <code>volumeSnapshotRef</code>, source <code>volumeHandle</code>, <code>volumeSnapshotClassName</code> if specified, <code>driver</code>, and <code>deletionPolicy</code>.</p>
</blockquote>

<p>You can restore PersistentVolumeClaim from a Volume Snapshot:</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restore-pvc
spec:
  storageClassName: csi-hostpath-sc
  dataSource:
    name: test-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
</code></pre>

<blockquote>
  <p>To enable support for restoring a volume from a volume snapshot data source, enable the  <code>VolumeSnapshotDataSource</code>  feature gate on the apiserver and controller-manager.</p>
</blockquote>

<p>What are the limitations?</p>

<blockquote>
  <ul>
  <li>Does not support reverting an existing volume to an earlier state represented by a snapshot (beta only supports provisioning a new volume from a snapshot).</li>
  <li>No snapshot consistency guarantees beyond any guarantees provided by storage system (e.g. crash consistency). These are the responsibility of higher level APIs/controllers</li>
  </ul>
</blockquote>

<p>EDIT:</p>

<p>To automate this process you would need to setup a <code>CronJob</code> or write a Python code using <a href="https://github.com/kubernetes-client/python" rel="nofollow noreferrer">Python client library for kubernetes</a> and change for example <a href="https://github.com/kubernetes-client/python/blob/master/examples/custom_object.py" rel="nofollow noreferrer">python/examples/custom_object.py</a> to your needs.</p>

<p>You can also use already developed apps like <a href="https://stash.run/" rel="nofollow noreferrer">stash.run</a>.</p>
