Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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-cliDu behöver Azure CLI-tillägget
fleet. Du kan installera det genom att köra följande kommando:az extension add --name fleetaz extension updateKö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:
Azure Kubernetes Service