(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo hacer un despliegue canario en Kubernetes con GitHub Actions: paso a paso

João Barros 10 de September de 2026 4 min de lectura

Este tutorial muestra cómo realizar un despliegue canario en Kubernetes con GitHub Actions para implementar nuevas versiones de forma gradual y reducir el riesgo. Explico por qué el despliegue canario es útil; a continuación detallo un flujo concreto con manifiestos de Kubernetes, GitHub Actions y verificación simple.

Requisitos previos

  • Cuenta en GitHub y repositorio con el código de la aplicación (por ejemplo: imagen Docker pública o registrada).
  • Cluster Kubernetes accesible (minikube, kind o cluster en la cloud) con el kubectl configurado.
  • Runner de GitHub Actions con permisos para el kubectl (use secrets KUBECONFIG o un token).
  • Conocimientos básicos de Kubernetes: Deployment, Service y labels.

Paso 1: Preparar manifiestos de Kubernetes para soporte de canario

Cree un Deployment principal y prepare un Deployment separado para el canario. La idea es tener dos Deployments (app-primary, app-canary) y un Service que balancee por label. Así podemos controlar el tráfico hacia el canario cambiando réplicas o weights en el Ingress/Service.

# deployment-primary.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-primary
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      role: primary
  template:
    metadata:
      labels:
        app: myapp
        role: primary
    spec:
      containers:
      - name: myapp
        image: myrepo/myapp:stable
        ports:
        - containerPort: 80

# deployment-canary.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      role: canary
  template:
    metadata:
      labels:
        app: myapp
        role: canary
    spec:
      containers:
      - name: myapp
        image: myrepo/myapp:canary
        ports:
        - containerPort: 80

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Paso 2: Configurar GitHub Actions para crear imagen y hacer deploy canario

Creе un workflow que construya la imagen canary, haga push al registry y aplique los manifiestos al cluster. Use un job que actualice solo el Deployment canary a la nueva tag; así el primary mantiene la versión estable.

# .github/workflows/canary-deploy.yaml
name: Canary Deploy
on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    - name: Build and push image
      uses: docker/build-push-action@v4
      with:
        push: true
        tags: myrepo/myapp:${{ github.sha }}
        # configure registry credentials via secrets
    - name: Configure kubectl
      run: |
        echo "$KUBECONFIG" > kubeconfig
        export KUBECONFIG=$PWD/kubeconfig
      env:
        KUBECONFIG: ${{ secrets.KUBECONFIG }}
    - name: Update canary deployment image
      run: |
        kubectl set image deployment/app-canary myapp=myrepo/myapp:${{ github.sha }}
        kubectl rollout status deployment/app-canary --timeout=60s

Paso 3: Aumentar gradualmente el tráfico hacia el canario

Hay varias formas de aumentar el tráfico: aumentar las réplicas del canario, usar Ingress/Service con weights (por ejemplo: Istio, Traefik) o manipular selectors. Aquí mostramos la forma simple: aumentar las réplicas del canario y, más tarde, reducir las del primary.

# scale-canary.sh  (ejecutar vía GitHub Action o manualmente)
kubectl scale deployment/app-canary --replicas=2
# tras la verificación
kubectl scale deployment/app-primary --replicas=2
# finalmente promover el canario a primary cambiando imágenes y restaurando réplicas
kubectl set image deployment/app-primary myapp=myrepo/myapp:${CANARY_TAG}
kubectl scale deployment/app-canary --replicas=0
kubectl scale deployment/app-primary --replicas=3

Paso 4: Monitorización y rollback automático

Configure health checks liveness/readiness y use un script simple para comprobar métricas (errores, latencia) o el estado de readiness. En el ejemplo abajo, un paso del workflow verifica endpoints y realiza rollback si la tasa de error aumenta.

# ejemplo simplificado de verificación vía curl
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://myapp-svc/health)
if [ "$STATUS" != "200" ]; then
  kubectl set image deployment/app-canary myapp=myrepo/myapp:stable
  kubectl rollout status deployment/app-canary --timeout=60s
  exit 1
fi

Verificar el resultado

Confirme que el canario está ejecutando la nueva imagen y sirviendo tráfico solo a una parte de los usuarios. Use kubectl para inspeccionar:

kubectl get deployments
kubectl get pods -l role=canary -o wide
kubectl describe deployment app-canary
kubectl logs deployment/app-canary --tail=50

Si usa un Ingress o Service con weight, verifique métricas en el controlador de Ingress o en las herramientas de observabilidad (Prometheus/Grafana). Pruebe endpoints y confirme que el rollback funciona simulando fallos.

Conclusión

El despliegue canario en Kubernetes con GitHub Actions permite reducir el riesgo de releases, controlando gradualmente el tráfico. Próximos pasos: integrar Istio/Linkerd para traffic shifting por weight, automatizar métricas con Prometheus y crear gates automáticos en el workflow. Consejo: empiece con réplicas y health checks simples antes de introducir un service mesh — ¿cuál es la mayor preocupación que desea mitigar con canarios?