Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le esecuzioni di aggiornamento a fasi di Azure Kubernetes Fleet Manager offrono un approccio controllato alla distribuzione di carichi di lavoro in più cluster membri usando un processo di staging per fase. Per ridurre al minimo i rischi, questo approccio viene distribuito in sequenza nei cluster di destinazione, con tempi di attesa facoltativi e controlli di approvazione tra fasi.
Questo articolo illustra come creare ed eseguire esecuzioni di aggiornamenti a fasi per distribuire i carichi di lavoro progressivamente ed eseguire il rollback alle versioni precedenti quando necessario.
Note
Azure Kubernetes Fleet Manager offre due approcci per gli aggiornamenti a fasi:
-
A livello di cluster: usare
ClusterStagedUpdateRunconClusterResourcePlacementper gli amministratori di fleet che gestiscono le modifiche a livello di infrastruttura -
Con Ambito spazio dei nomi: usare
StagedUpdateRunconResourcePlacementper i team delle applicazioni che gestiscono le distribuzioni all'interno dei rispettivi spazi dei nomi specifici
Gli esempi in questo articolo illustrano entrambi gli approcci usando le schede. Scegliere la scheda corrispondente all'ambito di distribuzione.
Prerequisites
È necessario un account Azure con una sottoscrizione attiva. Creare un account gratuito.
Per comprendere i concetti e la terminologia usati in questo articolo, leggere la panoramica concettuale delle strategie di implementazione a fasi.
Per completare questo articolo, è necessaria l'interfaccia della riga di comando di Azure versione 2.58.0 o successiva. Per eseguire l'installazione o l'aggiornamento, vedere Installare l'interfaccia della riga di comando di Azure.
Se l'interfaccia della riga di comando di Kubernetes (kubectl) non è ancora disponibile, è possibile installarla usando questo comando:
az aks install-cliÈ necessaria l'estensione dell'interfaccia della riga di comando di Azure
fleet. È possibile installarlo eseguendo il comando seguente:az extension add --name fleetEseguire il comando
az extension updateper effettuare l'aggiornamento alla versione più recente dell'estensione:az extension update --name fleet
Configurare l'ambiente demo
Questa demo viene eseguita in un Fleet Manager con un cluster hub e tre cluster membri. Se non è disponibile, seguire la guida introduttiva per creare un Fleet Manager con un cluster hub. Aggiungere quindi i cluster del servizio Azure Kubernetes come membri.
Questa esercitazione illustra le esecuzioni degli aggiornamenti a fasi usando un ambiente demo fleet con tre cluster membri con le etichette seguenti:
| nome del cluster | labels |
|---|---|
| member1 | environment=canary, order=2 |
| member2 | environment=staging |
| member3 | environment=canary, order=1 |
Per raggruppare i cluster in base all'ambiente e controllare l'ordine di distribuzione all'interno di ogni fase, queste etichette consentono di creare fasi.
Preparare i carichi di lavoro per il posizionamento
Pubblicare carichi di lavoro nel cluster hub in modo che possano essere inseriti nei cluster membri.
Creare uno spazio dei nomi e un file configmap per il carico di lavoro nel cluster hub:
kubectl create ns test-namespace
kubectl create cm test-cm --from-literal=key=value1 -n test-namespace
Per distribuire le risorse, creare un clusterResourcePlacement:
Note
spec.strategy.type è impostato su External per consentire l'implementazione attivata con ClusterStagedUpdateRun.
apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterResourcePlacement
metadata:
name: example-placement
spec:
resourceSelectors:
- group: ""
kind: Namespace
name: test-namespace
version: v1
policy:
placementType: PickAll
strategy:
type: External
Tutti e tre i cluster devono essere pianificati perché vengono usati i criteri PickAll, ma non è necessario distribuire risorse nei cluster membri perché non è stato ancora creato un oggetto ClusterStagedUpdateRun.
Verificare che il posizionamento sia pianificato:
kubectl get crp example-placement
L'output dovrebbe essere simile all'esempio seguente:
NAME GEN SCHEDULED SCHEDULED-GEN AVAILABLE AVAILABLE-GEN AGE
example-placement 1 True 1 51s
Gestire gli snapshot delle risorse
Fleet Manager crea snapshot delle risorse quando le risorse cambiano. Ogni snapshot ha un indice univoco che è possibile usare per fare riferimento a versioni specifiche delle risorse.
Tip
Per altre informazioni sugli snapshot delle risorse e sul relativo funzionamento, vedere Informazioni sugli snapshot delle risorse.
Controllare gli snapshot delle risorse correnti
Per controllare gli snapshot delle risorse correnti:
kubectl get clusterresourcesnapshots --show-labels
L'output dovrebbe essere simile all'esempio seguente:
NAME GEN AGE LABELS
example-placement-0-snapshot 1 60s kubernetes-fleet.io/is-latest-snapshot=true,kubernetes-fleet.io/parent-CRP=example-placement,kubernetes-fleet.io/resource-index=0
È disponibile una sola versione dello snapshot. È l'ultima versione (kubernetes-fleet.io/is-latest-snapshot=true) e contiene l'indice delle risorse 0 (kubernetes-fleet.io/resource-index=0).
Creare un nuovo snapshot della risorsa
Modificare ora la mappa di configurazione con un nuovo valore:
kubectl edit cm test-cm -n test-namespace
Aggiornare il valore da value1 a value2:
kubectl get configmap test-cm -n test-namespace -o yaml
L'output dovrebbe essere simile all'esempio seguente:
apiVersion: v1
data:
key: value2 # value updated here, old value: value1
kind: ConfigMap
metadata:
creationTimestamp: ...
name: test-cm
namespace: test-namespace
resourceVersion: ...
uid: ...
Verranno ora visualizzate due versioni degli snapshot delle risorse con indice 0 e 1 rispettivamente:
kubectl get clusterresourcesnapshots --show-labels
L'output dovrebbe essere simile all'esempio seguente:
NAME GEN AGE LABELS
example-placement-0-snapshot 1 2m6s kubernetes-fleet.io/is-latest-snapshot=false,kubernetes-fleet.io/parent-CRP=example-placement,kubernetes-fleet.io/resource-index=0
example-placement-1-snapshot 1 10s kubernetes-fleet.io/is-latest-snapshot=true,kubernetes-fleet.io/parent-CRP=example-placement,kubernetes-fleet.io/resource-index=1
L'etichetta più recente è impostata su example-placement-1-snapshot, che contiene i dati configmap più recenti:
kubectl get clusterresourcesnapshots example-placement-1-snapshot -o yaml
L'output dovrebbe essere simile all'esempio seguente:
apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourceSnapshot
metadata:
annotations:
kubernetes-fleet.io/number-of-enveloped-object: "0"
kubernetes-fleet.io/number-of-resource-snapshots: "1"
kubernetes-fleet.io/resource-hash: 10dd7a3d1e5f9849afe956cfbac080a60671ad771e9bda7dd34415f867c75648
creationTimestamp: "2025-07-22T21:26:54Z"
generation: 1
labels:
kubernetes-fleet.io/is-latest-snapshot: "true"
kubernetes-fleet.io/parent-CRP: example-placement
kubernetes-fleet.io/resource-index: "1"
name: example-placement-1-snapshot
ownerReferences:
- apiVersion: placement.kubernetes-fleet.io/v1beta1
blockOwnerDeletion: true
controller: true
kind: ClusterResourcePlacement
name: example-placement
uid: e7d59513-b3b6-4904-864a-c70678fd6f65
resourceVersion: "19994"
uid: 79ca0bdc-0b0a-4c40-b136-7f701e85cdb6
spec:
selectedResources:
- apiVersion: v1
kind: Namespace
metadata:
labels:
kubernetes.io/metadata.name: test-namespace
name: test-namespace
spec:
finalizers:
- kubernetes
- apiVersion: v1
data:
key: value2 # latest value: value2, old value: value1
kind: ConfigMap
metadata:
name: test-cm
namespace: test-namespace
Distribuire una strategia di aggiornamento a fasi
Un ClusterStagedUpdateStrategy oggetto definisce il modello di orchestrazione che raggruppa i cluster in fasi e specifica la sequenza di implementazione. Seleziona i cluster membri in base alle etichette. Per la dimostrazione, ne viene creata una con due fasi, staging e canary:
apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateStrategy
metadata:
name: example-strategy
spec:
stages:
- name: staging
labelSelector:
matchLabels:
environment: staging
afterStageTasks:
- type: TimedWait
waitTime: 1m
- name: canary
labelSelector:
matchLabels:
environment: canary
sortingLabelKey: order
afterStageTasks:
- type: Approval
Distribuire un'esecuzione di aggiornamento a fasi per implementare la modifica più recente
Un ClusterStagedUpdateRun esegue il rollout di un ClusterResourcePlacement in seguito a un ClusterStagedUpdateStrategy. Per attivare l'esecuzione dell'aggiornamento a fasi per ClusterResourcePlacement (CRP), viene creato un oggetto ClusterStagedUpdateRun che specifica il nome CRP, il nome della strategia updateRun e l'indice dello snapshot delle risorse più recente ("1"):
apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
name: example-run
spec:
placementName: example-placement
resourceSnapshotIndex: "1"
stagedRolloutStrategyName: example-strategy
L'esecuzione dell'aggiornamento a fasi viene inizializzata ed eseguita:
kubectl get csur example-run
L'output dovrebbe essere simile all'esempio seguente:
NAME PLACEMENT RESOURCE-SNAPSHOT-INDEX POLICY-SNAPSHOT-INDEX INITIALIZED SUCCEEDED AGE
example-run example-placement 1 0 True 7s
Un'analisi più dettagliata dello stato dopo la scadenza di un minuto TimedWait :
kubectl get csur example-run -o yaml
L'output dovrebbe essere simile all'esempio seguente:
apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
...
name: example-run
...
spec:
placementName: example-placement
resourceSnapshotIndex: "1"
stagedRolloutStrategyName: example-strategy
status:
conditions:
- lastTransitionTime: "2025-07-22T21:28:08Z"
message: ClusterStagedUpdateRun initialized successfully
observedGeneration: 1
reason: UpdateRunInitializedSuccessfully
status: "True" # the updateRun is initialized successfully
type: Initialized
- lastTransitionTime: "2025-07-22T21:29:53Z"
message: The updateRun is waiting for after-stage tasks in stage canary to complete
observedGeneration: 1
reason: UpdateRunWaiting
status: "False" # the updateRun is still progressing and waiting for approval
type: Progressing
deletionStageStatus:
clusters: [] # no clusters need to be cleaned up
stageName: kubernetes-fleet.io/deleteStage
policyObservedClusterCount: 3 # number of clusters to be updated
policySnapshotIndexUsed: "0"
stagedUpdateStrategySnapshot: # snapshot of the strategy used for this update run
stages:
- afterStageTasks:
- type: TimedWait
waitTime: 1m0s
labelSelector:
matchLabels:
environment: staging
name: staging
- afterStageTasks:
- type: Approval
labelSelector:
matchLabels:
environment: canary
name: canary
sortingLabelKey: order
stagesStatus: # detailed status for each stage
- afterStageTaskStatus:
- conditions:
- lastTransitionTime: "2025-07-22T21:29:23Z"
message: Wait time elapsed
observedGeneration: 1
reason: AfterStageTaskWaitTimeElapsed
status: "True" # the wait after-stage task has completed
type: WaitTimeElapsed
type: TimedWait
clusters:
- clusterName: member2 # stage staging contains member2 cluster only
conditions:
- lastTransitionTime: "2025-07-22T21:28:08Z"
message: Cluster update started
observedGeneration: 1
reason: ClusterUpdatingStarted
status: "True"
type: Started
- lastTransitionTime: "2025-07-22T21:28:23Z"
message: Cluster update completed successfully
observedGeneration: 1
reason: ClusterUpdatingSucceeded
status: "True" # member2 is updated successfully
type: Succeeded
conditions:
- lastTransitionTime: "2025-07-22T21:28:23Z"
message: All clusters in the stage are updated and after-stage tasks are completed
observedGeneration: 1
reason: StageUpdatingSucceeded
status: "False"
type: Progressing
- lastTransitionTime: "2025-07-22T21:29:23Z"
message: Stage update completed successfully
observedGeneration: 1
reason: StageUpdatingSucceeded
status: "True" # stage staging has completed successfully
type: Succeeded
endTime: "2025-07-22T21:29:23Z"
stageName: staging
startTime: "2025-07-22T21:28:08Z"
- afterStageTaskStatus:
- approvalRequestName: example-run-canary # ClusterApprovalRequest name for this stage
conditions:
- lastTransitionTime: "2025-07-22T21:29:53Z"
message: ClusterApprovalRequest is created
observedGeneration: 1
reason: AfterStageTaskApprovalRequestCreated
status: "True"
type: ApprovalRequestCreated
type: Approval
clusters:
- clusterName: member3 # according to the labelSelector and sortingLabelKey, member3 is selected first in this stage
conditions:
- lastTransitionTime: "2025-07-22T21:29:23Z"
message: Cluster update started
observedGeneration: 1
reason: ClusterUpdatingStarted
status: "True"
type: Started
- lastTransitionTime: "2025-07-22T21:29:38Z"
message: Cluster update completed successfully
observedGeneration: 1
reason: ClusterUpdatingSucceeded
status: "True" # member3 update is completed
type: Succeeded
- clusterName: member1 # member1 is selected after member3 because of order=2 label
conditions:
- lastTransitionTime: "2025-07-22T21:29:38Z"
message: Cluster update started
observedGeneration: 1
reason: ClusterUpdatingStarted
status: "True"
type: Started
- lastTransitionTime: "2025-07-22T21:29:53Z"
message: Cluster update completed successfully
observedGeneration: 1
reason: ClusterUpdatingSucceeded
status: "True" # member1 update is completed
type: Succeeded
conditions:
- lastTransitionTime: "2025-07-22T21:29:53Z"
message: All clusters in the stage are updated, waiting for after-stage tasks
to complete
observedGeneration: 1
reason: StageUpdatingWaiting
status: "False" # stage canary is waiting for approval task completion
type: Progressing
stageName: canary
startTime: "2025-07-22T21:29:23Z"
È possibile notare che il periodo TimedWait per la fase di staging scade e si nota anche che è stato creato l'oggetto per l'attività ClusterApprovalRequest di approvazione nella fase canary. Possiamo controllare il ClusterApprovalRequest generato e verificare che nessuno lo abbia ancora approvato.
kubectl get clusterapprovalrequest
L'output dovrebbe essere simile all'esempio seguente:
NAME UPDATE-RUN STAGE APPROVED APPROVALACCEPTED AGE
example-run-canary example-run canary 2m39s
Approvare l'esecuzione dell'aggiornamento a fasi
È possibile approvare ClusterApprovalRequest creando un file di patch JSON e applicandolo:
cat << EOF > approval.json
"status": {
"conditions": [
{
"lastTransitionTime": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"message": "lgtm",
"observedGeneration": 1,
"reason": "testPassed",
"status": "True",
"type": "Approved"
}
]
}
EOF
Inviare una richiesta di patch per approvare usando il file JSON creato.
kubectl patch clusterapprovalrequests example-run-canary --type='merge' --subresource=status --patch-file approval.json
Verificare quindi di aver approvato la richiesta:
kubectl get clusterapprovalrequest
L'output dovrebbe essere simile all'esempio seguente:
NAME UPDATE-RUN STAGE APPROVED APPROVALACCEPTED AGE
example-run-canary example-run canary True True 3m35s
Ora è possibile procedere e completare ClusterStagedUpdateRun:
kubectl get csur example-run
L'output dovrebbe essere simile all'esempio seguente:
NAME PLACEMENT RESOURCE-SNAPSHOT-INDEX POLICY-SNAPSHOT-INDEX INITIALIZED SUCCEEDED AGE
example-run example-placement 1 0 True True 5m28s
Verificare il completamento dell'implementazione
ClusterResourcePlacement mostra anche l'implementazione completata e le risorse sono disponibili in tutti i cluster membri:
kubectl get crp example-placement
L'output dovrebbe essere simile all'esempio seguente:
NAME GEN SCHEDULED SCHEDULED-GEN AVAILABLE AVAILABLE-GEN AGE
example-placement 1 True 1 True 1 8m55s
Il test-cm configmap deve essere distribuito in tutti e tre i cluster membri, con i dati più recenti:
apiVersion: v1
data:
key: value2
kind: ConfigMap
metadata:
...
name: test-cm
namespace: test-namespace
...
Distribuire un secondo clusterStagedUpdateRun per eseguire il rollback a una versione precedente
Implementare una seconda esecuzione di aggiornamento in fasi per effettuare il rollback
Si supponga che l'amministratore del carico di lavoro voglia eseguire il rollback della modifica della mappa di configurazione, ripristinando il valore value2 in value1. Anziché aggiornare manualmente la configmap dall'hub, è possibile creare un nuovo ClusterStagedUpdateRun utilizzando un indice di snapshot della risorsa precedente, nel nostro contesto "0", e riutilizzare la stessa strategia:
apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
name: example-run-2
spec:
placementName: example-placement
resourceSnapshotIndex: "0"
stagedRolloutStrategyName: example-strategy
Esaminiamo il nuovo ClusterStagedUpdateRun:
kubectl get csur
L'output dovrebbe essere simile all'esempio seguente:
NAME PLACEMENT RESOURCE-SNAPSHOT-INDEX POLICY-SNAPSHOT-INDEX INITIALIZED SUCCEEDED AGE
example-run example-placement 1 0 True True 13m
example-run-2 example-placement 0 0 True 9s
Al termine di un minutoTimedWait, verrà visualizzato l'oggetto ClusterApprovalRequest creato per il nuovo ClusterStagedUpdateRun.
kubectl get clusterapprovalrequest
L'output dovrebbe essere simile all'esempio seguente:
NAME UPDATE-RUN STAGE APPROVED APPROVALACCEPTED AGE
example-run-2-canary example-run-2 canary 75s
example-run-canary example-run canary True True 14m
Per approvare il nuovo ClusterApprovalRequest oggetto, riutilizzare lo stesso approval.json file per applicare patch:
kubectl patch clusterapprovalrequests example-run-2-canary --type='merge' --subresource=status --patch-file approval.json
Verificare se il nuovo oggetto è approvato:
kubectl get clusterapprovalrequest
L'output dovrebbe essere simile all'esempio seguente:
NAME UPDATE-RUN STAGE APPROVED APPROVALACCEPTED AGE
example-run-2-canary example-run-2 canary True True 2m7s
example-run-canary example-run canary True True 15m
Il file configmap test-cm deve ora essere distribuito in tutti e tre i cluster membri, con i dati ripristinati in value1:
apiVersion: v1
data:
key: value1
kind: ConfigMap
metadata:
...
name: test-cm
namespace: test-namespace
...
Differenze principali tra approcci
| Aspetto | Con ambito cluster | Con ambito spazio dei nomi |
|---|---|---|
| Risorsa strategia | ClusterStagedUpdateStrategy |
StagedUpdateStrategy |
| Aggiornare la risorsa di esecuzione | ClusterStagedUpdateRun |
StagedUpdateRun |
| Posizionamento di destinazione | ClusterResourcePlacement |
ResourcePlacement |
| Risorsa di approvazione |
ClusterApprovalRequest (nome breve: careq) |
ApprovalRequest (nome breve: areq) |
| Risorsa Snapshot | ClusterResourceSnapshot |
ResourceSnapshot |
| Scope | A livello di cluster | Vincolato allo spazio dei nomi |
| Caso d'uso | Implementazioni dell'infrastruttura | Distribuzioni di applicazioni |
| Autorizzazioni | Livello di amministratore del cluster | Livello del namespace |
Pulire le risorse
Al termine di questa esercitazione, è possibile pulire le risorse create:
kubectl delete csur example-run example-run-2
kubectl delete csus example-strategy
kubectl delete crp example-placement
kubectl delete namespace test-namespace
Passaggi successivi
In questo articolo si è appreso come usare le esecuzioni di aggiornamento a fasi per orchestrare le implementazioni tra cluster membri. Sono state create strategie di aggiornamento a fasi sia per le distribuzioni con ambito cluster che per le distribuzioni con ambito spazio dei nomi, sono state eseguite implementazioni progressive ed è stato eseguito il rollback alle versioni precedenti.
Per altre informazioni sulle esecuzioni degli aggiornamenti a fasi e sui concetti correlati, vedere le risorse seguenti: