Argo Workflows es un motor de flujos de trabajo nativo de Kubernetes: cada paso de un workflow se ejecuta como un pod, y las dependencias entre pasos se declaran en YAML como una secuencia o como un grafo acíclico dirigido (DAG). Se usa para pipelines de datos, entrenamiento de modelos, tareas de mantenimiento y CI. En este tutorial instalarás Argo Workflows y su CLI, configurarás los permisos que necesitan los workflows y crearás workflows secuenciales, un DAG, una plantilla reutilizable y un CronWorkflow.
Requisitos previos
- Un clúster de Kubernetes 1.28 o superior con al menos 2 GB de RAM libres, por ejemplo k3s en un VPS de CubePath o kind en tu equipo.
kubectlconfigurado con permisos de administrador del clúster, en Ubuntu 24.04 LTS o similar.curlinstalado.
Paso 1: Instalar Argo Workflows en el clúster
Argo Workflows se instala en su propio namespace con un único manifiesto publicado en cada release. Obtén la última versión estable desde la API de GitHub:
ARGO_VERSION=$(curl -fsSL https://api.github.com/repos/argoproj/argo-workflows/releases/latest | grep -Po '"tag_name": "\K[^"]+')
echo "$ARGO_VERSION"
v3.7.2
Crea el namespace y aplica el manifiesto. La opción --server-side evita el error de tamaño de anotación que dan los CRD grandes con kubectl apply clásico:
kubectl create namespace argo
kubectl apply -n argo --server-side -f "https://github.com/argoproj/argo-workflows/releases/download/${ARGO_VERSION}/install.yaml"
Espera a que el controlador y el servidor estén listos:
kubectl -n argo rollout status deployment/workflow-controller
kubectl -n argo rollout status deployment/argo-server
kubectl -n argo get pods
NAME READY STATUS RESTARTS AGE
argo-server-6c8d9f7b5-xk2lp 1/1 Running 0 60s
workflow-controller-7d9c6b8f4d-q8t5m 1/1 Running 0 60s
El workflow-controller vigila los objetos Workflow y crea los pods de cada paso; argo-server sirve la API y la interfaz web.
Paso 2: Instalar la CLI de Argo
La CLI argo permite enviar, seguir y depurar workflows. Usa la misma versión que el servidor:
curl -fsSLO "https://github.com/argoproj/argo-workflows/releases/download/${ARGO_VERSION}/argo-linux-amd64.gz"
gunzip argo-linux-amd64.gz
sudo install -m 0755 argo-linux-amd64 /usr/local/bin/argo
argo version --short
argo: v3.7.2
En servidores ARM64 descarga argo-linux-arm64.gz. La CLI usa tu kubeconfig para hablar con el clúster, así que no necesita configuración adicional.
Paso 3: Configurar la cuenta de servicio de los workflows
Cada pod de un workflow incluye un contenedor auxiliar (el executor) que informa al controlador de los resultados de cada paso creando objetos WorkflowTaskResult. La cuenta de servicio default no tiene ese permiso, así que crea una específica con el mínimo necesario:
nano argo-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-workflow
namespace: argo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: executor
namespace: argo
rules:
- apiGroups:
- argoproj.io
resources:
- workflowtaskresults
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-workflow-executor
namespace: argo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: executor
subjects:
- kind: ServiceAccount
name: argo-workflow
namespace: argo
kubectl apply -f argo-rbac.yaml
Si un paso necesita hacer algo más en el clúster (por ejemplo, ejecutar kubectl apply), añade esos permisos a una cuenta de servicio propia para ese workflow, no a esta.
Paso 4: Ejecutar un primer workflow
Un Workflow define un entrypoint y una lista de templates. El template más simple es un contenedor. Este recibe un parámetro con valor por defecto:
nano hola.yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hola-
spec:
serviceAccountName: argo-workflow
entrypoint: saludar
arguments:
parameters:
- name: mensaje
value: Hola desde Argo Workflows
templates:
- name: saludar
inputs:
parameters:
- name: mensaje
container:
image: alpine:3.20
command: [echo]
args: ["{{inputs.parameters.mensaje}}"]
generateName hace que cada ejecución tenga un nombre único. Envía el workflow y sigue su progreso con --watch:
argo submit -n argo --watch hola.yaml -p mensaje="Mi primer workflow"
Name: hola-7bq2x
Namespace: argo
ServiceAccount: argo-workflow
Status: Succeeded
Duration: 12 seconds
STEP TEMPLATE PODNAME DURATION MESSAGE
✔ hola-7bq2x saludar hola-7bq2x 8s
Consulta la salida del paso. @latest se refiere al último workflow enviado:
argo logs -n argo @latest
hola-7bq2x: Mi primer workflow
Paso 5: Encadenar pasos y pasar parámetros
La forma steps ejecuta grupos de pasos en orden. Cada elemento de la lista externa es un grupo que empieza cuando termina el anterior; los pasos dentro del mismo grupo se ejecutan en paralelo. Un paso puede exportar un parámetro de salida leyendo un archivo de su contenedor:
nano pasos.yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: pasos-
spec:
serviceAccountName: argo-workflow
entrypoint: principal
templates:
- name: principal
steps:
- - name: generar
template: generar-numero
- - name: mostrar
template: mostrar-numero
arguments:
parameters:
- name: numero
value: "{{steps.generar.outputs.parameters.numero}}"
- name: generar-numero
script:
image: python:3.12-alpine
command: [python]
source: |
import random
with open("/tmp/numero.txt", "w") as f:
f.write(str(random.randint(1, 100)))
outputs:
parameters:
- name: numero
valueFrom:
path: /tmp/numero.txt
- name: mostrar-numero
inputs:
parameters:
- name: numero
container:
image: alpine:3.20
command: [sh, -c]
args: ["echo El número generado es {{inputs.parameters.numero}}"]
El template de tipo script permite escribir el código directamente en el YAML. Ejecuta el workflow y revisa los logs:
argo submit -n argo --watch pasos.yaml
argo logs -n argo @latest
pasos-m4k8d-mostrar-numero-2214986710: El número generado es 42
Paso 6: Definir dependencias con un DAG
Cuando las dependencias no son una secuencia simple, usa un template dag. Cada tarea declara de qué tareas depende y Argo ejecuta en paralelo todo lo que puede. Este ejemplo tiene forma de rombo: preparar se ejecuta primero, procesar-a y procesar-b en paralelo, y combinar al final:
nano dag.yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: dag-
spec:
serviceAccountName: argo-workflow
entrypoint: rombo
templates:
- name: rombo
dag:
tasks:
- name: preparar
template: tarea
arguments:
parameters: [{name: nombre, value: preparar}]
- name: procesar-a
dependencies: [preparar]
template: tarea
arguments:
parameters: [{name: nombre, value: procesar-a}]
- name: procesar-b
dependencies: [preparar]
template: tarea
arguments:
parameters: [{name: nombre, value: procesar-b}]
- name: combinar
dependencies: [procesar-a, procesar-b]
template: tarea
arguments:
parameters: [{name: nombre, value: combinar}]
- name: tarea
inputs:
parameters:
- name: nombre
retryStrategy:
limit: "2"
retryPolicy: OnFailure
container:
image: alpine:3.20
command: [sh, -c]
args: ["echo Ejecutando {{inputs.parameters.nombre}}; sleep 5"]
retryStrategy reintenta hasta dos veces una tarea que falle, algo habitual en pasos que dependen de servicios externos. Ejecuta el DAG:
argo submit -n argo --watch dag.yaml
STEP TEMPLATE PODNAME DURATION MESSAGE
✔ dag-5vzqp rombo
├─✔ preparar tarea dag-5vzqp-tarea-2749512311 8s
├─✔ procesar-a tarea dag-5vzqp-tarea-1422918442 8s
├─✔ procesar-b tarea dag-5vzqp-tarea-1406140823 8s
└─✔ combinar tarea dag-5vzqp-tarea-3011262084 8s
Para ver el grafo, abre la interfaz web (paso 9): procesar-a y procesar-b aparecen en paralelo.
Paso 7: Reutilizar la lógica con WorkflowTemplate
Un WorkflowTemplate guarda un workflow en el clúster para lanzarlo tantas veces como quieras, desde la CLI, la interfaz web o un CronWorkflow. Crea una plantilla con un parámetro obligatorio:
nano plantilla-informe.yaml
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: informe
spec:
serviceAccountName: argo-workflow
entrypoint: generar
arguments:
parameters:
- name: entorno
ttlStrategy:
secondsAfterCompletion: 86400
podGC:
strategy: OnPodSuccess
templates:
- name: generar
inputs:
parameters:
- name: entorno
container:
image: alpine:3.20
command: [sh, -c]
args: ["echo Generando informe de {{inputs.parameters.entorno}} el $(date -u +%F)"]
ttlStrategy borra el workflow un día después de terminar y podGC elimina los pods que terminan bien, para que las ejecuciones recurrentes no llenen el clúster de objetos. Registra la plantilla y lánzala:
argo template create -n argo plantilla-informe.yaml
argo submit -n argo --from workflowtemplate/informe -p entorno=produccion --watch
argo template list -n argo
NAME
informe
Paso 8: Programar ejecuciones con CronWorkflow
Un CronWorkflow lanza un workflow según una expresión cron, igual que un CronJob de Kubernetes. En lugar de repetir la definición, referencia la plantilla del paso anterior:
nano cron-informe.yaml
apiVersion: argoproj.io/v1alpha1
kind: CronWorkflow
metadata:
name: informe-diario
spec:
schedules:
- "0 6 * * *"
timezone: Europe/Madrid
concurrencyPolicy: Forbid
startingDeadlineSeconds: 300
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
workflowSpec:
workflowTemplateRef:
name: informe
arguments:
parameters:
- name: entorno
value: produccion
La ejecución es a las 6:00 hora de Madrid. concurrencyPolicy: Forbid evita que empiece una ejecución si la anterior sigue en marcha, y los límites de historial conservan solo las últimas ejecuciones.
Notael campo
schedules(lista) existe desde Argo Workflows 3.6. En versiones anteriores se usaschedulecon una sola expresión.
Crea el CronWorkflow y, para probarlo sin esperar a la hora programada, lanza una ejecución manual:
argo cron create -n argo cron-informe.yaml
argo cron list -n argo
argo submit -n argo --from cronwf/informe-diario --watch
argo cron list muestra el CronWorkflow con su próxima ejecución, y la ejecución manual crea un workflow normal con el nombre informe-diario- seguido de un sufijo.
Para pausar las ejecuciones sin borrarlo, usa argo cron suspend -n argo informe-diario y argo cron resume para reanudarlas.
Paso 9: Acceder a la interfaz web
argo-server escucha en el puerto 2746 con HTTPS y un certificado autofirmado. Redirige el puerto a tu máquina:
kubectl -n argo port-forward svc/argo-server 2746:2746
Abre https://localhost:2746 y acepta el aviso del certificado. Por defecto el servidor usa el modo de autenticación client, que pide un token de Kubernetes. Genera uno de corta duración para una cuenta de servicio con permisos de lectura sobre los workflows, o bien, solo en un clúster local de pruebas, cambia al modo server, en el que la interfaz usa la cuenta de servicio del propio servidor:
kubectl -n argo patch deployment argo-server --type=json \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/args","value":["server","--auth-mode=server"]}]'
Advertenciacon
--auth-mode=servercualquiera que llegue al puerto 2746 puede ver y lanzar workflows. En clústeres compartidos o de producción usacliento SSO y no expongas el servicio públicamente.
Paso 10: Guardar artefactos (opcional)
Para pasar archivos entre pasos (no solo parámetros) o conservar resultados, Argo necesita un repositorio de artefactos compatible con S3. Se configura con un ConfigMap en el namespace de los workflows. Primero guarda las credenciales en un Secret:
kubectl -n argo create secret generic s3-credenciales \
--from-literal=accessKey=your_access_key \
--from-literal=secretKey=your_secret_key
nano artifact-repo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: artifact-repositories
namespace: argo
annotations:
workflows.argoproj.io/default-artifact-repository: default-v1
data:
default-v1: |
s3:
bucket: your_bucket
endpoint: your_s3_endpoint
insecure: false
accessKeySecret:
name: s3-credenciales
key: accessKey
secretKeySecret:
name: s3-credenciales
key: secretKey
kubectl apply -f artifact-repo.yaml
Sustituye your_bucket y your_s3_endpoint (por ejemplo s3.example.com, sin https://). Con esto, un template puede declarar outputs.artifacts con la ruta de un archivo, y otro paso puede recibirlo en inputs.artifacts, igual que con los parámetros del paso 5.
Solución de problemas
workflowtaskresults.argoproj.io is forbidden: el workflow se ejecuta con una cuenta de servicio sin el Role executor. Comprueba que spec.serviceAccountName es argo-workflow o concede ese Role a la cuenta que uses.
El workflow se queda en Pending: normalmente el pod no se puede programar por falta de recursos o por una cuota. Revisa los eventos:
kubectl -n argo get events --sort-by=.lastTimestamp | tail -n 20
kubectl -n argo describe resourcequota
Ver y relanzar workflows fallidos:
argo list -n argo --status Failed
argo get -n argo nombre-del-workflow
argo retry -n argo nombre-del-workflow
argo get muestra en la columna MESSAGE el motivo del fallo de cada paso, y argo retry vuelve a ejecutar solo los pasos que fallaron.
Conclusión
Has instalado Argo Workflows y su CLI, configurado una cuenta de servicio con los permisos mínimos y creado workflows secuenciales, un DAG con reintentos, una plantilla reutilizable y una ejecución programada. Como siguientes pasos, puedes configurar SSO para la interfaz web, añadir Argo Events para lanzar workflows a partir de webhooks o mensajes, o combinarlo con Argo CD para que los workflows y plantillas se desplieguen desde Git.
