AWS EKS安装[AWS 中国宁夏区]

本文介绍使用页面点击的方式在AWS中国宁夏区安装AWS EKS的全部流程,并使用Cluster Autoscaler实现底层资源的自动扩缩容。

其中涉及到如下的子部分

  • 安装AWS EKS
  • 为AWS EKS设置节点组(nodegroup)
  • Cluster Autoscaler实现节点组自动水平扩展
  • 为AWS EKS设置节点组自动水平扩展
  • 测试HPA和EC2的自动扩缩
  • 为AWS EKS设置Fargate
  • 让pod运行在Fargate
  • 安装

    网络检查

    AWS EKS在中国宁夏区创建前,我们现需要保证自己的VPC网络符合Amazon EKS VPC and subnet requirements and considerations要求,比如VPC中必须要有足够的private ip,必须同时开启DNS hostnameDNS resolution,必须为AWS EKS控制面提供2个AZ的子网。

    关于网络规划可以参考一文看懂 Amazon EKS 中的网络规划
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    本文我为EKS分配了3个AZ的子网;设计上AWS EKS管理的EC2在container-ec2-subnet子网,AWS EKS管理的Pod在containers-subnet子网,这样把EC2的private ip cidr和pod的private ip cidr分开管理;如果你不计划分开EC2和Pod的private ip cidr也完全没问题,这也是默认设置,此外VPC开启DNS hostnameDNS resolution

    权限检查

    你在创建AWS EKS的时候,必须有AWS相关的足够的权限,详情请看Getting started with Amazon EKS – Amazon Web Services Management Console and Amazon CLI中的Required IAM permissions部分

    安装AWS EKS控制面

    我们创建AWS EKS的时候,实际上只是创建了K8S的控制面(控制面做了自动的跨AZ高可用),后续的EC2/Fargate计算资源的管理、K8S deployment、service的管理、K8S插件的安装也会逐渐涉及。

    cluster role设置

    AWS EKS可以帮助我们管理资源并和其他AWS服务交互,所以我们必须给AWS EKS合适的role,让AWS EKS可以用这个role去执行相应的动作,详情可以看Amazon EKS cluster IAM role

    在AWS IAM控制台中,我们可以创建一个名为AmazonEKSClusterRole的role
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    检查AmazonEKSClusterPolicy是否被正确的选择了
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    最后检查下详情并创建role
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建成功后我们可以看到相应的role

    EKS安装

    在AWS EKS控制台,我们可以接着创建AWS EKS
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    我们在创建EKS的时候选择我们刚才创建的role来给EKS合适的权限,同时也建议选择最新的EKS版本。AWS EKS的发布周期和维护周期和K8S的支持周期基本一致,Amazon EKS Kubernetes versions里面列出了可选的版本,EKS一般每个版本的支持周期大约为12个月,当支持周期结束前建议大家提前安排好版本更新,避免由于结束支持后失去安全和bug修复保证。更多的详情可以看Amazon EKS Kubernetes versions、Amazon EKS platform versions

    Secrets encryption是可选的,用于对EKS里面的Kubernetes secrets数据做加密进一步的保证安全
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    接着我们选择网络,一般我推荐选择3个子网(subnet)跨越3个AZ保证绝对的可靠;然后EKS控制面会在这些子网里面放置网络接口,通过网络接口暴露控制面的API服务,这样我们后面的EC2/Fargate等安装了kubelet的计算资源以及pod就可以和这些网络接口通信,我们可以通过下面的security group做精细的控制)。此外cluster enpoint access我们可以按照自己的需求选择,详情请看Amazon EKS cluster endpoint access control,测试/开发环境建议选择public+private(互联网能访问控制面API,也能在VPC内访问控制面API,这样方便运维在本地电脑控制EKS),正式环境建议选择private(互联网不能访问控制面API,只能在VPC内访问控制面API,这样绝对避免互联网网络访问,就更安全)
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    一般我放行vpc cidr的全部入栈流量,你可以更加精细化设置
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    AWS EKS可以选择开启日志,你可以按自己需求选择
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    AWS EKS默认会安装必要的插件
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    选择默认版本或者最新的版本即可
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    检查全部的配置
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    提交创建,我们需要等几分钟等待AWS EKS创建完成
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    就绪后就可以使用了

    设置计算资源

    创建完成后,AWS EKS的控制面就提供给我们了。这时我们其实是没有底层计算资源的,我们有2种选择: ec2 node group和fargate,其中ec2 node group建议优先托管节点组(Managed node groups),它可以帮我们做好ec2的故障恢复,EC2随压力的伸缩

    设置托管节点组

    ec2 node的角色创建

    我们需要给EC2合适的role,这样EC2在创建后会有合适的权限加入EKS集群或者做其他的操作,我们可以参考Amazon EKS node IAM role

    我们首先在AWS IAM控制台创建role
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    选择添加3个必要的policy:AmazonEKSWorkerNodePolicy,AmazonEC2ContainerRegistryReadOnly,AmazonEKS_CNI_Policy
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    确认3个policy选择正确后提交,role名称我填为AmazonEKSNodeRole
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建成功

    创建托管节点组

    在EKS控制台,我们开始创建托管节点组。

    给这个节点组的节点赋予我们刚才创建的role
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    节点组中我们可以进一步的设置,比如选择操作系统,购买类型,机型,这个节点组的最小,最大节点数和当前期望的节点数
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    EC2节点的网络保持默认就好,你也可以选择为EC2节点打开SSH访问
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    检查设置并创建
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建中,需要等待几分钟
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建成功后的效果,我们可以看待节点组创建成功了,并且节点加入了集群

    补充说明:

  • 你可以后面自己手动调整节点组中EC2节点的数量
  • 你可以在操作系统的选择上可以选择标准的Amazon Linux和转为容器优化的Bottlerocket
  • 你可以选择普通的按需购买或者spot购买,后者更便宜但是有EC2回收的可能(回收前2分钟通知,做好优雅停机即可)
  • 你可以选择X86架构的CPU和ARM架构的Graviton CPU,后者更便宜
  • 你可以按照上面的属性的组合创建多个节点组并在EKS里面混合使用
  • 详情请看Managed node groups

    比如我可以结合spot/on-demand、x86/arm64、amazon linux/bottlerocket创建多个节点组,多元化使用结合弹性和成本

    Cluster Autoscaler实现节点组自动水平扩展

    AWS Autoscaling有2种节点组自动扩缩容组件:karpenter和Cluster Autoscaler,本文选择的是Cluster Autoscaler

    相关的链接

    • AWS EKS Autoscaling
    • AWS EKS Cluster Autoscaler
    • kubernetes autoscaler
    IAM OIDC provider设置

    为了让Cluster Autoscaler有权限操作nodegroup,我们需要设置安全策略

    在AWS EKS中复制集群的OpenID Connect provider URL
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    在AWS IAM补充OIDC,我们先创建Identity providers
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    填入前面复制的OpenID Connect provider URL,并将Audience设置为sts.amazonaws.com
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建完成

    EKS Nodegroup tags管理

    为了让Cluster Autoscaler能够发现我们指定的node group,我们可以给node group设置tag

    为需要被Cluster Autoscaler管理的node group设置tag

    tag有2个:

    名称
    k8s.io/cluster-autoscaler/enabled true
    k8s.io/cluster-autoscaler/ owned

    换为你实际的集群名称

    例如我的:

    创建IAM Policy

    将如下的policy保存为cluster-autoscaler-policy.json

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:SetDesiredCapacity",
                    "autoscaling:TerminateInstanceInAutoScalingGroup"
                ],
                "Resource": "*",
                "Condition": {
                    "StringEquals": {
                        "aws:ResourceTag/k8s.io/cluster-autoscaler/": "owned"
                    }
                }
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:DescribeAutoScalingInstances",
                    "autoscaling:DescribeAutoScalingGroups",
                    "ec2:DescribeLaunchTemplateVersions",
                    "autoscaling:DescribeTags",
                    "autoscaling:DescribeLaunchConfigurations",
                    "ec2:DescribeInstanceTypes"
                ],
                "Resource": "*"
            }
        ]
    }
    

    比如我的

    然后创建ploicy

    aws iam create-policy  --policy-name AmazonEKSClusterAutoscalerPolicy  --policy-document file://cluster-autoscaler-policy.json
    
    创建AmazonEKSClusterAutoscalerRole role

    在AWS IAM控制台创建role
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    policy选择上面新创的AmazonEKSClusterAutoscalerPolicy

    检查设置并创建,名称填为AmazonEKSClusterAutoscalerRole
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    保险起见,创建完成后检查AmazonEKSClusterAutoscalerRole是否和前面的OIDC签名一致

    正式安装autoscaler

    下载cluster-autoscaler-autodiscover.yaml

    curl -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
    

    将下载的文件进行修改,调整为你的集群名称
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    然后部署

    kubectl apply -f cluster-autoscaler-autodiscover.yaml
    

    为集群的cluster-autoscaler加上有关role的注解,将arn:aws:iam::ACCOUNT_ID:role/AmazonEKSClusterAutoscalerRole替换为前面场景的名为AmazonEKSClusterAutoscalerRole的role的实际的arn

    kubectl annotate serviceaccount cluster-autoscaler -n kube-system eks.amazonaws.com/role-arn=arn:aws:iam::ACCOUNT_ID:role/AmazonEKSClusterAutoscalerRole
    

    为cluster-autoscaler deployment打patch,补充注解

    kubectl patch deployment cluster-autoscaler  -n kube-system  -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'
    

    修改cluster-autoscaler

    kubectl -n kube-system edit deployment.apps/cluster-autoscaler
    

    加上如下的内容,加的使用缩进请用空格,不要用tab缩进

    --balance-similar-node-groups
    --skip-nodes-with-system-pods=false
    如下图,位置在

    设置cluster-autoscale的image地址和版本,这里中国直接访问registry.k8s.io一定失败,因为被屏蔽了

    kubectl set image deployment cluster-autoscaler  -n kube-system  cluster-autoscaler=registry.k8s.io/autoscaling/cluster-autoscaler:v1.27.3
    

    所以使用proxy替代即可

    kubectl set image deployment cluster-autoscaler  -n kube-system  cluster-autoscaler=registryk8s.azk8s.cn/autoscaling/cluster-autoscaler:v1.27.3
    

    到这里部署就完成了~~~~~~

    检查安装效果

    通过下面的命令查看log

    kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler
    

    出现No candidates for scale down类的字样,说明工作正常,正在尝试进行扩缩容评估

    Horizontal Pod Autoscaler设置

    首先安装Metrics Server,参考Installing the Kubernetes Metrics Server

    kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    

    这里建议先下载文件然后用registryk8s.azk8s.cn替换registry.k8s.io,避免网络问题

    继续参考Horizontal Pod Autoscaler进行测试

    以一个PHP样例为测试对象

    kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
    

    这里建议先下载文件然后用registryk8s.azk8s.cn替换registry.k8s.io,避免网络问题

    设置一个HPA,规定CPU压力超过50%后扩展

    kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
    

    查看HPA信息

    kubectl get hpa
    

    进行压力测试,通过压力让CPU指标上升

    kubectl run -i --tty load-generator  --rm --image=busybox  --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
    

    当施加压力后,我们看到pod数量随着CPU指标的上升而变多了,这时HPA工作正常
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    更多的pod需要更多的EC2承载,我们看到cluster-autoscaler自动为我们扩展了一个EC2

    当我们停止压力测试,过一段时间cluster-autoscaler会自动为我们回收EC2。

    清理测试,删除相关的资源

    kubectl delete deployment.apps/php-apache service/php-apache horizontalpodautoscaler.autoscaling/php-apache
    

    **到这里我们完成一个高可用,资源自动扩展的EKS部署,这样我们真正的实现了云上按需计算、高性价比、高可靠性的容器化服务搭建。
    **

    设置Fargate

    创建Amazon EKS Pod execution IAM role

    fargate正常运行需要有Amazon EKS Pod execution IAM role,详情可以参考Amazon EKS Pod execution IAM role

    编辑policy内容,并保存为pod-execution-role-trust-policy.json,其中region-codeaws-account需要填你真实的内容

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Condition": {
             "ArnLike": {
                "aws:SourceArn": "arn:aws-cn:eks:::fargateprofile/*"
             }
          },
          "Principal": {
            "Service": "eks-fargate-pods.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    

    创建role,名称可以自定义,我设置为AmazonEKSFargatePodExecutionRole

    aws iam create-role --role-name AmazonEKSFargatePodExecutionRole  --assume-role-policy-document file://"pod-execution-role-trust-policy.json"
    

    AmazonEKSFargatePodExecutionRoleAmazonEKSFargatePodExecutionRolePolicy关联

    aws iam attach-role-policy --policy-arn arn:aws-cn:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy --role-name AmazonEKSFargatePodExecutionRole
    

    创建fargate profile

    AWS EKS安装[AWS 中国宁夏区]-每日运维
    填写自己的fargate-profile名称,并选定刚才创建的AmazonEKSFargatePodExecutionRole
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    为这个profie填入合适的namespace设置,详情见AWS Fargate profile
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    检查并创建
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建需要几分钟
    AWS EKS安装[AWS 中国宁夏区]-每日运维
    创建完成

    测试fargate的使用

    这里是一个简单的nginx deployment样例,请注意它的namesapce必须要和fargate proflie中的namespace设置相匹配,匹配规则为AWS Fargate profile

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: eks-sample-linux-deployment
      # 必须和fargate proflie中的namespace设置相匹配,https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html
      namespace: prod-fargate
      labels:
        app: eks-sample-linux-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: eks-sample-linux-app
      template:
        metadata:
          labels:
            app: eks-sample-linux-app
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: kubernetes.io/arch
                        operator: In
                        values:
                          - amd64
                          - arm64
          containers:
            - name: nginx
              image: public.ecr.aws/nginx/nginx:1.23
              ports:
                - name: http
                  containerPort: 80
              imagePullPolicy: IfNotPresent
          nodeSelector:
            kubernetes.io/os: linux
    

    AWS EKS安装[AWS 中国宁夏区]-每日运维
    等待片刻我们发现fargate作为底层计算资源已经运行了正确的nginx

    fargate和ec2 node group不一样,只需要你设置好pod的HPA后,pod就可以自动的水平扩展并及时获取对应的fargate计算资源,不再需要autosacler等插件。

    关于fargate详情请看:

    • AWS fargate
    • AWS fargate doc
    • 聊聊 AWS Fargate 在容器世界中的角色定位