学习使用 eksctl 构建 EKS 集群

1,880 阅读3分钟

作为 k8s 小白的我,开始在 AWS 上折腾这玩意儿。

话不多说,这次的目标是:

  1. eksctl 构建一个超级简单的 k8s 集群;
  2. 配置 kubernetes dashboard
  3. 创建网络负载均衡器 NLB(Network LoadBalancer),用于分发流量;
  4. 启动 3 个 Nginx Pod

第一步,启动集群

使用 eksctl,可以帮助我们一键启动集群,并省去配置 VPC、子网、子网安全组的烦恼。

EKS 支持 EC2 运行和 Fargate 运行,这次我采用前者。

如下配置文件,声明了创建集群 coder418-basic-demo,且没做其他声明,意味着 VPC 会采用默认配置,每个可用区都会创建一个公有子网、一个私有子网。

会创建 2 个 Node Group,每个包含 2 台 t2.small 规格的 EC2 实例,默认挂载的 EBS 硬盘容量 40G。这里的 EC2 用了提前建好的 SSH Key。

区域选择了 ap-southeast-1,对于海外 AWS 来说,新加坡距离较近,是做试验不错的选择。

# eks-cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: coder418-basic-demo
  region: ap-southeast-1

nodeGroups:
  - name: ng-1
    instanceType: t2.small
    desiredCapacity: 2
    volumeSize: 40
    ssh:
      publicKeyName: coder418-ap-southeast-1
  - name: ng-2
    instanceType: t2.small
    desiredCapacity: 2
    volumeSize: 40
    ssh:
      publicKeyName: coder418-ap-southeast-1

一键部署!

$ eksctl create cluster -f eks-cluster.yaml

大概 10~20 分钟,所有资源创建完毕。

image.png

eksctl 会通过 cloudformation 创建出一系列资源堆栈。

image.png

在 EKS 界面,可查看刚建好的集群。

记得用 awscli 生成 kubectl 的配置文件,后续管理 k8s 集群会用到:

$ aws eks update-kubeconfig \
    --region ap-southeast-1 
    --name coder418-basic-demo

kubectl 可以用本地安装的,或者 AWS Cloud Shell 提供的。

第二步,部署 Dashboard

这里参考 AWS 官方教程

我们直接用 k8s 官方推荐的 dashboard 配置文件,创建所需的 ServiceAccount、Service、Role 等资源。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

dashboard 相关资源创建在 “kubernetes-dashboard” namespace 下面。

用 kubectl 查看 deployments 的情况:

$ kubectl get deployments -n kubernetes-dashboard

image.png

完事后,我们再创建管理员服务账户(ServiceAccount)集群角色(ClusterRole)的绑定,并添加一个 Secret,后面生成登录令牌(Token)会用到。

# eks-admin-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: eks-admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: eks-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: eks-admin
  namespace: kube-system
---
apiVersion: v1
kind: Secret
metadata:
  name: eks-admin-token
  namespace: kube-system
  annotations:
    kubernetes.io/service-account.name: eks-admin
type: kubernetes.io/service-account-token

然后用 kubectl 应用这个配置。

$ kubectl apply -f eks-admin-service-account.yaml

dashboard 部署工作结束。

生成令牌:

$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')

启动 kubectl 代理:

$ kubectl proxy

届时,用我们刚才拿到的令牌访问 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#!/login,就可以进到 dashboard 里面了。

image.png

dashboard 可以管理 K8S 集群,更新、删除资源。

第三步,创建 LoadBalancerController

关于负载均衡,我在之前的一篇博客中有整理——“当创建 Kubenetes ingress 的时候,AWS 会预置 ALB(应用层负载均衡器)。当创建类型为 LoadBalancer 的 Kubenetes 服务时,AWS 可提供 NLB(传输层负载均衡器)”。

coder418-basic-demo 中采用后者,也就是 LoadBalancer 服务配合 NLB 进行流量分发。

参考 AWS 文档进行 k8s LoadBalancerController 安装(后面的 Nginx 部署也可参考该文档)。

首先需要创建给 k8s LoadBalancerController 用的 IAM Policy 和 Role,以便负载均衡器有权限调用 AWS API。

下载 Policy 文件:

$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json

创建 Policy:

$ aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

创建 IAM OIDC 提供方:

$ eksctl utils associate-iam-oidc-provider \
    --region=ap-southeast-1 \
    --cluster=coder418-basic-demo \
    --approve

完成 IAM Role 的创建:

$ eksctl create iamserviceaccount \
    --region=ap-southeast-1 \
    --cluster=coder418-basic-demo \
    --namespace=kube-system \
    --name=aws-load-balancer-controller \
    --role-name AmazonEKSLoadBalancerControllerRole \
    --attach-policy-arn=arn:aws:iam::<此处略去 AWS Account ID>:policy/AWSLoadBalancerControllerIAMPolicy \
    --approve

安装负载均衡器,需要用到一个包管理工具:helm

更新仓库:

$ helm repo add eks https://aws.github.io/eks-charts &&
helm repo update

安装:

$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
    -n kube-system \
    --set clusterName=coder418-basic-demo \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller 

完事后可以用 kubectl 检查一下安装成功没。

$ kubectl get pod -n kube-system

image.png

最后,部署 Nginx Pods 和 LoadBalancer 服务

万事俱备,部署 Nginx Pods。

我们先创建一个叫 coder418-app 的 namespace,用来放 Nginx 服务。

$ kubectl create namespace coder418-app

写一个 deployment 配置,用来部 3 个 Nginx Pods。

# eks-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coder418-app
  namespace: coder418-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: public.ecr.aws/nginx/nginx:1.21
          ports:
            - name: tcp
              containerPort: 80

应用于集群:

$ kubectl apply -f eks-deployment.yaml

Pods 很快就启起来了。

image.png

然后还需要一个类型为 LoadBalancer 的服务,以便创建 NLB,将流量分发到 3 个 Nginx。

apiVersion: v1
kind: Service
metadata:
  name: coder418-service
  namespace: coder418-app
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: LoadBalancer
  selector:
    app: nginx

执行:

$ kubectl apply -f eks-service.yaml

现在,NLB 也已经启起来。

image.png

通过 LoadBalancer 提供的公网 DNS 名称,可以访问到 Nginx 服务。

image.png

成功完成了一个 EKS 集群搭建。

小结

作为小白的我,尝试到了 eksctl 带来的便捷。

经验告诉我们,生产环境的集群仅仅有此还是远远不够的,我们还需要面对许多问题。

可能需要 leader/follower 机制来保证服务的高可用;可能还要考虑 Stateless/Stateful 的问题,届时将会需要用到 EBS、EFS;如果有必要,还需要引入自动扩容机制,以提高服务并发处理能力,等等问题。

学习 AWS,任重道远!