1. 从零开始创建AWS EKS集群的完整指南
作为一名长期在云计算领域工作的工程师,我经常需要为企业搭建Kubernetes生产环境。AWS EKS(Elastic Kubernetes Service)是目前最受欢迎的托管Kubernetes服务之一,它让我们可以专注于应用部署而无需管理控制平面。本文将分享我从企业实践中总结的EKS创建全流程,包含许多官方文档中没有的实用技巧。
2. EKS核心架构解析
2.1 什么是Amazon EKS?
EKS是AWS提供的全托管Kubernetes服务,采用典型的主从架构分离模式:
-
AWS托管部分(无需用户运维):
- Kubernetes控制平面(Control Plane)
- etcd分布式键值存储
- API Server
- Scheduler调度器
-
用户管理部分:
- Worker Nodes工作节点
- Pods容器组
- 应用程序
- 网络配置(VPC、子网、安全组等)
这种分工模式既保证了Kubernetes核心组件的稳定性和高可用性,又给予用户足够的灵活性来管理工作负载。
2.2 EKS与传统自建Kubernetes的对比
| 特性 | 自建Kubernetes | AWS EKS |
|---|---|---|
| 控制平面管理 | 用户自行部署和维护 | AWS全托管 |
| 高可用性 | 需自行配置 | 默认跨AZ部署 |
| 升级维护 | 手动操作 | 一键升级 |
| 安全性 | 自行配置 | 集成IAM和VPC安全 |
| 初始配置复杂度 | 高 | 低 |
| 长期运维成本 | 高(人力成本) | 低(仅支付服务费用) |
对于大多数企业而言,EKS显著降低了Kubernetes的使用门槛和运维负担。
3. 环境准备与工具安装
3.1 AWS账号准备
在开始前,请确保:
- 拥有有效的AWS账号
- 账号具备足够的IAM权限(生产环境建议使用最小权限原则)
重要提示:即使是测试环境,也强烈建议开启MFA(多因素认证)保护root账号。我见过太多因root账号泄露导致的安全事故。
3.2 本地开发环境配置
3.2.1 安装AWS CLI
AWS命令行工具是与AWS服务交互的基础。建议安装最新版本:
bash复制# 检查当前版本
aws --version
# 安装AWS CLI v2(Linux示例)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
安装完成后,运行aws configure进行基本配置。这里有个实用技巧:为不同环境(如dev/test/prod)创建不同的named profile:
bash复制aws configure --profile dev
3.2.2 安装kubectl
kubectl是Kubernetes集群的管理工具:
bash复制# 下载最新稳定版(Linux)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
验证安装:
bash复制kubectl version --client
3.2.3 安装eksctl(强烈推荐)
eksctl是官方推荐的EKS管理工具,极大简化了集群创建过程:
bash复制# MacOS安装
brew install eksctl
# Linux安装
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 /usr/local/bin
验证安装:
bash复制eksctl version
4. 创建EKS集群实战
4.1 配置AWS凭证
在生产环境中,我建议使用IAM角色而非长期凭证。但对于快速测试,可以使用IAM用户:
- 创建IAM用户并附加
AmazonEKSFullAccess策略 - 获取访问密钥(Access Key和Secret Key)
- 配置AWS CLI:
bash复制aws configure
# 依次输入Access Key、Secret Key、默认区域(如us-east-1)和输出格式(如json)
4.2 使用eksctl创建集群
最简单的集群创建命令:
bash复制eksctl create cluster \
--name my-eks-cluster \
--region us-east-1 \
--nodegroup-name my-nodes \
--node-type t3.medium \
--nodes 2
这个命令会自动创建:
- 专用VPC网络
- 子网(跨多个可用区)
- 安全组
- EKS控制平面
- EC2工作节点
- IAM角色
整个过程通常需要15-25分钟。在此期间,eksctl会输出详细的创建日志。我建议将这些日志保存下来,便于后续排查问题:
bash复制eksctl create cluster [...] 2>&1 | tee eks-create.log
4.3 高级集群配置
对于生产环境,我们需要更精细的控制。下面是一个更完整的集群配置文件示例(cluster.yaml):
yaml复制apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: prod-eks-cluster
region: us-east-1
version: "1.27"
vpc:
cidr: "10.0.0.0/16"
subnets:
private:
us-east-1a: { cidr: "10.0.0.0/19" }
us-east-1b: { cidr: "10.0.32.0/19" }
public:
us-east-1a: { cidr: "10.0.64.0/19" }
us-east-1b: { cidr: "10.0.96.0/19" }
nodeGroups:
- name: ng-1
instanceType: m5.large
desiredCapacity: 3
privateNetworking: true
iam:
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
labels:
nodegroup-type: "default"
taints:
- key: "dedicated"
value: "app"
effect: "NoSchedule"
使用配置文件创建集群:
bash复制eksctl create cluster -f cluster.yaml
5. 集群验证与应用部署
5.1 验证集群状态
创建完成后,检查节点状态:
bash复制kubectl get nodes
健康状态应显示为Ready。如果遇到问题,可以检查节点详细状态:
bash复制kubectl describe nodes
5.2 部署测试应用
部署一个简单的Nginx应用:
bash复制# 创建Deployment
kubectl create deployment nginx --image=nginx:latest
# 暴露Service(使用LoadBalancer类型)
kubectl expose deployment nginx --type=LoadBalancer --port=80
查看服务状态:
bash复制kubectl get svc nginx
等待EXTERNAL-IP分配完成后,即可通过该IP访问Nginx。
5.3 生产级部署建议
对于生产环境,我建议使用更完善的部署方式:
- 使用Helm管理应用部署
- 配置HPA(Horizontal Pod Autoscaler)自动扩缩容
- 为Pod配置Resource Requests/Limits
- 使用ConfigMap和Secret管理配置
- 配置PodDisruptionBudget确保高可用性
6. 成本优化与集群清理
6.1 EKS成本结构
EKS的主要成本构成:
- 控制平面:每小时收费(约$0.10/小时)
- 工作节点:按EC2实例类型和运行时间计费
- 网络负载均衡器:按使用时长和数据传输量计费
- 存储:EBS卷或EFS文件系统费用
6.2 成本优化技巧
- 使用Spot实例运行可中断的工作负载
- 配置Cluster Autoscaler自动调整节点数量
- 使用Fargate按Pod计费(适合突发负载)
- 设置预算告警监控费用
- 非工作时间缩减测试环境规模
6.3 删除测试集群
为避免意外费用,测试完成后务必删除集群:
bash复制eksctl delete cluster --name my-eks-cluster --region us-east-1
对于使用配置文件创建的集群:
bash复制eksctl delete cluster -f cluster.yaml
7. 生产环境最佳实践
7.1 基础设施即代码
推荐使用Terraform管理EKS基础设施:
hcl复制module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0"
cluster_name = "prod-eks"
cluster_version = "1.27"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
default = {
desired_size = 3
min_size = 1
max_size = 5
instance_types = ["m5.large"]
}
}
}
7.2 安全加固措施
- 启用私有集群模式(控制平面不暴露公网)
- 使用IAM Roles for Service Accounts (IRSA)
- 配置网络策略限制Pod间通信
- 启用EKS控制平面日志记录
- 定期轮换Worker节点的SSH密钥
7.3 监控与日志
- 配置CloudWatch Container Insights监控集群性能
- 使用Prometheus+Grafana实现自定义监控
- 启用EKS控制平面日志(API审计日志等)
- 使用Fluent Bit将容器日志发送到CloudWatch Logs
8. 常见问题排查
8.1 节点无法加入集群
症状:kubectl get nodes显示节点NotReady
排查步骤:
- 检查节点EC2实例是否正常运行
- 查看kubelet日志:
journalctl -u kubelet -f - 验证节点IAM角色是否正确
- 检查安全组是否允许控制平面与节点的通信
8.2 服务无法访问
症状:LoadBalancer类型的Service没有分配EXTERNAL-IP
解决方案:
- 检查是否安装了AWS Load Balancer Controller
- 验证子网是否正确标记:
bash复制aws ec2 describe-subnets --subnet-ids <subnet-id> | grep "kubernetes.io/role/elb" - 检查IAM权限是否包含elbv2相关操作
8.3 Pod无法调度
症状:Pod处于Pending状态
常见原因:
- 节点资源不足(CPU/内存)
- 节点Selector不匹配
- Taints和Tolerations配置不当
- PersistentVolumeClaim无法绑定
使用以下命令诊断:
bash复制kubectl describe pod <pod-name>
kubectl get events --sort-by=.metadata.creationTimestamp
9. 扩展与进阶配置
9.1 多集群管理
对于大型企业,可能需要管理多个EKS集群:
- 使用AWS Organizations集中管理
- 配置共享服务集群(如集中日志收集)
- 使用GitOps工具(如Argo CD)统一部署应用
- 考虑EKS Distro保持跨环境一致性
9.2 混合云部署
将EKS与本地Kubernetes集群集成的方案:
- 使用Amazon EKS Anywhere管理本地集群
- 配置Cluster API统一管理
- 使用服务网格(如Istio)实现跨集群通信
- 考虑AWS Outposts实现混合云部署
9.3 性能调优
- 调整CNI插件(如使用AWS VPC CNI自定义配置)
- 优化kubelet参数(如maxPods)
- 使用节点本地DNS缓存
- 配置适当的Pod中断预算
在实际生产环境中,我通常会先创建一个基准测试集群,通过压力测试确定最佳配置参数,然后再应用到生产集群。这种方法可以避免很多性能问题的发生。