Dela via


Använd ClusterStagedUpdateRun för att samordna gradvisa distributioner över kluster

Azure Kubernetes Fleet Manager stegvisa uppdateringskörningar erbjuder ett kontrollerat tillvägagångssätt för att distribuera arbetsbelastningar över flera medlemskluster med hjälp av en stegvis process. Med den här metoden kan du minimera risken genom att distribuera till målkluster sekventiellt, med valfria väntetider och godkännandegrindar mellan faserna.

Den här artikeln visar hur du skapar och kör mellanlagrade uppdateringskörningar för att distribuera arbetsbelastningar progressivt och återställa till tidigare versioner när det behövs.

Prerequisites

  • Du behöver ett Azure-konto med en aktiv prenumeration. Skapa ett konto kostnadsfritt.

  • Om du vill förstå begreppen och terminologin som används i den här artikeln läser du den konceptuella översikten över stegvisa distributionsstrategier.

  • Du behöver Azure CLI version 2.58.0 eller senare installerat för att slutföra den här artikeln. Information om hur du installerar eller uppgraderar finns i Installera Azure CLI.

  • Om du inte redan har Kubernetes CLI (kubectl) kan du installera det med hjälp av det här kommandot:

    az aks install-cli
    
  • Du behöver Azure CLI-tillägget fleet . Du kan installera det genom att köra följande kommando:

    az extension add --name fleet
    

    az extension update Kör kommandot för att uppdatera till den senaste versionen av tillägget:

    az extension update --name fleet
    

Konfigurera demomiljön

Den här demonstrationen körs på en Fleet Manager med ett hubbkluster och tre medlemskluster. Om du inte har någon följer du snabbstarten för att skapa en Fleet Manager med ett hubbkluster. Anslut sedan Azure Kubernetes Service-kluster (AKS) som medlemmar.

Den här självstudien visar fasindelade uppdateringskörningar med hjälp av en demoflottsmiljö med tre medlemskluster som har följande etiketter:

klusternamn labels
member1 environment=canary, order=2
member2 environment=staging
member3 environment=canary, order=1

Med de här etiketterna kan vi skapa faser som grupperar kluster efter miljö och styra distributionsordningen i varje steg.

Förbereda arbetsflöden för utplacering

Publicera sedan arbetsbelastningar till hubbklustret så att de kan placeras i medlemskluster.

Skapa ett namnområde och en konfigurationskarta för arbetsbelastningen i hubbklustret:

kubectl create ns test-namespace
kubectl create cm test-cm --from-literal=key=value1 -n test-namespace

Om du vill distribuera resurserna skapar du ett ClusterResourcePlacement:

Note

spec.strategy.type är inställd på External för att tillåta en distribution som utlöses med en 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

Alla tre klustren bör schemaläggas eftersom vi använder policy PickAll, men inga resurser bör distribueras på medlemsklustren ännu eftersom vi inte har skapat någon ClusterStagedUpdateRun.

Kontrollera att placeringen är schemalagd:

kubectl get crp example-placement

Din utdata bör likna det följande exemplet:

NAME                GEN   SCHEDULED   SCHEDULED-GEN   AVAILABLE   AVAILABLE-GEN   AGE
example-placement   1     True        1                                           51s

Arbeta med resursögonblicksbilder

Fleet Manager skapar resursögonblicksbilder när resurserna ändras. Varje ögonblicksbild har ett unikt index som du kan använda för att referera till specifika versioner av dina resurser.

Tip

Mer information om resursögonblicksbilder och hur de fungerar finns i Förstå resursögonblicksbilder.

Kontrollera aktuella resursögonblicksbilder

Så här kontrollerar du aktuella resursögonblicksbilder:

kubectl get clusterresourcesnapshots --show-labels

Din utdata bör likna det följande exemplet:

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

Vi har bara en version av ögonblicksbilden. Det är den senaste (kubernetes-fleet.io/is-latest-snapshot=true) och har resursindex 0 (kubernetes-fleet.io/resource-index=0).

Skapa en ny resursögonblicksbild

Ändra nu konfigurationskartan med ett nytt värde:

kubectl edit cm test-cm -n test-namespace

Uppdatera värdet från value1 till value2:

kubectl get configmap test-cm -n test-namespace -o yaml

Din utdata bör likna det följande exemplet:

apiVersion: v1
data:
  key: value2 # value updated here, old value: value1
kind: ConfigMap
metadata:
  creationTimestamp: ...
  name: test-cm
  namespace: test-namespace
  resourceVersion: ...
  uid: ...

Nu bör du se två versioner av resursögonblicksbilder med index 0 respektive 1:

kubectl get clusterresourcesnapshots --show-labels

Din utdata bör likna det följande exemplet:

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

Den aktuella etiketten har satts till example-placement-1-snapshot, som innehåller de senaste configmap-data:

kubectl get clusterresourcesnapshots example-placement-1-snapshot -o yaml

Din utdata bör likna det följande exemplet:

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

Distribuera en strategi för klusteretappuppdateringar

A ClusterStagedUpdateStrategy definierar orkestreringsmönstret som grupperar kluster i faser och anger distributionssekvensen. Den väljer medlemskluster efter etiketter. I vår demonstration skapar vi en med två steg, mellanlagring och kanariefågel:

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

Distribuera en ClusterStagedUpdateRun för att distribuera den senaste ändringen

