Álvaro Beleño

Administración de sistemas

Crear un CronJob para reiniciar deployment en AKS

Tras estar bastante tiempo sin subir un post, he decidido subir cosas interesantes que haga en mi trabajo que considere que pueden ser útiles o que, simplemente, quiera tener en algún sitio y así no perderlo de vista :)

Hoy os hablaré de cómo crear un recurso cronJob en AKS para manejar el reinicio de uno (O varios) deployments. Realmente esto se podría hacer en cualquier instancia de Kubernetes, con lo cual no aplica sólo a la plataforma de Azure. Aunque es en servicios gestionados como este donde esta solución llega a ser más interesante.

Lo que haremos será crear un recurso cronJob que reinicie el deployment indicado a la hora indicada. Este cronJob lanzará un pod que ejecutará kubectl para llevar a cabo el reinicio.

Creación del serviceAccount

Para esto, lo primero que haremos será crear un recurso serviceAccount. Este será usado por el pod para autenticarse y poder hacer uso de la API interna del cluster de k8s. Ejecutaremos el siguiente comando para su creación:

kubectl create serviceaccount deployment-restart-sa

Creación del role

Una vez tengamos creado este serviceAccount, necesitaremos un recurso role que definirá los permisos que tendrá dicho serviceAccount. Para crear este role, generamos un fichero YAML que contenga lo siguiente:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployment-restart-role
  namespace: <nombre-del-namespace>
rules:
  - apiGroups: ["apps", "extensions"]
    resources: ["deployments"]
    resourceNames: ["<deployment-a-reiniciar>"] # Podemos añadir varios deployments separando con comas
    verbs: ["get", "patch"]
...

Aquí, el apartado verbs definirá las acciones que podrá realizar el serviceAccount. En este caso get y patch serán las acciones que nos permitirán obtener información sobre el deployment y modificarlo. Teniendo listo el fichero, crearemos el role con:

kubectl apply -f <nombre-del-fichero>

Creación del roleBinding

Acto seguido, tenemos que definir un recurso roleBinding para relacionar el role con el serviceAccount anteriormente creados.

IMPORTANTE: Si no creamos este roleBinding, el serviceAccount no tendrá asignados los permisos necesarios para poder reiniciar el deployment, con lo cual el cronJob no funcionará.

Crearemos el roleBinding con el siguiente comando:

kubectl create rolebinding deployment-restart-rb --role=deployment-restart-role --serviceaccount=<namespace>:deployment-restart-sa

Aquí es importante ver que al especificar el serviceAccount, tenemos que especificar también el namespace en el que reside.

Creación del cronJob

Por último, crearemos el recurso cronJob que se encargará del reinicio. Para esto, crearemos otro fichero YAML con el siguiente contenido:

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: deployment-restart
  namespace: <nombre-del-namespace>
spec:
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 1
  schedule: '0 2 * * *' # Aquí definimos la hora a la que se ejecuta, en este caso a la 2:00 AM
  jobTemplate:
    spec:
      backoffLimit: 2
      activeDeadlineSeconds: 100
      template:
        spec:
          serviceAccountName: deployment-restart-sa
          restartPolicy: Never
          containers:
            - name: kubectl
              image: bitnami/kubectl
              command:
                - 'kubectl'
                - 'rollout'
                - 'restart'
                - 'deployment/<deployment-a-reiniciar>'
...

En este fichero, algunas partes a destacar son:

  • Cuando establecemos la hora a la que queremos que se ejecute el job, tendremos que tener en cuenta la zona horaria del cluster AKS, que por defecto es UTC.

  • Tener currencyPolicy en Forbid significa que no se permiten jobs concurrentes. Es decir, si cuando el job se va a ejecutar todavía hay otro ejecutándose, este job nuevo no se ejecuta.

  • El parámetro backoffLimit define el número de intentos que se llevarán a cabo antes de considerar el job como “fallido”.

  • El parámetro activeDeadlineSeconds es una forma de terminar el job, definiendo el tiempo en segundos que pasará hasta la terminación de este.

  • successfulJobsHistoryLimit define el número de ejecuciones exitosas que se retendrán. Estando en “1”, significa que persistirán los recursos creados por la última ejecución exitosa del job. Si queremos que se borren automáticamente los recursos correspondientes (Normalmente pods), simplemente tendremos que ponerlo a “0”.

Teniendo ya el fichero completo, crearemos el recurso utilizando de nuevo el comando:

kubectl apply -f <nombre-del-fichero>

Finalmente, podremos utilizar el siguiente comando para verificar que nuestro cronJob se ha creado:

kubectl get cronjobs

Fuente: https://stackoverflow.com/questions/52422300/how-to-schedule-pods-restart