背景

随着应用容器化不断流行与深入,采用Kubernetes(K8S)作为容器编排方式的应用也随之增加。作为亚马逊云科技的用户,在云上使用Amazon Web Services托管的K8S服务Amazon Elastic Kubernetes Service(Amazon EKS)服务的客户也在不断增加。同时根据K8S社区的发布规则K8S每年会有三个小版本的发布, 相应的Amazon EKS也会跟随上游K8S的版本发布3个版本,目前支持的版本以及相应终止支持的时间信息可以参考亚马逊Amazon EKS发布日历。每个上游的K8S版本都会有1年支持窗口加上2个月升级过渡窗口,为了保持与K8S社区版本的同步来获得社区的支持,客户每隔一段时间都要对现有的K8S或者Amazon EKS集群做升级,也就是说K8S与Amazon EKS的升级已经成为常态。

  • 亚马逊Amazon EKS发布日历

    https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/kubernetes-versions.html

在Amazon EKS上这个升级主要涉及到控制平面升级、数据平面升级与插件组件升级。其中以数据平面的升级最为繁琐与复杂,所以本着减少无差别的繁重的运维工作为出发点,本文通过一个端到端的实验详细介绍通过使用托管节点组与启动模板简化客户的升级操作的过程与方法,从而为运维人员减负。并实现应用的平滑升级与灵活回退,进而保证应用与业务的稳定和可用性。

???? 想要了解更多亚马逊云科技最新技术发布和实践创新,敬请关注2021亚马逊云科技中国峰会!点击图片报名吧~

了解Amazon EKS的用户或者读者知道Amazon EKS的数据平面可以分为有服务器与无服务器两大类:有服务器即采用Amazon EC2的方式来运行K8S的应用;无服务器的方式即Amazon EKS Fargete,客户将工作负载部署在Fargate的环境而不是自己的VPC内,Amazon EKS节点对客户透明。有服务器Amazon EC2的节点管理方式又分为两种模式:托管节点组(Managed Node Group)与非托管节点组(Unmanaged Node Group)。非托管节点组的命名来自于官方的Amazon EKS创建与维护工具eksctl.io文档中Unmanaged Node Group的中文直译,根据Amazon EKS官方文档, 非托管节点组模式被称为自行管理的节点(Self-managed nodes),为了简化与对比起见本文统一称为非托管节点组。托管节点组即将集群Amazon EC2节点的创建与生命周期管理由Amazon EKS服务来自动化管理,不需要客户干预。根据eksctl对非托管节点组的设计原则,非托管节点组中的节点除了可以做扩缩容其他配置均不可变。下表列出了两种模式的主要区别:

  • 托管节点组

    https://eksctl.io/usage/eks-managed-nodes/

  • 非托管节点组

    https://eksctl.io/usage/nodegroup-upgrade/

  • eksctl对非托管节点组的设计原则

    https://eksctl.io/usage/managing-nodegroups/#nodegroup-immutability

  • 官方文档

    https://docs.aws.amazon.com/eks/latest/userguide/update-workers.html

考虑到Amazon EKS 1.17将于2021年11月终止支持,同时目前绝大部分客户使用的还是Amazon EC2的方式,并且因为非托管节点组相对于托管节点组的功能是更早发布,加上早期的托管节点组功能较少的原因,一部分客户还停留在非托管节点组的模式,所以本文的实验通过将非托管节点组转换为托管节点组结合启动模板的方式简化Amazon EKS 集群从1.17升级到1.18的升级过程(虽然本实验进行的的是1.17到1.18的升级,但过程和其中的方法对其他Amazon EKS版本的升级同样适用,比如从1.15升级到1.16或者1.18升级到1.19)。其中主要内容涵盖:控制平面升级、数据平面非托管节点组迁移到托管节点组、托管节点组升级与变更等。

