你可以自己搭建 Kubernetes 集群,有几个选择。除了在托管基础设施上部署之外,你还可以创建一个与特定云环境集成的托管集群,从而可以使用该云环境中的其他服务和概念。
本文是一篇关于在 AWS 上设置 Elastic Kubernetes 服务(EKS)的实战教程。一步步地,你将学习如何下载所需的二进制文件,获取 AWS 的授权,准备 EKS 配置文件,并完成集群的安装过程。你还将学习如何使用 kubectl
和 SSH 访问集群,以及如何更新集群。
本文最初发表在我的博客上admantium.com。
要完成本教程,你需要有一个注册并激活的AWS账户。此账户还需要具备管理这些资源的完整权限,例如AWS实例、VPC和IAM用户。
你也需要一台专门用于此目的的计算机来安装所需的二进制文件并完成安装,并且可以通过这台机器连接到集群,使用kubectl
或SSH进行连接。在接下来的文章中,我们将把这台机器称为EKS控制器。
最后,请确保您愿意为这个体验买单!在三天的时间里,我花了30美元。您可以随时通过成本仪表板查看所有费用,但是只有在费用产生后,您才能看到它们。
首先,我们需要在EKS控制器上装好所有必需的二进制工具。
用于与 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目录
这个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
集群创建只需要执行一次命令。集群可以预配置,也可以自行设定,通过标志或配置文件来定制。配置选项非常全面——请查阅完整的配置文件文档了解所有选项。在本教程中,我将主要使用预设的默认设置。
要开始,我们需要定义以下几点:
kubectl
版本。m5.large
实例类型。除了这些之外,您还需要提供 AWS 凭证,例如通过设置环境变量 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
。
我第一次尝试是把所有选项都作为参数传递。这是命令:
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
为了看看集群更新是怎么工作的,我重新安装了一遍新集群,并使用了 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
我想知道集群使用了哪些Kubernetes组件。当我运行kubectl get all -A
时,我发现了这些信息:
Amazon EKS 是一个管理的 Kubernetes 发行版。在这篇文章中,你学习了所有入门所需的内容:a) 确保你已经有一个完整注册的 AWS 账户,b) 安装所需的二进制文件 eksctl
和 kubectl
,c) 通过执行 dry-run
安装来创建集群,然后自定义配置文件。集群安装可能需要大约 20 分钟的时间 - 请不要中途停止,否则你可能需要手动清理多个 AWS 资源。完成之后,你可以通过 kubectl
并通过 SSH 连接到节点。最后,你还了解了升级集群 Kubernetes 版本的步骤,并了解了一些集群的内部细节。