EKS 101 动手实验(一)创建EKS集群

EKS动手实验合集请参考这里

EKS 1.27 & 1.28版本 @2023-11 AWS Global区域测试通过

一、AWSCLI安装和AKSK准备

1、客户端下载

本步骤对所有操作系统下都需要安装。请到这里下载对应的操作系统的安装包。

2、配置AKSK和区域

配置进入AWS控制台,创建IAM用户,附加AdministratorAccess的IAM Policy,最后给这个用户生成AKSK密钥。

在安装好AWSCLI的客户端上,进入命令行窗口,执行aws configure,然后填写正确的AKSK。同时,在命令的最后一步配置region的时候,设置region为本次实验的ap-southeast-1

请注意:如果是通过EventEngine或者Workshop Studio自动创建的实验环境,在EventEngine或者Workshop Studio界面上会提供一套默认的AKSK密钥,且这套AKSK需要搭配SessionToken使用。这套默认的密钥权限是不足以完成EKS集群创建的。因此,必须按照本文要求,重新创建一个新的管理员用户,然后新创建一个AKSK附加到本用户,才可以进行后续实验。

二、安装EKS客户端和Kubectl客户端(三个OS类型根据实验者选择其一)

请注意,eksctl版本和创建EKS的版本有对应关系,因此请升级您的客户端的eksctl到最新版本。

1、Windows下安装eksctl和kubectl工具

eksctl的安装可通过choco包管理工具进行。先使用管理员权限打开powershell,执行:

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

即可安装好choco。然后在cmd下用管理员权限安装eksctl和jq工具(本步骤需要管理员权限):

choco install -y eksctl jq curl wget vim 7zip

此外很多日常软件都可以后续执行choco install安装。

下载Windows版本的kubectl工具:

curl.exe -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.1/2023-04-19/bin/windows/amd64/kubectl.exe

下载后将kubectl.exe放入系统PATH目录,例如C:\Windows\system32\,之后即可在任意下执行kubectl命令。

2、Linux下安装eksctl和kubectl工具

在Linux下安装eks工具,包括eksctl和kubectl两个。

Intel架构的执行如下命令:

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /bin
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.28.3/2023-11-14/bin/linux/amd64/kubectl
chmod 755 kubectl
sudo mv kubectl /bin
eksctl version

Graviton2的ARM架构的Linux执行如下命令:

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_arm64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /bin
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.28.3/2023-11-14/bin/linux/arm64/kubectl
chmod 755 kubectl
sudo mv kubectl /bin
eksctl version

安装完毕后即可看到eksctl版本,同时kubectl也下载完毕。

3、MacOS下安装eksctl和kubectl工具

先安装homebrew包管理工具。这一步需要从Github下载,因此最好能使用国外VPN确保安装成功。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

然后使用brew工具即可安装eksctl。这里需要安装最新版本的eksctl,旧版本的不能创建最新EKS集群。

brew upgrade eksctl && { brew link --overwrite eksctl; } || { brew tap weaveworks/tap; brew install weaveworks/tap/eksctl; }
eksctl version

最后安装kubectl工具,也使用brew安装:

brew reinstall kubernetes-cli

客户端准备完毕。

三、创建EKS集群的配置文件(两种场景二选一)

EKS集群分成EC2模式和无EC2的Fargate模式。本文为有EC2模式的配置,不讨论Fargate配置。在接下来的网络模式又有两种:

  • 创建集群时候,如果不指定参数,那么eksctl默认会自动生成一个全新的VPC、子网并使用192.168的网段,然后在其中创建nodegroup节点组。此时如果希望位于默认VPC的现有业务系统与EKS互通,那么需要配置VPC Peering才可以打通网络;如果需求是此场景,请参考下述第一个章节所介绍的方式创建配置文件
  • 如果希望EKS使用现有VPC和子网,例如一个包含有Public Subnet/Private Subnet和NAT Gateway的VPC,那么请使用第二个章节所介绍的方式创建配置文件

1、创建全新VPC

执行如下命令。注意如果是多人在同一个账号内实验,需要更改EKS集群的名字避免冲突。如果多人在不同账号内做实验,无需修改名称,默认的名称即可。

编辑配置文件newvpc.yaml,内容如下:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eksworkshop
  region: ap-southeast-1
  version: "1.28"

vpc:
  clusterEndpoints:
    publicAccess:  true
    privateAccess: true

kubernetesNetworkConfig:
  serviceIPv4CIDR: 10.50.0.0/24

managedNodeGroups:
  - name: managed-ng
    labels:
      Name: managed-ng
    instanceType: t3.2xlarge
    minSize: 3
    desiredCapacity: 3
    maxSize: 6
    volumeType: gp3
    volumeSize: 100
    volumeIOPS: 3000
    volumeThroughput: 125
    tags:
      nodegroup-name: ng1
    iam:
      withAddonPolicies:
        imageBuilder: true
        autoScaler: true
        certManager: true
        efs: true
        ebs: true
        albIngress: true
        xRay: true
        cloudWatch: true

cloudWatch:
  clusterLogging:
    enableTypes: ["api", "audit", "authenticator", "controllerManager", "scheduler"]
    logRetentionInDays: 30

请替换以上配置文件中集群名称、region为实际使用的地区。

执行如下命令创建集群。

eksctl create cluster -f newvpc.yaml

创建完成。

2、使用现有VPC的子网

(1)给EKS要使用的Subnet子网打标签

请确保本子网已经设置了正确的路由表,且VPC内包含NAT Gateway可以提供外网访问能力。然后接下来为其打标签。

找到当前的VPC,找到有EIP和NAT Gateway的Public Subnet,为其添加标签:

  • 标签名称:kubernetes.io/role/elb,值:1

接下来进入Private subnet,为其添加标签:

  • 标签名称:kubernetes.io/role/internal-elb,值:1

接下来请重复以上工作,三个AZ的子网都实施相同的配置,注意第一项标签值都是1。

请不要跳过以上步骤,否则后续使用ELB会遇到错误。

(2)要求EKS Nodegroup使用特定的Subnet

编辑配置文件existingsubnet.yaml,内容如下:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eksworkshop
  region: ap-southeast-1
  version: "1.28"

vpc:
  clusterEndpoints:
    publicAccess:  true
    privateAccess: true
  subnets:
    private:
      ap-southeast-1a: { id: subnet-04a7c6e7e1589c953 }
      ap-southeast-1b: { id: subnet-031022a6aab9b9e70 }
      ap-southeast-1c: { id: subnet-0eaf9054aa6daa68e }

kubernetesNetworkConfig:
  serviceIPv4CIDR: 10.50.0.0/24

managedNodeGroups:
  - name: managed-ng
    labels:
      Name: managed-ng
    instanceType: t3.2xlarge
    minSize: 3
    desiredCapacity: 3
    maxSize: 6
    privateNetworking: true
    subnets:
      - subnet-04a7c6e7e1589c953
      - subnet-031022a6aab9b9e70
      - subnet-0eaf9054aa6daa68e
    volumeType: gp3
    volumeSize: 100
    volumeIOPS: 3000
    volumeThroughput: 125
    tags:
      nodegroup-name: managed-ng
    iam:
      withAddonPolicies:
        imageBuilder: true
        autoScaler: true
        certManager: true
        efs: true
        ebs: true
        albIngress: true
        xRay: true
        cloudWatch: true

cloudWatch:
  clusterLogging:
    enableTypes: ["api", "audit", "authenticator", "controllerManager", "scheduler"]
    logRetentionInDays: 30

请替换以上配置文件中集群名称、region、子网ID为实际使用的地区。

执行如下命令创建集群。

eksctl create cluster -f existingsubnet.yaml

创建完成。

四、查看创建结果

此过程需要10-15分钟才可以创建完毕。执行如下命令查询节点。

kubectl get node

返回节点如下表示正常。

NAME                                                 STATUS   ROLES    AGE    VERSION
ip-192-168-122-179.ap-southeast-1.compute.internal   Ready    <none>   159m   v1.22.6-eks-7d68063
ip-192-168-137-83.ap-southeast-1.compute.internal    Ready    <none>   159m   v1.22.6-eks-7d68063
ip-192-168-181-37.ap-southeast-1.compute.internal    Ready    <none>   159m   v1.22.6-eks-7d68063

五、创建集群并配置Dashboard图形界面(本章节可选)

本章节可跳过不影响后续实验。

1、部署K8S原生控制面板

执行如下命令部署Dashboard:

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

在以上命令中,采用的是直接调用Github托管的yaml文件,其域名是raw.githubusercontent.com。在国内网络条件下访问这个网址可能会失败。

因此本实验另外提供了另外的网址可在国内的yaml文件。请执行如下命令开始启动。

kubectl apply -f https://myworkshop.bitipcman.com/eks101/01/kubernetes-dashboard.yaml

部署需要等待3-5分钟。

2、登录到Dashboard

访问Dashboard的身份验证是通过token完成,执行以下命令获取token。注意需要手工替换EKS集群名称和region名称为实际操作环境。如果集群名称、Region信息不匹配,生成的token会报告401错误无法登录。

aws eks get-token --cluster-name eksworkshop --region ap-southeast-1 | jq -r .status.token

