--- title: "Cómo instalar Argo Workflows y orquestar jobs en Kubernetes" description: "Instala Argo Workflows en Kubernetes, configura sus permisos y crea workflows con pasos, DAG, plantillas reutilizables y tareas programadas con CronWorkflow." category: "Ingeniería de Plataformas" language: es source: https://cubepath.com/es/docs/ingeniería-de-plataformas/argo-workflows-orquestacion-de-jobs-kubernetes updated: 2026-09-25 --- # Cómo instalar Argo Workflows y orquestar jobs en Kubernetes 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. - `kubectl` configurado con permisos de administrador del clúster, en Ubuntu 24.04 LTS o similar. - `curl` instalado. ## 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: ```bash ARGO_VERSION=$(curl -fsSL https://api.github.com/repos/argoproj/argo-workflows/releases/latest | grep -Po '"tag_name": "\K[^"]+') echo "$ARGO_VERSION" ``` ```output 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: ```bash 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: ```bash kubectl -n argo rollout status deployment/workflow-controller kubectl -n argo rollout status deployment/argo-server kubectl -n argo get pods ``` ```output 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: ```bash 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 ``` ```output 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: ```bash nano argo-rbac.yaml ``` ```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 ``` ```bash 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: ```bash nano hola.yaml ``` ```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`: ```bash argo submit -n argo --watch hola.yaml -p mensaje="Mi primer workflow" ``` ```output 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: ```bash argo logs -n argo @latest ``` ```output 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: ```bash nano pasos.yaml ``` ```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: ```bash argo submit -n argo --watch pasos.yaml argo logs -n argo @latest ``` ```output 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: ```bash nano dag.yaml ``` ```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: ```bash argo submit -n argo --watch dag.yaml ``` ```output 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: ```bash nano plantilla-informe.yaml ``` ```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: ```bash argo template create -n argo plantilla-informe.yaml argo submit -n argo --from workflowtemplate/informe -p entorno=produccion --watch ``` ```bash argo template list -n argo ``` ```output 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: ```bash nano cron-informe.yaml ``` ```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. > Nota: el campo `schedules` (lista) existe desde Argo Workflows 3.6. En versiones anteriores se usa `schedule` con una sola expresión. Crea el CronWorkflow y, para probarlo sin esperar a la hora programada, lanza una ejecución manual: ```bash 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: ```bash 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: ```bash kubectl -n argo patch deployment argo-server --type=json \ -p='[{"op":"replace","path":"/spec/template/spec/containers/0/args","value":["server","--auth-mode=server"]}]' ``` > Advertencia: con `--auth-mode=server` cualquiera que llegue al puerto 2746 puede ver y lanzar workflows. En clústeres compartidos o de producción usa `client` o 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: ```bash kubectl -n argo create secret generic s3-credenciales \ --from-literal=accessKey=your_access_key \ --from-literal=secretKey=your_secret_key ``` ```bash nano artifact-repo.yaml ``` ```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 ``` ```bash 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: ```bash kubectl -n argo get events --sort-by=.lastTimestamp | tail -n 20 kubectl -n argo describe resourcequota ``` **Ver y relanzar workflows fallidos**: ```bash 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.