写在前面
版本说明:AWS CLI 2.x + eksctl 0.18x+ + EKS 1.30(2026);命令在 us-east-1 验证。
承接 AKS 篇。同样的 demo(nginx 静态页),换 AWS EKS 跑一遍。重点体感三个对比点:
1
2
3
4
| 相比 AKS 的差异:
① 控制平面收费:EKS $73/月(AKS 免费)
② 配置更繁:现代 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 拉私有镜像
⑤ 部署 + 暴露(Classic LB 起,LB Controller 升级)
⑥ 接监控(CloudWatch Observability)
⑦ 清理 + 算账(含 $73/月)
|
一、准备:账号 + 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 事实标准 CLI,比 aws eks 好用十倍)
# 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
10
| CLUSTER=myEKS
eksctl create cluster \
--name $CLUSTER \
--region $REGION \
--version 1.30 \
--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 集群(~$73/月从这里开始计费)
✓ 创建集群 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.30.x
# ip-10-0-2-34.ec2.internal Ready <none> 1m v1.30.x
|
创建过程 ~15-20 分钟(VPC + 控制平面 + 节点都要等)。比 AKS 慢一截。
四、身份:节点角色 + IRSA 拉私有镜像
EKS 的镜像拉取有两层:
第一层(默认能用):eksctl 创建的节点 IAM 角色挂了 AmazonEC2ContainerRegistryReadOnly 策略 → 节点上所有 Pod 默认能用节点角色拉 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):给特定 ServiceAccount 绑 IAM Role(细粒度,Pod 只能拉它该拉的)。
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,绑 ECR 权限
eksctl create iamserviceaccount \
--name web-sa --namespace default \
--cluster $CLUSTER --region $REGION \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
--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,Pod 就用这个 Role 拉镜像(而不是节点共享角色)。
对比 AKS 的 --attach-acr:AKS 是"集群级 kubelet identity 一次性授权",EKS IRSA 是"逐 SA 授权"——更细但更繁。两家机制本质同构(OIDC 联邦)。
五、部署 + 暴露: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,免去命令行。
七、清理 + 算账(含 $73/月!)
务必清理——EKS 控制平面按小时收费,忘了删一个月 $73 没了。
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($73/月 ÷ 730h)
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 控制平面也照收 $0.10/h。这是 EKS 和 AKS/GKE Standard 最直白的成本差异。
八、踩坑速记
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 坑 1:忘了删集群 → 控制平面 $73/月 蒸发
→ 开 Billing Alert; eksctl delete cluster 别忘
坑 2:type=LoadBalancer 创建的是老 CLB
→ 装 AWS Load Balancer Controller,注解指定 nlb/alb
坑 3:IRSA 注解没生效 → Pod 还在用节点角色
→ 确认 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;生产用 IRSA 细粒度
→ 装 AWS Load Balancer Controller 才能用现代 LB
→ CloudWatch Observability addon 接监控
→ eksctl delete cluster(务必,$73/月!)
|
适合谁:已经在 AWS、重度用 IAM、需要 CLB/NLB/ALB 细粒度控制的团队。AWS 生态绑定深、企业合规全。
不适合谁:小团队、要多集群测试(控制平面成本累积)、追求开箱即用。
下一篇:GCP GKE 端到端实战——三家里体验最顺的(K8s 娘家出品),Autopilot 模式连节点都不用管,看它怎么把"省心"做到极致。