以上命令会输出类似如下的token,稍后复制下来,登录Dashboard会使用。

k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtc291dGhlYXN0LTEuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFSSEc2NFVGR1NTT01JWDZXJTJGMjAyMjAzMTglMkZhcC1zb3V0aGVhc3QtMSUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjIwMzE4VDE2NDYzMlomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTFjZDkzMGZjMjNhNTI2MmIyYWNhNDlmMzM0ZTZlMTRhNzFhMDE1NzU0MjY4YjYyOTgzMzA5ZmJjYTAxZjY5NTQ

使用如下命令启动Proxy将Dashboard的访问映射出来。

kubectl proxy

使用Chrome等不受安全策略限制的浏览器,在实验者的本机上访问如下地址(部分Firefox受到安全策略限制访问有兼容问题)。http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

登录页面打开后,选择第一项使用token登录,然后输入上一步获取的token,即可访问dashboard.

至此Dashboard配置完成。

3、删除Dashboard服务(可选)

测试完成后,如果需要删除Dashboard,执行如下命令。

kubectl delete -f https://myworkshop.bitipcman.com/eks101/kubernetes-dashboard.yaml

本命令为可选,建议保留Dashboard,在后续实验中也可以继续通过Dashboard做监控。

六、部署Nginx测试应用并使用NodePort+NLB模式对外暴露服务

1、创建服务

这个测试应用将在当前集群的node上创建nginx应用pod,并使用default namespace运行Service,然后通过NodePort模式和NLB对外发布在80端口。

内容如下:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: public.ecr.aws/nginx/nginx:1.24-alpine-slim
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: "service-nginx"
  annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  selector:
    app: nginx
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

执行如下命令。

kubectl apply -f nginx-nlb.yaml 

2、检查部署结果

查看创建出来的pod,执行如下命令。

kubectl get pods

返回结果如下Running表示运行正常。

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-85ff79dd56-8l8wn   1/1     Running   0          2m

确认部署执行如下命令。

kubectl get deployment nginx-deployment

返回结果如下,状态是Available表示工作正常。

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           9m12s

3、测试从浏览器访问

本实验使用的是NLB,创建NLB过程需要3-5分钟。此时可以通过AWS EC2控制台,进入Load Balance负载均衡界面,可以看到NLB处于Provisioning创建中的状态。等待其变成Active状态。

接下来进入NLB的listener界面,可以看到NLB将来自80端口的流量转发到了k8s-default-servicen这个target group。点击进入Target Group,可以看到当前两个node的状态是initial,等待其健康检查完成,变成healthy状态,即可访问。

查看运行中的Service,执行如下命令。

kubectl get service service-nginx -o wide 

返回结果如下。其中的ELB域名地址就是对外访问入口。其中的CLUSTER-IP即可看到是创建集群时候指定的IP范围。

NAME            TYPE           CLUSTER-IP   EXTERNAL-IP                                                                          PORT(S)        AGE    SELECTOR
service-nginx   LoadBalancer   10.50.0.12   a4fa7cb23a0754d8b8198fad9fa7b133-114a5df4c6565d90.elb.ap-southeast-1.amazonaws.com   80:31411/TCP   156m   app=nginx

用浏览器访问ELB地址,即可验证应用启动结果。

3、测试从命令行访问(可选)

也可以在命令行上通过curl命令访问。

Linux和MacOS操作系统如下命令是通过命令行访问:

在Linux的bash/sh/zsh上执行如下脚本,可获取NLB地址并通过curl访问:

NLB=$(kubectl get service service-nginx -o json | jq -r '.status.loadBalancer.ingress[].hostname')
echo $NLB
curl -m3 -v $NLB

Windows操作系统如下命令是通过命令行访问:

获取NLB地址:

kubectl get service service-nginx -o json | jq -r .status.loadBalancer.ingress[].hostname

通过CURL验证访问:

curl -m3 -v 上文获取到的NLB入口地址

由此即可访问到测试应用,看到 Welcome to nginx! 即表示访问成功。 

4、删除服务(可选)

执行如下命令:

kubectl delete -f nginx-deployment.yaml

至此服务删除完成。

5、删除集群(可选)

请先删除应用,这样应用对应的负债均衡也会自动删除。

执行如下命令删除集群:

eksctl delete cluster --name eksworkshop --region ap-southeast-1

请将以上命令中的集群名称、region代号替换为您的真实环境,即可删除集群。

七、参考文档

AWS GCR Workshop:

https://github.com/aws-samples/eks-workshop-greater-china/tree/master/china/2020EKSLaunch_Workshop

K8S的Dashboard安装:

https://github.com/kubernetes/dashboard

eksctl的安装:

https://github.com/weaveworks/eksctl