在升级路径的选择上,也可以先将控制平面由1.17升级到1.18,然后创建托管节点组,再将工作负载由非托管节点组迁移到托管节点组,这样可以减少一次数据平面托管节点组的升级,加快集群整体升级的过程。因为本文的重点是介绍推广托管节点组结合启动模板的实践方法,先升级控制平面再创建托管节点组的做法,笔者测试下来对于文中简单的样例应用Nginx是可以的,遵从K8S官方的Version Skew Policy:kubelet must not be newer than kube-apiserver, and may be up to two minor versions older。笔者尝试过将控制平面从1.17升级到1.18再连续升级到1.19,然后再创建托管节点组与迁移工作负载也是可以成功通过的,但如果集群中有对1.17到1.18/1.19版本变化敏感或者需要改造的应用,稳妥起见还是建议按照本实验的顺序来操作,并引入必要的测试。有兴趣的读者可以自行测试验证。

  • Version Skew Policy

    https://kubernetes.io/releases/version-skew-policy/

本文目标读者:Amazon EKS运维与管理人员

实验所需时长:3小时

操作步骤

前提:当前使用的用户具有Administrator Access权限

准备Cloud9实验环境

在亚马逊云科技管理控制台中选择Cloud9服务,然后创建一个名称为:eksworkshop的环境,将Cost-saving setting选项设置为:After four hours,其他配置保持默认。创建完毕后关闭Welcome和底部的工作区页面,然后在主工作区中打开一个新的Terminal。

在Amazon IAM服务中,使用链接创建一个名称为:eksworkshop-admin的角色,确认:Amazon service和Amazon EC2被选中,点击下一步,确认AdministratorAccess策略被选中,点击下一步,跳过Tag选项,点击下一步在Review页面中输入eksworkshop-admin作为新角色的名称,点击创建角色完成创建。

  • 链接

    https://console.aws.amazon.com/iam/home#/roles$new?step=type&commonUseCase=EC2%2BEC2&selectedUseCase=EC2&policies=arn:aws:iam::aws:policy%2FAdministratorAccess

点击链接在Amazon EC2服务中查看刚刚创建的Cloud9环境对应的Amazon EC2实例,选中该实例,然后在菜单选择:Actions / Security / Amazon Modify IAM Role,在Amazon IAM Role的下拉列表中选择eksworkshop-admin的角色,点击保存。

  • 链接

    https://console.aws.amazon.com/ec2/v2/home?#Instances:tag:Name=aws-cloud9-eksworkshop;sort=desc:launchTime

返回刚刚创建好的Cloud9环境,点击页面右上角的齿轮,打开首选项设置页面,然后选择 SETTINGS,关闭Amazon managed temporary credentials单选框,最后关闭首选项设置页面。

在打开的终端中运行以下命令确认临时的秘钥凭证已经被删除干净,并验证在返回结果的ARN 中包含eksworkshop-admin。

rm -vf ${HOME}/.aws/credentials

aws sts get-caller-identity

运行下列脚本安装实验所需的Kubernetes 工具:

eksctl,kubectl,helm,jq,amazon cli

# create a folder for the scripts
mkdir ~/environment/scripts
# tools script
cat > ~/environment/scripts/install-tools <<-"EOF"
#!/bin/bash -ex
sudo yum install -y jq gettext bash-completion

# install kubectl
sudo curl --silent --location -o /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.18.10/bin/linux/amd64/kubectl
sudo chmod +x /usr/local/bin/kubectl
echo 'source <(kubectl completion bash)' >>~/.bashrc
source ~/.bashrc
# install eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin
if ! [ -x "$(command -v jq)" ] || ! [ -x "$(command -v envsubst)" ] || ! [ -x "$(command -v kubectl)" ] || ! [ -x "$(command -v eksctl)" ] || ! [ -x "$(command -v ssm-cli)" ]; then
  echo 'ERROR: tools not installed.' >&2
  exit 1
fi
#pip install awscli --upgrade --user
# install aws cli v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
. ~/.bash_profile
# install helm 3
curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm version --short
helm repo add stable https://charts.helm.sh/stable
helm completion bash >> ~/.bash_completion
. /etc/profile.d/bash_completion.sh
. ~/.bash_completion
source <(helm completion bash)
helm repo update
EOF
chmod +x ~/environment/scripts/install-tools
~/environment/scripts/install-tools

创建Amazon EKS集群(版本:1.17)

配置创建集群需要的环境变量

export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')
export EKS_CLUSTER_NAME=eksworkshop
export EKS_UNMANAGED_NODEGROUP_NAME=ung-1
export EKS_MANAGED_NODEGROUP_NAME=mng-1
export AWS_DEFAULT_REGION=$AWS_REGION
echo "export ACCOUNT_ID=${ACCOUNT_ID}" >> ~/.bash_profile
echo "export AWS_REGION=${AWS_REGION}" >> ~/.bash_profile
echo "export AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}" >> ~/.bashrc
echo "export EKS_CLUSTER_NAME=${EKS_CLUSTER_NAME}" >> ~/.bashrc
echo "export EKS_MANAGED_NODEGROUP_NAME=${EKS_MANAGED_NODEGROUP_NAME}" >> ~/.bashrc
echo "export EKS_UNMANAGED_NODEGROUP_NAME=${EKS_UNMANAGED_NODEGROUP_NAME}" >> ~/.bashrc
aws configure set default.region ${AWS_REGION}
aws configure get default.region

运行下列命令创建Amazon EKS集群配置模板文件 eks-cluster.yml.template

cat > ~/environment/scripts/eks-cluster.yml.template <<-"EOF"
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: $EKS_CLUSTER_NAME
  region: $AWS_REGION
  version: "1.17"
nodeGroups:
  - name: $EKS_UNMANAGED_NODEGROUP_NAME
    minSize: 1
    maxSize: 3
    desiredCapacity: 2
    labels: {role: unmanaged-ng-worker}
    tags:
      Name: unmanaged-ng-worker
EOF

利用 eksctl 工具来创建 Amazon EKS 集群,运行下列命令创建一个 Amazon EKS 1.17 的集群,同时会创建一个新的 VPC,并且在该VPC中创建 一个含有2个节点的非托管节点组,整个过程大概需要 20 分钟左右(集群和节点组各10分钟左右)。

envsubst < ~/environment/scripts/eks-cluster.yml.template > ~/environment/scripts/eks-cluster.yml

eksctl create cluster -f ~/environment/scripts/eks-cluster.yml
  •  eksctl 

    https://eksctl.io/

在Amazon EKS服务界面上验证集群eksworkshop已经成功创建。运行下列命令验证 Amazon EKS 集群节点组ung-1已经成功创建

eksctl get nodegroup --cluster $EKS_CLUSTER_NAME

运行下列命令测试 Amazon EKS 集群节点是否正常工作

kubectl get nodes --show-labels

运行下列命令将当前登录管理控制台的用户加入到Amazon EKS集群管理员组中,这样使得当前登录用户可以在Amazon EKS服务界面上查看集群信息。

c9builder=$(aws cloud9 describe-environment-memberships --environment-id=$C9_PID | jq -r '.memberships[].userArn')
if echo ${c9builder} | grep -q user; then
    rolearn=${c9builder}
        echo Role ARN: ${rolearn}
elif echo ${c9builder} | grep -q assumed-role; then
        assumedrolename=$(echo ${c9builder} | awk -F/ '{print $(NF-1)}')
        rolearn=$(aws iam get-role --role-name ${assumedrolename} --query Role.Arn --output text) 
        echo Role ARN: ${rolearn}
fi
eksctl create iamidentitymapping --cluster $EKS_CLUSTER_NAME --arn ${rolearn} --group system:masters --username admin

我们可以在Amazon EC2控制台看到新创建了2个名称为eksworkshop-ung-1-Node类型为m5.large 的Amazon EC2实例,也可以在管理控制台的Amazon EKS服务的集群列表中查看刚刚创建好的集群节点、网络和其他集群配置信息。因为我们刚刚创建的是一个非托管节点组,所以如下图所示在Amazon EKS > Clusters > eksworkshop > Compute界面查看托管节点组为空

同时,因为eksctl工具的底层实现是依赖Amazon CloudFormation服务的,所以可以再Amazon CloudFormation服务的管理界面查看为了创建集群而新建的2个

Amazon CloudFormaiton模板:集群控制平面Amazon CloudFormaiton Stack、非托管节点组Amazon CloudFormaiton Stack。

部署样例工作负载

cat > ~/environment/scripts/nginx.yaml <<-"EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: "nginx"
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
EOF
kubectl apply -f ~/environment/scripts/nginx.yaml

通过下列命令参考样例Nginx程序已经成功部署

kubectl get deploy

kubectl get po

创建启动模板

进入Amazon EC2服务,选择Launch Templates > Create launch template,分别填入

  • Launch template name:demo

  • Instance type:large

  • Security groups:在Amazon EKS集群管理控制台 Amazon EKS > Clusters > eksworkshop > Networking中显示Cluster security groupInfo的安全组ID

  • Resource Tags Key: Name, Value: eksworkshop-mng-1, Resource types: Instances

  • User Data: 如果某些客户在使用非托管节点组的配置YAML文件中有使用:preBootstrapCommands或者overrideBootstrapCommand之类的一些自定义命令,那么在转换到托管节点组加启动模板这种方式后将不再支持,如果继续使用会出现错误:cannot set instanceType, ami, …, preBootstrapCommands, overrideBootstrapCommand, placement in managedNodeGroup when a launch template is supplied。用户可以将这些选项中配置的SHELL命令迁移到User Data中。如果有使用自定义Amazon AMI,则必须在User Data中填入下列命令将节点加入到集群,否则会出现错误:node bootstrapping script (UserData) must be set when using a custom AMI。具体User Data输入的MIME格式要求请参考这里的官方文档

    #!/bin/bash
    /etc/eks/bootstrap.sh cluster_name
    
  • 官方文档

    https://docs.amazonaws.cn/eks/latest/userguide/launch-templates.html

点击Create launch template创建启动模板。在启动模板的版本列表中查看刚刚创建好的版本号为1的启动模板,因为启动模板的版本是不可变的,只能通过选择版本1后点击Actions > Modify template (Create new version)来创建新的版本。

如果在Amazon EKS集群中有使用自定义Amazon AMI,那么可以在创建模板过程中指定已经定义好的Amazon AMI。需要注意的是,根据Amazon EKS升级官方文档在升级控制平面之前要求自定义Amazon AMI的节点版本需要与控制平面的版本相同。在本实验中来说就是要求自定义Amazon AMI及kubelet版本必须是1.17。这样当控制平面升级到1.18以后就会导致托管节点组还停留在1.17版本,存在一个小版本的差异。这样在托管节点组升级到1.18之前是不能将控制平面升级到版本1.19,否则得到错误提示:Nodegroups xxx must be updated to match cluster version 1.1x before updating cluster version。如果自定义Amazon AMI的节点组比控制平面低一个版本,则不能直接在界面上通过点击“Update now”操作来升级节点组。如果后续有继续将版本从1.18升级到更高版本的需求则需要根据目标Amazon EKS版本的Amazon EKS优化Amazon AMI重新定义自己的Amazon AMI,通过创建新的启动模板版本来指定这个新的Amazon AMI,然后再托管节点组中切换启动模板版本即可完成升级。具体切换启动模板版本的流程可以参考下面的章节“切换启动模板版本”。

  • Amazon EKS升级官方文档

    https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html

创建托管节点组

运行下列命令设置环境变量并创建托管节点组

export LT_ID=$(aws ec2 describe-launch-templates --launch-template-name demo --output json | jq -r '.LaunchTemplates[0].LaunchTemplateId')
cat > ~/environment/scripts/mng-1.yml.template <<-"EOF"
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: $EKS_CLUSTER_NAME
  region: $AWS_REGION
  version: "1.17"
managedNodeGroups:
  - name: $EKS_MANAGED_NODEGROUP_NAME
    minSize: 1
    maxSize: 3
    desiredCapacity: 2
    labels: {role: managed-ng-worker}
    launchTemplate:
      id: $LT_ID
      version: "1"
EOF
envsubst < ~/environment/scripts/mng-1.yml.template > ~/environment/scripts/mng-1.yml
eksctl create nodegroup -f ~/environment/scripts/mng-1.yml

整个过程大概需要 3分钟左右。之后我们可以在Amazon EC2控制台看到新创建了2个名称为eksworkshop-mng-1类型为m5.large 的Amazon EC2实例。同时因为我们刚刚创建的是一个托管节点组,所以如下图所示在Amazon EKS > Clusters > eksworkshop > Compute界面可以查看到刚刚创建的托管节点组。

注意上述托管节点组的配置文件中设置的版本1.17是与控制平面一致的版本,如果托管节点组配置的版本与Amazon EKS集群控制平面不一致时,eksctl会自动使用控制平面版本。

从选中的部分可以看出托管节点组mng-1对应的启动模本名称为demo版本为1。也可以运行下列命令验证 Amazon EKS 集群节点组mng-1已经成功创建

eksctl get nodegroup --cluster $EKS_CLUSTER_NAME

运行下列命令测试 Amazon EKS 集群新加入的两个节点是否正常工作

kubectl get nodes --show-labels

需要特别指出的是启动模板对于创建托管节点组是一个推荐的可选项。不预先配置启动模板,而是直接利用下列的配置文件也可以创建托管节点组。因为在配置中没有显示的配置启动模板,eksctl会根据配置自动生成一个名称为“eksctl-集群名称-nodegroup-托管节点组名称 (N)”的一个启动模板,这个启动模板是由eksctl创建、管理和维护,因此不建议手动创建新版本修改或者复用。这种方式下创建的每个托管节点组的启动模板都是独立的,不能复用,如果有统一配置的需求和后续针对单个节点组的修改需求就更加麻烦。同时因为没有在配置文件中显示的指定启动模板,需要根据命名规则或者在Amazon EKS的托管节点组控制界面上查询这个启动模板,所以这种方式不利于配置变更的跟踪。而显示的声明在多个托管节点组中可以共用一个启动模板,当出现不同的配置需求时又可以通过新建启动模板版本来解决,相对于隐式的方式更加灵活高效,所以在本实验中托管节点组采用的是显示的启动模板。

---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: eksworkshop
  region: us-east-1
  version: "1.17"
  availabilityZones: ["us-east-1a", "us-east-1b", "us-east-1c"]
managedNodeGroups:
- name: nodegroup
  minSize: 1
  maxSize: 3
  desiredCapacity: 3
  instanceType: m5.large
  ssh:
    enableSsm: true

迁移工作负载并删除非托管节点组

因为非托管节点组的不可变性,除了改变节点数量无法更改其配置,所以当遇到升级集群版本的情况是需要创建新的非托管节点组然后迁移负载再删除旧的节点组的方法来实现升级节点组。而托管节点组可以做到原地(In place)升级,所以本实验先将样例工作负载迁移到托管节点组再做集群的升级。

  • 不可变性

    https://eksctl.io/usage/managing-nodegroups/#nodegroup-immutability

运行下列命令查验当前的nginx pod运行在非托管节点组的节点上

kubectl get po -o wide

运行下列命令将在非托管节点组的节点上的工作负载驱逐到刚刚创建的托管节点组

eksctl drain nodegroup --cluster=$EKS_CLUSTER_NAME --name=$EKS_UNMANAGED_NODEGROUP_NAME

运行命令:

kubectl get no

可以发现旧节点组的状态已经变为:Ready,SchedulingDisabled,重新运行下列命令查当前的nginx pod运行在托管节点组的节点上

kubectl get po -o wide

运行下列命令删除非托管节点组

eksctl delete nodegroup --cluster $EKS_CLUSTER_NAME --name $EKS_UNMANAGED_NODEGROUP_NAME

运行下列命令监视节点删除情况直至非托管节点组被完全删除。

kubectl get no -w

升级集群控制平面

如下图所示在Amazon EKS集群控制台上点击Update Now升级集群控制平面,因为K8S需要逐个版本升级,所以只有1.18目标版本是可选状态。

升级后如下图所示集群处于Updating状态,整个升级过程大约需要30~40分钟。这步升级操作也可以通过eksctl命令或者Amazon CLI来完成,具体做法请参考官方文档

  • 官方文档

    https://docs.amazonaws.cn/eks/latest/userguide/update-cluster.html

升级成功后可以看到集群版本变为1.18。

需要注意的是如果有多个托管节点组,在升级控制平面之前,需要确认所有的托管节点组都已经升级到控制平面的版本,否则升级时会得到错误提示:Nodegroups xxx must be updated to match cluster version 1.1x before updating cluster version。

升级托管节点组

如下图所示进入Amazon EKS > Clusters > eksworkshop > Compute可以看到New Amazon AMI Release versios are avaiable for 1 Node Group的提示,并且在Node Groups中mng-1的Amazon AMI release version列的旁边出现了Update now的链接

点击Update now升级托管节点组到1.18

在上面的弹出的对话框中可以看到Update Strategy设置为Rolling update,也即滚动更新,点击Update开始节点组升级更新,整个过程需要约20分钟。

其间可以在Amazon EC2控制台中查看新旧节点的变化情况,在新启动的实例细节信息里查验Amazon AMI name已经改为amazon-eks-node-1.18-v2021xxxx。通过运行命令:kubectl get no可以看到旧的节点被设置为SchedulingDisabled状态,Nginx Pod在被逐步迁移到新的节点上。

可以通过如下图所示的编辑托管节点组 Amazon EKS > Clusters > eksworkshop > Node Group: mng-1 > Edit Node Group的Node Group update configuration来设置最大不可用节点数目或者比例数,从而控制滚动更新的颗粒度。当然也可以变更最小、最大、期望节点数,k8s labels,taints和tags等其他配置。

相比之下,如果我们这里使用的依旧是非托管节点组,那么在这个步骤中我们就要重新创建一个与控制平面版本一致的1.18的新的非托管节点组,然后将工作负载从旧的1.17的节点组迁移到新的1.18的节点组再删除1.17的非托管节点组,这个过程相对于上述托管节点组的一键升级的流程复杂许多,而且存在一个新旧非托管节点组同时存在的时间窗口给集群的管理与维护增加了难度与不确定性。更令运维人员头疼的是,这个升级过程在后续的版本升级中(比如1.18到1.19)仍然需要重复一遍。对比可见数据平面的升级在托管节点组的支持下变得非常简单方便。

切换启动模板版本

在日常集群的维护中,我们经常会有一些变更需求,比如切换实例类型,修改各种资源比如Amazon EC2的名称等,这些在非托管节点组是无法实现的,而在配置了启动模板的托管节点组中可以轻松实现,下面将演示将节点组实例类型切换为m5.2xlarge的方法。

基于启动模板demo的版本1新创建一个新版本:version 2,将实例类型设置为m5.2xlarge同时保持其他选项不变。

等待托管节点组mng-1升级到1.18完成后,可以看到节点组的Amazon AMI release version改为1.18.20-xxxx,同时因为我们增加了一个新的启动模板的版本,点击Change version将mng-1节点组切换到新创建的版本2从而修改节点组的实例类型到m5.2xlarge。

