Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Progressive Delivery a otro nivel con Gateway API y Argo Rollouts

By Chimbu ChinnaduraiOct 2, 20246 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

En el entorno actual de entrega de software, donde todo avanza a gran velocidad, la innovación debe ir de la mano de la confiabilidad. La progressive delivery permite a los equipos liberar funcionalidades de forma segura, gradual y controlada. En un entorno tan dinámico como Kubernetes, la progressive delivery cumple un rol clave: mantener la estabilidad del servicio sin frenar la innovación continua.

Si ya conoces herramientas como Argo Rollouts, sabes lo bien que gestionan este tipo de despliegues por etapas. Argo Rollouts puede apoyarse opcionalmente en un proveedor de tráfico para repartir el tráfico entre pods de forma gradual y con control total.

Hasta hace poco, integrar un nuevo proveedor de tráfico en Argo Rollouts exigía soporte de código ad-hoc. Sin embargo, dos avances recientes han dejado atrás ese proceso.

  • El primero es el soporte de traffic plugins en Argo Rollouts a partir de la versión 1.5.
  • El segundo es la nueva Gateway API de Kubernetes, que ofrece un control granular del enrutamiento de tráfico y abre nuevas posibilidades para service mesh, ingress y mucho más.

Con la adopción de la Gateway API en Argo Rollouts, la integración se vuelve mucho más sencilla: cualquier proveedor de tráfico que implemente la Gateway API queda soportado de forma automática por Argo Rollouts. En el sitio de la Gateway API encontrarás una lista de las implementaciones conocidas.

En este blog vamos a ver cómo usar la Gateway API junto con las funcionalidades de Argo Rollouts en Google Kubernetes Engine para hacer progressive delivery.

Requisitos previos

Limitaciones

  • El plugin de Gateway API para Argo Rollouts no es compatible con la estrategia de despliegue blue/green.
  • Esta funcionalidad solo está disponible para application load balancers basados en envoy en GCP. Los Classic Application Load Balancers y los Network Load Balancers no la soportan de forma directa.

Desplegar el plugin de Gateway API para Argo Rollouts

  • Aplica el siguiente manifest en el cluster para crear un configmap. Revisa la página de Releases para conocer las versiones disponibles y cambia la arquitectura si fuera necesario.
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: argo-rollouts-config # must be so name
  namespace: argo-rollouts # must be in this namespace
data:
  trafficRouterPlugins: |-
    - name: "argoproj-labs/gatewayAPI"
      location: "https://github.com/argoproj-labs/rollouts-plugin-trafficrouter-gatewayapi/releases/download/v0.3.0/gateway-api-plugin-linux-amd64"
EOF
  • Reinicia el pod de Argo Rollouts y el plugin se descargará durante el arranque.

Ejemplo de log del pod donde se ve la instalación del plugin

Desplegar el recurso Gateway

  • Un recurso Gateway representa un data plane que enruta tráfico en Kubernetes. Según la GatewayClass que use, un gateway puede representar distintos tipos de balanceo de carga y enrutamiento.
  • Aplica el siguiente manifest para crear un Application Load Balancer global externo.
cat <<EOF | kubectl apply -f -
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: argo-rollouts-demo-external-http
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
  - name: http
    protocol: HTTP
    port: 80
EOF

Ejemplo de recurso Gateway API

Permitir que Argo Rollouts edite los HTTP Routes

  • Aplica el siguiente manifest para que Argo Rollouts pueda editar los recursos HTTP Routes.
cat <<EOF | kubectl apply -f -
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: gateway-controller-role
  namespace: argo-rollouts
rules:
  - apiGroups:
      - gateway.networking.k8s.io
    resources:
      - httproutes
    verbs:
      - get
      - patch
      - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gateway-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: gateway-controller-role
subjects:
  - namespace: argo-rollouts
    kind: ServiceAccount
    name: argo-rollouts
EOF

Crear el HTTPRoute y los servicios de Kubernetes

  • Crea un HTTPRoute de ejemplo y conéctalo al recurso Gateway que ya creaste.
cat <<EOF | kubectl apply -f -
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: argo-rollouts-demo-http-route
spec:
  parentRefs:
  - kind: Gateway
    name: argo-rollouts-demo-external-http
  hostnames:
  - "argo-rollouts-demo.example.com"
  rules:
    - backendRefs:
        - name: argo-rollouts-demo-stable-service
          port: 80
        - name: argo-rollouts-demo-canary-service
          port: 80
