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
- Un cluster GKE con la Gateway API abilitata.
- Argo Rollouts installato nel cluster.
- Il plugin kubectl installato per gestire e visualizzare i rollout dalla riga di comando.
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.