<p>I want to apply <code>VPA</code> <strong>vertical pod auto scaling</strong> for database pods. Can we use <code>VPA</code> for database auto scaling (Vertical) as <code>VPA</code> requires at least 2 replicas (ref : <a href="https://github.com/kubernetes/autoscaler/issues/1665#issuecomment-464679271" rel="nofollow noreferrer">https://github.com/kubernetes/autoscaler/issues/1665#issuecomment-464679271</a>) as it delete pods when set criteria is reached. So pods are deleted hence also data.</p>
<p>What is good practice for using <code>VPA</code> with database pods?</p>

Developer Desk
<p><code>VPA</code> - Vertical pod autoscaler can work in 2 ways:</p>
<ul>
<li>Recommendation mode - it will recommend the requests and limits for pods based on resources used</li>
<li>Auto mode - it will automatically analyze the usage and set the request and limits on pods. This will result in pod termination to recreate it with new specification as stated here:</li>
</ul>
<blockquote>
<p>Due to Kubernetes limitations, the only way to modify the resource requests of a running Pod is to recreate the Pod. If you create a <code>VerticalPodAutoscaler</code> with an <code>updateMode</code> of &quot;Auto&quot;, the <code>VerticalPodAutoscaler</code> evicts a Pod if it needs to change the Pod's resource requests.</p>
<p><em><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/verticalpodautoscaler" rel="nofollow noreferrer">Cloud.google.com: Kubernetes Engine: Docs: Concepts: Vertical pod autoscaler</a></em></p>
</blockquote>
<p>Please refer to above link for more information regarding the concepts of <code>VPA</code>.</p>
<p>The fact that it needs at least 2 replicas is most probably connected with the fact of high availability. As the pods are getting evicted to support new limits they are unable to process the request. If it came to situation where there is only 1 replica at the time, this replica wouldn't be able to respond to requests when in terminating/recreating state.</p>
<p>There is an official guide to run VPA on <code>GKE</code>:</p>
<ul>
<li><em><a href="https://cloud.google.com/kubernetes-engine/docs/how-to/vertical-pod-autoscaling" rel="nofollow noreferrer">Cloud.google.com: Kubernetes Engine: How to: Vertical pod autoscaling</a></em></li>
</ul>
<p><code>VPA</code> supports: <code>Deployments</code> as well as <code>StatefulSets</code>.</p>
<blockquote>
<h3>StatefulSet</h3>
<p>Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.</p>
<p><strong>If you want to use storage volumes to provide persistence for your workload, you can use a StatefulSet as part of the solution.</strong></p>
<p><em><a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" rel="nofollow noreferrer">Kubernetes.io: StatefulSet</a></em></p>
</blockquote>
<p>Configuring <code>StatefulSet</code> with <code>PersistentVolumes</code> will ensure that the data stored on <code>PV</code> will not be deleted in case of pod termination.</p>
<p>To be able to use your database with <code>replicas</code> &gt; <code>1</code> you will need to have <em><a href="https://www.ibm.com/support/knowledgecenter/SSXW43_8.9.13/com.ibm.i2.ibase.admin.doc/what_is_database_replication.html" rel="nofollow noreferrer">replication</a></em> implemented within your database environment.</p>
<p>There are guides/resources/solutions on running databases within Kubernetes environment. Please choose the solution most appropriate to your use case. Some of them are:</p>
<ul>
<li><em><a href="https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/" rel="nofollow noreferrer">Kubernetes.io: Run replicated stateful application</a></em></li>
<li><em><a href="https://github.com/zalando/postgres-operator" rel="nofollow noreferrer">Github.com: Zalando: Postgres operator</a></em></li>
<li><em><a href="https://github.com/oracle/mysql-operator" rel="nofollow noreferrer">Github.com: Oracle: Mysql operator</a></em></li>
</ul>
<p>After deploying your database you will be able to run below command to extract the name of the <code>StatefulSet</code>:</p>
<ul>
<li><code>$ kubectl get sts</code></li>
</ul>
<p>You can then apply the name of the <code>StatefulSet</code> to the <code>VPA</code> like below:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: DB-VPA 
spec:
  targetRef:
    apiVersion: &quot;apps/v1&quot;
    kind:       StatefulSet
    name:       &lt;INSERT_DB_STS_HERE&gt;
  updatePolicy:
    updateMode: &quot;Auto&quot;
</code></pre>
<p>I encourage you also to read this article:</p>
<ul>
<li><em><a href="https://cloud.google.com/blog/products/databases/to-run-or-not-to-run-a-database-on-kubernetes-what-to-consider" rel="nofollow noreferrer">Cloud.google.com: Blog: To run or not to run a database on Kubernetes, what to consider</a></em></li>
</ul>
