手记

亚马逊弹性Kubernetes服务(EKS)实战:轻松搭建Kubernetes平台

你可以自己搭建 Kubernetes 集群,有几个选择。除了在托管基础设施上部署之外,你还可以创建一个与特定云环境集成的托管集群,从而可以使用该云环境中的其他服务和概念。

本文是一篇关于在 AWS 上设置 Elastic Kubernetes 服务(EKS)的实战教程。一步步地,你将学习如何下载所需的二进制文件,获取 AWS 的授权,准备 EKS 配置文件,并完成集群的安装过程。你还将学习如何使用 kubectl 和 SSH 访问集群,以及如何更新集群。

本文最初发表在我的博客上admantium.com

第一部分:前提

要完成本教程,你需要有一个注册并激活的AWS账户。此账户还需要具备管理这些资源的完整权限,例如AWS实例、VPC和IAM用户。

你也需要一台专门用于此目的的计算机来安装所需的二进制文件并完成安装,并且可以通过这台机器连接到集群,使用kubectl或SSH进行连接。在接下来的文章中,我们将把这台机器称为EKS控制器。

最后,请确保您愿意为这个体验买单!在三天的时间里,我花了30美元。您可以随时通过成本仪表板查看所有费用,但是只有在费用产生后,您才能看到它们。

第二部分:安装工具

首先,我们需要在EKS控制器上装好所有必需的二进制工具。

kubectl:用于与 Kubernetes 集群交互的命令行工具

用于与 Kubernetes 集群交互的二进制工具。可以从包管理器安装,或者直接下载适合您架构的二进制文件。

要在Linux系统上安装版本1.24.0的,请运行以下命令如下:

    cd ~  # 切换到用户主目录  
    curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl  # 下载kubectl到当前目录  
    chmod +x kubectl  # 赋予kubectl文件执行权限  
    mkdir -p ~/.local/bin  # 创建~/.local/bin目录  
    mv ./kubectl ~/.local/bin/kubectl  # 将kubectl移动到~/.local/bin目录
eksctl (eksctl工具)

这个CLI工具可以创建和管理Kubernetes集群。它是由Amazon提供的一个二进制文件。访问它的GitHub发布页面,并下载适合您操作系统的二进制文件。

对于一台 Linux 主机,运行这些命令:

    # 使用curl命令从GitHub下载eksctl的最新版本,并解压缩到/tmp目录
    curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp  
    # 将eksctl脚本设置为可执行文件
    chmod +x /tmp/eksctl  
    # 创建~/.local/bin目录,如果它不存在的话
    mkdir -p ~/.local/bin  
    # 将eksctl移动到~/.local/bin目录下
    mv /tmp/eksctl ~/.local/bin/eksctl
第三部分:集群的设置

集群创建只需要执行一次命令。集群可以预配置,也可以自行设定,通过标志或配置文件来定制。配置选项非常全面——请查阅完整的配置文件文档了解所有选项。在本教程中,我将主要使用预设的默认设置。

要开始,我们需要定义以下几点:

  • 名称:集群的名称
  • 地域:您想要部署集群的 AWS 可用区域
  • Kubernetes 版本:请查阅EKS 支持的 Kubernetes 版本,并确保安装兼容的 kubectl 版本。
  • 工作节点数量:集群应拥有多少个工作节点
  • AWS 实例(可选):节点的实例类型,参见 AWS 文档。如果不指定,系统将默认使用 m5.large 实例类型。
  • 节点类型:在 EKS 中,K8S 工作负载可以运行在 ECS 实例的容器中,这意味着容器运行在虚拟机中,或者它们也可以在使用 Amazon Fargate 的裸机服务器上运行。

除了这些之外,您还需要提供 AWS 凭证,例如通过设置环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

第4部分:集群的部署
第一次试玩:台

我第一次尝试是把所有选项都作为参数传递。这是命令:

