创建 EKS 集群

介绍

EKSAmazon Elastic Kubernetes Service)是 AWS 提供的 Kubernetes 服务,它能大大减轻创建和维护 Kubernetes 集群的负担。

创建 EKS 集群

有两种方式来创建 EKS 集群,一种是使用本地的 eksctl 程序;另一种是通过 AWS 的管理后台(AWS Management Console),这里选择通过 AWS 的管理后台来创建 EKS 集群。

创建 Cluster service role

创建 EKS 集群时需要绑定一个 IAM 角色,因为 Kubernetescontrol plane 需要管理集群内的资源,所以需要有相应的操作权限。

首先进入 IAM 控制台,选择左侧 Access management 下的 Roles,点击 Create role。在 Trusted entity type 下选择 AWS service,然后在 Use cases for other AWS services 下选择 EKS,接着选择 EKS - Cluster 并点击 Next。在 Add permissions 这步直接点击 Next。在最后一步设置所创建的角色的名字,如 eksClusterRole,最后点击 Create role 创建角色。

创建集群

我们通过 AWS 管理后台中的 Amazon Elastic Kubernetes Service 界面来创建集群,第一步的 Configure cluster 主要设置集群的名称,如 my-cluster,以及绑定在之前步骤中所创建的 Cluster service role。第二步的 Specify networking 这里基本都保持默认,只是将 Cluster endpoint access 设置为 Public and private。第三步的 Configure logging 可以暂时不开启日志监控。最后在第四步的 Review and create 点击 Create 创建集群。

创建 Node group

当集群的状态变为 Active 后就表示集群创建成功,不过此时集群中还没有任何 Node,所以系统级别的 Pod 还无法正常工作,比如在集群详情的 Resources 下查看某个 corednsPod 会显示 FailedScheduling,因为 no nodes available to schedule pods

我们需要创建 Node group 来为系统添加可用的 Node

创建 Node IAM role

在创建 Node group 前,需要创建一个 Node IAM role。因为集群中的 Node 内部会运行着一个叫做 kubelet 的程序,它负责和集群的 control plane 进行通信,例如将当前 Node 注册到集群中,而某些操作需要调用 AWS 的接口,所以和 Cluster service role 类似,也需要绑定相应的权限。

这里同样也是通过 IAM 控制台 来创建角色,在 Trusted entity type 下选择 AWS service,在 Use case 下选择 EC2,然后点击 Next。在第二步的 Add permissions 需要添加 AmazonEKSWorkerNodePolicyAmazonEC2ContainerRegistryReadOnlyAmazonEKS_CNI_Policy 三个权限,虽然文档中说不建议将 AmazonEKS_CNI_Policy 权限添加到 Node IAM role 上,不过这里作为示例教程将三个权限都绑定在了 Node IAM role 上。最后也是点击 Create role 创建角色。

创建 Node group

在集群详情的 Compute 下点击 Add node group 来创建 Node group,在第一步 Configure node group 中设置 node group 的名称及绑定在之前步骤中所创建的 Node IAM role。在第二步 Set compute and scaling configuration 里配置节点的类型和数量等信息,作为教程都采用默认配置。第三步 Specify networking 同样采用默认配置。最后在第四步的 Review and create 点击 Create 完成创建。

最后当所创建的 Node group 的状态变为 Active 以及该 Node group 下的 Node 的状态变为 Ready 时说明节点创建成功。此时再查看集群详情下 ResourcescorednsPod 已成功分配了 Node 运行。

连接 EKS 集群

日常需要通过 kubectl 管理集群,所以需要先在本地配置访问 EKS 集群的权限。kubectl 本质上是和 Kubernetes API server 打交道,而创建集群时 Cluster endpoint access 部分选择的是 Public and private,所以在这个场景下能够从公网管理 EKS 集群。

首先需要安装 AWS CLIkubectl。然后在本地通过 aws configure 来设置 AWS Access Key IDAWS Secret Access Key。根据 Enabling IAM user and role access to your cluster 的描述,创建集群的账户会自动授予集群的 system:masters 权限,本文是通过 AWS 的管理后台创建集群,当前登录的账户为 root,所以 aws configure 需要设置为 rootAWS Access Key IDAWS Secret Access Key

When you create an Amazon EKS cluster, the AWS Identity and Access Management (IAM) entity user or role, such as a federated user that creates the cluster, is automatically granted system:masters permissions in the cluster’s role-based access control (RBAC) configuration in the Amazon EKS control plane.

一般公司生产环境中的 AWS 是不会直接使用 root 账户登录的,而是创建 IAM 用户,由于这里是个人的 AWS 账户所以直接使用了 root,反之就需要使用 IAM 用户的 AWS Access Key IDAWS Secret Access Key。设置完成之后可以通过 aws sts get-caller-identity 来验证当前用户是否设置正确:

1
2
3
4
5
{
"UserId": "123",
"Account": "123",
"Arn": "arn:aws:iam::123:user"
}

然后运行 aws eks update-kubeconfig --region us-west-2 --name my-cluster 来更新本地的 kubeconfig,其中 us-west-2 需要修改为实际的 AWS Regionmy-cluster 需要修改为实际的集群名称。最后就可以通过 kubectl get all 来验证能否访问集群,如果没有问题就会输出如下类似内容:

1
2
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 175m

设置其他用户的集群访问权限

创建集群的账户可能权限较高,所以需要单独给某些账户开通集群的访问权限。可以通过 kubectl describe -n kube-system configmap/aws-auth 查看当前的权限分配情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Name:         aws-auth
Namespace: kube-system
Labels: <none>
Annotations: <none>

Data
====
mapRoles:
----
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::123:role/AmazonEKSNodeRole
username: system:node:{{EC2PrivateDNSName}}


BinaryData
====

Events: <none>

假设我们需要授予某个 IAM 用户 eks system:masters 的角色,首先运行 kubectl edit -n kube-system configmap/aws-auth

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::123:role/AmazonEKSNodeRole
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
- groups:
- system:masters
userarn: arn:aws:iam::123:user/eks
username: eks
kind: ConfigMap
metadata:
creationTimestamp: "2022-09-11T06:33:38Z"
name: aws-auth
namespace: kube-system
resourceVersion: "33231"
uid: 6b186686-548c-4c99-9f65-0381da1366a4

这里在 data 下新增了 mapUsers,授予用户 eks system:masters 的角色:

1
2
3
4
5
mapUsers: |
- groups:
- system:masters
userarn: arn:aws:iam::123:user/eks
username: eks

保存后可以通过 kubectl describe configmap -n kube-system aws-auth 验证改动是否生效。然后下载 aws-auth-cm.yaml

1
curl -o aws-auth-cm.yaml https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/aws-auth-cm.yaml

将其中的 <ARN of instance role (not instance profile)> 替换为之前创建的 Node IAM role,然后执行 kubectl apply -f aws-auth-cm.yaml 应用修改,执行 kubectl get nodes --watch 观察是否所有的节点的状态都变为了 Ready

接着删除本地的 ~/.kube/config 来验证权限是否生效。重新运行 aws configure 来设置某个 IAM 用户的信息,因为我们要重新执行 aws eks update-kubeconfig --region us-west-2 --name my-cluster 来生成新的 ~/.kube/config,这里要求当前 IAM 用户拥有 DescribeCluster 的权限,这个权限是 AWS 层面的资源访问权限,而不是 EKS 集群的权限,添加权限后可能需要等待几分钟才会生效。当重新生成了 ~/.kube/config 文件之后,就可以继续通过 kubectl get all 验证访问权限是否生效。

参考