Version: v26.06

Backend Declarative Upgrade Guide

Backend Declarative Upgrade Introduction

Application Scenarios

Declarative upgrade is a cluster version upgrade method provided by openFuyao based on declarative APIs. Users only need to declare the desired target version, and the system will automatically complete the entire process including upgrade path validation, upgrade resource preparation, orderly component upgrades, and status tracking. Through backend upgrades, users can view phase information during the upgrade process and understand the upgrade execution steps.

Applicable to the following scenarios:

  • Upgrading the openFuyao version of a cluster from v26.06-rc.2 and subsequent versions to a higher version.
  • Cluster version upgrades in both online and offline environments.

Capability Scope

  • Declarative upgrade trigger: Modify the desiredVersion field of ClusterVersion CR (Custom Resource) to trigger the upgrade, and the system automatically issues upgrade instructions.
  • Automatic upgrade path validation: Based on UpgradePath rules, automatically validates whether the upgrade path from the current version to the target version is valid.
  • Automatic multi-hop upgrade execution: When no direct upgrade path exists, the system automatically executes upgrades hop by hop through intermediate versions.
  • DAG (Directed Acyclic Graph) driven parallel upgrade: Upgrade components build a DAG topology based on dependency relationships, supporting parallel upgrades of components in the same batch.
  • Both online and offline scenarios are supported.
  • Both management clusters and business clusters can be upgraded. Business cluster upgrades must be performed on the cluster managing their lifecycle (management cluster or bootstrap node).

Highlight Features

  • Declarative trigger: Only need to declare the target version (modify the desiredVersion field of ClusterVersion CR), without worrying about upgrade execution details.
  • DAG parallel upgrade: Compared to the legacy serial PhaseFlow upgrade, declarative upgrade supports components executing in parallel based on dependency topology, reducing overall upgrade time.
  • Automatic multi-hop execution: During cross-version upgrades, the system automatically calculates intermediate hop versions and executes hop by hop, requiring no manual intervention from users.

Basic Concepts

ConceptDescription
ClusterVersionThe trigger CR for declarative upgrade, declaring the desired target version by setting the spec.desiredVersion field
UpgradePathUpgrade path rule CR, defining valid upgrade paths between versions, including from, to, blocked, etc.
ReleaseImageVersion release image CR, containing the component list, dependency relationships, and execution method (inline or manifest) required for upgrade
ComponentVersionComponent version definition CR, defining the type, version, dependencies, upgrade strategy, and prerequisite resources of a single upgrade component
Upgrade DAGA directed acyclic graph built based on the dependency relationships of ReleaseImage and ComponentVersion, determining the execution order of upgrade components
Multi-hop UpgradeWhen no direct upgrade path exists from the current version to the target version but multi-hop paths exist, the system automatically executes upgrades hop by hop through intermediate versions

The trigger and execution flow of declarative upgrade is as follows:

Flow step descriptions:

  1. Modify desiredVersion: Modify the spec.desiredVersion field of ClusterVersion CR to the target version.
  2. Detect Version Change: ClusterVersionReconciler detects that desiredVersion is inconsistent with currentVersion, triggering the upgrade flow.
  3. Query Upgrade Path: ClusterVersionReconciler queries the UpgradePath CR, validating whether the upgrade path from the current version to the target version is valid.
  4. Ensure Resource Exists: Ensure the ReleaseImage CR exists and its status is Valid; the system automatically pulls and parses it from the OCI image repository.
  5. Write Upgrade Annotation: Write the upgrade-ready annotation on BKECluster, triggering BKEClusterReconciler to enter the upgrade flow.
  6. Detect Upgrade Annotation: BKEClusterReconciler detects the upgrade-ready annotation on BKECluster and enters the declarative upgrade flow.
  7. Parse Upgrade Components: Parse ReleaseImage to obtain the upgrade component list and dependency relationships.
  8. Build DAG Topology: Build the DAG topology based on the upgrade component list from ReleaseImage and the dependency relationships from ComponentVersion.
  9. Execute Upgrades in Parallel: Execute component upgrades in parallel by DAG topology batches; inline components (etcd, kubernetes, etc.) are executed via PhaseRunner, manifest components (provider, coredns, etc.) are executed via ClusterApplier.
  10. Determine Upgrade Success: Check whether all components have been upgraded successfully.
  11. Update Status: After successful upgrade, update BKECluster and ClusterVersion status; update DeclarativeUpgradeStatus after each component completes.
  12. Record Failed Components: When upgrade fails, record the failed component information.
  13. Determine Whether Target Version Reached: Check whether the current version equals the target version; if not, continue executing the next hop upgrade.
  14. Upgrade Complete: The current version equals the target version; all upgrades are complete, and upgrade annotations are cleared.

