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
| Concept | Description |
|---|---|
| ClusterVersion | The trigger CR for declarative upgrade, declaring the desired target version by setting the spec.desiredVersion field |
| UpgradePath | Upgrade path rule CR, defining valid upgrade paths between versions, including from, to, blocked, etc. |
| ReleaseImage | Version release image CR, containing the component list, dependency relationships, and execution method (inline or manifest) required for upgrade |
| ComponentVersion | Component version definition CR, defining the type, version, dependencies, upgrade strategy, and prerequisite resources of a single upgrade component |
| Upgrade DAG | A directed acyclic graph built based on the dependency relationships of ReleaseImage and ComponentVersion, determining the execution order of upgrade components |
| Multi-hop Upgrade | When 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:
- Modify desiredVersion: Modify the spec.desiredVersion field of ClusterVersion CR to the target version.
- Detect Version Change: ClusterVersionReconciler detects that desiredVersion is inconsistent with currentVersion, triggering the upgrade flow.
- Query Upgrade Path: ClusterVersionReconciler queries the UpgradePath CR, validating whether the upgrade path from the current version to the target version is valid.
- 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.
- Write Upgrade Annotation: Write the upgrade-ready annotation on BKECluster, triggering BKEClusterReconciler to enter the upgrade flow.
- Detect Upgrade Annotation: BKEClusterReconciler detects the upgrade-ready annotation on BKECluster and enters the declarative upgrade flow.
- Parse Upgrade Components: Parse ReleaseImage to obtain the upgrade component list and dependency relationships.
- Build DAG Topology: Build the DAG topology based on the upgrade component list from ReleaseImage and the dependency relationships from ComponentVersion.
- 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.
- Determine Upgrade Success: Check whether all components have been upgraded successfully.
- Update Status: After successful upgrade, update BKECluster and ClusterVersion status; update DeclarativeUpgradeStatus after each component completes.
- Record Failed Components: When upgrade fails, record the failed component information.
- Determine Whether Target Version Reached: Check whether the current version equals the target version; if not, continue executing the next hop upgrade.
- Upgrade Complete: The current version equals the target version; all upgrades are complete, and upgrade annotations are cleared.
Usage Restrictions
| Restriction Item | Description |
|---|---|
| Downgrade Not Supported | Only version upgrade functionality is provided; version downgrade functionality is not provided |
| Minimum Version Requirement | The currently supported minimum upgradable version is v26.06-rc.2 |
| Upgrade Impact | When upgrading K8s-related components in a non-high-availability cluster, there will be a brief apiserver service unavailability |
| etcd Backup Recommendation | It is recommended to back up etcd data before upgrading; manual rollback is required if upgrade fails |
| Offline Upload Restriction | Offline scenario patch upload is not supported in online mode |
| Cluster Health Requirement | The cluster status must be Healthy before upgrading; otherwise the upgrade may fail |
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
# 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 firstStep 2: Query Upgradable Paths
# View upgrade path rules in UpgradePath CR
kubectl get upgradepath openfuyao-upgrade-paths -o yamlStep 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.
# 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>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:
# View ClusterVersion status
kubectl get clusterversion <cluster-name> -n <namespace> -wClusterVersion phase field meanings:
| Phase | Description |
|---|---|
| Pending | Upgrade request submitted, awaiting processing |
| PreChecking | Pre-upgrade validation in progress |
| Upgrading | Upgrade execution in progress |
| Upgraded | Single-hop upgrade completed (in multi-hop scenarios, subsequent hops remain) |
| Ready | All upgrades completed, currentVersion equals desiredVersion |
| Blocked | Upgrade path is blocked |
| PreCheckFailed | Pre-upgrade validation failed |
| Failed | Upgrade failed |
# View overall cluster health status
kubectl get bkecluster <cluster-name> -n <namespace> -wDeclarative upgrade phase sequence (executed by DAG topology):
| Upgrade Batch | Phase Name | CR Phase Name | Description |
|---|---|---|---|
| Batch 1 | Provider Self-upgrade | EnsureProviderSelfUpgrade | cluster-api-provider-bke own image rolling upgrade |
| Batch 2 | Agent Upgrade | EnsureAgentUpgrade | Upgrade bke-agent on each node |
| Batch 3 | Containerd Upgrade | EnsureContainerdUpgrade | Upgrade containerd on each node |
| Batch 4 | etcd Upgrade | EnsureEtcdUpgrade | Rolling upgrade of etcd cluster |
| Batch 5 | Master Upgrade | EnsureMasterUpgrade | Rolling upgrade of Master node kubernetes components |
| Batch 5 | Worker Upgrade | EnsureWorkerUpgrade | Rolling upgrade of Worker node kubernetes components |
| Batch 6 | kube-proxy Upgrade | manifest method | Apply YAML manifests via ClusterApplier |
| Batch 6 | coredns Upgrade | manifest method | Apply YAML manifests via ClusterApplier |
| Batch 6 | calico Upgrade | manifest method | Apply YAML manifests via ClusterApplier |
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
# 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
Download the openFuyao version index file to obtain the correspondence between versions and file names.
bashwget https://openfuyao.obs.cn-north-4.myhuaweicloud.com/openFuyao/version-config/index.yamlIndex file sample content:
yaml- openFuyaoVersion: v26.06 filePath: ./VersionConfig-v26.06.yaml - openFuyaoVersion: v26.06-rc.2 filePath: ./VersionConfig-v26.06-rc.2.yamlDownload the target version configuration file based on the index file.
bashwget 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
# 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.
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:
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"] }Restart docker:
bashsystemctl restart dockerPrepare 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:
bashbke build -f VersionConfig-v26.06-rc.2.yaml -t offline-v26.06-rc.2.tar.gzNote:
Please replace the version number in the command with your actual target upgrade version number.
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:
| Content | Description |
|---|---|
| Container Images | All container images defined by repos in the version configuration file |
| Registry Image | The registry:2 image for the bootstrap node local image source |
| Binary Files | Binary files such as containerd, kubelet, kubectl defined by files in the version configuration file |
| RPM/deb Packages | Operating system dependency packages defined by rpms/debs in the version configuration file |
| Helm Charts | Helm chart packages defined by charts in the version configuration file |
| Version Patches | VersionConfig patch files defined by patches in the version configuration file |
| bke Installation Tool | bkeadm installation command tool |
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
Place the full offline package file in the /etc/openFuyao directory on the bootstrap node.
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/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:
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.
# 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
# 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 Cause | Description | Troubleshooting Command |
|---|---|---|
| Cluster Not Healthy | Cluster status was not Healthy before upgrade | kubectl get bkecluster <name> -n <name> -o jsonpath='{.status.clusterHealthState}' |
| Upgrade Path Blocked | UpgradePath rules mark the path as blocked | kubectl get upgradepath -o yaml |
| Image Pull Failure | In offline scenarios, image packages were not correctly synchronized | Log in to the bootstrap node to check the image source service |
| Insufficient Resources | Node CPU/memory/disk resource shortages | kubectl top nodes |
| Network Issues | Abnormal network communication between nodes | kubectl get nodes to check node Ready status |
FAQ
What is the difference between declarative upgrade and legacy PhaseFlow upgrade?
Comparison Item Legacy PhaseFlow Declarative Upgrade Trigger Method Modify BKECluster.spec.openFuyaoVersion Modify ClusterVersion.spec.desiredVersion Execution Method Serial execution of all upgrade phases DAG topology driven parallel execution Component Order Fixed sequence Dynamically determined by dependency relationships Multi-hop Upgrade Not supported Supports 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.