AWS EKS 配置及相关操作
EKS 集群特性总结
- 节点的 IP 地址(EXTERNAL-IP 和 INTERNAL-IP)不固定,会变化。特别是在自治模式中,节点被视为 临时资源(Ephemeral) ,可能会频繁地进行节点池优化。
如果集群需要固定的出口 IP,最推荐,最标准的做法是 使用 NAT 网关 ,将 EKS 节点部署在私有子网中,所有访问外部网络的流量都会经过 NAT 网关
通过 AWS 管理控制台部署 EKS 集群
- Kubernetes 版本: v1.35
本示例中使用 EKS 自治模式(EKS Auto Mode)
EKS 自治模式 接管了原本需要手动管理的节点、存储和网络配置,因此它需要一组非常具体且强大的权限
EKS 自治模式 有额外的费用,大概比 EC2 价格高 12%
EKS 自治模式 在集群创建完成后可修改(编辑)为非自治模式
EKS 自治模式 中的 Worker Nodes 配置 不能在控制台修改参数、不能自定义 ,具体的配置可以通过 API 接口查看
nodepool资源
# kubectl describe nodepool general-purpose
Name: general-purpose
Namespace:
Labels: app.kubernetes.io/managed-by=eks
Annotations: karpenter.sh/nodepool-hash: 4012513481623584108
karpenter.sh/nodepool-hash-version: v3
API Version: karpenter.sh/v1
Kind: NodePool
Metadata:
Creation Timestamp: 2026-02-06T09:38:18Z
Generation: 1
Resource Version: 784637
UID: e85261b9-3a4b-41b0-ac5...
Spec:
Disruption:
Budgets:
Nodes: 10% # 这是一个安全阀。在同一时间内,由于缩容或更新导致的节点离线比例不能超过 10%。这保证了你的集群不会因为自动优化而导致业务大面积中断。
Consolidate After: 30s # 节点达到上述状态 30 秒后,EKS 就会考虑将其关闭,并把上面的 Pod 迁移到更划算的节点上。
Consolidation Policy: WhenEmptyOrUnderutilized # 当节点变为空闲(没有 Pod)或者利用率较低(比如一个大节点只跑了一个小 Pod)时,EKS 会自动触发节点合并。
limits: # 资源限制
cpu: "1000"
memory: 1000Gi
Template:
Metadata:
Spec:
Expire After: 336h # 节点的最大“寿命”是 14 天(336 小时),强制节点定期更换,以确保所有节点都运行在最新的安全补丁和 Bottlerocket 镜像上,防止出现长期未重启的“僵尸节点”。
Node Class Ref: # nodeclass 信息,可通过 kubectl get nodeclass 查看
Group: eks.amazonaws.com
Kind: NodeClass
Name: default
Requirements: # 节点选择标准 (Requirements)
Key: karpenter.sh/capacity-type # 实例类型,on-demand 为 按需实例
Operator: In
Values:
on-demand
Key: eks.amazonaws.com/instance-category # 限定了实例系列 c: 计算优化型(适合高并发); m: 通用型(平衡 CPU 和内存); r: 内存优化型(适合数据库或缓存)。
Operator: In
Values:
c
m
r
Key: eks.amazonaws.com/instance-generation # 只使用 4 代以后的机型(如 c5, m6i 等)。这确保了节点拥有较新的硬件特性和性能。
Operator: Gt
Values:
4
Key: kubernetes.io/arch # CPU 架构。如果你想尝试性价比更高的 ARM 架构(Graviton),需要在这里添加 arm64
Operator: In
Values:
amd64
Key: kubernetes.io/os # 节点操作系统(OS)类型
Operator: In
Values:
linux
Termination Grace Period: 24h0m0sEKS 自治模式限制资源上限 编辑 NodePool,修改
spec.limits.cpu和spec.limits.memory。这决定了该池子最多能“烧”掉多少 EC2 资源。强制回收节点 : 如果你想让 EKS 重新平衡节点(例如你更改了实例限制),可以手动删除节点,Auto Mode 会自动根据 Pod 需求拉起符合新规的新节点
kubectl delete node <node-name>同时要关注
nodeclass资源,其中定义了 子网(Subnet)和安全组(Security Group)等信息
kubectl get nodeclass
NAME ROLE READY AGE
default eksNodeRole True 44h
kubectl describe nodeclass default
Name: default
Namespace:
Labels: app.kubernetes.io/managed-by=eks
Annotations: eks.amazonaws.com/nodeclass-hash: 13740036326424352917
eks.amazonaws.com/nodeclass-hash-version: v2
API Version: eks.amazonaws.com/v1
Kind: NodeClass
Metadata:
Creation Timestamp: 2026-02-06T09:38:18Z
Finalizers:
eks.amazonaws.com/termination
Generation: 2
Resource Version: 827607
UID: 5065b0f3-3795-4347-893a-338ae6fa882d
Spec:
Ephemeral Storage:
Iops: 3000
Size: 80Gi
Throughput: 125
Network Policy: DefaultAllow
Network Policy Event Logs: Disabled
Role: eksNodeRole
Security Group Selector Terms:
Id: sg-058bd1ef...
Snat Policy: Random
Subnet Selector Terms:
Id: subnet-07963d9b...
Id: subnet-0e359aac...
Id: subnet-0e76c601...
| 角色名称 | 关联策略示例 | 作用对象 |
|---|---|---|
| 集群 IAM 角色(Cluster Role) | AmazonEKSClusterPolicy | EKS 控制平面。用于管理网络、负载均衡等 |
| 节点 IAM 角色(Node Role) | AmazonEKSWorkerNodePolicy | EC2 节点。用于让节点加入集群、拉取镜像。 |
| Pod 角色(IRSA) | 自定义权限(如 S3 读写) | 应用程序 (Pod)。用于业务代码访问 AWS 资源。 |
创建 EKS 集群 IAM 角色
每个集群都需要一个 Amazon EKS 集群 IAM 角色。由 Amazon EKS 管理的 Kubernetes 集群会使用此角色来管理节点
AWS 官方参考文档: https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/cluster-iam-role.html#create-service-role进入 IAM 控制台 -> 角色 -> 创建角色。
选择 AWS 服务,找到 EKS。
选择 EKS - Cluster 用例。
确保关联了以下权限策略。
AmazonEKSClusterPolicyAmazonEKSComputePolicyAmazonEKSBlockStoragePolicyAmazonEKSNetworkingPolicyAmazonEKSLoadBalancingPolicy
修改角色 信任关系 (Trust relationships) ,在
Action列表中添加sts:TagSession{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": ["sts:AssumeRole",
"sts:TagSession"
]}
]
}命名为
eksClusterRole并保存。
创建 EKS 节点 IAM 角色
Amazon EKS 节点 kubelet 守护进程代表您调用 AWS API。节点通过 IAM 实例配置文件和关联的策略获得这些 API 调用的权限。您必须先为节点创建 IAM 角色以在启动它们时使用,然后才能启动这些节点并在集群中注册它们。
AWS 官方参考文档: https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/create-node-role.html通过 https://console.aws.amazon.com/iam/ 打开 IAM 控制台。
在左侧导航窗格中,选择 Roles(角色) 。
在 Roles(角色)页面上,选择
Create role(创建角色)。在
Select trusted entity(选择受信任的实体)页面上,请执行以下操作:- 在可信实体类型部分中,选择 AWS 服务。
- 在 Use case(使用案例)下,选择 EC2。
- 选择下一步。
在添加权限页面上,附加自定义策略或执行以下操作:
- 在
Filter policies (筛选器策略)框中,输入AmazonEKSWorkerNodePolicy。 - 选中搜索结果中的
AmazonEKSWorkerNodePolicy左侧的复选框。 - 请选择 Clear filters(清除筛选条件) 。
- 在 Filter policies (筛选器策略) 框中,输入
AmazonEC2ContainerRegistryPullOnly。 - 选中搜索结果中的
AmazonEC2ContainerRegistryPullOnly左侧的复选框。 - 选择下一步。
- 在
在 Name, review, and create(命名、查看和创建)页面中 ,对角色(Role)命名,本示例使用
eksNodeRole。选择 创建角色 。
可以根据需求为 EKS 集群中的工作节点(Nodes)新建 私有子网 (Private Subnet) 并配置 NAT Gateway 以使集群 Nodes 的出口 IP 固定。
EKS 允许你动态更新集群关联的子网。这一步会告诉 EKS 控制平面以后在新的 Subnets 中工作。
创建集群控制平面
- 进入 EKS 控制台 -> 集群 -> 添加集群 -> 创建。
- 配置集群:输入名称,选择 Kubernetes 版本,并选择已经创建的 集群 IAM 角色
eksClusterRole和 节点 IAM 角色eksNodeRole - 其他配置使用默认即可。
若要通过命令行来管理 Amazon EKS 集群,参考 官方文档安装
aws cli、kubectl和eksctl
AWS EKS 控制台基本不提供 Deployment / Pod 的创建、编辑、删除能力。只具备集群可视化、运维辅助的功能。对集群的变更操作主要通过 通过 API / kubectl ,集群管理可通过接入 Rancher ,它提供多集群管理、 RBAC 权限控制、审计等诸多方便 。
aws eks 常用命令
列出集群
aws eks list-clusters |
为集群创建或更新 kubeconfig 文件用于和集群通信
在配置了 aws cli 命令授权(如 ak/sk )的(EKS)外部系统上执行以下命令可配置 EKS 鉴权信息以和 EKS 集群进行通信。
aws eks update-kubeconfig --region region-code --name my-cluster |
更新 kubeconfig 文件成功后,会创建 ~/.kube/config 文件,里面包含集群的 API 信息和认证信息,凭此可以和 Kubernetes 集群进行通信
kubectl get nodes -o wide |
在 EKS 集群内部创建 Bastion Pod 并管理 EKS 集群
如果只能在 EKS 内部授权的情况下,例如不能提供 ak/sk 或其他鉴权信息给外部系统,此时可以参考以下步骤在 EKS 内部部署 Bastion Pod、给 Bastion Pod 授予 Kubernetes API 权限并开放 SSH 连接到 Bastion Pod 以管理 EKS 集群
方案架构 :
- 镜像 : 推荐使用包含
kubectl、helm、aws-cli的基础镜像(如bitnami/kubectl或自定义 Alpine Linux 镜像) - 数据持久化 : 使用 EBS CSI Driver 挂载一个 PVC 到
/root或/home/user,确保你的脚本、kubeconfig和工具配置在 Pod 重启后不会丢失。 - ssh 端口 : 暴露一个 LoadBalancer 类型的 Service,将容器的 22 端口映射出来。 为了安全,一定要使用 SSH Key 登录(禁止密码)并设置严格的安全组(准入)
- Kubernetes API 鉴权 : 使用 IAM Role for Service Account(IRSA) 将有相应权限的 IAM Role 绑定到 Pod 使用的 ServiceAccount 上。
- 使用 StatefulSet
使用 StatefulSet 部署 Pod,参考以下配置
# 定义 PVC,使用 storageClassName: gp3
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: eks-cluser-admin-bastion-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: gp3
---
# 镜像初始化脚本,安装常用软件,添加账户,设置密码,配置 sshd 等
apiVersion: v1
kind: ConfigMap
metadata:
name: eks-cluser-admin-bastion-init-script
data:
setup.sh: |
#!/bin/bash
# 1. 安装必要组件 (加入 sudo)
apk update && apk add --no-cache \
openssh-server \
curl \
python3 \
py3-pip \
bash \
sudo
# 2. 配置 SSH 密钥
ssh-keygen -A
# 3. 创建用户 op 并设置密码
# -D 表示不创建密码(后面统一设),-s 指定 shell
if ! id "op" &>/dev/null; then
adduser -D -s /bin/bash op
echo "op:YourStrongPassword" | chpasswd
fi
# 4. 配置 sudo (允许 op 组免密执行 sudo)
echo "op ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/op
chmod 0440 /etc/sudoers.d/op
# 5. SSH 安全配置
# 禁止 root 登录
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
# 确保允许密码登录(如果你不使用 SSH Key 的话)
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
# 6. 启动 SSH 服务
echo "Starting sshd..."
exec /usr/sbin/sshd -D
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eks-cluser-admin-bastion
spec:
serviceName: "eks-admin-bastion"
replicas: 1
selector:
matchLabels:
app: eks-cluser-admin-bastion-pod
template:
metadata:
labels:
app: eks-cluser-admin-bastion-pod
spec:
containers:
- name: bastion
image: alpine:latest # 使用极小镜像
command: ["/bin/sh", "/mnt/scripts/setup.sh"]
volumeMounts:
- name: scripts
mountPath: /mnt/scripts
# # 挂载 PVC 里的 root 子目录到容器的 /root
- name: eks-cluser-admin-bastion-data
mountPath: /root/ # 持久化 /root 目录
subPath: root
# 挂载 PVC 里的 home 子目录到容器的 /home
- name: eks-cluser-admin-bastion-data
mountPath: /home
subPath: home
volumes:
- name: scripts
configMap:
name: eks-cluser-admin-bastion-init-script
- name: eks-cluser-admin-bastion-data
persistentVolumeClaim:
claimName: eks-cluser-admin-bastion-pvceks-cluser-admin-bastion-pod部署成功后,可以在集群中启动一个临时的测试 Pod(kubectl run netshoot-tmp --image=nicolaka/netshoot -it --rm -- /bin/bash) 测试是否能通过ssh连接到 Bastion Podnetshoot-tmp:~# ssh -v op@10.1.26.100
debug1: OpenSSH_10.2p1, OpenSSL 3.5.4 30 Sep 2025
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 22: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: Connecting to 10.1.26.100 [10.1.26.100] port 22.
debug1: Connection established.
...
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?可以正常
ssh连接 Bastion Pod,说明以上配置无误,可正常工作。为 Bastion Pod 创建面向互联网的 NLB(Network Load Balancer)。创建
type: LoadBalancer的 Service 对象。
apiVersion: v1
kind: Service
metadata:
name: eks-cluser-admin-bastion-svc
annotations:
# 强制指定为公网负载均衡器
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
# 建议同时指定使用 NLB (网络负载均衡器),更适合 SSH
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
spec:
type: LoadBalancer
ports:
- port: 22
targetPort: 22
selector:
app: eks-cluser-admin-bastion-podNLB 创建成功后,从互联网测试访问。
EKS Admin Bastion Pod 可以正常从互联网访问后,接着需要为其授权可管理 EKS 集群。因为 Pod 在 EKS 集群内部,只需要使用 IRSA(IAM Role for Service Account) 为其 ServiceAccount 绑定一个合适的 IAM Role 即可授予其对应的权限。不在容器里放 AWS 密钥,从而避免在容器内硬编码 Access Key
以下配置基于 IRSA(IAM Roles for Service Accounts) 机制,新版本(大于等于 1.34 EKS)使用了 Pod Identity(IRSA 的进化版)机制实现了让 Pod 获得权限。EKS Pod Identity 它更符合云原生的简洁逻辑,配置也更简单,新版本建议使用。
前提条件:
EKS 集群必须启用 OIDC Provider,用于 Pod 关联 IAM Role
每个 EKS 集群都有一个唯一的 OIDC 发行者 URL。你需要确保 AWS IAM 中已经存在对应的身份提供者。执行命令获取 URL:
aws eks describe-cluster --name <集群名称> --query "cluster.identity.oidc.issuer" --output text
https://oidc.eks.ap-east-1.amazonaws.com/id/7785E5DC362954034E73
# 检查是否已经注册
aws iam list-open-id-connect-providers如果你还没关联(注册)过,执行以下命令(推荐使用
eksctl,最简便),或在 AWS 控制台 EKS → Cluster → Configuration → Authentication → Associate OIDC Providereksctl utils associate-iam-oidc-provider --cluster <你的集群名> --approve
你需要有 管理员权限,可创建 IAM Role / Policy / ServiceAccount
kubectl 可以访问 EKS API
创建 IAM Role 并配置信任策略
你需要创建一个 IAM Role 或者使用现有 Role,并授予它管理 EKS 的权限(例如集群管理策略
AmazonEKSClusterPolicy或自定义权限)。假设你想给 Pod 完全 EKS 权限(kubectl、awscli),创建 Policy以下示例创建一个给运维人员使用的 Role,禁止 删除整个集群 但是能查看集群,能使用 Kubernetes API
aws iam create-policy \
--policy-name EKSClusterOpsAdminPolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
# "eks:*", # 全权管理 EKS。包括创建/删除集群、更新版本、增删节点组(Nodegroup)、配置 Fargate Profile、管理插件等。谨慎授予此权限
"eks:Describe*",
"eks:List*", # eks:Describe* / List*: 允许他看集群状态。
"eks:AccessKubernetesApi", # 至关重要。没有这个权限,他连 kubectl 认证都过不去。
"ec2:Describe*",
"iam:ListRoles", # 列出账号下所有 IAM 角色。在创建集群或节点组时,用于在下拉列表中选择已有的 Role。
"iam:GetRole" # 查看特定 IAM 角色的详情。用于验证所选角色的信任关系是否正确。
],
"Resource": "*"
}
]
}'可以根据需要收紧权限,例如只允许
eks:DescribeCluster或指定 Cluster ARN信任策略 (Trust Policy)
该 Role 必须允许你的 EKS OIDC 身份提供者来“扮演”它。信任策略示例如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<账号ID>:oidc-provider/<OIDC地址,如 oidc.eks.ap-east-1.amazonaws.com/id/ABCDE1234567890>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<OIDC地址,如 oidc.eks.ap-east-1.amazonaws.com/id/ABCDE1234567890>:sub": "system:serviceaccount:<命名空间>:<ServiceAccount名称>",
"<OIDC地址>:aud": "sts.amazonaws.com"
}
}
}
]
}
创建 IAM Role
aws iam create-role \
--role-name eks-admin-bastion-role \
--assume-role-policy-document file://trust.json
绑定 Policy
aws iam attach-role-policy \
--role-name eks-admin-bastion-role \
--policy-arn arn:aws:iam::<ACCOUNT_ID>:policy/EKSClusterOpsAdminPolicy创建 Kubernetes ServiceAccount 。在集群中创建一个 ServiceAccount,并通过 Annotation (注解) 将其指向刚才创建的 IAM Role。
apiVersion: v1
kind: ServiceAccount
metadata:
name: eks-bastion-admin-sa
namespace: default
annotations:
# 替换为你创建的 IAM Role ARN
eks.amazonaws.com/role-arn: arn:aws:iam::<账号ID>:role/<Role名称>执行命令创建 ServiceAccount
kubectl apply -f serviceaccount.yaml在 StatefulSet 中引用 ServiceAccount 。最后,修改你的 StatefulSet 配置,在
spec.template.spec中指定serviceAccountName。apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eks-cluser-admin-bastion
spec:
template:
spec:
serviceAccountName: eks-admin-sa # 引用刚才创建的 SA
containers:
- name: bastion
image: alpine:latest
# ... 其他配置保持不变
部署完成后,检查 Pod 是否挂载了上面创建的 ServiceAccount
$ kubectl describe pod eks-cluser-admin-bastion-0 |
Service Account: eks-bastion-admin-sa 存在说明已经成功挂载到 ServiceAccount。
进入 Pod 后,导入相关环境变量即可获取到 AWS Role 对应的权限,
export AWS_ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/eks-admin-bastion-role |
要永久生效将其写入 ~/.bashrc
cat <<EOF >> ~/.bashrc |
此时检查环境变量中会包含 AWS 相关的凭证
env | grep AWS |
执行以下命令更新 kubeconfig 配置
aws eks update-kubeconfig --name <YOUR_CLUSTER_NAME> --region ap-east-1 |
此时访问集群会报错
kubectl get pods |
此时你的 aws sts get-caller-identity 成功了,意味着在 AWS 资源层面(非 Kubernetes 集群内)已经承认你是这个 IAM Role,可以访问这个 Role 关联的 Policy 中定义的资源权限。
但 EKS 集群(Kubernetes API)还不认识这个 IAM Role,在 EKS 中, 即便你是 AWS 的管理员 Role,也必须在集群的 Access Entries 中显式登记。此处登记的 Policy 才决定了你对 Kubernetes 集群有怎样的权限 。
EKS 的 Access Entry 中 Policies 实际上是 AWS 预定义的、对应了 K8s 内部 ClusterRole:
- AmazonEKSClusterAdminPolicy : 映射到 K8s 内部的
cluster-admin - AmazonEKSViewerPolicy : 映射到 K8s 内部的
view
打开 AWS EKS 控制台 -> 点击你的集群 。
进入 Access (访问) 选项卡。
点击 Create access entry 。
IAM Role ARN : 填入你的
arn:aws:iam::<ACCOUNT_ID>:role/eks-admin-bastion-role。Type : 选择 Standard 。
关联策略:
点击 Add policy 。
选择
AmazonEKSClusterAdminPolicy,这是 Kubernetes 集群管理员权限,也可以根据需求给其他权限,如AmazonEKSViewerPolicy(允许查看集群级别和所有命名空间的资源)、AmazonEKSViewPolicy(较低级别的查看权限) 。Access scope 选择
Cluster。
后续如果需要调整此 Role 在 Kubernetes 中的权限,只需要要更改 EKS Access Entries 中对应 Role 关联的 Policy 即可。
可通过以下命令验证验证权限已绑定
aws eks list-associated-access-policies \ |
应该能在返回的 associatedPolicies 列表中看到 AmazonEKSClusterAdminPolicy
再次检查,可正常看到集群资源
kubectl get nodes |
常见错误
集群角色缺少建议的托管策略
EKS 自治模式 的集群创建过程中缺少必要的权限
集群角色缺少建议的托管策略 |
EKS 自治模式 接管了原本需要手动管理的节点、存储和网络配置,因此它需要一组非常具体且强大的权限. 解决方法如下
登录 IAM 控制台,找到“角色 (Roles)”。
搜索并点击你为 EKS 集群创建的角色名称,本示例中为
eksClusterRole。在 权限 (Permissions) 选项卡下,点击
添加权限 (Add permissions) -> 附加策略 (Attach policies)。在搜索框中分别搜索并勾选上述四个策略:
AmazonEKSComputePolicyAmazonEKSBlockStoragePolicyAmazonEKSNetworkingPolicyAmazonEKSLoadBalancingPolicy
最终的 权限策略 如下图所示:
集群角色信任策略缺少必需的操作
EKS 自治模式 的集群创建过程中缺少必要的权限
集群角色信任策略缺少必需的操作 |
在 EKS 自治模式下,EKS 需要使用 sts:TagSession 来为它替你创建的资源(如自动生成的节点)进行身份标识和追踪。
修改 IAM 角色的 信任关系 (Trust relationships) ,将 sts:TagSession 操作添加到允许列表中。
- 进入 IAM 控制台 -> 角色 (Roles)。
- 搜索并点击你的 EKS 集群角色,本示例中为
eksClusterRole。 - 点击 信任关系 (Trust relationships) 选项卡。
- 点击 编辑信任策略 (Edit trust policy) 。默认内容如下 修改为以下内容,在
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}Action列表中添加sts:TagSession{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": ["sts:AssumeRole",
"sts:TagSession"
]}
]
} - 修改完成后,点击 更新策略 (Update policy)
EKS 集群相关配置及操作
修改 EKS 集群 API server endpoint 访问权限
默认 EKS 集群部署后,API server endpoint access 模式提供了三种:
- Public Only :API Server endpoint 仅通过公网访问。
- Public and Private :同时开启。VPC 内流量走私有 Endpoint,外部走公网。
- Private Only :彻底关闭公网入口。这是安全性最高但也最复杂的模式。
默认为 Public and private
因此 API server endpoint 可以公网和 VPC 私网中访问。
要修改,可以在控制台 Cluster –> Networking: Manage –> endpoint access 进行修改,如果配置为 Public 或者 Public and Private ,可以通过修改 Add/edit sources to public access endpoint. 为公网访问添加白名单,提高安全性。
也可通过 AWS CLI 修改
aws eks update-cluster-config \ |
如果开启了 仅限私有访问 ,你必须确保 VPC 满足以下条件,否则集群将无法正常工作:
启用私有 DNS 支持 :
VPC 必须开启
enableDnsHostnames和enableDnsSupport。这样 EKS 才能在私有网络内解析 API Server 的域名。VPC 端点 (Interface VPC Endpoints) :
由于 Node 无法访问公网,它们必须通过 VPC Endpoints 连接 AWS 服务。你通常需要为以下服务创建 Interface Endpoint:
ec2 (用于挂载卷/管理网卡)
ecr.api 和 ecr.dkr(用于拉取镜像)
s3 (Gateway Endpoint)
logs (CloudWatch 日志)
管理通道 :
你必须拥有一个进入 VPC 的手段(如 AWS Client VPN 或 堡垒机 (Bastion Host)),否则你将无法运行任何
kubectl命令。
为 EKS 集群安装 AWS Loadbalancer Controller
在集群中使用 AWS LoadBalance 向互联网提供 EKS 集群中的服务,需要在集群中安装 AWS Load Balancer Controller (LBC) ,类似要使用 Ingress Nginx 则需要在集群中安装 Ingress Nginx Controller 一样。
AWS 负载均衡器控制器(AWS Load Balancer Controller)官方文档
LBC 会在您创建 Kubernetes Ingress 时创建 AWS 应用程序负载均衡器(ALB)。
若集群所在 VPC 中存在公有子网和私有子网,为了让 EKS 自动识别哪些子网用于存放负载均衡器,哪些用于存放 Pod,你需要确保子网拥有正确的标签(只有共有子网可忽略此配置):
公有子网 (NAT Gateway 所在的子网) :
- 标签:
kubernetes.io/role/elb = 1
- 标签:
私有子网 (EKS 节点所在的子网) :
- 标签:
kubernetes.io/role/internal-elb = 1
- 标签:
检查集群中是否安装了 AWS Load Balancer Controller
kubectl get pods -n kube-system | grep -i controller |
使用 Helm 和 eksctl 安装 AWS Load Balancer Controller(负载均衡器控制器)
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-4 |
参考以下步骤安装 AWS Load Balancer Controller,本示例版本 v3.0.0
下载 AWS 负载均衡器控制器(Load Balancer Controller)的 IAM 策略,该策略允许负载均衡器代表您调用 AWS API。
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v3.0.0/docs/install/iam_policy.json
使用上一步中下载的策略创建一个 IAM 策略。
# 检查是否已存在策略 AWSLoadBalancerControllerIAMPolicy
aws iam list-policies | grep -i AWSLoadBalancerControllerIAMPolicy
# 使用下载的策略文件创建新策略 AWSLoadBalancerControllerIAMPolicy
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
aws iam list-policies | grep -B 1 -A 10 -i AWSLoadBalancerControllerIAMPolicy
{
"PolicyName": "AWSLoadBalancerControllerIAMPolicy",
"PolicyId": "ANPATVYVE6LERMKGVRCSF",
"Arn": "arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-02-09T12:44:19+00:00",
"UpdateDate": "2026-02-09T12:44:19+00:00"
},在 EKS 集群中创建
iamserviceaccount,替换命令中集群名称、区域代码和账户 ID 的值。eksctl create iamserviceaccount \
--cluster=<cluster-name> \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--region <aws-region-code> \
--approve
# 检查 EKS 系统中的 iamserviceaccount
eksctl get iamserviceaccount --cluster <cluster-name>
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::<AWS_ACCOUNT_ID>:role/eksctl-<cluster-name>-addon-iamserviceaccount-kube-syst-Role1-dUL3ua7Mv2Gv如果创建报错:
no IAM OIDC provider associated with cluster, try 'eksctl utils associate-iam-oidc-provider --region=ap-east-1 --cluster=<cluster-name>',先执行下面的命令 为 EKS 集群关联 OIDC Provider 然后在创建iamserviceaccounteksctl utils associate-iam-oidc-provider \
--region <aws-region-code> \
--cluster <cluster-name> \
--approve安装 AWS 负载均衡器控制器(AWS Load Balancer Controller)
helm repo add eks https://aws.github.io/eks-charts
helm repo list
NAME URL
eks https://aws.github.io/eks-charts
helm repo update eks
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
Update Complete. ⎈Happy Helming!⎈
# 获取集群使用的 VPC ID,安装 aws-load-balancer-controller 时需要显式指定
aws eks describe-cluster --name <cluster-name> --query "cluster.resourcesVpcConfig.vpcId" --output text
vpc-05840086...
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=<cluster-name> \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set vpcId=<VPC_ID> \
--version 3.0.0
NAME: aws-load-balancer-controller
LAST DEPLOYED: Mon Feb 9 13:11:30 2026
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!验证控制器是否已安装成功,最主要是要有
ingressClass albkubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-load-balancer-controller-949f9d848-4qtlz 1/1 Running 0 41s
kube-system aws-load-balancer-controller-949f9d848-ww5jv 1/1 Running 0 23s
kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 41m
kubectl get ingressclass -A
NAME CONTROLLER PARAMETERS AGE
alb ingress.k8s.aws/alb <none> 43m
AWS Load Balancer controller 相关错误
AWS Load Balancer controller 部署后 Pod 状态为 CrashLoopBackOff
AWS Load Balancer controller 版本: v3.0.0
kubectl get pod -A |
关键报错信息 failed to get VPC ID: failed to fetch VPC ID from instance metadata: error in fetching vpc id through ec2 metadata: get mac metadata: operation error ec2imds: GetMetadata, canceled, context deadline exceeded
ALB Controller 启动时必须知道自己在哪个 VPC ,此报错说明控制器无法从 EC2 元数据服务 (IMDS) 获取 VPC ID。可以为控制器显式指定 VPC ID
aws eks describe-cluster --name <CLUSTER_NAME> --query "cluster.resourcesVpcConfig.vpcId" --output text |
unable to resolve at least one subnet
Ingress 部署后,ALB 未成功创建
kubectl get ingress -o wide |
关键报错信息 "error":"couldn't auto-discover subnets: unable to resolve at least one subnet. Evaluated 0 subnets: 0 are tagged for other clusters, and 0 have insufficient available IP addresses"
目前 VPC 架构如图所示,EKS 专用的 VPC 中,存在三个子网,且最终路由都指向了 Nat Gateway,因此都是 私有子网(Private Subnet) 。不具备被公有互联网访问的条件(只能出不能进)。
在此中架构下(EKS 资源运行于 NAT Gateway 网络下),VPC 中需要有 公有子网(Public Subnet) 用于部署 ALB 以能在互联网上访问 ALB。
你需要在同一个 VPC ( eks-hk-vpc ) 中 新建至少两个公有子网来部署 ALB 。并为其打上标签 kubernetes.io/role/elb=1
Target is in an Availability Zone that is not enabled for the load balancer
原因为 ALB 可用区只有两个,而 Pod 可用区有 3 个,当 Pod 部署在 ALB 不可用的区域时会发生此错误
在 EKS 自动模式集群中检查 Amazon EBS CSI 控制器状态
EKS 自动模式(EKS Auto Mode)默认无需在集群上安装 Amazon EBS CSI 控制器。官方文档说明
查看集群中已经安装的 CSI Driver 。EKS 自动模式(EKS Auto Mode)默认安装了 ebs.csi.eks.amazonaws.com 和 efs.csi.aws.com 两个 SCI Driver 用于创建 EBS 和 EFS 类型的 StorageClass
kubectl get csidrivers |
查看 StorageClass 信息,EKS 自动模式(EKS Auto Mode)使用 provisioner: ebs.csi.eks.amazonaws.com ,普通 EKS 集群安装的 AWS EBS SCSI Drive 使用 provisioner: ebs.csi.aws.com
kubectl get storageclasses |
此 Storageclass
gp3对应的 YAML 配置文件如下
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.eks.amazonaws.com
parameters:
type: gp3
fsType: ext4
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: true
为集群分配只读权限的账户
EKS 账户权限是 AWS IAM 权限 + Kubernetes RBAC 两层权限一起管。
本示例目标是:用户能看集群资源( kubectl get/describe ),但不能改( create/update/delete )。
在 AWS IAM 中创建用户如
EKSReadOnlyUSER,确保该 IAM 用户或角色在 AWS 层面能够“看到”集群。创建一个名为EKSReadOnlyPolicy的策略并关联给该用户EKSReadOnlyPolicy {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}使用 EKS 的 Access Entries (访问条目) 机制为集群访问创建 访问条目 (Access Entry)
新版本的 EKS 集群启用了 API 身份验证模式 (API Authentication Mode) 。可以直观的通过 访问条目 (Access Entry) 控制对集群的访问

