En este blog vamos a abordar la temática de las pipelines de Kubernetes (Tekton), y cómo éstas han supuesto una revolución en la forma de gestionar los flujos de trabajo de CI/CD en el desarrollo de software, permitiendo una mayor flexibilidad respecto a su creación y gestión.
Las principales características de las pipelines con Tekton son:
- Se trata de un marco de trabajo de código abierto nativo.
- Es un modelo potente y flexible para crear sistemas CI/CD, permitiendo a los desarrolladores crear, probar y desplegar a través de proveedores en la nube y sistemas locales.
- Proporciona extensiones a las definiciones de recursos personalizadas (CRD) para facilitar la creación y estandarización de canalizaciones. Tiene soporte incorporado para el acoplamiento con herramientas CI/CD existentes en la industria como Jenkins, Jenkins X, Skaffold, Knative y OpenShift.
- La integración en OpenShift de Tekton (OpenShift Pipelines), introduce aún más potencia y flexibilidad en este sistema, a través de las herramientas para desarrolladores de RedHat y OpenShift.
¿Qué beneficios aporta?
Personalizable
Reutilizable
Ampliable
Estandarizado
Escalable
- Personalizable: Son totalmente personalizables, lo que permite un alto grado de flexibilidad.
- Reutilizable: Al ser completamente portátiles, una vez definidas, los desarrolladores pueden construir rápidamente pipelines complejas sin “reinventar la rueda”.
- Ampliable: Tekton Catalog es un repositorio impulsado por la comunidad de los componentes básicos de Tekton. Puede crear rápidamente tuberías nuevas y ampliar las existentes utilizando componentes prefabricados del catálogo.
- Estandarizado: Se instala y ejecuta como una extensión en Kubernetes y utiliza el modelo de recursos bien establecido. Las cargas de trabajo se ejecutan dentro de los contenedores de Kubernetes.
- Escalable: Para aumentar su capacidad de carga de trabajo, simplemente se pueden agregar nodos al clúster. Tekton escala sin la necesidad de redefinir sus asignaciones de recursos o cualquier otra modificación a sus canalizaciones.
Cómo trabajar con Tekton
Tkn es la interfaz de línea de comandos para interactuar con Tekton. Provee una experiencia rápida y optimizada, que incluye comandos de alto nivel y codificación de colores.
Kubectl proporciona una granularidad sustancialmente mayor para controlar Tekton, a expensas de una mayor complejidad. Utilizado mayormente para depurar pipelines y solucionar problemas en sus compilaciones.
Tekton APIs, disponible actualmente para Pipelines y Triggers, permite interactuar mediante programación con los componentes.
Tekton pipelines
Es una extensión de Kubernetes que se instala y ejecuta en el clúster. Define un conjunto de recursos personalizados que actúan como bloques de construcción a partir de los cuales se pueden montar pipelines de CI/CD.
Se define con las siguientes entidades:
Task: Es una colección de pasos que se definen y organizan en un orden específico de ejecución, como parte del flujo de integración continua. Cada uno de los pasos es un contenedor dentro del Pod de la Tarea. Aislar este tipo de secuencia de pasos relacionados en una única tarea reutilizable proporciona a Tekton una gran versatilidad y flexibilidad.
Ejemplo:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: echo-example
namespace: tekton-pipelines
spec:
params:
- name: message
type: string
default: ‘Hello World’
steps:
- name: hello
image: ubuntu
command: ["echo"]
args: ["$(params.message)"]
volumes:
- name: example-volume
emptyDir: {}
TaskRun: Permite instanciar una task en el cluster ejecutando los pasos de la misma en el orden especificado, hasta que todos se hayan ejecutado con éxito o se produzca un fallo.
Ejemplo de cómo instanciar la task anterior:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: echo-example-
namespace: tekton-pipelines
spec:
params:
- name: message
vault: ‘Goodbye world’
taskref:
name: echo-example
kind: Task
volumes:
- name: example-volume
emptyDir: {}
Pipeline: Es una colección de tasks en orden. Tekton recopila todas las tareas, las conecta en un gráfico acíclico dirigido (DAG) y ejecuta el gráfico en secuencia. En otras palabras, crea una cantidad de pods de Kubernetes y garantiza que cada pod se ejecute correctamente como se desea.
Tekton otorga a los desarrolladores el control total del proceso: uno puede configurar un escenario de finalización de la task de entrada/salida, pedirle a Tekton que vuelva a intentarlo automáticamente si existe una prueba inestable, o especificar una condición que debe cumplir una tarea antes de continuar.
Ejemplo:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-example
namespace: tekton-pipelines
spec:
params:
- name: context
type: string
description: Path to context
default: /some/where
tasks:
- name: example-build
taskRef:
name: build-push
params:
- name: pathToContext
value: "$(params.context)"
PipelineRun: es una ejecución específica de un pipeline. Por ejemplo, se puede pedir a Tekton que ejecute un flujo de trabajo CI/CD dos veces al día, y cada ejecución se convertirá en un recurso PipelineRun rastreable en su clúster Kubernetes.
Puede visualizar el estado de su flujo de trabajo CI/CD, incluidos los detalles específicos de cada ejecución de tarea con PipelineRun.
Ejemplo para instanciar el anterior Pipeline:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: pipeline-example-
namespace: tekton-pipelines
spec:
pipelineRef:
name: pipeline-example
params:
- name: context
value: "/tmp/example"
Workspaces: permiten a las Tasks declarar partes del sistema de archivos que necesitan ser proporcionadas en tiempo de ejecución por los TaskRuns, estos, pueden hacer que esas partes del sistema de archivos estén disponibles de muchas maneras: utilizando un ConfigMap o Secret de sólo lectura, un PersistentVolumeClaim existente compartido con otras Tareas, crear un PersistentVolumeClaim a partir de un VolumeClaimTemplate proporcionado, o simplemente un emptyDir que se descarta cuando el TaskRun finaliza.
Los Workspaces son similares a los Volúmenes excepto en que permiten al autor de una tarea diferir a los usuarios y sus TaskRuns a la hora de decidir qué clase de almacenamiento utilizar.
Casos de uso frecuentes:
- Almacenamiento de entradas y/o salidas
- Compartir datos entre Tareas
- Un punto de montaje para credenciales guardadas en Secretos
- Un punto de montaje para configuraciones guardadas en ConfigMaps
- Un punto de montaje para herramientas comunes compartidas por una organización
- Una caché de artefactos de construcción que aceleran los trabajos
Aquí vemos un diagrama donde se integran las anteriores entidades:
Tekton Triggers
Es un componente que permite detectar y extraer información de eventos de diversas fuentes e instanciar y ejecutar de forma determinista TaskRuns y PipelineRuns, basándose en esa información. También puede enviar información extraída de eventos directamente a TaskRuns y PipelineRuns.
Consta de un servicio controlador que se ejecuta en un clúster Kubernetes, así como de las siguientes definiciones de recursos personalizados (CRD) de Kubernetes que amplían la funcionalidad de Tekton Pipelines para admitir eventos:
EventListeners: es un objeto de Kubernetes que escucha eventos en un puerto especificado de su clúster. Expone un sumidero direccionable que recibe el evento entrante y especifica uno o más Triggers. El sumidero es un servicio de Kubernetes que ejecuta la lógica dentro de un Pod dedicado.
Ejemplo:
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: eventlistener
spec:
triggers:
- name: trigger
serviceAccountName: trigger-sa
interceptors:
- github:
eventTypes: ["pull_request"]
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template
Triggers: Especifica lo que ocurre cuando el EventListener detecta un evento. Especifica un TriggerTemplate, un TriggerBinding y, opcionalmente, un Interceptor.
Ejemplo:
apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
name: trigger
spec:
interceptors:
- ref:
name: "cel"
params:
- name: "filter"
value: "header.match('X-GitHub-Event', 'pull_request')"
- name: "overlays"
value:
- key: extensions.truncated_sha
expression: "body.pull_request.head.sha.truncate(7)"
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template
TriggerBindings: Especifica los campos de la carga útil del evento de los que desea extraer datos y los campos de su correspondiente TriggerTemplate que debe rellenar con los valores extraídos. A continuación, puede utilizar los campos rellenados en el TriggerTemplate para rellenar los campos en el TaskRun o PipelineRun asociado.
Ejemplo:
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: pipeline-binding
spec:
params:
- name: gitrevision
value: $(body.head_commit.id)
- name: gitrepositoryurl
value: $(body.repository.url)
- name: contenttype
value: $(header.Content-Type)
TriggerTemplate: especifica un modelo para el recurso, como un TaskRun o PipelineRun, que quieres instanciar y/o ejecutar cuando tu EventListener detecta un evento. Expone parámetros que puedes utilizar en cualquier lugar dentro de la plantilla de tu recurso.
Ejemplo:
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: pipeline-template
spec:
params:
- name: gitrevision
description: The git revision
default: main
- name: gitrepositoryurl
description: The git repository url
- name: message
description: The message to print
default: This is the default message
- name: contenttype
description: The Content-Type of the event
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: simple-pipeline-run-
spec:
pipelineRef:
name: simple-pipeline
params:
- name: message
value: $(tt.params.message)
- name: contenttype
value: $(tt.params.contenttype)
- name: git-revision
value: $(tt.params.gitrevision)
- name: git-url
value: $(tt.params.gitrepositoryurl)
workspaces:
- name: git-source
emptyDir: {}
Interceptors: Es un procesador de eventos “comodín” para una plataforma específica que se ejecuta antes del TriggerBinding y que permite realizar el filtrado de la carga útil, la verificación (mediante un secreto), la transformación, definir y probar las condiciones de activación y otros procesamientos útiles. Una vez que los datos del evento pasan a través de un interceptor, van al Trigger antes de que pases los datos de la carga útil al TriggerBinding.
Tekton Triggers soporta los siguientes interceptores para ayudarte a comenzar:
- Webhook Interceptors
- GitHub Interceptors
- GitLab Interceptors
- Bitbucket Interceptors
- Bitbucket Server
- Bitbucket Cloud
- CEL Interceptors
Ejemplo:
interceptors:
- name: "validate GitHub payload and filter on eventType"
ref:
name: "github"
params:
- name: "secretRef"
value:
secretName: github-secret
secretKey: secretToken
- name: "eventTypes"
value: ["pull_request"]
- name: "CEL filter: only when PRs are opened"
ref:
name: "cel"
params:
- name: "filter"
value: "body.action in ['opened', 'reopened']"
A continuación, podemos ver un diagrama donde se relacionan los recursos:
¿Qué puedo hacer con Triggers?
Como ejemplo, puede implementar el siguiente flujo de trabajo CI/CD:
- Triggers está a la escucha de un evento git commit o git pull request. Cuando detecta uno, ejecuta una prueba unitaria Pipeline sobre el código confirmado.
- Triggers espera un evento git push que indique que la prueba ha finalizado con éxito. Cuando detecta uno, valida el resultado de la prueba y ejecuta un Pipeline que construye el código probado.
- Cuando el PipelineRun asociado completa la ejecución, Triggers comprueba el resultado de la construcción, y si tiene éxito, ejecuta una tarea que sube los artefactos de construcción al registro Docker de tu elección.
- Por último, el registro Docker envía un evento a Pub/Sub, que activa un Pipeline que envía los artefactos de compilación a un entorno de preparación.
Tekton Dashboard
Es una interfaz web para los recursos Tekton Pipelines y Tekton Triggers. Permite a los usuarios gestionar y ver la creación, ejecución y finalización de recursos.
Algunas de las características que soporta el Dashboard de Tekton son:
- Vista en tiempo real del estado y los registros de PipelineRun y TaskRun
- Filtrar recursos por etiqueta
- Ver el resumen de recursos y YAML
- Mostrar recursos para todo el clúster o limitar la visibilidad a un espacio de nombres concreto
- Importar recursos directamente desde un repositorio git
- Añadir funciones mediante extensiones
Conclusión
Cada vez son más las empresas que deciden contenerizar y desplegar sus aplicaciones en servicios de kubernetes (AKS, EKS, GKE, etc…) y sus equipos de desarrollo necesitan ser ágiles mediante herramientas de CI/CD, donde puedan automatizar a través de pipelines el proceso de análisis, construcción, pruebas y despliegue de nuevas versiones.
Los pipelines de Tekton utilizan clusters de Kubernetes como tipo de primera clase y contenedores como sus principales bloques de construcción, ejecutando las tareas de forma aislada, sin verse afectadas por otros procesos que se estén ejecutando en el mismo sistema.
Tekton, promueve enérgicamente el acoplamiento flexible, por lo que la oportunidad de reutilización surge directamente. Es decir, el trabajo de un proyecto puede recogerse, encadenarse y utilizarse en otro lugar. Esto facilita el despliegue de servicios en múltiples soluciones en la nube suministradas por diferentes proveedores o incluso en sistemas locales.