文中大部分使用默认配置来创建 EKS 集群,是一个简单快速上手 EKS 的教程。

应用程序架构

此项目使用 Amazon EKS、Amazon EC2 和 Elastic Load Balancing,如下图所示:
AWS EKS 快速使用 - 图1

环境安装

OS:Ubuntu

AWS CLI:Version2 for Linux

  • 在 Linux 上安装、更新和卸载 AWS CLI 版本 2

    • 安装

      1. $ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
      2. $ unzip awscliv2.zip
      3. $ sudo ./aws/install
      4. $ aws --version
    • 卸载 ```shell

      使用which找到符号链接和安装路径

      $ which aws

使用 ls 命令查找符号链接指向的目录

$ ls -l /usr/local/bin/aws

删除

$ sudo rm /usr/local/bin/aws $ sudo rm /usr/local/bin/aws_completer $ sudo rm -rf /usr/local/aws-cli

  1. - 使用 aws configure 快速配置
  2. ```shell
  3. $ aws configure --profile produser
  4. AWS Access Key ID [None]: xxxxAKIAIOSFODNN7EXAMPLE
  5. AWS Secret Access Key [None]: xxxxwJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  6. Default region name [None]: us-west-2
  7. Default output format [None]: json
  8. # 使用示例
  9. $ aws s3 ls --profile produser
  10. # 要更新这些设置,请再次运行 aws configure --profile produser

kubectl

将执行权限应用于二进制文件

$ chmod +x ./kubectl

将二进制文件复制到 中的文件夹PATH

$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin

$ echo ‘export PATH=$PATH:$HOME/bin’ >> ~/.bashrc $ kubectl version —short —client

  1. <a name="Df1bx"></a>
  2. ## 必需 IAM 权限
  3. <a name="PLHXj"></a>
  4. # 创建 Amazon EKS 集群
  5. - 以下内容使用默认设置创建集群和节点的步骤。
  6. - 但是在创建集群和节点用于生产用途之前,还是需要熟悉所有设置,并部署具有满足要求的配置的集群和节点。有关更多信息,请参阅 创建 [Amazon EKS 集群](https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/create-cluster.html) 和 [Amazon EKS 个节点](https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/eks-compute.html)。
  7. <a name="PcZef"></a>
  8. ## 创建集群
  9. - 创建Amazon VPC具有满足 Amazon EKS 要求的公有子网和私有子网的 。
  10. ```shell
  11. $ aws cloudformation create-stack \
  12. --stack-name my-eks-vpc-stack \
  13. --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml
  • 创建集群IAM角色,并将所需的 Amazon EKS IAM 托管策略附加到该角色。

    • 将以下内容复制到名为 cluster-role-trust-policy.json 的文件中。

      1. {
      2. "Version": "2012-10-17",
      3. "Statement": [
      4. {
      5. "Effect": "Allow",
      6. "Principal": {
      7. "Service": "eks.amazonaws.com"
      8. },
      9. "Action": "sts:AssumeRole"
      10. }
      11. ]
      12. }
    • 创建角色

      1. $ aws iam create-role \
      2. --role-name myAmazonEKSClusterRole \
      3. --assume-role-policy-document file://"cluster-role-trust-policy.json"
    • 将 Amazon EKS 托管所需的 IAM 策略附加到角色。

      1. $ aws iam attach-role-policy \
      2. --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
      3. --role-name myAmazonEKSClusterRole
  • 进入控制台界面创建集群: my-cluster

image.png
image.png
image.png
经过 Review and create (审核和创建) 页面上,选择 Create (创建)
等待几分钟,直到集群预配置过程完成。在状态为 Active (活动) 之前,请勿继续执行下一步。

使用 kubectl CLI 与集群通信

  • 为集群创建或更新 kubeconfig 文件。 如有必要,请将 us-west-2 替换为您在其中创建集群的区域。

    • 默认情况下,在 中创建config该文件~/.kube,或者将新集群的配置添加到 中的现有config文件~/.kube。
      1. aws eks update-kubeconfig \
      2. --region us-west-2 \
      3. --name my-cluster
  • 测试配置 ```shell kubectl get svc

输出

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/kubernetes ClusterIP 10.100.0.1 443/TCP 1m

  1. <a name="QhMj8"></a>
  2. ## 创建 IAM OpenID 连接 (OIDC) 提供商
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1471554/1615171156399-1f160231-b445-46ad-b7f5-583745b23eac.png#align=left&display=inline&height=403&margin=%5Bobject%20Object%5D&name=image.png&originHeight=403&originWidth=1104&size=48990&status=done&style=shadow&width=1104)<br />通过以下网址打开 IAM 控制台:[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1471554/1615171286801-d7629d8b-b6ea-4261-a33a-875181379cad.png#align=left&display=inline&height=421&margin=%5Bobject%20Object%5D&name=image.png&originHeight=421&originWidth=1251&size=80441&status=done&style=shadow&width=1251)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1471554/1615172216930-5ae6ab80-9483-479f-b8b3-159b0294b0ae.png#align=left&display=inline&height=233&margin=%5Bobject%20Object%5D&name=image.png&originHeight=233&originWidth=1329&size=51655&status=done&style=none&width=1329)
  4. <a name="csVGL"></a>
  5. ## 创建节点
  6. 有两种常用节点类型:
  7. - **Fargate – Linux** 如果要在 上运行 Linux 应用程序,请选择此类型 AWS Fargate。
  8. - **托管节点 – Linux** 如果要在 – 实例上运行 Amazon Linux 应用程序 Amazon EC2。
  9. **下面演示添加 EC2 作为节点的步骤:**
  10. - 在控制台添加 CNI 插件(EKS Amazon VPC CNI 插件默认安装在集群中,如果没有安装就控制台手动安装);
  11. - 这个插件允许 Kubernetes pod 在 pod 中拥有和 VPC 网络中相同的 IP 地址。
  12. - 为 VPC CNI 插件创建一个 IAM 角色,并将所需的 EKS IAM 策略附加到该角色:
  13. - 创建 cni-role-trust-policy.json 文件,填入内容
  14. - `<111122223333>` 替换成根账号 ID;
  15. - `<XXXXXXXXXX45D83924220DC4815XXXXX>` 替换成 OpenID 设置时获取的序列号;
  16. ```json
  17. {
  18. "Version": "2012-10-17",
  19. "Statement": [
  20. {
  21. "Effect": "Allow",
  22. "Principal": {
  23. "Federated": "arn:aws:iam::<111122223333>:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<XXXXXXXXXX45D83924220DC4815XXXXX>"
  24. },
  25. "Action": "sts:AssumeRoleWithWebIdentity",
  26. "Condition": {
  27. "StringEquals": {
  28. "oidc.eks.us-west-2.amazonaws.com/id/<XXXXXXXXXX45D83924220DC4815XXXXX>:sub": "system:serviceaccount:kube-system:aws-node"
  29. }
  30. }
  31. }
  32. ]
  33. }
  • 为 IAM CNI 插件创建创建 VPC 角色

    1. $ aws iam create-role \
    2. --role-name myAmazonEKSCNIRole \
    3. --assume-role-policy-document file://"cni-role-trust-policy.json"
  • 将 CNI 插件所需的 EKS 策略附加到角色

    1. $ aws iam attach-role-policy \
    2. --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
    3. --role-name myAmazonEKSCNIRole
  • 将 VPC CNI 插件使用的 k8s 服务账户与 IAM 角色关联。

    • 将 <111122223333> 替换成 根账户 ID
      1. $ aws eks update-addon \
      2. --cluster-name my-cluster \
      3. --addon-name vpc-cni \
      4. --service-account-role-arn arn:aws:iam::<111122223333>:role/myAmazonEKSCNIRole
  • 创建一个节点 IAM 角色,并将所需的 EKS 策略附加到该角色。

    • 创建文件 node-role-trust-policy.json,填入内容:

      1. {
      2. "Version": "2012-10-17",
      3. "Statement": [
      4. {
      5. "Effect": "Allow",
      6. "Principal": {
      7. "Service": "ec2.amazonaws.com"
      8. },
      9. "Action": "sts:AssumeRole"
      10. }
      11. ]
      12. }
    • 创建节点 IAM 角色

      1. $ aws iam create-role \
      2. --role-name myAmazonEKSNodeRole \
      3. --assume-role-policy-document file://"node-role-trust-policy.json"
    • 将所需 EKS 策略附加到角色 ```shell $ aws iam attach-role-policy \ —policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \ —role-name myAmazonEKSNodeRole

$ aws iam attach-role-policy \ —policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \ —role-name myAmazonEKSNodeRole

  1. - 登录 EKS 控制台,**my-cluster** -> **Configuration** -> **Compute **-> **Add Node Group**
  2. - **Configuration node group** 页面上,填写相应参数,其余选择默认值,然后 **Next**
  3. - **Name **托管节点组的唯一名称,shawn-nodegroup
  4. - **Node IAM role name** (节点角色名称),选择 myAmazonEKSNodeRole
  5. - 文档中,此角色只能用于此节点组,而不能用于其他节点组
  6. - **Set compute and scaling configuration** (设置计算和扩展配置) 页面,保持默认值,然后 **Next**
  7. - Sepecify networking 页面,选择 SSH Key pair 密钥对,然后 Next
  8. - 如果没有密钥对,可以创建一个
  9. ```shell
  10. $ aws ec2 create-key-pair --region us-west-2 --key-name shawnKeyPair
  • Review and Create (审核并创建) 页面上,Create
  • 等待几分钟,状态为 Active 就可以执行下一步

查看资源

  • Cluster -> Overview,看到节点列表
  • Cluster -> Workloads,查看部署到 EKS 的工作负载列表

删除集群和节点

  • 删除节点组和 Fargate 配置文件
    • Configuration -> Compute:
      • 选择要删除的节点组
      • 选择要删除的 Fargate Profile(配置文件)
  • 删除集群
  • 删除 VPC AWS CloudFormation 堆栈
  • 删除 IAM Role
    • IAM Console -> Roles
      • 删除 myAmazonEKSClusterRole
      • 删除 myAmazonEKSFargatePodExecutionRolemyAmazonEKSNodeRole
      • 删除 myAmazonEKSCNIRole


部署 Kubernetes Dashboard(Web UI)

本教程将指导您完成将 Kubernetes 控制面板部署到 Amazon EKS 集群的过程,包括 CPU 和内存指标。它还帮助您创建可用于安全地连接到控制面板以查看和控制集群的 Amazon EKS 管理员服务账户。

前提:已安装 Kubernetes Metrics Server

  • Kubernetes Metrics Server 是集群中资源使用情况数据的聚合器,它在 Amazon EKS 集群中默认不部署。
  • 部署步骤:

    • 使用以下命令部署 Metrics Server:

      1. $ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    • 使用以下命令验证 metrics-server 部署是否运行所需数量的 Pod: ```shell $ kubectl get deployment metrics-server -n kube-system

输出

NAME READY UP-TO-DATE AVAILABLE AGE metrics-server 1/1 1 1 6m

  1. <a name="nQFJS"></a>
  2. ## 部署 Dashboard
  3. - 北京和宁夏 中国以外的所有区域:
  4. ```shell
  5. $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml

创建 eks-admin 服务账户和集群角色绑定

默认情况下,Kubernetes 控制面板用户的权限是有限的。在此部分,将创建一个可以使用管理员权限的账号 eks-admin 来和集群角色绑定。

  • 使用以下文本创建一个名为 eks-admin-service-account.yaml 的文件。 ```json apiVersion: v1 kind: ServiceAccount metadata: name: eks-admin namespace: kube-system

apiVersion: rbac.authorization.k8s.io/v1beta1 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 ```

  • 将此配置应用到集群中

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

连接到 Dashboard

现在,已将 Kubernetes 控制面板部署到集群,并且已具有可用于查看和控制集群的管理员服务账户,可使用该服务账户连接到控制面板。

  • 检索 eks-admin 服务账户的身份验证令牌。从输出中复制 值。您可以使用此令牌连接到控制面板。 ```shell $ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk ‘{print $1}’)

输出

Name: eks-admin-token-b5zv4 Namespace: kube-system Labels: Annotations: kubernetes.io/service-account.name=eks-admin kubernetes.io/service-account.uid=bcfe66ac-39be-11e8-97e8-026dce96b6e8

Type: kubernetes.io/service-account-token

Data

ca.crt: 1025 bytes namespace: 11 bytes token:

  1. - 启动 kubectl proxy
  2. ```shell
  3. $ kubectl proxy

AWS EKS 快速使用 - 图5 :::info 可能需要等待几分钟,之后 CPU 和内存指标才会显示在控制面板中。 :::

使用 Amazon ECR

前提

  • 具有足够权限的 IAM 账户
  • 安装 AWC CLI
  • 安装 Docker

创建 Docker Image

此部分,将在本地环境中创建一个基于 NodeJS 的简单 Web 服务,并在本地系统中测试此映像,然后将此映像推送至 ECR,以便能在 EKS 中使用它。

创建 NodeJS web 服务的 Docker Image

  • 使用 Express.js 框架创建一个 NodeJS Web 应用;
  • 创建 Dockerfile 文件
    • 选择 node:12 作为基础镜像,它已经安装了 Node.js 和 NPM;
    • 创建一个 目录来保存镜像中的应用程序代码,作为应用程序的工作目录;
    • 使用 npm 安装应用程序的依赖
    • 将程序源码拷贝到镜像中
    • 将应用程序绑定到端口,对应用程序中监听的端口
    • 启动命令 ```dockerfile FROM node:12