点击Update开始节点组滚动更新,类似的整个过程需要约20分钟。等待更新完毕后,按照相同的方法可以重新切换回版本1。启动模版的版本信息可以通过下列命令导出到yaml作为配置变更管理的一部分通过git等源代码版本管理工具来管理。

aws ec2 describe-launch-template-versions --launch-template-name demo --output yaml

需要注意的是在启动模板的不同版本间做切换目前不支持在有使用Amazon EKS优化Amazon AMI与自定义Amazon AMI的不同版本间切换。否则会得到错误:You cannot specify an image id within the launch template, since your nodegroup is configured to use an Amazon EKS optimized AMI(默认Amazon EKS优化版本改为自定义Amazon AMI版本)或者The request must contain the parameter ImageId(自定义Amazon AMI版本改为默认Amazon EKS优化版本)。如果有将默认Amazon AMI替换为自定义Amazon AMI的需求,可以通过创建一个新的托管节点组来引用配置有自定义Amazon AMI的启动模板的版本来解决。

删除Amazon EKS集群和Cloud9环境

eksctl delete cluster --name $EKS_CLUSTER_NAME

最后,在亚马逊云科技控制台的Cloud9服务的环境列表中删除eksworkshop。

总结

本文通过一个端到端的例子说明了将非托管节点组转换到托管节点组来实现工作负载的迁移。同时完成集群和托管节点组从 1.17到1.18的版本升级。最后通过在不同启动模板版本间切换的方法实现了节点组配置的灵活原地更新。需要特别指出虽然上述实验进行的的是1.17到1.18的升级,但过程对于其他Amazon EKS版本的升级同样适用,比如从1.18升级到1.19。

相比Amazon EKS集群的托管节点组,非托管节点组具有不可变性,所以必须通过新建节点组然后迁移工作负载的方式来更新。而托管节点组则可以通过改变启动模板的版本然后进行滚动更新来实现常用配置的变更,同时在出现失败的情况下支持回退,所以在日常变更管理与集群版本升级上更加简便。并且一个集群或者多个集群中的多个节点组可以共用一个启动模板,极大的简化了维护与管理的成本。另外将多项节点组配置选项转移到启动模板中,实现了节点组配置一定程度的解耦。最后因为启动模板支持多个版本,同一托管节点组可以在同一个启动模板的不同版本间灵活切换,也极大的方便了日常节点组的变更与维护。关于更多托管节点组的新功能请参考托管节点组最新动态博客Amazon EKS官方文档

  • 托管节点组最新动态博客

    https://aws.amazon.com/blogs/containers/catching-up-with-managed-node-groups-in-amazon-eks/

  • Amazon EKS官方文档

    https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html

最后需要指出的是Amazon EKS升级的范畴远大于文中介绍的内容,鉴于篇幅所限,其他方面的升级方法请读者自行参考官方K8S升级手册与官方Amazon EKS升级文档。

参考资料

  • https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html

  • https://eksctl.io/usage/managing-nodegroups/#nodegroup-immutability

  • https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html

  • https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html

  • https://aws.amazon.com/blogs/containers/catching-up-with-managed-node-groups-in-amazon-eks/

  • https://aws.amazon.com/blogs/containers/introducing-launch-template-and-custom-ami-support-in-amazon-eks-managed-node-groups/

  • https://docs.amazonaws.cn/eks/latest/userguide/launch-templates.html

  • https://www.eksworkshop.com/

  • https://eksctl.io/usage/schema/


本篇作者

田大鹏

亚马逊云科技

解决方案架构师

负责云计算架构的咨询与架构设计

何归丽

亚马逊云科技

高级解决方案架构师

主要负责云计算方案的咨询与架构设计

潘文明

亚马逊云科技

解决方案架构师

负责帮助客户进行云计算方案的设计和咨询

听说,点完下面4个按钮

就不会碰到bug了!

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