Upgrade Cluster
PMK supports fully automated rolling upgrades to Kubernetes clusters. Upgrades are performed across major versions of Kubernetes, so you can continue leveraging latest Kubernetes features without the hassle of having to upgrade the cluster yourself.
We upgrade nodes in a cluster one at a time, ensuring that the last upgraded node is healthy before upgrading the next. This is called a rolling upgrade, and has the following benefits.
- Your applications will not experience downtime during the cluster upgrade, as long as they tolerate the failure of a single node.
- Your cluster users and your Kubernetes-native applications - ones that talk to the Kubernetes API server - will be able use the API while worker nodes are being upgraded. If your cluster has multiple masters, then your API server will remain available across upgrades to master nodes as well. For a single master cluster, the API server will experience a momentary downtime while the master node is being upgraded.
- All nodes in your cluster will remain compatible during the cluster upgrade, despite running different versions of Kubernetes as the upgrade proceeds.
You can upgrade a cluster at any time after a new Platform9 release or mid-release Kubernetes upgrade. Clusters that have an upgrade available will be marked with an "Upgrade Available" status on the Infrastructure Clusters dashboard.
Upgrade your Cluster
You must be an administrator to perform this operation.
Follow the steps given below to upgrade a cluster.
- Navigate to Infrastructure dashboard Clusters tab.
- Select a Cluster.
- Click the Upgrade action in the table action bar.
The cluster will be upgraded.
Planning for an Upgrade
To upgrade a node, PMK first requests Kubernetes to not schedule any further pods on the node. It then evacuates (or drains, in the Kubernetes parlance) existing pods from the node. Evacuating a node will remove **unmanaged pods**
(see explanation below) and permanently erase data in **emptyDir Volumes**
(see explanation below).
Managed vs Unmanaged Pods
A Kubernetes pod falls into two categories:
Managed Pods
Pods are managed by one of the following controllers and each type behaves differently during an upgrade:** **
ReplicationController - rescheduled by Kubernetes to other nodes as long as resources are available.
ReplicaSet - rescheduled by Kubernetes to other nodes as long as resources are available.
Job - rescheduled by Kubernetes to other nodes as long as resources are available.
DaemonSet - stopped during the upgrade, but the pods remain on the node.
Unmanaged Pods
These are pods that are not managed by any Kubernetes controller. These pods will be removed from the node during the upgrade and will not be rescheduled by Kubernetes. For that reason, unmanaged pods should not be used in production, though they are useful for experimenting and debugging.
Pods using 'emptyDir Volumes'
Pods have access to persistent storage through Kubernetes persistent volumes. If your pod uses an emptyDir Volume
, be warned that all data stored in this volume will be erased when the pod is removed from the node. This warning applies to any unmanaged pod as well as all pods managed by a ReplicationController
, a ReplicaSet
, or a Job
.
Note that, if the node fails, the data on this volume may be unrecoverable. For the reason, emptyDir
Volumes should not be used in production.
##
You deployed your application using a Replication Controller and can tolerate momentary downtime
You can temporarily scale your application to zero pods using the following bash script.
# Usage: temporary_scale_to_zero.sh myrc
replicationcontroller=$1
current_replicas=$(kubectl get rc $replicationcontroller -o jsonpath="{.status.replicas}") kubectl scale rc $replicationcontroller --replicas=0
kubectl scale rc $replicationcontroller --replicas=$current_replicas
Example usage:
temporaryscale to_zero.sh myrc
You deployed your application using a Replication Controller and cannot tolerate momentary downtime
If you cannot tolerate any downtime, you can simulate an in-place rolling update. We implement this by copying your existing Replication Controller definition, replacing its name, then performing a rolling update from the existing to the new Replication Controller.
# Usage: inplace_rolling_update.sh myrc myrc_newname
replicationcontroller=$1
replicationcontroller_newname=$2
kubectl patch rc/$replicationcontroller -p '{"spec":{"selector":{"secrets":"old"},"template":{"metadata":{"labels":{"secrets":"old"}}}}}'
kubectl get rc/$replicationcontroller -o yaml | sed -e 's/secrets: old/secrets: new/g' -e "0,/name: ${replicationcontroller}/{s/name:${replicationcontroller}/name:${replicationcontroller_newname}/}" -e 's/resourceVersion.*//' | kubectl rolling-update $replicationcontroller --update-period=10s -f -
Example usage:
inplace_rolling_update.sh myrc myrc_newname
You deployed your application as one or more stand-alone Pods
If you deployed your application as one or more Pods that are not managed by a Replication Controller, you will need to delete and re-create each of the Pods.
# Usage: delete_recreate_pod.sh mypod
pod=$1 kubectl get pod $pod -o yaml | kubectl replace -f -
Example usage:
delete_recreate_pod.sh mypod