eksctl 创建集群命令如下:
使用 eksctl 工具在欧洲中部地区 (eu-central-1) 创建一个 Kubernetes 集群,版本为 1.23,拥有 2 个节点,并启用 Fargate。
eksctl create cluster \  
  --region=欧洲中部地区 (eu-central-1) \  
  --version=1.23 \  
  --nodes=2 \  
  --fargate

日志记录:

2022-11-05 12:37:51 [ℹ] eksctl 版本:0.117.0  
2022-11-05 12:37:51 [ℹ] 使用区域 eu-central-1  
2022-11-05 12:37:51 [ℹ] 设置可用区为 [eu-central-1a, eu-central-1b, eu-central-1c]  
2022-11-05 12:37:51 [ℹ] eu-central-1a 的子网段 - 公共:192.168.0.0/19 私有:192.168.96.0/19  
2022-11-05 12:37:51 [ℹ] eu-central-1b 的子网段 - 公共:192.168.32.0/19 私有:192.168.128.0/19  
2022-11-05 12:37:51 [ℹ] eu-central-1c 的子网段 - 公共:192.168.64.0/19 私有:192.168.160.0/19  
2022-11-05 12:37:51 [ℹ] 节点组 "ng-83b22df4" 将使用 "AmazonLinux2/1.23" 版本  
2022-11-05 12:37:51 [ℹ] 使用 Kubernetes 版本 1.23  
2022-11-05 12:37:51 [ℹ] 在 "eu-central-1" 区域创建 EKS 集群 "scrumptious-hideout-1667648262",并使用管理节点  
2022-11-05 12:37:51 [ℹ] 将创建 2 个单独的 CloudFormation 栈,分别用于集群本身和初始管理节点组  
2022-11-05 12:37:51 [ℹ] 如遇任何问题,请查看 CloudFormation 控制台或尝试使用 'eksctl utils describe-stacks --region=eu-central-1 --cluster scrumptious-hideout-1667648262'  
2022-11-05 12:37:51 [ℹ] Kubernetes API 端点访问将默认设置为 {publicAccess=true, privateAccess=false},适用于 'eu-central-1' 区域的 'scrumptious-hideout-1667648262' 集群  
2022-11-05 12:37:51 [ℹ] 不会在 'eu-central-1' 区域为 'scrumptious-hideout-1667648262' 集群启用 CloudWatch 日志  
2022-11-05 12:37:51 [ℹ] 可以使用 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=eu-central-1 --cluster scrumptious-hideout-1667648262' 启用它  
2022-11-05 12:37:51 [ℹ]  
2 个顺序任务:{ 创建集群控制平面 "scrumptious-hideout-1667648262"; 2 个顺序子任务:{ 等待控制平面准备好; 创建管理节点组 "ng-83b22df4" } }  
2022-11-05 12:37:51 [ℹ] 构建集群栈 "eksctl-scrumptious-hideout-1667648262-cluster"  
2022-11-05 12:37:52 [ℹ] 部署栈 "eksctl-scrumptious-hideout-1667648262-cluster"

我的第一次尝试没有成功,eksctl 命令卡在了 部署堆栈 的消息上。所以我再次运行了命令,并给集群起了一个专用的名字。

eksctl 创建集群命令 \  
  --name=staging \  
  --region=eu-central-1 \  
  --version=1.23 \  
  --nodes=2 \  
  --fargate=Fargate

这导致了相同的提示。再次运行后出现了一个错误,提示集群可用,但我无法访问。这是什么情况?登录到AWS管理控制台后,我发现创建了几个安全组、VPC、网络接口和集群名称的弹性IP地址,但没有看到实例。嗯,奇怪。

所有这些资源的删除是一个繁琐的手动过程,必须按照以下顺序进行:首先,断开所有网络接口(NIC),然后删除弹性IP地址,接着删除之前断开的网络接口(NIC),最后删除虚拟私有云(VPC)。

再一次尝试:配置文件

第二次尝试是使用配置文件,你可以选择一个最基本的方法。比如参考eksctl.io文档中的配置文件,或者通过运行命令eksctl --dry-run来自动生成配置文件。我选择了后者并对其进行了自定义。