Usage Restrictions

Restriction ItemDescription
Downgrade Not SupportedOnly version upgrade functionality is provided; version downgrade functionality is not provided
Minimum Version RequirementThe currently supported minimum upgradable version is v26.06-rc.2
Upgrade ImpactWhen upgrading K8s-related components in a non-high-availability cluster, there will be a brief apiserver service unavailability
etcd Backup RecommendationIt is recommended to back up etcd data before upgrading; manual rollback is required if upgrade fails
Offline Upload RestrictionOffline scenario patch upload is not supported in online mode
Cluster Health RequirementThe cluster status must be Healthy before upgrading; otherwise the upgrade may fail

icon Notice:
For upgrading from v26.03 to v26.06, refer to Upgrade Guide. The following guide applies to upgrading from v26.06-rc.2 and subsequent versions.

Online Scenario Upgrade Operations

Prerequisites

  • The management cluster is running normally.
  • The management cluster can access the remote version repository.
  • The cluster to be upgraded has a status of Healthy.

Step 1: Check Cluster Status

bash
# View business cluster status
kubectl get bkecluster <cluster-name> -n <namespace> 

# Expected output: Healthy
# If the output is not Healthy, troubleshoot and fix cluster issues first

Step 2: Query Upgradable Paths

bash
# View upgrade path rules in UpgradePath CR
kubectl get upgradepath openfuyao-upgrade-paths -o yaml

Step 3: Trigger Upgrade

Operate ClusterVersion CR via kubectl

If you want to upgrade to v26.06, you can execute the following operations to trigger the upgrade.

bash
# Patch update desiredVersion
kubectl patch clusterversion <cluster-name> -n <namespace> --type merge -p '{"spec":{"desiredVersion":"v26.06"}}'
# Or edit the clusterversion resource, changing desiredVersion to v26.06
kubectl edit clusterversion <cluster-name> -n <namespace>

icon Note:
Modifying the desiredVersion field of ClusterVersion CR is the only way to trigger declarative upgrade. After the system detects that desiredVersion is inconsistent with currentVersion, it automatically enters the upgrade flow.

Step 4: Monitor Upgrade Progress

View various statuses during the upgrade process via kubectl:

bash
# View ClusterVersion status
kubectl get clusterversion <cluster-name> -n <namespace> -w

ClusterVersion phase field meanings:

PhaseDescription
PendingUpgrade request submitted, awaiting processing
PreCheckingPre-upgrade validation in progress
UpgradingUpgrade execution in progress
UpgradedSingle-hop upgrade completed (in multi-hop scenarios, subsequent hops remain)
ReadyAll upgrades completed, currentVersion equals desiredVersion
BlockedUpgrade path is blocked
PreCheckFailedPre-upgrade validation failed
FailedUpgrade failed
bash
# View overall cluster health status
kubectl get bkecluster <cluster-name> -n <namespace> -w

Declarative upgrade phase sequence (executed by DAG topology):

Upgrade BatchPhase NameCR Phase NameDescription
Batch 1Provider Self-upgradeEnsureProviderSelfUpgradecluster-api-provider-bke own image rolling upgrade
Batch 2Agent UpgradeEnsureAgentUpgradeUpgrade bke-agent on each node
Batch 3Containerd UpgradeEnsureContainerdUpgradeUpgrade containerd on each node
Batch 4etcd UpgradeEnsureEtcdUpgradeRolling upgrade of etcd cluster
Batch 5Master UpgradeEnsureMasterUpgradeRolling upgrade of Master node kubernetes components
Batch 5Worker UpgradeEnsureWorkerUpgradeRolling upgrade of Worker node kubernetes components
Batch 6kube-proxy Upgrademanifest methodApply YAML manifests via ClusterApplier
Batch 6coredns Upgrademanifest methodApply YAML manifests via ClusterApplier
Batch 6calico Upgrademanifest methodApply YAML manifests via ClusterApplier

icon Note:
1. Components within the same batch execute in parallel; different batches execute serially in dependency order. Batches 1~6 are automatically determined by DAG topology sorting; dependency relationships come from the spec.dependencies field of each ComponentVersion in ReleaseImage.
2. In Batch 5, Master Upgrade and Worker Upgrade execute in parallel; in Batch 6, kube-proxy, coredns, and calico execute in parallel.
3. In multi-hop upgrade scenarios, each hop executes all the above phases before automatically proceeding to the next hop.
4. After provider self-upgrade completes, a new Pod will take over the subsequent upgrade process, and the old Pod will automatically exit.

