{#if upgrade.toNextMinor.length === 0 || upgrade.toNextMinor[0] !== upgrade.nextMinorEntry}
You are viewing documentation for Kubernetes 1.27, Cluster Stack release hetzner-apalla-1-27-v15.
## Update your Cluster Stack release first
To upgrade to Kubernetes 1.28, first update your cluster to Cluster Stack release hetzner-apalla-1-27-v19 by following this guide: [Updating the cluster with same Kubernetes version](/docs/hetzner/apalla/clusters/upgrades/update-within-a-version). Once that update is complete, return to this guide to upgrade your Kubernetes version.
## Not sure which version your cluster uses?
[Check the Kubernetes version and Cluster Stack](/docs/hetzner/apalla/clusters/configure/how-to-check-the-kubernetes-version-and-stack) of your cluster.
{:else}
{#if release.hasArmImages}
## Check for ARM-based nodes
If your cluster isn't running ARM-based nodes, skip this step.
Starting from `hetzner-apalla-1-33-v11`, `hetzner-apalla-1-34-v8`, and `hetzner-apalla-1-35-v3`, ARM is temporarily not supported. If your cluster has any, the upgrade will fail unless you migrate them to x86 nodes first — see [Migrate ARM servers to x86 in your cluster](/docs/hetzner/apalla/servers-and-nodes/provision/migrate-arm-to-x86) for instructions.
{/if}
This guide will detail the process of upgrading your cluster from Kubernetes 1.27 to 1.28.
## Upgrading the cluster
Adding a new Cluster Stack
Add a new `ClusterStack` and `HetznerClusterStackReleaseTemplate` for the newer Kubernetes minor version:
{#if upgrade.nextMinorEntry === nextMinor?.latest}
```yaml vars title="clusterstack.yaml"
apiVersion: clusterstack.x-k8s.io/v1alpha1
kind: ClusterStack
metadata:
name: hetzner-apalla-1-28
spec:
provider: hetzner
name: apalla
kubernetesVersion: "1.28"
channel: stable
autoSubscribe: true
providerRef:
name: hetzner-apalla-1-28
kind: HetznerClusterStackReleaseTemplate
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
---
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
kind: HetznerClusterStackReleaseTemplate
metadata:
name: hetzner-apalla-1-28
spec:
template:
spec:
nodeImages:
- controlplaneamd64hcloud
- workeramd64hcloud
```
{:else}
```yaml vars title="clusterstack.yaml"
apiVersion: clusterstack.x-k8s.io/v1alpha1
kind: ClusterStack
metadata:
name: hetzner-apalla-1-28
spec:
provider: hetzner
name: apalla
kubernetesVersion: "1.28"
channel: stable
autoSubscribe: true
versions: ["v19"]
providerRef:
name: hetzner-apalla-1-28
kind: HetznerClusterStackReleaseTemplate
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
---
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
kind: HetznerClusterStackReleaseTemplate
metadata:
name: hetzner-apalla-1-28
spec:
template:
spec:
nodeImages:
- controlplaneamd64hcloud
- workeramd64hcloud
```
{/if}
```yaml vars title="clusterstack.yaml"
apiVersion: clusterstack.x-k8s.io/v1alpha1
kind: ClusterStack
metadata:
name: hetzner-apalla-1-28
spec:
provider: hetzner
name: apalla
kubernetesVersion: "1.28"
channel: stable
autoSubscribe: false
versions: ["v19","v11"]
providerRef:
name: hetzner-apalla-1-28
kind: HetznerClusterStackReleaseTemplate
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
---
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
kind: HetznerClusterStackReleaseTemplate
metadata:
name: hetzner-apalla-1-28
spec:
template:
spec:
nodeImages:
- controlplaneamd64hcloud
- workeramd64hcloud
```
Apply it to the cluster with your tool of choice.
> [!TIP]
> For versions before hetzner-apalla-1-35-v1, node images for the new version will start to build. The build process takes around 5 minutes. You can check the status of the newly created Cluster Stack object if something seems wrong.
Checking the available ClusterStackReleases
The next step is to is to check the available `ClusterStackReleases`:
{#if upgrade.nextMinorEntry === nextMinor?.latest}
```console vars
$ kubectl get clusterstackrelease
NAME K8S VERSION READY AGE REASON MESSAGE
hetzner-apalla-1-27-v15 v1.27.13 true 2d
hetzner-apalla-1-28-v11 v1.28.15 true 1m
```
{:else}
```console vars
$ kubectl get clusterstackrelease
NAME K8S VERSION READY AGE REASON MESSAGE
hetzner-apalla-1-27-v15 v1.27.13 true 2d
... ... true 1m
hetzner-apalla-1-28-v11 v1.28.15 true 1m
```
{/if}
Note down the values of the `NAME` and `K8S VERSION` columns from the release you want to upgrade to.
Now we edit our cluster and change the `spec.topology.class` and `spec.topology.version` to match the `NAME` and `K8S VERSION` of our Cluster Stack release:
{#if upgrade.nextMinorEntry === nextMinor?.latest}
> [!NOTE]
> The manifest below uses `cluster.x-k8s.io/v1beta2`, the current API version for cluster manifests. `v1beta1` keeps working for now, but Syself recommends migrating: see [Migrate a manifest to v1beta2](/docs/hetzner/apalla/clusters/upgrades/migrate-a-manifest-to-v1beta2).
```yaml vars persistBlur title="cluster.yaml"
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: mycluster
spec:
topology:
classRef:
name: hetzner-apalla-1-28-v11
version: v1.28.15
controlPlane:
replicas: 3
workers:
machineDeployments:
- class: workeramd64hcloud
name: md-0
replicas: 1
failureDomain: nbg1
variables:
overrides:
- name: workerMachineTypeHcloud
value: cpx42
variables:
- name: region
value: nbg1
- name: controlPlaneMachineTypeHcloud
value: cpx42
```
{:else}
{/if}
This can be achieved either by editing the resource inside the management cluster, or by updating it in your GitOps repository.
Syself now rolls the cluster to the new Kubernetes minor version, one node at a time. The control plane and the API server stay available throughout. Bare-metal control-plane and worker pools run one fewer node during each step, so size them with headroom; the [prechecks](/docs/hetzner/apalla/clusters/upgrades/plan-maintenance-and-prechecks) cover this.
When the roll finishes, confirm every node reports the new version and `Ready`, the control plane and etcd are healthy, and your workloads still serve traffic. If a rollout stalls, see [Stuck or failed upgrade](/docs/hetzner/apalla/clusters/troubleshooting/stuck-or-failed-upgrade).
If you are no longer using the old `ClusterStack` and `HetznerClusterStackReleaseTemplate` anymore, you can remove them now.
## Not sure which Kubernetes minor and Cluster Stack release your cluster uses?
[Check the Kubernetes version and Cluster Stack](/docs/hetzner/apalla/clusters/configure/how-to-check-the-kubernetes-version-and-stack) of your cluster.
{/if}