Updating a cluster
You can update an existing cluster to a new Kubernetes version or configure managed add-ons for your cluster.
Updating an Amazon EKS cluster Kubernetes version
When a new Kubernetes version is available in Amazon EKS, you can update your cluster to the latest version.
We recommend that before updating to a new Kubernetes version that you review the information in Amazon EKS Kubernetes versions and in the update steps in this topic.
New Kubernetes versions have introduced significant changes. Therefore, we recommend that you test the behavior of your applications against a new Kubernetes version before you update your production clusters. You can achieve this by building a continuous integration workflow to test your application behavior before moving to a new Kubernetes version.
The update process consists of Amazon EKS launching new API server nodes with the updated Kubernetes version to replace the existing ones. Amazon EKS performs standard infrastructure and readiness health checks for network traffic on these new nodes to verify that they're working as expected. If any of these checks fail, Amazon EKS reverts the infrastructure deployment, and your cluster remains on the prior Kubernetes version. Running applications aren't affected, and your cluster is never left in a non-deterministic or unrecoverable state. Amazon EKS regularly backs up all managed clusters, and mechanisms exist to recover clusters if necessary. We're constantly evaluating and improving our Kubernetes infrastructure management processes.
To update the cluster, Amazon EKS requires two to three free IP addresses from the subnets that were provided when you created the cluster. If these subnets don't have available IP addresses, then the update can fail. Additionally, if any of the subnets or security groups that were provided during cluster creation have been deleted, the cluster update process can fail.
Even though Amazon EKS runs a highly available control plane, you might experience minor service interruptions during an update. For example, if you attempt to connect to an API server just before or just after it's terminated and replaced by a new API server running the new version of Kubernetes, you might experience API call errors or connectivity issues. If this happens, retry your API operations until they succeed.
Amazon EKS doesn't modify any of your Kubernetes add-ons when you update a cluster. After updating your cluster, we recommend that you update your add-ons to the versions listed in the following table for the new Kubernetes version that you're updating to. Steps to accomplish this are included in the update procedures.
Kubernetes version | 1.19 | 1.18 | 1.17 | 1.16 | 1.15 |
---|---|---|---|---|---|
Amazon VPC CNI plug-in | 1.7 (latest patch version) | 1.7 (latest patch version) | 1.7 (latest patch version) | 1.7 (latest patch version) | 1.7 (latest patch version) |
DNS (CoreDNS) | 1.8.0 | 1.7.0 | 1.6.6 | 1.6.6 | 1.6.6 |
KubeProxy | 1.19.6 | 1.18.8 | 1.17.9 | 1.16.13 | 1.15.11 |
If you're using additional add-ons for your cluster that aren't listed in the previous table, update them to the latest compatible versions after updating your cluster.
Update an existing cluster
Update the cluster and Kubernetes add-ons.
To update an existing cluster
-
Compare the Kubernetes version of your cluster control plane to the Kubernetes version of your nodes.
-
Get the Kubernetes version of your cluster control plane with the following command.
kubectl version --short
-
Get the Kubernetes version of your nodes with the following command. This command returns all self-managed and managed Amazon EC2 and Fargate nodes. Each Fargate pod is listed as its own node.
kubectl get nodes
The Kubernetes minor version of the managed and Fargate nodes in your cluster must be the same as the version of your control plane's current version before you update your control plane to a new Kubernetes version. For example, if your control plane is running version 1.18 and any of your nodes are running version 1.17, update your nodes to version 1.18 before updating your control plane's Kubernetes version to 1.19. We also recommend that you update your self-managed nodes to the same version as your control plane before updating the control plane. For more information see Updating a managed node group and Self-managed node updates. To update the version of a Fargate node, delete the pod that is represented by the node and redeploy the pod after you update your control plane.
-
-
The pod security policy admission controller is enabled by default on Amazon EKS clusters. Before updating your cluster, ensure that the proper pod security policies are in place before you update to avoid any issues. You can check for the default policy with the following command:
kubectl get psp eks.privileged
If you receive the following error, see default pod security policy before proceeding.
Error from server (NotFound): podsecuritypolicies.extensions "eks.privileged" not found
-
If you originally deployed your cluster on Kubernetes
1.17
or earlier, then you may need to remove a discontinued term from your CoreDNS manifest.-
Check to see if your CoreDNS manifest has a line that only has the word
upstream
.kubectl get configmap coredns -n kube-system -o jsonpath='{$.data.Corefile}' | grep upstream
If no output is returned, your manifest doesn't have the line and you can skip to the next step to update your cluster. If the word
upstream
is returned, then you need to remove the line. -
Edit the configmap, removing the line near the top of the file that only has the word
upstream
. Don't change anything else in the file. After the line is removed, save the changes.kubectl edit configmap coredns -n kube-system -o yaml
-
-
Update your cluster using
eksctl
, the AWS Management Console, or the AWS CLI.Important -
Because Amazon EKS runs a highly available control plane, you can update only one minor version at a time. See Kubernetes Version and Version Skew Support Policy
for the rationale behind this requirement. Therefore, if your current version is 1.17 and you want to update to 1.19, then you must first update your cluster to 1.18 and then update it from 1.18 to 1.19. -
Make sure that the
kubelet
on your managed and Fargate nodes are at the same Kubernetes version as your control plane before you update. We also recommend that your self-managed nodes are at the same version as the control plane, though they can be up to one version behind the control plane's current version. -
Updating a cluster from 1.16 to 1.17 will fail if you have any AWS Fargate pods that have a
kubelet
minor version earlier than 1.16. Before updating your cluster from 1.16 to 1.17, you need to recycle your Fargate pods so that theirkubelet
is 1.16 before attempting to update the cluster to 1.17. -
You may need to update some of your deployed resources before you can update to 1.16. For more information, see Kubernetes 1.16 update prerequisites.
-
Updating your cluster to a newer version may overwrite custom configurations.
-
-
Patch the
kube-proxy
daemonset to use the image that corresponds to your cluster's Region and current Kubernetes version (in this example,1.19.6
).Kubernetes version 1.19 1.18 1.17 1.16 1.15 KubeProxy 1.19.6 1.18.8 1.17.9 1.16.13 1.15.11 -
First, retrieve your current
kube-proxy
image:kubectl get daemonset kube-proxy --namespace kube-system -o=jsonpath='{$.spec.template.spec.containers[:1].image}'
Example output
602401143452
.dkr.ecr.us-west-2
.amazonaws.com/eks/kube-proxy:v1.18.8
-eksbuild.1 -
Update
kube-proxy
to the recommended version by replacing
,602401143452
, and andus-west-2
with the values from your output and replacecom
with your cluster's recommended1.19.6
kube-proxy
version. If you're deploying a version that is earlier than1.19.6
, then replace
witheksbuild.2
eksbuild.1
.kubectl set image daemonset.apps/kube-proxy \ -n kube-system \ kube-proxy=
602401143452
.dkr.ecr.us-west-2
.amazonaws.com
/eks/kube-proxy:v1.19.6
-eksbuild.2
-
(Optional) If you're using x86 and Arm nodes in the same cluster and your cluster was deployed before August 17,2020. Then, edit your
kube-proxy
manifest to include a node selector for multiple hardware architectures with the following command. This is a one-time operation. After you've added the selector to your manifest, you don't need to do it each time you update. If your cluster was deployed on or after August 17, 2020, thenkube-proxy
is already multi-architecture capable.kubectl edit -n kube-system daemonset/kube-proxy
Add the following node selector to the file in the editor and then save the file. For an example of where to include this text in the editor, see the CNI manifest
file on GitHub. This enables Kubernetes to pull the correct hardware image based on the node's hardware architecture. - key: "beta.kubernetes.io/arch" operator: In values: - amd64 - arm64
-
(Optional) If your cluster was oriniginally created with Kubernetes v1.14 or later, then you can skip this step because
kube-proxy
already includes thisAffinity Rule
. If you originally created an Amazon EKS cluster with Kubernetes version 1.13 or earilier and intend to use Fargate nodes, then edit yourkube-proxy
manifest to include aNodeAffinity
rule to preventkube-proxy
pods from sheduling on Fargate nodes. This is a one-time edit. Once you've added theAffinity Rule
to your manifest, you don't need to do it each time you upgrade your cluster. Edit yourkube-proxy
daemonset.kubectl edit -n kube-system daemonset/kube-proxy
Add the following
Affinity Rule
to theDaemonset
spec
section of the file in the editor and then save the file. For an example of where to include this text in the editor, see the CNI manifestfile on GitHub. - key: eks.amazonaws.com/compute-type operator: NotIn values: - fargate
-
-
Check your cluster's DNS provider. Clusters that were created with Kubernetes version 1.10 shipped with
kube-dns
as the default DNS and service discovery provider. If you have updated a 1.10 cluster to a newer version and you want to use CoreDNS for DNS and service discovery, then you must install CoreDNS and removekube-dns
.To check if your cluster is already running CoreDNS, use the following command.
kubectl get pod -n kube-system -l k8s-app=kube-dns
If the output shows
coredns
in the pod names, you're already running CoreDNS in your cluster. If not, see Installing or upgrading CoreDNS to install CoreDNS on your cluster, update it to the recommended version, return here, and skip steps 7-8. -
Check the current version of your cluster's
coredns
deployment.kubectl describe deployment coredns --namespace kube-system | grep Image | cut -d "/" -f 3
Output:
coredns:v
<1.6.6>
The recommended
coredns
versions for the corresponding Kubernetes versions are as follows:Kubernetes version 1.19 1.18 1.17 1.16 1.15 CoreDNS 1.8.0 1.7.0 1.6.6 1.6.6 1.6.6 -
If your current
coredns
version is 1.5.0 or later, but earlier than the recommended version, then skip this step. If your current version is earlier than 1.5.0, then you need to modify the config map forcoredns
to use theforward
plug-in, rather than theproxy
plug-in.-
Open the configmap with the following command.
kubectl edit configmap coredns -n kube-system
-
Replace
proxy
in the following line withforward
. Save the file and exit the editor.proxy . /etc/resolv.conf
-
-
Retrieve your current
coredns
image:kubectl get deployment coredns --namespace kube-system -o=jsonpath='{$.spec.template.spec.containers[:1].image}'
-
Update
coredns
to the recommended version by replacing
,602401143452
, andus-west-2
in the following command with your output from the previous command. Replaceamazonaws.com
with the version recommended for your cluster's Kubernetes version and then run the modified command.1.8.0
kubectl set image --namespace kube-system deployment.apps/coredns \ coredns=
602401143452
.dkr.ecr.us-west-2
.amazonaws.com
/eks/coredns:v1.8.0
-eksbuild.1 -
(Optional) If you're using x86 and Arm nodes in the same cluster and your cluster was deployed before August 17,2020, then edit your
coredns
manifest to include a node selector for multiple hardware architectures with the following command. This is a one-time operation. After you've added the selector to your manifest, you don't need to do it each time you update. If you cluster was deployed on or after August 17, 2020, thencoredns
is already multi-architecture capable.kubectl edit -n kube-system deployment/coredns
Add the following node selector to the file in the editor and then save the file. For an example of where to include this text in the editor, see the CNI manifest
file on GitHub. - key: "beta.kubernetes.io/arch" operator: In values: - amd64 - arm64
-
Check the version of your cluster's Amazon VPC CNI Plugin for Kubernetes. Use the following command to print your cluster's CNI version.
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
The output is as follows:
amazon-k8s-cni:
<1.6.3>
If your CNI version is earlier than 1.7, then use the appropriate command below to update your CNI version to the latest 1.7 patch version. You can view the latest patch version
on GitHub. Important Any changes you've made to the plugin's default settings on your cluster can be overwritten with default settings when applying the new version of the manifest. To prevent loss of your custom settings, download the manifest, change the default settings as necessary, and then apply the modified manifest to your cluster.
-
China (Beijing) (
cn-north-1
) or China (Ningxia) (cn-northwest-1
)kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.7/config/v1.7/aws-k8s-cni-cn.yaml
-
For all other Regions
-
Download the manifest file.
curl -o aws-k8s-cni.yaml https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.7/config/v1.7/aws-k8s-cni.yaml
-
Replace
in the following command with the Region that your cluster is in. Then, run the modified command to replace the Region code in the file (currently<region-code>
us-west-2
).sed -i -e 's/us-west-2/
<region-code>
/' aws-k8s-cni.yaml -
Apply the modified manifest file to your cluster.
kubectl apply -f aws-k8s-cni.yaml
-
-
-
(Optional) If you deployed the Kubernetes Cluster Autoscaler to your cluster before updating the cluster, update the Cluster Autoscaler to the latest version that matches the Kubernetes major and minor version that you updated to.
-
Open the Cluster Autoscaler releases
page in a web browser and find the latest Cluster Autoscaler version that matches your cluster's Kubernetes major and minor version. For example, if your cluster's Kubernetes version is 1.19 find the latest Cluster Autoscaler release that begins with 1.19. Record the semantic version number ( <1.19.n>
) for that release to use in the next step. -
Set the Cluster Autoscaler image tag to the version that you recorded in the previous step with the following command. If necessary, replace
1.19
.n
with your own value.kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v
1.19
.n
-
-
(Clusters with GPU nodes only) If your cluster has node groups with GPU support (for example,
p3.2xlarge
), you must update the NVIDIA device plugin for KubernetesDaemonSet on your cluster with the following command. kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.8.0/nvidia-device-plugin.yml
-
After your cluster update is complete, update your nodes to the same Kubernetes version of your updated cluster. For more information, see Self-managed node updates or Updating a managed node group. Any new pods launched on Fargate will have a
kubelet
version that matches your cluster version. Existing Fargate pods won't be changed.
Kubernetes 1.16 update prerequisites
As noted in the Kubernetes 1.15 changelog
If you don't change these APIs before updating to 1.16, workloads fail after the update is complete.
-
NetworkPolicy resources will no longer be served from
extensions/v1beta1
in v1.16. Migrate use to thenetworking.k8s.io/v1
API, available since v1.8. Existing persisted data can be retrieved through thenetworking.k8s.io/v1
API. -
PodSecurityPolicy resources will no longer be served from
extensions/v1beta1
in v1.16. Migrate to thepolicy/v1beta1
API, available since v1.10. Existing persisted data can be retrieved through thepolicy/v1beta1
API. -
DaemonSet, Deployment, StatefulSet, and ReplicaSet resources will no longer be served from
extensions/v1beta1
,apps/v1beta1
, orapps/v1beta2
in v1.16. Migrate to theapps/v1
API, available since v1.9. Existing persisted data can be retrieved through theapps/v1
API. For example, to convert a Deployment that currently usesapps/v1beta1
, enter the following command.kubectl convert -f ./<my-deployment.yaml> --output-version apps/v1
Note The previous command may use different default values from what is set in your current manifest file. To learn more about a specific resource, see the Kubernetes API reference
.
If you originally created an Amazon EKS cluster with Kubernetes version 1.11 or earlier
and haven't removed the --resource-container
flag from the
kube-proxy
DaemonSet, then updating to Kubernetes 1.16 will cause
kube-proxy
failures. This flag is no longer supported in Kubernetes
1.16. For more information, see kube-proxy
in Kubernetes 1.16 Deprecations and removals
What you need to do before updating to 1.16
-
Change your YAML files to reference the new APIs.
-
Update custom integrations and controllers to call the new APIs.
-
Ensure that you use an updated version of any third party tools, such as ingress controllers, continuous delivery systems, and other tools that call the new APIs.
To easily check for discontinued API usage in your cluster, make sure that the
audit
control plane log is enabled, and specifyv1beta
as a filter for the events. All of the replacement APIs are in Kubernetes versions later than 1.10. Applications on any supported version of Amazon EKS can begin using the updated APIs now. -
Remove the
--resource-container=""
flag from yourkube-proxy
DaemonSet, if your cluster was originally deployed with Kubernetes 1.11 or earlier or use a kube-proxy configuration file (recommended). To determine whether your current version ofkube-proxy
has the flag, enter the following command.kubectl get daemonset kube-proxy --namespace kube-system -o yaml | grep 'resource-container='
If you receive no output, then you don't need to remove anything. If you receive output similar to
--resource-container=""
, then you need to remove the flag. Enter the following command to edit your currentkube-proxy
config.kubectl edit daemonset kube-proxy --namespace kube-system
With the editor open, remove the
--resource-container=""
line, and save the file. We recommend that you instead, start using a kube-proxy configuration file. To do so, download the following manifest.curl -o kube-proxy-daemonset.yaml https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2020-06-10/kube-proxy-daemonset.yaml
Determine your cluster's endpoint with the following command.
aws eks describe-cluster \ --name
<cluster-name>
\ --region<region-code>
\ --query 'cluster.endpoint' \ --output textThe output is as follows:
https://
<A89DBB2140C8AC0C2F920A36CCC6E18C>
.sk1.<region-code>
.eks.amazonaws.comEdit the
kube-proxy-daemonset.yaml
file that you downloaded. In your editor, replace<MASTER_ENDPOINT>
(including<>
) with the output from the previous command. Replace<REGION>
with your cluster's Region. On the same line, replace the version with the version of your cluster if necessary. Apply the file with the following command.kubectl apply -f kube-proxy-daemonset.yaml
Configure an Amazon EKS add-on
An add-on is Kubernetes operational software that provides capabilities like
observability, scaling, networking, and AWS cloud resource integrations for your Amazon
EKS
cluster. You can manage add-ons yourself, or let Amazon EKS control the launch and
version of
the add-on through the Amazon EKS API for clusters running Kubernetes version 1.18
with
platform version eks.3
or later. Amazon EKS add-ons use the Kubernetes Server-Side Apply feature, which is only available with
Kubernetes version 1.18 or later. For more information, see Server-Side
Apply
You can configure an eksctl
using eksctl or the AWS Management Console.
Enabling envelope encryption on an existing cluster
If you enable secret encryption, the Kubernetes secrets are encrypted using the AWS
Key Management Service (KMS) customer master key (CMK) that you select. The CMK must
be
symmetric, created in the same region as the cluster, and if the CMK was created in
a
different account, the user must have access to the CMK. For more information, see
Allowing
users in other accounts to use a CMK in the AWS Key Management Service Developer
Guide. Enabling envelope encryption on an existing cluster is supported
for Kubernetes version 1.13
or later.
You cannot disable envelope encryption after enabling it. This action is irreversible.
After you have enabled encryption on your cluster, you will need to encrypt all existing secrets with the new key:
eksctl
users do not need to run the following command unless they
chose to opt-out of re-encrypting their secrets automatically.
kubectl get secrets --all-namespaces -o json | kubectl annotate --overwrite -f - kms-encryption-timestamp="<time value>"
If you enable envelope encryption for an existing cluster and the key that you use is ever deleted, then there is no path to recovery for the cluster. Deletion of the CMK will permanently put the cluster in a degraded state.
By default, the create-key
command creates a symmetric key with a key policy that gives the account's root user
admin access on AWS KMS actions and resources. If you want to scope down the
permissions, make sure that the kms:DescribeKey
and
kms:CreateGrant
actions are permitted on the key policy for the
principal that will be calling the create-cluster
API.
Amazon EKS does not support the key policy condition kms:GrantIsForAWSResource
. Creating a cluster will not work
if this action is in the key policy statement.