<p>I would like to run <code>kubectl</code> command from a pre-upgrade <code>helm hook</code>, but I can't seem to any documentation on how to achieve this. </p>

<p>Do I have to create a docker image that contains <code>kubectl</code> in order to achieve this? </p>

<p>or is there some way of achieving this without using a container? </p>

<p>I have a basic <code>helm hook</code> which looks like this </p>

<pre><code>
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Chart.Name }}-change-pvc-hook
  labels:
    app: {{ .Chart.Name }}
  annotations:
    "helm.sh/hook": pre-upgrade
    "helm.sh/hook-delete-policy": hook-succeeded, before-hook-creation
spec:
  template:
    metadata:
      name: "{{.Release.Name}}"
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Never
      containers:
        - name: pre-upgrade-change-pvc
</code></pre>

<p>if someone could explain how to run <code>kubectl</code> on without a container or how I can achieve this, that would be great</p>

<p>You can do it like Prometheus operator does the cleanup (pre-delete hook) in their helm chart: <a href="https://github.com/helm/charts/blob/d58247103fafd5930792bb1fd3ac240547523200/stable/prometheus-operator/templates/prometheus-operator/cleanup-crds.yaml#L33" rel="noreferrer">prometheus operator kubectl usage</a></p>

<p>basically, you can use the image = <code>k8s.gcr.io/hyperkube:v1.12.1</code>
something like this:</p>

<pre><code>apiVersion: batch/v1
kind: Job
metadata:
  name:somename-operator-cleanup
  namespace: somenamespace
  annotations:
    "helm.sh/hook": pre-delete
    "helm.sh/hook-weight": "3"
    "helm.sh/hook-delete-policy": hook-succeeded
  labels:
    app: someapp-operator
spec:
  template:
    metadata:
      name: somename-operator-cleanup
      labels:
        app: someapp
    spec:
    {{- if .Values.global.rbac.create }}
      serviceAccountName: {{ template "prometheus-operator.operator.serviceAccountName" . }}
    {{- end }}
      containers:
        - name: kubectl
          image: "k8s.gcr.io/hyperkube:v1.12.1"
          imagePullPolicy: "IfNotPresent"
          command:
          - /bin/sh
          - -c
          - &gt;
              kubectl your command here.
              kubectl delete alertmanager   --all;
              kubectl delete prometheus     --all;
              kubectl delete prometheusrule --all;
              kubectl delete servicemonitor --all;
              sleep 10;
              kubectl delete crd alertmanagers.monitoring.coreos.com;
              kubectl delete crd prometheuses.monitoring.coreos.com;
              kubectl delete crd prometheusrules.monitoring.coreos.com;
              kubectl delete crd servicemonitors.monitoring.coreos.com;
              kubectl delete crd podmonitors.monitoring.coreos.com;
      restartPolicy: OnFailure

</code></pre>

<p>Other option is to CURL to the Kubernetes API like <a href="https://github.com/ethz-hpc/k8s-OpenNebula/blob/2bbec2e31ca20159a51abbf7d51624d8e86ac1f2/Chart/templates/auto-ssh-secret-job.yaml#L42" rel="noreferrer">here</a>
note you need <code>automountServiceAccountToken: true</code>
and then you can use the Barear token from <code>/var/run/secrets/kubernetes.io/serviceaccount/token</code></p>

<p>You just need an image with curl for that. You can use zakkg3/opennebula-alpine-bootstrap for this.</p>

<p>For example here i create a secret based on a file using curl instead of kubectl:</p>

<pre><code>url -s -X POST -k https://kubernetes.default.svc/api/v1/namespaces/${NAMESPACE}/secrets \
                -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \
                -H "Content-Type: application/json" \
                -H "Accept: application/json" \
                -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ include "opennebula.fullname" . }}-ssh-keys\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"authorized_keys\": \"$( cat opennebula-ssh-keys/authorized_keys | base64 | tr -d '\n' )\", \"config\": \"$( cat opennebula-ssh-keys/config | base64 | tr -d '\n' )\", \"id_rsa\": \"$( cat opennebula-ssh-keys/id_rsa | base64 | tr -d '\n' )\", \"id_rsa.pub\": \"$( cat opennebula-ssh-keys/id_rsa.pub | base64 | tr -d '\n' )\" } }" &gt; /dev/null
</code></pre>

<p>Note its good practice to output to >  /dev/null otherwise you will end up with this output in your logging management (ELK / LOKI).</p>