Step 5: Confirm Upgrade Completion

bash
# Confirm ClusterVersion currentVersion equals desiredVersion
kubectl get clusterversion <cluster-name> -n <namespace> -o jsonpath='{.status.currentVersion}'

# Confirm ClusterVersion phase is Ready
kubectl get clusterversion <cluster-name> -n <namespace> -o jsonpath='{.status.phase}'

# Confirm cluster status has returned to Healthy
kubectl get bkecluster <cluster-name> -n <namespace> -o jsonpath='{.status.clusterHealthState}'

Offline Scenario Upgrade Operations

Prerequisites

  • The management cluster is running normally and in an offline environment.
  • The cluster is in offline mode.
  • The cluster to be upgraded has a status of Healthy.
  • The version configuration file has been prepared (for preparing the full offline package); offline package preparation must be done in an online environment, and the prepared offline package is then uploaded to the bootstrap node.

Offline Package Preparation Step 1: Prepare Version Configuration File

  1. Download the openFuyao version index file to obtain the correspondence between versions and file names.

    bash
    wget https://openfuyao.obs.cn-north-4.myhuaweicloud.com/openFuyao/version-config/index.yaml

    Index file sample content:

    yaml
    - openFuyaoVersion: v26.06
      filePath: ./VersionConfig-v26.06.yaml
    - openFuyaoVersion: v26.06-rc.2
      filePath: ./VersionConfig-v26.06-rc.2.yaml
  2. Download the target version configuration file based on the index file.

    bash
    wget https://openfuyao.obs.cn-north-4.myhuaweicloud.com/openFuyao/version-config/VersionConfig-v26.06-rc.2.yaml

Offline Package Preparation Step 2: Upload Version Configuration File

Operate ConfigMap directly via kubectl

bash
# Create version configuration ConfigMap (under the openfuyao-patch namespace)
kubectl create configmap cm.v26.06-rc.2 -n openfuyao-patch \
  --from-literal=v26.06-rc.2="$(cat VersionConfig-v26.06-rc.2.yaml)"

# Update bke-config ConfigMap, add patch index
kubectl patch configmap bke-config -n cluster-system --type merge \
  -p '{"data":{"patch.v26.06-rc.2":"cm.v26.06-rc.2"}}'

Offline Package Preparation Step 3: Prepare Full Offline Package

Based on the version configuration file downloaded in Offline Package Preparation Step 1: Prepare Version Configuration File, prepare a full offline package containing all images, binary files, and version patches required for upgrade.

  1. Install docker (using version 20.10.13 or 18.09.0) and configure docker; edit the /etc/docker/daemon.json file and add the following configuration:

    icon Note:
    If the daemon.json file does not exist, create it manually. If the file already has other configuration items, add "insecure-registries" to the existing configuration; do not replace the entire file content.

    json
    {
      "insecure-registries": ["0.0.0.0/0"]
    }
  2. Restart docker:

    bash
    systemctl restart docker
  3. Prepare the full offline package based on the version configuration file. Here, v26.06-rc.2 is used as an example; replace the file name and offline package name with the actual target version:

    bash
    bke build -f VersionConfig-v26.06-rc.2.yaml -t offline-v26.06-rc.2.tar.gz

    icon Note:
    Please replace the version number in the command with your actual target upgrade version number.

icon Note:
Here, v26.06-rc.2 is used as an example; please replace the version number in the command with your actual target upgrade version number.

The full offline package contains the following:

ContentDescription
Container ImagesAll container images defined by repos in the version configuration file
Registry ImageThe registry:2 image for the bootstrap node local image source
Binary FilesBinary files such as containerd, kubelet, kubectl defined by files in the version configuration file
RPM/deb PackagesOperating system dependency packages defined by rpms/debs in the version configuration file
Helm ChartsHelm chart packages defined by charts in the version configuration file
Version PatchesVersionConfig patch files defined by patches in the version configuration file
bke Installation Toolbkeadm installation command tool

icon Note:
1. The version configuration file defines all images, binary files, and dependency packages required for the full offline package, serving as the input configuration for offline package preparation.
2. The full offline package ensures that all resources required for upgrade are available in the offline environment, avoiding upgrade failures due to missing dependencies.

