自建集群的NFS存储部署在单独的EC2上,稳定性和扩展性很差,生产业务使用相对风险较大
EKS集群可以集成EFS存储,和开源NFS存储使用方式一样,但稳定性基于云平台,稳定性更佳,维护成本也比自建分布式存储要低很多,更加容易上手。
第一次使用EKS集群,给我的感觉就是权限管理太细,没有自建集群权限自由,另外不需要关心集群控制节点和Node节点确实舒坦。
此次部署需要以下材料
1、 一个安装好的EKS集群
2、 管理节点上装有aws eksctl kubectl命令 (最好是最新版本,客户端版本和集群对不上会有API错误)
3、有管理员权限
4、拥有集群的OIDC
一、AWS Role创建
参考官方文档
https://docs.aws.amazon.com/eks/latest/userguide/efs-csi.html
1.1、eksctl创建
自定义cluste_name变量,使用命令eksctl get cluster
查看集群名称,role_name不用配置
export cluster_name=my-cluster
export role_name=AmazonEKS_EFS_CSI_DriverRole
eksctl create iamserviceaccount \
--name efs-csi-controller-sa \
--namespace kube-system \
--cluster $cluster_name \
--role-name $role_name \
--role-only \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
--approve
TRUST_POLICY=$(aws iam get-role --role-name $role_name --query 'Role.AssumeRolePolicyDocument' | \
sed -e 's/efs-csi-controller-sa/efs-csi-*/' -e 's/StringEquals/StringLike/')
aws iam update-assume-role-policy --role-name $role_name --policy-document "$TRUST_POLICY"
方法二选一
1.2、aws控制台创建
过滤出oidc id
oidc_id=$(aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
如果不存在需要创建IAM oidc提供商,安装EKS插件都需要使用到oidc
eksctl utils associate-iam-oidc-provider --cluster $cluster_name --approve
添加角色Role --> 选择aws服务的EC2服务 --> 策略添加AmazonEFSCSIDriverPolicy(这是aws托管策略) ->角色名称AmazonEKS_EFS_CSI_DriverRole
--> 然后点击确认添加完成
需要修改Role中的受信任实体
,将下面的json贴进去,注意有几个属性需要修改.
$USERID
$OIDC
$REGION
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::$USERID:oidc-provider/oidc.eks.$REGION.amazonaws.com/id/$OIDC"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.$REGION.amazonaws.com/id/$OIDC:sub": "system:serviceaccount:kube-system:efs-csi-controller-sa",
"oidc.eks.$REGION.amazonaws.com/id/$OIDC:aud": "sts.amazonaws.com"
}
}
}
]
}
我们现在已经创建好了Role,稍后在安装EFS插件时把Role绑定给插件
- 指定信任关系
JSON 中的 Principal 部分使用了 Federated 方式,指定了 EKS 的 OIDC 提供者(arn:aws:iam:: U S E R I D : o i d c − p r o v i d e r / o i d c . e k s . USERID:oidc-provider/oidc.eks. USERID:oidc−provider/oidc.eks.REGION.amazonaws.com/id/$OIDC),用于在 EKS 集群中使用 IAM 角色。
权限作用域: - 权限作用域
Condition 部分使用了 StringLike 条件来限制此角色的使用。 system:serviceaccount:kube-system:efs-csi-,这意味着只有在 kube-system 命名空间中的服务账户 efs-csi- 才能使用该角色。 - Role绑定到kube-system命名空间下的服务账户
在安装 EFS 插件时,这个 IAM 角色将被绑定到插件使用的服务账户,使插件能够正确获取所需权限来管理 EFS。
二、安装EFS插件
2.1、eksctl安装插件
查看当前EKS版本可用的插件
eksctl utils describe-addon-versions --kubernetes-version 1.29 | grep AddonName
注意修改$USERID,也可以export把这些变量都定义好。
这一步就是安装插件,然后给插件绑定一个serviceaccount role(IAM Role),让其拥有我们之前配置Role的权限
eksctl create addon --name aws-efs-csi-driver --cluster $cluster_name --service-account-role-arn arn:aws:iam::$USERID:role/AmazonEKS_EFS_CSI_DriverRole
二选一操作
2.2 EKS控制台安装插件
如果不太熟悉上面命令行的绑定方式,图形界面会更加容易理解它做了什么操作
插件绑定了我们之前配置好的IAM Role
安装好以后可以查看kube-system下的efs pod状态
三、配置EFS存储
3.1、创建EFS
创建很简单输入EFS名称和VPC就行,我部署在EKS集群所在VPC
待会儿会用到这个文件系统ID
3.2、创建EFS安全组
默认会使用default安全组,不方便维护和管理
点击进入存储 -> 网络选项 -> 管理 -> 更换安全组
安全组的条目我放开了所有端口给EKS VPC的整个CIDR
四、EKS集群集成EFS
要实现的小目标
1、创建pvc自动创建pv
2、应用成功挂载pvc
4.1、创建storage class
directoryPerms: "700"
目录权限如果没有配置会出现无法自动创建pv的情况,我贴出它的详细错误信息
错误信息
Warning ProvisioningFailed 3s (x4 over 10s) efs.csi.aws.com_efs-csi-controller-664d6889d4-jff7p_e280d2ff-d33f-4fe6-8f87-920fdc233422 failed to provision volume with StorageClass “dev-eks-efs”: rpc error: code = Internal desc = Failed to create Access point in File System $fs-id : Failed to create access point: InvalidParameter: 1 validation error(s) found.
minimum field size of 3, CreateAccessPointInput.RootDirectory.CreationInfo.Permissions.
错误处理
问题出现在创建访问点时的权限设置上。错误信息表明,CreateAccessPointInput.RootDirectory.CreationInfo.Permissions 字段的值不符合最小长度要求。这通常是因为提供的权限字符串格式不正确或太短。
在 EFS CSI 驱动中,directoryPerms 需要一个正确格式的权限字符串,这应该是一个三位的数字,如 700、755 等。直接贴出可用配置
要修改自己的$fs-id
cat <<EOF | kubectl create -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: dev-eks-efs
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: $fs-id
directoryPerms: "700"
gidRangeStart: "1000"
gidRangeEnd: "2000"
EOF
4.2、创建pvc
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-sijia-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: dev-eks-efs
resources:
requests:
storage: 100Mi
EOF
这三个都是自动创建的pv
4.3、创建应用测试EFS挂载
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-efs-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-efs
template:
metadata:
labels:
app: nginx-efs
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: efs-volume
mountPath: /usr/share/nginx/html
volumes:
- name: efs-volume
persistentVolumeClaim:
claimName: test-sijia-pvc
EOF
4.4、查看容器信息
已经正确挂载
Volumes:
efs-volume:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: test-sijia-pvc
ReadOnly: false
如需删除测试storageclass和pvc
kubectl delete deployments.apps nginx-efs-deployment
kubectl delete pvc test-sijia-pvc
kubectl delete sc dev-eks-efs
问题1
部署新集群时遇到的问题,EFS的DNS无法解析
https://stackoverflow.com/questions/53011147/cant-resolve-dns-name-of-efs-while-mounting-it-on-red-hat-ec2-instances-using-p
问题2
这次部署的是1.31版本,授权策略中
system:serviceaccount:kube-system:efs-csi-* 这次我写了通配符以后出错了,写成efs-csi-controller-sa以后重启或者重新安装EFS插件
EFS测试完成,我helm部署vault时也是用了EFS。
结尾再说一下,最初接触EKS可能权限这块不太好理解,我第一次部署出现了403错误,因为我把EBS的role给了EFS插件,第二次插件给对就好了。