但是请注意!仅仅运行 eksctl create cluster --dry-run,会生成一个非常不同的文件,相比更定制化的 eksctl create cluster --name=staging --region=eu-central-1 --dry-run。使用第一个命令(不带任何参数)。为了完整性起见,这里提供的是成功安装所用的完整配置文件。

eksctl 创建集群实例 --name=staging --dry-run
    apiVersion: eksctl.io/v1alpha5  
    availabilityZones:  
    - eu-central-1c  
    - eu-central-1b  
    - eu-central-1a  
    cloudWatch:  
      clusterLogging: {}  
    iam:  
      vpcResourceControllerPolicy: true  
      withOIDC: false  
    kind: ClusterConfig  
    kubernetesNetworkConfig:  
      ipFamily: IPv4  
    managedNodeGroups:  
    - amiFamily: AmazonLinux2  
      desiredCapacity: 2  
      disableIMDSv1: false  
      disablePodIMDS: false  
      iam:  
        withAddonPolicies:  
          albIngress: false  
          appMesh: false  
          appMeshPreview: false  
          autoScaler: false  
          awsLoadBalancerController: false  
          certManager: false  
          cloudWatch: false  
          ebs: false  
          efs: false  
          externalDNS: false  
          fsx: false  
          imageBuilder: false  
          xRay: false  
      instanceSelector: {}  
      labels:  
        alpha.eksctl.io/cluster-name: staging  
        alpha.eksctl.io/nodegroup-name: ng-c3cdc337  
      maxSize: 2  
      minSize: 2  
      name: ng-c3cdc337  
      privateNetworking: false  
      releaseVersion: ""  
      securityGroups:  
        withLocal: null  
        withShared: null  
      ssh:  
        allow: false  
        publicKeyPath: ""  
      tags:  
        alpha.eksctl.io/nodegroup-name: ng-c3cdc337  
        alpha.eksctl.io/nodegroup-type: managed  
      volumeIOPS: 3000  
      volumeSize: 80  
      volumeThroughput: 125  
      volumeType: gp3  
    metadata:  
      name: staging  
      region: eu-central-1  
      version: "1.23"  
    privateCluster:  
      enabled: false  
      skipEndpointCreation: false  
    vpc:  
      autoAllocateIPv6: false  
      cidr: 192.168.0.0/16  
      clusterEndpoints:  
        privateAccess: false  
        publicAccess: true  
      manageSharedNodeSecurityGroupRules: true  
      nat:  
        gateway: Single

在这文件里,我只把集群名字改成了 eksctl-superb-hedgehog,并修改了 managedNodeGroups.ssh 以便通过 SSH 访问节点。

    管理中的节点组:  
      - amiFamily: AmazonLinux2  
        #注释:...  
        SSH:  
          设置:  
            allow: true  
            公钥路径: "~/.ssh/eksctl_rsa.key"

集群创建花了很长时间——我在网上查找 eksctl 安装卡住的问题时,发现这个 stackoverflow 讨论:集群创建可能需要长达 20 分钟的时间!

