Skip to content

Commit

Permalink
Enable k3s cluster upgrades (#15)
Browse files Browse the repository at this point in the history
Signed-off-by: Atanas Dinov <[email protected]>
  • Loading branch information
atanasdinov authored Jul 23, 2024
1 parent 0aaa478 commit 66923db
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 13 deletions.
38 changes: 31 additions & 7 deletions internal/controller/reconcile_kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package controller
import (
"context"
"fmt"
"strings"

lifecyclev1alpha1 "github.com/suse-edge/upgrade-controller/api/v1alpha1"
"github.com/suse-edge/upgrade-controller/internal/upgrade"
"github.com/suse-edge/upgrade-controller/pkg/release"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -14,21 +16,26 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

func (r *UpgradePlanReconciler) reconcileKubernetes(ctx context.Context, upgradePlan *lifecyclev1alpha1.UpgradePlan, kubernetesVersion string) (ctrl.Result, error) {
func (r *UpgradePlanReconciler) reconcileKubernetes(ctx context.Context, upgradePlan *lifecyclev1alpha1.UpgradePlan, release *release.Release) (ctrl.Result, error) {
nodeList := &corev1.NodeList{}
if err := r.List(ctx, nodeList); err != nil {
return ctrl.Result{}, fmt.Errorf("listing nodes: %w", err)
}

kubernetesVersion, err := targetKubernetesVersion(nodeList, release)
if err != nil {
return ctrl.Result{}, fmt.Errorf("identifying target kubernetes version: %w", err)
}

controlPlanePlan := upgrade.KubernetesControlPlanePlan(kubernetesVersion)
if err := r.Get(ctx, client.ObjectKeyFromObject(controlPlanePlan), controlPlanePlan); err != nil {
if err = r.Get(ctx, client.ObjectKeyFromObject(controlPlanePlan), controlPlanePlan); err != nil {
if !errors.IsNotFound(err) {
return ctrl.Result{}, err
}

return ctrl.Result{}, r.createPlan(ctx, upgradePlan, controlPlanePlan)
}

nodeList := &corev1.NodeList{}
if err := r.List(ctx, nodeList); err != nil {
return ctrl.Result{}, fmt.Errorf("listing nodes: %w", err)
}

selector, err := metav1.LabelSelectorAsSelector(controlPlanePlan.Spec.NodeSelector)
if err != nil {
return ctrl.Result{}, fmt.Errorf("parsing node selector: %w", err)
Expand Down Expand Up @@ -65,6 +72,23 @@ func (r *UpgradePlanReconciler) reconcileKubernetes(ctx context.Context, upgrade
return ctrl.Result{Requeue: true}, nil
}

func targetKubernetesVersion(nodeList *corev1.NodeList, release *release.Release) (string, error) {
if len(nodeList.Items) == 0 {
return "", fmt.Errorf("unable to determine current kubernetes version due to empty node list")
}

kubeletVersion := nodeList.Items[0].Status.NodeInfo.KubeletVersion

switch {
case strings.Contains(kubeletVersion, "k3s"):
return release.Components.Kubernetes.K3S.Version, nil
case strings.Contains(kubeletVersion, "rke2"):
return release.Components.Kubernetes.RKE2.Version, nil
default:
return "", fmt.Errorf("upgrading from kubernetes version %s is not supported", kubeletVersion)
}
}

func isKubernetesUpgraded(nodeList *corev1.NodeList, selector labels.Selector, kubernetesVersion string) bool {
for _, node := range nodeList.Items {
if !selector.Matches(labels.Set(node.Labels)) {
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/upgradeplan_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (r *UpgradePlanReconciler) executePlan(ctx context.Context, upgradePlan *li
// Upgrade OS here...

if !meta.IsStatusConditionTrue(upgradePlan.Status.Conditions, lifecyclev1alpha1.KubernetesUpgradedCondition) {
return r.reconcileKubernetes(ctx, upgradePlan, release.Components.Kubernetes.RKE2.Version)
return r.reconcileKubernetes(ctx, upgradePlan, release)
}

// Upgrade rest of the components here...
Expand Down
21 changes: 16 additions & 5 deletions internal/upgrade/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

const (
rke2UpgradeImage = "rancher/rke2-upgrade"
k3sUpgradeImage = "rancher/k3s-upgrade"

controlPlaneKey = "control-plane"
workersKey = "workers"
Expand All @@ -20,12 +21,21 @@ func kubernetesPlanName(typeKey, version string) string {
return fmt.Sprintf("%s-%s", typeKey, strings.ReplaceAll(version, "+", "-"))
}

func kubernetesUpgradeImage(version string) string {
if strings.Contains(version, "k3s") {
return k3sUpgradeImage
}

return rke2UpgradeImage
}

func KubernetesControlPlanePlan(version string) *upgradecattlev1.Plan {
controlPlanePlanName := kubernetesPlanName(controlPlaneKey, version)
upgradeImage := kubernetesUpgradeImage(version)

controlPlanePlan := baseUpgradePlan(controlPlanePlanName)
controlPlanePlan.Labels = map[string]string{
"rke2-upgrade": "control-plane",
"k8s-upgrade": "control-plane",
}
controlPlanePlan.Spec.NodeSelector = &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
Expand All @@ -40,7 +50,7 @@ func KubernetesControlPlanePlan(version string) *upgradecattlev1.Plan {
}
controlPlanePlan.Spec.Concurrency = 1
controlPlanePlan.Spec.Upgrade = &upgradecattlev1.ContainerSpec{
Image: rke2UpgradeImage,
Image: upgradeImage,
}
controlPlanePlan.Spec.Version = version
controlPlanePlan.Spec.Cordon = true
Expand Down Expand Up @@ -71,10 +81,11 @@ func KubernetesControlPlanePlan(version string) *upgradecattlev1.Plan {
func KubernetesWorkerPlan(version string) *upgradecattlev1.Plan {
controlPlanePlanName := kubernetesPlanName(controlPlaneKey, version)
workerPlanName := kubernetesPlanName(workersKey, version)
upgradeImage := kubernetesUpgradeImage(version)

workerPlan := baseUpgradePlan(workerPlanName)
workerPlan.Labels = map[string]string{
"rke2-upgrade": "worker",
"k8s-upgrade": "worker",
}
workerPlan.Spec.Concurrency = 2
workerPlan.Spec.NodeSelector = &metav1.LabelSelector{
Expand All @@ -93,10 +104,10 @@ func KubernetesWorkerPlan(version string) *upgradecattlev1.Plan {
"prepare",
controlPlanePlanName,
},
Image: rke2UpgradeImage,
Image: upgradeImage,
}
workerPlan.Spec.Upgrade = &upgradecattlev1.ContainerSpec{
Image: rke2UpgradeImage,
Image: upgradeImage,
}
workerPlan.Spec.Version = version
workerPlan.Spec.Cordon = true
Expand Down

0 comments on commit 66923db

Please sign in to comment.