- 应用程序架构
- 环境安装
- 使用which找到符号链接和安装路径
- 使用 ls 命令查找符号链接指向的目录
- 删除
- 将执行权限应用于二进制文件
- 将二进制文件复制到 中的文件夹PATH
- 输出
- 部署 Kubernetes Dashboard(Web UI)
- 输出
- Data
- 使用 Amazon ECR
- Create app directory
- Install app dependencies
- A wildcard is used to ensure both package.json AND package-lock.json are copied
- Bundle app source
- 推送 Image 到 ECR
- 部署 NodeJS 应用到 EKS
- deploy
- service
文中大部分使用默认配置来创建 EKS 集群,是一个简单快速上手 EKS 的教程。
应用程序架构
此项目使用 Amazon EKS、Amazon EC2 和 Elastic Load Balancing,如下图所示:
环境安装
OS:Ubuntu
AWS CLI:Version2 for Linux
使用 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
- 使用 aws configure 快速配置
```shell
$ aws configure --profile produser
AWS Access Key ID [None]: xxxxAKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: xxxxwJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json
# 使用示例
$ aws s3 ls --profile produser
# 要更新这些设置,请再次运行 aws configure --profile produser
kubectl
- 安装 kubectl
- 版本示例:1.17 kubectl 客户端应使用 Kubernetes 1.16、1.17 和 1.18 集群
- 适用于 Kubernetes1.18: ```shell $ curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/linux/amd64/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
<a name="Df1bx"></a>
## 必需 IAM 权限
<a name="PLHXj"></a>
# 创建 Amazon EKS 集群
- 以下内容使用默认设置创建集群和节点的步骤。
- 但是在创建集群和节点用于生产用途之前,还是需要熟悉所有设置,并部署具有满足要求的配置的集群和节点。有关更多信息,请参阅 创建 [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)。
<a name="PcZef"></a>
## 创建集群
- 创建Amazon VPC具有满足 Amazon EKS 要求的公有子网和私有子网的 。
```shell
$ aws cloudformation create-stack \
--stack-name my-eks-vpc-stack \
--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 的文件中。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
创建角色
$ aws iam create-role \
--role-name myAmazonEKSClusterRole \
--assume-role-policy-document file://"cluster-role-trust-policy.json"
将 Amazon EKS 托管所需的 IAM 策略附加到角色。
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
--role-name myAmazonEKSClusterRole
进入控制台界面创建集群: my-cluster
经过 Review and create (审核和创建) 页面上,选择 Create (创建)。
等待几分钟,直到集群预配置过程完成。在状态为 Active (活动) 之前,请勿继续执行下一步。
使用 kubectl CLI 与集群通信
为集群创建或更新 kubeconfig 文件。 如有必要,请将 us-west-2 替换为您在其中创建集群的区域。
- 默认情况下,在 中创建config该文件~/.kube,或者将新集群的配置添加到 中的现有config文件~/.kube。
aws eks update-kubeconfig \
--region us-west-2 \
--name my-cluster
- 默认情况下,在 中创建config该文件~/.kube,或者将新集群的配置添加到 中的现有config文件~/.kube。
测试配置 ```shell kubectl get svc
输出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes ClusterIP 10.100.0.1
<a name="QhMj8"></a>
## 创建 IAM OpenID 连接 (OIDC) 提供商
![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)
<a name="csVGL"></a>
## 创建节点
有两种常用节点类型:
- **Fargate – Linux** 如果要在 上运行 Linux 应用程序,请选择此类型 AWS Fargate。
- **托管节点 – Linux** 如果要在 – 实例上运行 Amazon Linux 应用程序 Amazon EC2。
**下面演示添加 EC2 作为节点的步骤:**
- 在控制台添加 CNI 插件(EKS Amazon VPC CNI 插件默认安装在集群中,如果没有安装就控制台手动安装);
- 这个插件允许 Kubernetes pod 在 pod 中拥有和 VPC 网络中相同的 IP 地址。
- 为 VPC CNI 插件创建一个 IAM 角色,并将所需的 EKS IAM 策略附加到该角色:
- 创建 cni-role-trust-policy.json 文件,填入内容
- `<111122223333>` 替换成根账号 ID;
- `<XXXXXXXXXX45D83924220DC4815XXXXX>` 替换成 OpenID 设置时获取的序列号;
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<111122223333>:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<XXXXXXXXXX45D83924220DC4815XXXXX>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-2.amazonaws.com/id/<XXXXXXXXXX45D83924220DC4815XXXXX>:sub": "system:serviceaccount:kube-system:aws-node"
}
}
}
]
}
为 IAM CNI 插件创建创建 VPC 角色
$ aws iam create-role \
--role-name myAmazonEKSCNIRole \
--assume-role-policy-document file://"cni-role-trust-policy.json"
将 CNI 插件所需的 EKS 策略附加到角色
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
--role-name myAmazonEKSCNIRole
将 VPC CNI 插件使用的 k8s 服务账户与 IAM 角色关联。
- 将 <111122223333> 替换成 根账户 ID
$ aws eks update-addon \
--cluster-name my-cluster \
--addon-name vpc-cni \
--service-account-role-arn arn:aws:iam::<111122223333>:role/myAmazonEKSCNIRole
- 将 <111122223333> 替换成 根账户 ID
创建一个节点 IAM 角色,并将所需的 EKS 策略附加到该角色。
创建文件 node-role-trust-policy.json,填入内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
创建节点 IAM 角色
$ aws iam create-role \
--role-name myAmazonEKSNodeRole \
--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
- 登录 EKS 控制台,**my-cluster** -> **Configuration** -> **Compute **-> **Add Node Group**
- 在 **Configuration node group** 页面上,填写相应参数,其余选择默认值,然后 **Next**
- **Name **托管节点组的唯一名称,shawn-nodegroup
- **Node IAM role name** (节点角色名称),选择 myAmazonEKSNodeRole。
- 文档中,此角色只能用于此节点组,而不能用于其他节点组
- 在 **Set compute and scaling configuration** (设置计算和扩展配置) 页面,保持默认值,然后 **Next**
- 在 Sepecify networking 页面,选择 SSH Key pair 密钥对,然后 Next
- 如果没有密钥对,可以创建一个
```shell
$ 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(配置文件)
- Configuration -> Compute:
- 删除集群
- 删除 VPC AWS CloudFormation 堆栈
- 删除 IAM Role
- IAM Console -> Roles
- 删除
myAmazonEKSClusterRole
- 删除
myAmazonEKSFargatePodExecutionRole
或myAmazonEKSNodeRole
- 删除
myAmazonEKSCNIRole
- 删除
- IAM Console -> Roles
部署 Kubernetes Dashboard(Web UI)
本教程将指导您完成将 Kubernetes 控制面板部署到 Amazon EKS 集群的过程,包括 CPU 和内存指标。它还帮助您创建可用于安全地连接到控制面板以查看和控制集群的 Amazon EKS 管理员服务账户。
前提:已安装 Kubernetes Metrics Server
- Kubernetes Metrics Server 是集群中资源使用情况数据的聚合器,它在 Amazon EKS 集群中默认不部署。
部署步骤:
使用以下命令部署 Metrics Server:
$ 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
<a name="nQFJS"></a>
## 部署 Dashboard
- 北京和宁夏 中国以外的所有区域:
```shell
$ 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 ```
将此配置应用到集群中
$ 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:
Type: kubernetes.io/service-account-token
Data
ca.crt: 1025 bytes
namespace: 11 bytes
token:
- 启动 kubectl proxy
```shell
$ kubectl proxy
要访问控制面板终端节点,请使用 Web 浏览器打开以下链接:http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#!/login。
选择 Token (令牌),将上一个命令
<authentication_token>
的输出粘贴到 Token (令牌) 字段中,然后选择 SIGN IN (登录)。
:::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”]
:::info
这里将 package.json 与源码分开复制,而不是复制整个工作目录,是为了利用缓存的 Docker 层。通常 package.json 变化少,这样单独放在前面,前面几层的 Docker 层可以重复利用。
:::
- 在与 Dockerfile 相同的目录中创建一个 **.dockerignore** 文件,其中包含以下内容:
- 这样可以防止将本地模块和调试日志复制到 Docker 镜像上
node_modules npm-debug.log
- cd 到具有 Dockerfile 的目录,构建镜像
```shell
$ docker build -t <your username>/node-web-app .
#构建完成后查看Image
$ docker images
运行镜像进行测试
使用
-d
运行镜像以分离模式运行容器,使容器在后台运行,-p
标志将公共端口重定向到容器内的私有端口,运行之前构建的镜像:$ docker run -p 49160:3000 -d <your username>/node-web-app
如果需要进入容器内部,你可以使用
exec
命令:# Enter the container
$ docker exec -it <container id> /bin/bash
推送 Image 到 ECR
:::info 注意替换命令中的 region、aws_account_id :::
向 ECR 验证身份
$ 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 推送至此
aws ecr create-repository \
--repository-name shawn-demo \
--image-scanning-configuration scanOnPush=true \
--region us-west-2
- 创建一个 shawn-demo 的存储库,稍后将 Image 推送至此
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
- Pull Image from ECR
```shell
$ docker pull aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest
Delete Image from ECR
$ aws ecr batch-delete-image \
--repository-name shawn-demo \
--image-ids imageTag=latest
删除存储库
- 默认情况下,不能删除包含映像的存储库;但是,—force 标记允许此操作
$ aws ecr delete-repository \
--repository-name shawn-demo \
--force
- 默认情况下,不能删除包含映像的存储库;但是,—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
- name: shawn-demo
image: aws_account_id.dkr.ecr.us-west-2.amazonaws.com/shawn-demo:latest
ports:
service
apiVersion: v1 kind: Service metadata: name: web-demo spec: ports:
- port: 80
protocol: TCP
targetPort: 3000
selector: app: shawn-demo type: LoadBalancer
- 部署应用
```shell
$ kubectl apply -f node-demo-deploy.yaml
$ kubectl get svc -o wide
#输出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP
web-demo LoadBalancer 10.100.17.70 ab22xxxxx107.us-west-2.elb.amazonaws.com 80:31826/TCP
- 测试:在浏览器中使用 Service: web-demo 提供的 External IP 就可以访问到服务