确实,这差不多就是所需的时间:

    2022-11-07 20:08:36 [ℹ]  eksctl 版本 0.117.0  
    2022-11-07 20:08:36 [ℹ]  区域为 eu-central-1  
    2022-11-07 20:08:36 [ℹ]  eu-central-1b 区域的子网 - 公共:192.168.0.0/19 私有:192.168.96.0/19  
    2022-11-07 20:08:36 [ℹ]  eu-central-1a 区域的子网 - 公共:192.168.32.0/19 私有:192.168.128.0/19  
    2022-11-07 20:08:36 [ℹ]  eu-central-1c 区域的子网 - 公共:192.168.64.0/19 私有:192.168.160.0/19  
    2022-11-07 20:08:36 [ℹ]  节点组 "ng-9bf41c12" 将使用 "AmazonLinux2" 和 "1.23"  
    2022-11-07 20:08:36 [ℹ]  使用 Kubernetes 版本 1.23  
    2022-11-07 20:08:36 [ℹ]  将创建名为 "superb-hedgehog-staging" 的 EKS 集群,位于 "eu-central-1" 区域,使用托管节点  
    2022-11-07 20:08:36 [ℹ]  将包括 1 个节点组 (ng-9bf41c12)  
    2022-11-07 20:08:36 [ℹ]  将为集群本身创建一个 CloudFormation 栈,无需创建节点组栈  
    2022-11-07 20:08:36 [ℹ]  将为集群本身创建一个 CloudFormation 栈和 1 个托管节点组栈  
    # ....  
    2022-11-07 20:08:37 [ℹ]  部署栈 "eksctl-superb-hedgehog-staging-cluster"  
    2022-11-07 20:09:07 [ℹ]  等待 CloudFormation 栈 "eksctl-superb-hedgehog-staging-cluster"  
    # ...  
    2022-11-07 20:26:49 [ℹ]  等待 CloudFormation 栈 "eksctl-superb-hedgehog-staging-nodegroup-ng-9bf41c12"  
    2022-11-07 20:26:49 [ℹ]  等待控制平面稳定  
    2022-11-07 20:26:51 [✔]  已保存 kubeconfig 至 "~.kube/config"  
    # ...  
    2022-11-07 20:26:53 [✔]  "eu-central-1" 区域的 EKS 集群 "superb-hedgehog-staging" 已准备就绪

查看一下 AWS 管理控制台,可以看到创建的实例和卷:

第五部分:集群的管理和维护

安装完成后,自动生成的 kubeconfig 文件会被自动放置在 ~/.kube/config。使用该文件来获取集群访问。

    export KUBECONFIG=~/.kube/config  

    kubectl  get nodes  
    NAME                                              状态:   角色:    年龄:   版本:  
    ip-192-168-34-211.eu-central-1.compute.internal   Ready    <none>   12分钟   v1.23.9-eks-ba74326  
    ip-192-168-73-218.eu-central-1.compute.internal   Ready    <none>   11分钟   v1.23.9-eks-ba74326

对于SSH接入,你需要从AWS管理控制台找到节点的公共DNS名称,然后使用ec2-user进行连接。

