写在前面
版本说明:AWS CLI 2.x + 当前版 eksctl(2026);创建前请用 aws eks describe-addon-versions 和 EKS 版本日历确认目标区域支持的 Kubernetes 与插件版本。
承接 AKS 篇。同样的 demo(nginx 静态页),换 AWS EKS 跑一遍。重点体感三个对比点:
1
2
3
4
| 相比 AKS 的差异:
① 集群按版本支持阶段收费:标准支持 $0.10/h,延长支持更高
② 配置更繁:现代 LB 要装 AWS Load Balancer Controller(AKS 内置)
③ 身份用 IRSA(IAM Roles for ServiceAccounts)
|
1
2
3
4
5
6
7
8
| 本篇路线(7 步,和 AKS 篇对齐):
① 准备:账号 + CLI + eksctl
② 建 ECR + 推镜像
③ 创建 EKS 集群(eksctl 一条命令)
④ 身份:节点角色拉镜像 + IRSA 访问云 API
⑤ 部署 + 暴露(Classic LB 起,LB Controller 升级)
⑥ 接监控(CloudWatch Observability)
⑦ 清理 + 按官方价格估算
|
一、准备:账号 + CLI + eksctl
1
2
3
4
5
6
7
8
9
10
11
12
| # AWS CLI 配置密钥(IAM 用户 access key)
aws configure
# AWS Access Key ID: ...
# Secret Access Key: ...
# Default region name: us-east-1
# Default output format: json
# 装 eksctl(简化 EKS、VPC、IAM 与节点组创建)
# macOS: brew install weaveworks/tap/eksctl
# Linux: 下载二进制(见官方)
eksctl version # 确认
|
为什么用 eksctl 不用 aws eks?因为 aws eks create-cluster 要你自己管 VPC/子网/IAM 角色/node group 一堆,eksctl 一条命令全包(建 VPC、IAM、控制平面、节点组)。生产 Terraform 化时再拆。
二、建 ECR + 推镜像
ECR(Elastic Container Registry)——AWS 镜像仓库。
1
2
3
4
5
6
7
8
9
10
| AWS_ACCT=$(aws sts get-caller-identity --query Account --output text)
REGION=us-east-1
REPO=$AWS_ACCT.dkr.ecr.$REGION.amazonaws.com/demo/web
# 建仓库
aws ecr create-repository --repository-name demo/web --region $REGION
# 登录(token 12 小时有效)
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin $AWS_ACCT.dkr.ecr.$REGION.amazonaws.com
|
构建并推:
1
2
3
4
5
6
7
| cat > Dockerfile <<'EOF'
FROM nginx:alpine
RUN echo "<h1>Hello from EKS</h1>" > /usr/share/nginx/html/index.html
EOF
docker build -t $REPO:v1 .
docker push $REPO:v1
|
三、创建 EKS 集群(eksctl 一条命令)
1
2
3
4
5
6
7
8
9
| CLUSTER=myEKS
eksctl create cluster \
--name $CLUSTER \
--region $REGION \
--nodegroup-name standard-ng \
--node-type t3.medium \
--nodes 2 \
--nodes-min 1 --nodes-max 3 \
--managed
|
eksctl 这一招替你做了:
1
2
3
4
5
| ✓ 创建 VPC + 子网(2 AZ)+ NAT 网关 + 安全组
✓ 创建 EKS 集群(标准版本支持期按 $0.10/集群小时计费)
✓ 创建集群 IAM 角色 + 节点 IAM 角色(含 ECR 拉镜像权限)
✓ 创建 managed node group(2 个 t3.medium)
✓ 配 kubeconfig(kubectl 开箱即用)
|
接入集群(eksctl 自动写 kubeconfig,或手动):
1
2
3
4
5
| eksctl utils write-kubeconfig --cluster $CLUSTER --region $REGION
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# ip-10-0-1-12.ec2.internal Ready <none> 1m v1.x.y
# ip-10-0-2-34.ec2.internal Ready <none> 1m v1.x.y
|
创建过程 ~15-20 分钟(VPC + 控制平面 + 节点都要等)。比 AKS 慢一截。
四、身份:节点角色拉镜像,IRSA 授权应用
在 EC2 节点上,私有镜像由 kubelet 在容器启动前拉取。eksctl 创建的节点 IAM 角色通常具备所需 ECR 读取权限:
1
2
3
| Pod 拉镜像 → kubelet 用节点 EC2 instance profile
→ 节点角色有 ECR ReadOnly
→ 拉取成功(粗粒度:整个节点所有 Pod 共享)
|
所以下面的 Deployment 直接能用(不用配 imagePullSecret):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: <ACCOUNT>.dkr.ecr.<REGION>.amazonaws.com/demo/web:v1
ports: [{ containerPort: 80 }]
|
IRSA 则用于给已经启动的工作负载授予调用 S3、SQS、DynamoDB 等 AWS API 的权限。它不替代节点角色拉取 ECR 镜像;Fargate 另由 Pod execution role 承担镜像拉取。
1
2
3
4
5
6
7
8
9
| # 1. 集群启用 IAM OIDC Provider(没开就补)
eksctl utils associate-iam-oidc-provider --cluster $CLUSTER --region $REGION --approve
# 2. 示例:创建 IAM Role + K8s ServiceAccount,授予应用读取某个 S3 存储桶所需的自定义策略
eksctl create iamserviceaccount \
--name web-sa --namespace default \
--cluster $CLUSTER --region $REGION \
--attach-policy-arn arn:aws:iam::<ACCT>:policy/WebReadOwnBucket \
--approve
|
这会创建一个带注解的 SA:
1
2
3
4
5
6
7
| apiVersion: v1
kind: ServiceAccount
metadata:
name: web-sa
annotations:
# 关键注解:绑哪个 IAM Role
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCT>:role/eksctl-myEKS-addon-iamserviceaccount-xxx
|
Deployment 里指定 serviceAccountName: web-sa 后,应用使用该 Role 调用获准的 AWS API;镜像仍由 kubelet 使用节点角色拉取。
不要把两条身份链混在一起:AKS --attach-acr 与 EKS 节点角色都是镜像拉取身份;AKS Workload Identity 与 EKS IRSA 才是面向应用的工作负载身份。
五、部署 + 暴露:Classic LB 起,LB Controller 升级
部署应用:
1
2
3
4
| # 填镜像
sed -i "s|<ACCOUNT>|$AWS_ACCT|;s|<REGION>|$REGION|" web.yaml
kubectl apply -f web.yaml
kubectl get pods
|
暴露 Service。这里有个 EKS 的坑点:直接 type: LoadBalancer 会创建老式 Classic Load Balancer(CLB,已不推荐),现代要用 NLB/ALB 必须装 AWS Load Balancer Controller。
简化版(Classic LB,跑通就行):
1
2
3
4
5
6
7
8
9
| # web-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: LoadBalancer
selector: { app: web }
ports: [{ port: 80, targetPort: 80 }]
|
1
2
3
| kubectl apply -f web-svc.yaml
kubectl get svc web -w
# EXTERNAL-IP 会是 <xxx>.elb.amazonaws.com
|
生产版(装 AWS Load Balancer Controller,用 NLB):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 1. 先建 controller 自己的 IRSA(它要调 AWS API 创建 LB)
eksctl create iamserviceaccount \
--name aws-load-balancer-controller \
--namespace kube-system \
--cluster $CLUSTER --region $REGION \
--attach-policy-arn arn:aws:iam::<ACCT>:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts --approve
# 2. helm 装 controller
helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=$CLUSTER \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
|
然后 Service 加注解指定 NLB:
1
2
3
4
| metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
|
1
2
3
| 对比 AKS 的暴露:
AKS type=LoadBalancer → 内置 cloud controller 自动建 Standard LB(零配置)
EKS type=LoadBalancer → 默认老 CLB;要 NLB/ALB 得装 AWS LB Controller(多两步)
|
这是 EKS 体感"更繁"的典型:底层更灵活(CLB/NLB/ALB 任选、Ingress 细控),但开箱即用程度不如 AKS/GKE。
六、接监控:CloudWatch Observability
新版 EKS 用 managed addon amazon-cloudwatch-observability(替代老的 Container Insights):
1
2
3
4
5
6
7
8
9
10
11
| # 给 addon 的 agent 建 IRSA(绑 CloudWatchAgentServerPolicy)
eksctl create iamserviceaccount \
--name cloudwatch-agent --namespace amazon-cloudwatch \
--cluster $CLUSTER --region $REGION \
--attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
--override-existing-serviceaccounts --approve
# 启用 managed addon
eksctl create addon \
--name amazon-cloudwatch-observability \
--cluster $CLUSTER --region $REGION
|
开完几分钟,CloudWatch Console → Container Insights 就有集群/Pod/节点指标。查询用 CloudWatch Logs Insights(类 KQL 但语法不同)。
也可在 EKS Console → Add-ons → 一键添加 amazon-cloudwatch-observability,免去命令行。
七、清理 + 算账
务必清理——EKS 按集群小时收费;若 Kubernetes 版本进入延长支持期,集群费还会从 $0.10/h 升到 $0.60/h。
1
2
3
4
5
| # 删集群(eksctl 连带删 node group、CloudFormation 栈)
eksctl delete cluster --name $CLUSTER --region $REGION
# ECR 仓库(可选删)
aws ecr delete-repository --repository-name demo/web --region $REGION --force
|
注意:eksctl 删集群有时漏删 CloudWatch log groups 和部分 LB,残留资源在 AWS Billing 里会冒头,定期对账。
一小时成本(粗算,us-east-1 按需):
1
2
3
4
5
6
7
8
9
10
| 资源 一小时成本(美元,粗算)
──────────────────────────────────────────────
EKS 集群(标准支持期) $0.10
2 × t3.medium 节点 ~$0.082
NAT 网关(eksctl 建的) ~$0.045 + 流量
Classic LB / NLB ~$0.025 + 流量
ECR(少量存储) ~$0.002
出口流量 ~$0.09/GB
──────────────────────────────────────────────
合计空载一小时 ~$0.27 左右(其中 $0.10 是控制平面)
|
即使一个节点都不开,EKS 也会收集群费。AKS 和 GKE 也必须结合所选定价层、月度抵扣与 SLA 比较,不能只用“免费/收费”二分。
八、踩坑速记
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 坑 1:忘了删集群 → 持续产生集群及关联资源费用
→ 开 Billing Alert; eksctl delete cluster 别忘
坑 2:type=LoadBalancer 创建的是老 CLB
→ 装 AWS Load Balancer Controller,注解指定 nlb/alb
坑 3:IRSA 注解没生效 → 应用调用 AWS API 时回退到其他凭据或直接失败
→ 确认 SA 的 eks.amazonaws.com/role-arn 注解 + Pod 指定 serviceAccountName
坑 4:节点拉 ECR 跨 region
→ ECR 在某 region,集群在另一 region → 拉镜像慢且收跨区流量
→ 同 region 部署
坑 5:eksctl 删集群漏资源
→ CloudWatch log group、ELB、EBS 残留
→ 用 aws resourcegroupstaggingapi 按 Cluster 标签清理
|
九、小结
EKS 的体感一句话:功能最全、灵活性最高,但配置最繁、控制平面收费。
1
2
3
4
5
6
7
| EKS 端到端的核心:
aws configure → aws ecr create → docker push
→ eksctl create cluster(一条命令,但要等 15-20 分钟)
→ 节点角色拉 ECR;应用访问 AWS API 时用 IRSA/Pod Identity 做细粒度授权
→ 装 AWS Load Balancer Controller 才能用现代 LB
→ CloudWatch Observability addon 接监控
→ eksctl delete cluster,并检查负载均衡器、卷、日志组等关联资源
|
适合谁:已经在 AWS、重度用 IAM、需要 CLB/NLB/ALB 细粒度控制的团队。AWS 生态绑定深、企业合规全。
不适合谁:小团队、要多集群测试(控制平面成本累积)、追求开箱即用。
下一篇:GCP GKE 端到端实战——看看 Autopilot 如何把节点基础设施交给平台管理,以及它与 Standard 模式的边界。
参考资料