En ClusterStagedUpdateRun kör distributionen av en ClusterResourcePlacement efter en ClusterStagedUpdateStrategy. För att utlösa den stegvisa uppdateringskörningen för vårt ClusterResourcePlacement (CRP) skapar vi ett ClusterStagedUpdateRun som anger CRP-namnet, namnet på updateRun-strategin och resursögonblicksbildens senaste index ("1"):

apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
  name: example-run
spec:
  placementName: example-placement
  resourceSnapshotIndex: "1"
  stagedRolloutStrategyName: example-strategy

Den etappvisa uppdateringskörningen initieras och körs:

kubectl get csur example-run

Din utdata bör likna det följande exemplet:

NAME          PLACEMENT           RESOURCE-SNAPSHOT-INDEX   POLICY-SNAPSHOT-INDEX   INITIALIZED   SUCCEEDED   AGE
example-run   example-placement   1                         0                       True                      7s

En mer detaljerad titt på statusen efter att en minut TimedWait har förflutit:

kubectl get csur example-run -o yaml

Din utdata bör likna det följande exemplet:

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"

Vi kan se att TimedWait-perioden för staging-steget har förflutit och vi ser också att ClusterApprovalRequest objektet för godkännandeaktiviteten i canary stage skapades. Vi kan kontrollera den genererade ClusterApprovalRequest och se att den ännu inte har godkänts.

kubectl get clusterapprovalrequest

Din utdata bör likna det följande exemplet:

NAME                 UPDATE-RUN    STAGE    APPROVED   APPROVALACCEPTED   AGE
example-run-canary   example-run   canary                                 2m39s

Vi kan godkänna ClusterApprovalRequest genom att skapa en json-korrigeringsfil och tillämpa den:

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

Skicka en korrigeringsbegäran för att godkänna med hjälp av JSON-filen som skapats.

kubectl patch clusterapprovalrequests example-run-canary --type='merge' --subresource=status --patch-file approval.json

Kontrollera sedan att den är godkänd:

kubectl get clusterapprovalrequest

Din utdata bör likna det följande exemplet:

NAME                 UPDATE-RUN    STAGE    APPROVED   APPROVALACCEPTED   AGE
example-run-canary   example-run   canary   True       True               3m35s

Nu kan ClusterStagedUpdateRun fortsätta och slutföra:

kubectl get csur example-run

Din utdata bör likna det följande exemplet:

NAME          PLACEMENT           RESOURCE-SNAPSHOT-INDEX   POLICY-SNAPSHOT-INDEX   INITIALIZED   SUCCEEDED   AGE
example-run   example-placement   1                         0                       True          True        5m28s

Visar ClusterResourcePlacement också att distributionen har slutförts och att resurser är tillgängliga i alla medlemskluster:

kubectl get crp example-placement

Din utdata bör likna det följande exemplet:

NAME                GEN   SCHEDULED   SCHEDULED-GEN   AVAILABLE   AVAILABLE-GEN   AGE
example-placement   1     True        1               True        1               8m55s

Configmap test-cm ska distribueras på alla tre medlemskluster med senaste data:

apiVersion: v1
data:
  key: value2
kind: ConfigMap
metadata:
  ...
  name: test-cm
  namespace: test-namespace
  ...

Distribuera en andra ClusterStagedUpdateRun för att återställa till en tidigare version

Anta nu att arbetsbelastningsadministratören vill återställa konfigurationsmappsändringen och återställa värdet value2 till value1. I stället för att manuellt uppdatera konfigurationskartan från hubben kan de skapa en ny ClusterStagedUpdateRun med ett tidigare resursögonblicksindex, "0" i vår kontext och de kan återanvända samma strategi:

apiVersion: placement.kubernetes-fleet.io/v1beta1
kind: ClusterStagedUpdateRun
metadata:
  name: example-run-2
spec:
  placementName: example-placement
  resourceSnapshotIndex: "0"
  stagedRolloutStrategyName: example-strategy

Nu ska vi kontrollera den nya ClusterStagedUpdateRun:

kubectl get csur

Din utdata bör likna det följande exemplet:

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

När en minut TimedWait har gått bör vi se objektet ClusterApprovalRequest som skapats för den nya ClusterStagedUpdateRun:

kubectl get clusterapprovalrequest

Din utdata bör likna det följande exemplet:

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

Om du vill godkänna det nya ClusterApprovalRequest objektet ska vi återanvända samma approval.json fil för att korrigera det:

kubectl patch clusterapprovalrequests example-run-2-canary --type='merge' --subresource=status --patch-file approval.json

Kontrollera om det nya objektet har godkänts:

kubectl get clusterapprovalrequest                                                                            

Din utdata bör likna det följande exemplet:

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

Konfigurationskartan test-cm bör nu distribueras på alla tre medlemskluster, med data återställda till value1:

apiVersion: v1
data:
  key: value1
kind: ConfigMap
metadata:
  ...
  name: test-cm
  namespace: test-namespace
  ...

Rensa resurser

När du är klar med den här självstudien kan du rensa de resurser som du har skapat:

# Delete the staged update runs
kubectl delete csur example-run example-run-2

# Delete the staged update strategy
kubectl delete csus example-strategy

# Delete the cluster resource placement
kubectl delete crp example-placement

# Delete the test namespace (this will also delete the configmap)
kubectl delete namespace test-namespace

Nästa steg

I den här artikeln har du lärt dig hur du använder ClusterStagedUpdateRun för att samordna mellanlagrade distributioner mellan medlemskluster. Du har skapat stegvisa uppdateringsstrategier, kört progressiva distributioner och utfört återställningar till tidigare versioner.

Mer information om etappvisa uppdateringskörningar och relaterade begrepp finns i följande resurser: