<p>In my use case i need to scale up a stateful set upon specific logic, and scale it down.
I'm not sure HPA will help as i need to create exactly one replica each time, and later raise a notification to scale it down, meaning - the application will be scaled, and then for a specific amount of time there will be no scaling down (HPA will continue spinning pods until its conditions are met, if they are met, it will scale down the pod which is a problem).</p>

<p>I'm deploying using helm.</p>

<p>Should i:</p>

<ul>
<li>Make the pod access K8s API and change the replica count?</li>
<li>Use helm controller to maybe create/update a CRD that contains the replica count?</li>
<li>run kubectl scale inside the pod when the conditions are met?</li>
</ul>

<p>what's the best practices here?</p>

ArielB
<p>You can setup a <a href="https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/" rel="nofollow noreferrer">CronJob</a> that will spawn a pod each (x minutes) and check, for example by using <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/" rel="nofollow noreferrer">ConfigMap</a> if it needs to scale up/down the <a href="https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/" rel="nofollow noreferrer">StatefulSet</a>.</p>

<p>This <code>Job</code> will use the <a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/" rel="nofollow noreferrer">REST API</a>, with it you can use <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/" rel="nofollow noreferrer">API reference docs</a> to <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#replace-scale-replicationcontroller-v1-core" rel="nofollow noreferrer"><code>Replace</code></a> or <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#patch-scale-replicationcontroller-v1-core" rel="nofollow noreferrer"><code>Patch</code></a> your StatefulSet.</p>

<p>You can do that by:</p>

<p><a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#using-kubectl-proxy" rel="nofollow noreferrer">Using kubectl proxy</a></p>

<blockquote>
  <p><code>$ kubectl proxy --port=8080 &amp;</code>
  See <a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands/#proxy" rel="nofollow noreferrer">kubectl proxy</a> for more details.</p>
  
  <p>Then you can explore the API with curl, wget, or a browser, like so:</p>
  
  <p><code>$ curl http://localhost:8080/api/</code>
  The output is similar to this:</p>
</blockquote>

<pre><code>{
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}
</code></pre>

<p><a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#without-kubectl-proxy" rel="nofollow noreferrer">Without kubectl proxy</a></p>

<blockquote>
  <p>It is possible to avoid using kubectl proxy by passing an authentication token directly to the API server, like this:</p>
  
  <p>Using  <code>grep/cut</code>  approach:</p>
</blockquote>

<pre class="lang-sh prettyprint-override"><code># Check all possible clusters, as you .KUBECONFIG may have multiple contexts:
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

# Select name of cluster you want to interact with from above output:
export CLUSTER_NAME="some_server_name"

# Point to the API server refering the cluster name
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

# Gets the token value
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -d)

# Explore the API with TOKEN
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
</code></pre>

<blockquote>
  <p>The output is similar to this:</p>
</blockquote>

<pre><code>{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}
</code></pre>

<p>Or with programmatic access to the API, Kubernetes officially supports <a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#go-client" rel="nofollow noreferrer">Go</a> and <a href="https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#python-client" rel="nofollow noreferrer">Python</a> client libraries.</p>

<p>I hope this helps you a bit, if you have further questions please ask.</p>