AWS Console(控制台)查看 Access Entry

aws命令查看 Access Entryaws eks list-access-entries --cluster-name MY_CLUSTER
{
"accessEntries": [
"arn:aws:iam::25291...:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS",
"arn:aws:iam::25291...:role/eksNodeRole",
"arn:aws:iam::252910...:user/CLUSTER_USER"
]
}EKS 的 Access Policies 中有个内置的策略
AmazonEKSViewPolicy,已经实现了只读效果(能get / list / watch不能create / update / delete),因此只需要创建新的 IAM access entry 并将AmazonEKSViewPolicy策略附加其上即可。
在客户端使用 IAM 用户
EKSReadOnlyUSER的身份凭证登陆即可进行验证kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "arn:aws:iam::25....:user/EKSReadOnlyUSER" cannot list resource "nodes" in API group "" at the cluster scope
kubectl get pods
NAME READY STATUS RESTARTS AGE
netshoot-daemonset-s5sbr 1/1 Running 0 6h42m
nginx-deployment-5746cdf7c8-9vw9w 1/1 Running 0 4h49m
nginx-deployment-5746cdf7c8-j772t 1/1 Running 0 4h49m
如果 EKS 集群接入 Rancher 进行管理,可以直接通过 Rancher 的 RBAC 机制进行用户权限分配,会比 EKS 和原生 K8S 更加的直观方便。
启用 EKS 中的 Ingress 的 Access Log 记录
EKS 中创建的 Ingress 的 IngressClass 为 alb 时,AWS Load Balancer Controller 会为 Ingress 创建对应的 ALB(AWS Load Balancer),ALB 默认的访问日志(Access Logs)是关闭的。要 开启访问日志(Access Logs),需要通过修改 Kubernetes Ingress 资源的 Annotation(注解) 来实现 。
在 AWS 的架构设计中,S3 是 ALB 访问日志的法定落脚点。目前 ALB 的访问日志(七层请求详情)在 AWS 控制台或 API 配置中,仅支持写入 S3。它不支持直接推送至 CloudWatch Logs 或 Kinesis 。
因此要开启 ALB 的访问日志(七层请求详情),要首先准备好 S3 桶和权限。S3 要注意以下事项:
- S3 Bucket 必须与 ALB 处于同一个 AWS 区域(例如都在 ap-southeast-1 新加坡)。
- 如果 S3 配置不正确,日志投递会失败,但这绝不会影响 ALB 的正常流量转发。
- ALB 将日志发送到同一个区域的 S3 是免收流量费的
- 记得给 S3 设置 生命周期规则(Lifecycle Policy),比如 30 天后自动删除或转入冷存储,否则长期积累会导致存储费上涨。
参考以下步骤配置 S3,为 Application Load Balancer 启用访问日志官方文档
创建 S3 存储桶(Bucket), 桶的区域 (Region) 必须和 ALB 一致,该存储桶和负载均衡器可由不同的账户拥有 。
配置 Bucket Policy(存储桶策略),S3 存储桶必须具有为 Elastic Load Balancing 授予将访问日志写入存储桶的权限的存储桶策略 。
在 Permissions (权限) 选项卡中,编辑 Bucket Policy。
{
"Version":"2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "logdelivery.elasticloadbalancing.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<BUCKET NAME>/*"
}
]
}
然后修改 Ingress 配置。在 Ingress 中添加 Annotation
apiVersion: networking.k8s.io/v1 |
alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=<你的-s3-bucket-名字>,access_logs.s3.prefix=<logs-prefix>配置指定启用 Access Logs 写入 S3,指定日志写入 S3 中的路径,多项目多集群可以按照项目或集群多目录分割,如 access_logs.s3.prefix=EKS_CLUSTER_A/PROJECT_A
部署 ALB 后,可在 AWS Console 中查看 ALB 中是否有日志传送相关配置, AWS Console -> EC2 -> Load balancers -> Attributes: Monitoring
当你修改了 EKS 的 Ingress Annotation 开启日志后,可以去 S3 桶里看看
- 测试文件 : ALB 开启成功后的几分钟内,通常会先往桶里写入一个名为
ELBAccessLogTestFile的文件。 - 看到这个文件,就说明权限配置完全正确。
需要分析时可下载日志解压查看内容
http 2026-02-13T05:22:42.367084Z app/k8s-argocd-argocd-8e8cb645d5/026e67072db1ff28 54.254.220.119:57674 172.31.68.217:8080 0.000 -1 -1 460 - 1537 0 "GET http://k8s-argocd-argocd-8e8cb645d5-1951055800.ap-east-1.elb.amazonaws.com:80/api/v1/stream/applications?resourceVersion=3228300&fields=result.type%2Cresult.application.metadata.name%2Cresult.application.metadata.namespace%2Cresult.application.metadata.annotations%2Cresult.application.metadata.labels%2Cresult.application.metadata.creationTimestamp%2Cresult.application.metadata.deletionTimestamp%2Cresult.application.spec%2Cresult.application.operation.sync%2Cresult.application.status.sourceHydrator%2Cresult.application.status.sync.status%2Cresult.application.status.sync.revision%2Cresult.application.status.health%2Cresult.application.status.operationState.phase%2Cresult.application.status.operationState.finishedAt%2Cresult.application.status.operationState.operation.sync%2Cresult.application.status.summary%2Cresult.application.status.resources&selector=&appNamespace= HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36" - - arn:aws:elasticloadbalancing:ap-east-1:252910564041:targetgroup/k8s-argocd-argocdse-b493e951a4/7f99bffde71cf22d "Root=1-698eb521-7f4353266a582d904a42b4a2" "-" "-" 1 2026-02-13T05:22:41.230000Z "forward" "-" "-" "172.31.68.217:8080" "-" "-" "-" TID_2642ce98c4c35148ad54404d5523a955 "-" "-" "-" |
ALB 日志字段参考 :
type: 协议类型(http, https, h2, ws, wss)。timestamp: ALB 收到请求并完成响应的时间。elb: ALB 名称/资源 ID(app/k8s-argocd-argocd-8e8cb645d5/026e67072db1ff28)client:port: 发起请求的客户端 IP 和端口。target:port: 后端 Target(Pod) 的私网 IP 和端口。 如果为-表示请求未到达后端。request_processing_time: 请求处理时间target_processing_time: 后端 Target(Pod) 的处理时间response_processing_time: 响应处理时间elb_status_code: ALB 返回给客户端的状态码。target_status_code: 后端 Pod 返回的状态码。 如果是-说明 ALB 自己挂了或主动拦截了。request_bytes: ALB 收到的字节数response_bytes: ALB 发送给客户端的字节数。request: 完整的 HTTP 请求行。user_agent: 客户端浏览器信息。ssl_cipher: SSL 加密套件和协议(非 HTTPS 请求则为-)。ssl_protocol: SSL 加密套件和协议(非 HTTPS 请求则为-)。target_group_arn: 处理该请求的 Target Group 的 ARN。trace_id: X-Amzn-Trace-Id,可用于全链路追踪。domain_name: 请求匹配的Host头部,如果没有Host匹配规则则为-chosen_cert_arn: 匹配到的 ACM 证书 ARN(HTTPS Listener)matched_rule_priority: 匹配到的 Listener Rule 优先级request_creation_time: ALB 接收到请求的时间actions_executed: 执行的动作,可能值:forward, redirect, fixed-response, authenticate, wafredirect_url: 如果执行redirect,显示重定向 URLerror_reason: 错误原因(当发生错误时),如Target.ResponseCodeMismatch,Target.Timeout,ELB.5XXtarget:port_list: 如果多个目标,列出所有目标target_status_code_list: 多个目标返回状态码classification: 请求分类,如waf,monitoring,health-checkclassification_reason: 分类原因说明
EKS 部署 Prometheus 监控
- kube-prometheus-stack-82.2.0 helm Chart Version: v0.89.0
最标准的部署方式是使用 kube-prometheus-stack 。这套方案不仅包含 Prometheus 本身,还集成了 Operator、Grafana、告警管理以及预设的 K8s 监控面板。
可以参考以下配置文件 kube-prometheus-stack-values.yam 部署服务
#### 部署命令如下 |
执行部署
添加仓库 |
检查相关资源
kubectl get pods,svc,ingresses -n monitoring |
相关案例或错误排查
自治模式创建的集群无法部署 Pod 上去
自治模式(EKS Auto Mode)的集群节点上,默认会为节点配置特定的 污点(Taints) ,如果 Pod 配置中没有设置对应的 Tolerations(容忍度),Pod 会无法调度到对应的节点上去。
比如以下 DaemonSet 配置,在 EKS 集群上可能无法成功部署
apiVersion: apps/v1 |
查看 DaemonSet 状态
kubectl describe daemonset netshoot-daemonset |
其中没有可调度的节点
Desired Number of Nodes Scheduled: 0 |
检查节点的 Taints 信息,可以看到节点配置了 Taints effect:NoSchedule key:CriticalAddonsOnly
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints |
为了让 Pod 能调度到此节点上去,可以为 DaemonSet 配置添加 Tolerations
apiVersion: apps/v1 |
EKS 部署 Nginx 服务并在互联网上可以访问
本示例中的 Worker Nodes 和 Pod 子网为 私有子网 (Private Subnet),通过 NAT Gateway 访问互联网 。
首先要确保 EKS 集群的 AWS Load Balancer Controller 正常安装,才能通过 ALB 对外提供服务。
参考以下配置文件,部署 Nginx 服务相关资源
apiVersion: apps/v1 |
使用以下命令部署服务
kubectl apply -f nginx.yaml |
部署后检查服务相关服务状态
kubectl get pods -o wide |
部署成功后,AWS Load Balancer Controller(LBC) 会为服务生成 ALB(AWS Load Balancer)地址,通过此地址(k8s-default-nginxing-f6eb483edf-2017046049.ap-east-1.elb.amazonaws.com) 即可在互联网上访问此服务。
如果需要绑定自己的域名,参考以下步骤:
如果域名 NS 指向 AWS Route 53(域名解析在 AWS Route 53),在 Route 53 选择自有域名,添加/修改解析
Record Type: A
Alias:✅ 打开
Alias target: ALB DNS(`k8s-default-nginxing-f6eb483edf-2017046049.ap-east-1.elb.amazonaws.com`)
Routing policy:Simple如果域名 NS 不是指向 AWS Route 53(域名解析未在 AWS Route 53),就用 CNAME
Record Type: CNAME
CNAME Value: ALB DNS(`k8s-default-nginxing-f6eb483edf-2017046049.ap-east-1.elb.amazonaws.com`)
本示例中的 Ingress 未指定域名(HOSTS: *),任意域名解析到此 ALB 都会命中 nginx 服务
kubectl get ingress -o wide |
如果需要为 Ingress 绑定特定域名,使用 host 参数,如 host: www.example.com
apiVersion: networking.k8s.io/v1 |
绑定特定域名后查看 Ingress
kubectl get ingress |
此时,只有 www.example.com 可以访问,其他域名访问会返回 404.
ALB 域名无法访问排查步骤
部署了 IngressClassName: alb 类型的 Ingress 后,无法正常访问
kubectget ingress -A -o wide |
此时可以先检查 AWS Load Balancer 中对应自由的状态,登录 AWS 控制台 -> EC2 -> Load Balancers ,检查对应的 ALB 状态:
- ALB 的 State 是否为
Active,如果是Provisioning或Failed,说明还在创建中或配置有误。

- 检查监听器 (Listeners) 是否监听了对应的端口

- 检查安全组 (Security Groups) 是否放通了相关端口
- 检查 Resource Map ,看后端 Targets 是否检测正常

- 在 AWS 控制台 -> EC2 -> Target Groups 中检查相关的后端 Target (Pod)是否正常


Pod 挂载 EBS PV 失败
Pod 状态不正常
kubectl get PODS -n monitoring |
Pod 状态 Pending ,报错 running PreBind plugin "VolumeBinding": binding volumes: context deadline exceeded
错误指向 存储绑定失败 ,接着检查存储相关
kubectl get STORAGECLASS |
EKS 默认不包含 EBS 驱动。如果没有驱动,Kubernetes 无法调用 AWS API 去创建 EBS 磁盘。 检查 AWS EBS CSI 驱动是否运行
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver |
以上结果说明 EKS 中未安装 EBS CSI 驱动,需要为 EKS 安装这个 Add-on
加入 PVC 报错信息如下:
Events: |
说明 AWS EBS CSI 驱动工作正常,但是 EBS CSI 驱动想要创建磁盘,但它 不知道这个节点到底在哪个可用区 (Availability Zone) 。EBS 磁盘是不能跨可用区挂载的。正常情况下,节点应该带有 topology.ebs.csi.aws.com/zone 标签,驱动靠这个标签来决定在哪个 AZ 创建磁盘。
这种情况在 手动创建节点 或 EBS CSI 驱动在节点加入集群后才安装 时经常发生。节点上的 CSI 插件没有正确上报拓扑信息。
检查 StorageClass 配置
kubectl get storageclass gp2 -o yaml |
其中的 provisioner: kubernetes.io/aws-ebs ,这是过时的旧的内建驱动,已被废弃,且无法识别 CSI 驱动特有的拓扑标签(即报错中的 topology.ebs.csi.eks.amazonaws.com/zone )。它在较新的 K8s 版本中兼容性较差。 使用新的 EBS CSI 驱动 ( ebs.csi.aws.com )
删除旧的 storageclass gp2
|
创建正确的 CSI StorageClass ,使用 provisioner: ebs.csi.aws.com
apiVersion: storage.k8s.io/v1 |
查看新的 StorageClass
kubectl get storageclass |
之后 PVC 依旧报错
Events: |
这大概率是因为只有 ebs-csi-controller 而没有 ebs-csi-node 。CSI 驱动依赖一个叫做 CSINode 的集群资源来识别节点支持哪些驱动及其所在区域。确保每个节点对应的 ebs-csi-node-xxxx 都是 Running 状态。
kubectl get pods -n kube-system |
没有 ebs-csi-node DaemonSet