Create app directory

WORKDIR /usr/src/app

Install app dependencies

A wildcard is used to ensure both package.json AND package-lock.json are copied

COPY package*.json ./ RUN npm install

Bundle app source

COPY . .

EXPOSE 3000

CMD [“node”, “app.js”]

  1. :::info
  2. 这里将 package.json 与源码分开复制,而不是复制整个工作目录,是为了利用缓存的 Docker 层。通常 package.json 变化少,这样单独放在前面,前面几层的 Docker 层可以重复利用。
  3. :::
  4. - 在与 Dockerfile 相同的目录中创建一个 **.dockerignore** 文件,其中包含以下内容:
  5. - 这样可以防止将本地模块和调试日志复制到 Docker 镜像上

node_modules npm-debug.log

  1. - cd 到具有 Dockerfile 的目录,构建镜像
  2. ```shell
  3. $ docker build -t <your username>/node-web-app .
  4. #构建完成后查看Image
  5. $ docker images

运行镜像进行测试

  • 使用 -d 运行镜像以分离模式运行容器,使容器在后台运行, -p 标志将公共端口重定向到容器内的私有端口,运行之前构建的镜像:

    1. $ docker run -p 49160:3000 -d <your username>/node-web-app
  • 如果需要进入容器内部,你可以使用 exec 命令:

    1. # Enter the container
    2. $ docker exec -it <container id> /bin/bash

    推送 Image 到 ECR

    :::info 注意替换命令中的 region、aws_account_id :::

  • 向 ECR 验证身份

    1. $ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com
  • 创建 ECR 存储库

    • 创建一个 shawn-demo 的存储库,稍后将 Image 推送至此
      1. aws ecr create-repository \
      2. --repository-name shawn-demo \
      3. --image-scanning-configuration scanOnPush=true \
      4. --region us-west-2
  • Tag and Push Image to ECR ```shell $ docker tag node-web-app:latest aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest

$ docker push aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest

  1. - Pull Image from ECR
  2. ```shell
  3. $ docker pull aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest
  • Delete Image from ECR

    1. $ aws ecr batch-delete-image \
    2. --repository-name shawn-demo \
    3. --image-ids imageTag=latest
  • 删除存储库

    • 默认情况下,不能删除包含映像的存储库;但是,—force 标记允许此操作
      1. $ aws ecr delete-repository \
      2. --repository-name shawn-demo \
      3. --force

部署 NodeJS 应用到 EKS

  • 编写应用的 yaml 文件:
    • 如果服务不需要对外暴露,仅供内部使用,Service Type 使用默认的 Cluster IP 就可以;
    • 如果服务需要对外暴露访问(例如 frontend ),在 AWS 云平台上需要使用 Service Type: LoadBalancer,AWS 会自动为服务创建 Network LoadBalancer,提供一个 External IP 供外网访问。 ```yaml

      deploy

      apiVersion: apps/v1 kind: Deployment metadata: name: shawn-demo spec: selector: matchLabels: app: shawn-demo replicas: 2 template: metadata: labels: app: shawn-demo spec: containers:
      • name: shawn-demo image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest ports:
        • containerPort: 3000

service

apiVersion: v1 kind: Service metadata: name: web-demo spec: ports:

  1. - port: 80
  2. protocol: TCP
  3. targetPort: 3000

selector: app: shawn-demo type: LoadBalancer

  1. - 部署应用
  2. ```shell
  3. $ kubectl apply -f node-demo-deploy.yaml
  4. $ kubectl get svc -o wide
  5. #输出
  6. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
  7. kubernetes ClusterIP 10.100.0.1 <none> 443/TCP
  8. web-demo LoadBalancer 10.100.17.70 ab22xxxxx107.us-west-2.elb.amazonaws.com 80:31826/TCP
  • 测试:在浏览器中使用 Service: web-demo 提供的 External IP 就可以访问到服务