EOF
  • Crea el servicio canary.
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: Service
metadata:
  name: argo-rollouts-demo-canary-service
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: argo-rollouts-demo
EOF
  • Crea el servicio stable.
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: Service
metadata:
  name: argo-rollouts-demo-stable-service
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: argo-rollouts-demo
EOF

Load balancer externo con la configuración de rutas

Crear un Canary Rollout

  • Un rollout es un custom resource de Kubernetes equivalente a un objeto Deployment. Está pensado para reemplazar al Deployment cuando se necesitan funcionalidades de despliegue más avanzadas o de progressive delivery.
  • Puedes crear un rollout nuevo o vincular deployments existentes dentro de un recurso rollout. El plugin de Gateway API para Argo Rollouts solo soporta el despliegue canary. Consulta la Rollout Specification para ver las opciones disponibles.
  • Aplica el siguiente manifest en el cluster, espera a que la aplicación esté lista y luego abre la IP del Gateway en el navegador.

cat <<EOF | kubectl apply -f -
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: argo-rollouts-demo
  namespace: default
spec:
  replicas: 5
  strategy:
    canary:
      canaryService: argo-rollouts-demo-canary-service # canary service
      stableService: argo-rollouts-demo-stable-service # stable service
      trafficRouting:
        plugins:
          argoproj-labs/gatewayAPI:
            httpRoute: argo-rollouts-demo-http-route # httproute
            namespace: default
      steps:
      - setWeight: 50
      - pause: {}
      - setWeight: 100
      - pause: {}
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: argo-rollouts-demo
  template:
    metadata:
      labels:
        app: argo-rollouts-demo
    spec:
      containers:
        - name: argo-rollouts-demo
          image: argoproj/rollouts-demo:blue
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            requests:
              memory: 32Mi
              cpu: 5m
EOF
  • Describe el recurso httproute y revisa los logs del pod de Argo Rollouts para confirmar que el despliegue se realizó con éxito. Argo Rollouts modificará el valor de weight en el httproute, que luego se sincroniza con el load balancer.

Configuración inicial de enrutamiento del load balancer

Respuesta de la aplicación de ejemplo. Se usó el plugin ModHeader de Chrome para personalizar el header Host

Ejecutar un despliegue Canary

  • Ejecuta el siguiente comando para cambiar la imagen y disparar un nuevo proceso de rollout.
kubectl argo rollouts set image argo-rollouts-demo argo-rollouts-demo=argoproj/rollouts-demo:yellow
  • Argo Rollouts creará la cantidad de pods necesaria para igualar el porcentaje de tráfico. En este caso, levantará 3 pods nuevos para alcanzar el 50% de tráfico hacia la nueva versión.
  • Ejecuta el siguiente comando para monitorear el progreso del rollout. El plugin de kubectl de Argo Rollouts puede levantar un UI Dashboard local para visualizar tus rollouts.
kubectl argo rollouts get rollout rollouts-demo

Estado inicial del rollout

  • Inspecciona el HttpRoute y verifica que Argo Rollouts haya cambiado los pesos de los servicios backend.

Ejemplo de HTTPRoute

Reglas de enrutamiento del load balancer

  • En este punto, cada versión debería recibir el 50% de las solicitudes. Puedes comprobarlo desde tu navegador.

Rollout canary inicial

  • Promueve el rollout con el siguiente comando para aumentar el porcentaje de tráfico hacia la nueva versión. Revisa la configuración del HttpRoute y de las reglas de enrutamiento del load balancer.
kubectl argo rollouts promote rollouts-demo
  • Ejecuta el comando promote una vez más para completar el rollout y espera a que se destruyan los pods de la versión anterior. Si vuelves a cambiar la imagen del Rollout, el proceso comenzará de nuevo.

Estado del rollout una vez finalizado

Reglas de enrutamiento del load balancer ya actualizadas

Rollout canary completado

En resumen, la integración de la Gateway API con Argo Rollouts potencia de forma notable las capacidades de progressive delivery en Kubernetes. Esta combinación simplifica el enrutamiento de tráfico y facilita la ejecución de despliegues canary, además de permitir gestionar el tráfico entre versiones con precisión y control.

Espero que este blog te haya resultado útil. Si quieres saber más o te interesan nuestros servicios, no dudes en escribirnos. Puedes contactarnos aquí.