Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Progressive delivery senza compromessi con Gateway API e Argo Rollouts

By Chimbu ChinnaduraiOct 2, 20246 min read

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

Nel software delivery di oggi, dai ritmi sempre più serrati, innovazione e affidabilità devono procedere di pari passo. La progressive delivery permette ai team di rilasciare nuove funzionalità in modo sicuro, graduale e controllato. In un ambiente dinamico come Kubernetes assume un ruolo decisivo: garantisce la stabilità del servizio senza frenare l'innovazione continua.

Chi conosce strumenti come Argo Rollouts sa quanto siano efficaci nel gestire deployment a fasi. Argo Rollouts può appoggiarsi facoltativamente a un traffic provider per ripartire il traffico tra i pod in modo graduale e con pieno controllo.

Fino a poco tempo fa, integrare un nuovo traffic provider in Argo Rollouts richiedeva codice di supporto ad hoc. Due novità recenti hanno però reso superfluo questo passaggio.

  • La prima è il supporto ai plugin di traffic routing introdotto in Argo Rollouts a partire dalla versione 1.5.
  • La seconda è la nuova Gateway API di Kubernetes, che offre un controllo granulare sul routing del traffico e apre nuove possibilità per service mesh, ingress e altro ancora.

Con l'adozione della Gateway API in Argo Rollouts l'integrazione si semplifica notevolmente: qualsiasi traffic provider che implementi la Gateway API è automaticamente supportato da Argo Rollouts. Il sito della Gateway API riporta l'elenco delle implementazioni note.

In questo articolo vediamo come usare la Gateway API insieme alle funzionalità di Argo Rollouts su Google Kubernetes Engine per la progressive delivery.

Prerequisiti

Limitazioni

  • Il plugin Gateway API di Argo Rollouts non supporta la strategia di deployment blue/green.
  • La funzionalità è disponibile solo per gli Application Load Balancer basati su envoy in GCP. Classic Application Load Balancer e Network Load Balancer non la supportano in modo nativo.

Deploy del plugin Gateway API di Argo Rollouts

  • Applicare il manifest seguente al cluster per creare un configmap. Per le versioni disponibili consultare la pagina delle Release e modificare l'architettura se necessario.
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
  • Riavviare il pod di Argo Rollouts: il plugin verrà scaricato all'avvio.

Esempio di log del pod che mostra l'installazione del plugin

Deploy della risorsa Gateway

  • Una risorsa Gateway rappresenta un data plane che instrada il traffico in Kubernetes. A seconda della GatewayClass utilizzata, un gateway può rappresentare diversi tipi di load balancing e di routing.
  • Applicare il manifest seguente per creare un Application Load Balancer esterno globale.
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

Esempio di risorsa Gateway API

Consentire ad Argo Rollouts di modificare le HTTP Route

  • Applicare il manifest seguente per consentire ad Argo Rollouts di modificare le risorse 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

Creare HTTPRoute e i servizi Kubernetes

  • Creare una HTTPRoute di esempio e collegarla alla risorsa Gateway creata in precedenza.
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
  • Creare il servizio 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
  • Creare il servizio 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 esterno con la configurazione delle route

Creare un Canary Rollout

  • Un rollout è una custom resource di Kubernetes equivalente a un oggetto Deployment ed è pensato per sostituirlo negli scenari che richiedono funzionalità di deployment o di progressive delivery più avanzate.
  • È possibile creare un nuovo rollout oppure collegare deployment esistenti a una risorsa rollout. Il plugin Gateway API di Argo Rollouts supporta solo il canary deployment. Per le opzioni disponibili consultare la specifica del Rollout.
  • Applicare il manifest seguente al cluster, attendere che l'applicazione sia pronta e visitare l'IP del Gateway dal browser.

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
  • Eseguire il describe della risorsa httproute e controllare i log del pod di Argo Rollouts per confermare il buon esito del deployment. Argo Rollouts modificherà il valore del peso nella httproute, che verrà sincronizzato con il load balancer.

Configurazione iniziale del routing del load balancer

Risposta dell'applicazione di esempio. Per impostare un header Host personalizzato è stato usato il plugin ModHeader per Chrome

Eseguire un Canary Deployment

  • Eseguire il comando seguente per cambiare l'immagine e avviare un nuovo processo di rollout.
kubectl argo rollouts set image argo-rollouts-demo argo-rollouts-demo=argoproj/rollouts-demo:yellow
  • Argo Rollouts creerà i pod necessari a rispettare la percentuale di traffico impostata. In questo caso verranno avviati 3 nuovi pod per portare il 50% del traffico alla nuova versione.
  • Eseguire il comando seguente per monitorare l'avanzamento del rollout. Il plugin Kubectl di Argo Rollouts può esporre una dashboard UI locale per visualizzare i Rollout.
kubectl argo rollouts get rollout rollouts-demo

Esempio di stato iniziale del rollout

  • Ispezionare la HttpRoute e verificare che Argo Rollouts abbia aggiornato i pesi dei servizi di backend.

Esempio di HTTPRoute

Regole di routing del load balancer

  • A questo punto ogni versione dovrebbe ricevere il 50% delle richieste. È possibile verificarlo direttamente dal browser.

Canary rollout iniziale

  • Promuovere il rollout con il comando seguente per aumentare la quota di traffico verso la nuova versione. Verificare la HttpRoute e la configurazione delle regole di routing del load balancer.
kubectl argo rollouts promote rollouts-demo
  • Eseguire di nuovo il comando promote per completare il rollout e attendere l'eliminazione dei pod della vecchia versione. Modificando ancora una volta l'immagine del Rollout, il processo ripartirà da capo.

Stato del rollout al termine del processo

Regole di routing aggiornate del load balancer

Canary rollout completato

In sintesi, l'integrazione tra Gateway API e Argo Rollouts amplia in modo significativo le potenzialità della progressive delivery in Kubernetes. Una combinazione che semplifica il traffic routing e rende più immediato eseguire canary deployment e gestire il traffico tra versioni con precisione e controllo.

Mi auguro che questo articolo le sia stato utile. Se desidera approfondire o conoscere meglio i nostri servizi, non esiti a contattarci qui.