ssh ec2-user@ec2-3-70-174-13.eu-central-1.compute.amazonaws.com  
上次登录: 2022年11月5日 星期六 02:57:35 来自 205.251.233.105  

          __|  __|_  )  
           _|  (     /   Amazon Linux 2 AMI  
          ___|\___|___|  
    https://aws.amazon.com/amazon-linux-2/  
    在18个可用的安全更新包中,有12个安全更新包需要安装  
    运行, "sudo yum update" 以应用所有更新。  
    [ec2-user@ip-192-168-69-138 ~]$ kubelet --version  
    Kubernetes v1.23.9-eks-ba74326
第6部分:集群维护

为了看看集群更新是怎么工作的,我重新安装了一遍新集群,并使用了 v1.22 版本的 Kubernetes。

和之前一样,建立集群花了些时间才完成的。

2022-11-09 20:11:11 [ℹ] eksctl 版本 0.117.0.  
2022-11-09 20:11:11 [ℹ] 使用区域 eu-central-1.  
2022-11-09 20:11:11 [ℹ] eu-central-1b 的子网设置 - 公共:192.168.0.0/19 私有:192.168.96.0/19  
#...  
2022-11-09 20:28:59 [ℹ] 节点 "ip-192-168-69-138.eu-central-1.compute.internal" 已就绪  
2022-11-09 20:29:01 [ℹ] kubectl 命令应可通过 "/Users/guenthers/.kube/config" 运行,试试 'kubectl get nodes'  
2022-11-09 20:29:01 [✔] 区域 eu-central-1 中的 EKS 集群 "staging" 已就绪

升级过程是逐步进行的。你需要选择新的 Kubernetes 版本,然后将其传递给升级命令执行。升级命令的目标包括控制平面节点、kube-proxy、AWS 节点等,最后是 CoreDNS。

这里是一些具体的更新命令以及它们的结果:

修改为:

这里是一些具体的更新指令以及它们的结果:

eksctl upgrade cluster --name=staging --version=1.23  
2022-11-09 20:47:44 [ℹ] 正在重建集群堆栈 'eksctl-staging-cluster'  
2022-11-09 20:47:44 [✔] 集群堆栈 'eksctl-staging-cluster' 中的所有资源都已处于最新状态  
2022-11-09 20:47:44 [ℹ] 正在检查所有节点组的安全组配置  
2022-11-09 20:47:44 [ℹ] 所有节点组的 CloudFormation 模板都已更新  
eksctl utils update-kube-proxy --cluster=staging --approve  
2022-11-09 20:48:53 [ℹ] "kube-proxy" 现在已经是最新状态了  

eksctl utils update-aws-node --cluster=staging --approve  
2022-11-09 20:49:21 [ℹ] 跳过了已存在的 "kube-system:ServiceAccount/aws-node"  
2022-11-09 20:49:21 [ℹ] 替换为 "CustomResourceDefinition.apiextensions.k8s.io/eniconfigs.crd.k8s.amazonaws.com"  
2022-11-09 20:49:21 [ℹ] 替换为 "ClusterRole.rbac.authorization.k8s.io/aws-node"  
2022-11-09 20:49:22 [ℹ] 替换为 "ClusterRoleBinding.rbac.authorization.k8s.io/aws-node"  
2022-11-09 20:49:22 [ℹ] 替换为 "kube-system:DaemonSet.apps/aws-node"  
2022-11-09 20:49:22 [ℹ] "aws-node" 现在已经是最新状态了  

eksctl utils update-coredns --cluster=staging --approve  
2022-11-09 20:49:47 [ℹ] 替换为 "kube-system:Service/kube-dns"  
2022-11-09 20:49:47 [ℹ] 替换为 "kube-system:ServiceAccount/coredns"  
2022-11-09 20:49:47 [ℹ] 替换为 "kube-system:ConfigMap/coredns"  
2022-11-09 20:49:47 [ℹ] 替换为 "kube-system:Deployment.apps/coredns"  
2022-11-09 20:49:48 [ℹ] 替换为 "ClusterRole.rbac.authorization.k8s.io/system:coredns"  
2022-11-09 20:49:48 [ℹ] 替换为 "ClusterRoleBinding.rbac.authorization.k8s.io/system:coredns"  
2022-11-09 20:49:48 [ℹ] "coredns" 现在已经是最新状态了

我没有遇到任何错误,所有的部署和守护集都在正常运行。为了检查结果,我通过SSH连接到节点并查看了kubectl的版本,情况如下。你可以看到,某些部署或守护集的镜像标签已经更新到了新的Kubernetes版本。

    kubectl describe 守护集 kube-proxy -n kube-system  
    名称:           kube-proxy  
    #...  
      容器:  
       kube-proxy:  
        镜像:      602401143452.dkr.ecr.eu-central-1.amazonaws.com/eks/kube-proxy:v1.23.13-eksbuild.1
第7部分:EKS集群的内部运作

我想知道集群使用了哪些Kubernetes组件。当我运行kubectl get all -A时,我发现了这些信息:

  • Linux发行版: amazon-eks-ami
  • 容器运行时: containerd
  • 网络组件: coredns, kube-proxy, amazon-vpc-cni
  • 入口控制器: aws-load-balancer-controller
结尾

Amazon EKS 是一个管理的 Kubernetes 发行版。在这篇文章中,你学习了所有入门所需的内容:a) 确保你已经有一个完整注册的 AWS 账户,b) 安装所需的二进制文件 eksctlkubectl,c) 通过执行 dry-run 安装来创建集群,然后自定义配置文件。集群安装可能需要大约 20 分钟的时间 - 请不要中途停止,否则你可能需要手动清理多个 AWS 资源。完成之后,你可以通过 kubectl 并通过 SSH 连接到节点。最后,你还了解了升级集群 Kubernetes 版本的步骤,并了解了一些集群的内部细节。

0人推荐
随时随地看视频
慕课网APP