Offline Upgrade Step 1: Upload Offline Package to Bootstrap Node

  1. Place the full offline package file in the /etc/openFuyao directory on the bootstrap node.

  2. Synchronize the offline package to the bootstrap node image source service:

    bash
    # Log in to the bootstrap node
    
    # Extract the full offline package
    tar -xzvf /etc/openFuyao/offline-v26.06-rc.2.tar.gz
    
    # Synchronize images to the local image source
    bke registry patch --source ./offline-v26.06-rc.2 --target <bootstrap-node-IP>:40443
    
    # Copy binary files to the specified directory
    cp containerd-*.tar.gz /bke/mount/source_registry/files/

    icon Note:
    Here, v26.06-rc.2 is used as an example; please replace the version number in the command with your actual target upgrade version number.

Offline Upgrade Step 2: Check Cluster Status

Same as the online scenario:

bash
kubectl get bkecluster <cluster-name> -n <namespace>

Offline Upgrade Step 3: Trigger Upgrade

Same as the online scenario:

If you want to upgrade to v26.06, you can execute the following operations to trigger the upgrade.

bash
# Patch update desiredVersion
kubectl patch clusterversion <cluster-name> -n <namespace> --type merge -p '{"spec":{"desiredVersion":"v26.06"}}'
# Or edit the clusterversion resource, changing desiredVersion to v26.06
kubectl edit clusterversion <cluster-name> -n <namespace>

Offline Upgrade Step 4: Monitor Upgrade Progress

Same as the online scenario, refer to Online Scenario - Monitor Upgrade Progress.

Offline Upgrade Step 5: Confirm Upgrade Completion

Same as the online scenario, refer to Online Scenario - Confirm Upgrade Completion.

Upgrade Failure Handling

View Failure Details

bash
# View ClusterVersion status
kubectl get clusterversion <cluster-name> -n <namespace> -o yaml

# View failure records in DeclarativeUpgradeStatus
kubectl get bkecluster <cluster-name> -n <namespace> -o jsonpath='{.status.declarativeUpgrade.lastFailure}'

# View cluster status
kubectl get bkecluster <cluster-name> -n <namespace> -o jsonpath='{.status.clusterHealthState}'

Common Failure Causes

Failure CauseDescriptionTroubleshooting Command
Cluster Not HealthyCluster status was not Healthy before upgradekubectl get bkecluster <name> -n <name> -o jsonpath='{.status.clusterHealthState}'
Upgrade Path BlockedUpgradePath rules mark the path as blockedkubectl get upgradepath -o yaml
Image Pull FailureIn offline scenarios, image packages were not correctly synchronizedLog in to the bootstrap node to check the image source service
Insufficient ResourcesNode CPU/memory/disk resource shortageskubectl top nodes
Network IssuesAbnormal network communication between nodeskubectl get nodes to check node Ready status

FAQ

  • What is the difference between declarative upgrade and legacy PhaseFlow upgrade?

    Comparison ItemLegacy PhaseFlowDeclarative Upgrade
    Trigger MethodModify BKECluster.spec.openFuyaoVersionModify ClusterVersion.spec.desiredVersion
    Execution MethodSerial execution of all upgrade phasesDAG topology driven parallel execution
    Component OrderFixed sequenceDynamically determined by dependency relationships
    Multi-hop UpgradeNot supportedSupports automatic hop-by-hop execution
  • Why is the upgrade version list empty?

    bash
    # Check whether UpgradePath CR exists
    kubectl get upgradepath
    
    # Check path rules
    kubectl get upgradepath openfuyao-upgrade-paths -o jsonpath='{.spec.paths}'

    Possible causes: 1) The current version is already the latest version; 2) The UpgradePath rules have no reachable upgrade paths for the current version; 3) In online mode, the remote version repository is unreachable.

  • What is multi-hop upgrade?

    When no direct upgrade path exists from the current version to the target version (such as v26.06-rc.2 to v26.06), the system automatically calculates the intermediate hop version path (such as v26.06-rc.2 -> v26.06-rc.3 -> v26.06) and executes upgrades hop by hop. After each hop completes, it automatically proceeds to the next hop until reaching the final target version.

  • Why is there a brief interruption after provider self-upgrade during the upgrade process?

    Provider self-upgrade uses the Kubernetes Deployment rolling update mechanism: after the old Pod's image is patched, K8s creates a new Pod, and after the new Pod is Ready, the old Pod is terminated. The new Pod will automatically take over the subsequent upgrade process after starting. This process typically completes within 1-2 minutes.