【免费下载链接】charts
⚠️(OBSOLETE) Curated applications for Kubernetes
导读
本文以 Helm Charts 仓库中的 stable/efs-provisioner 图表为核心,系统讲解如何在 Kubernetes 集群中部署 AWS EFS 外部存储 Provisioner,并通过 StorageClass 实现 PersistentVolumeClaim(PVC)到 EFS PersistentVolume 的动态供给。读完本文,你将掌握 EFS 前置条件准备、Helm 安装命令、values.yaml全部核心参数的语义与默认值、底层 Deployment/StorageClass 模板的渲染逻辑,以及基于 RBAC 与 PodSecurityPolicy 的完整安全配置方法。
一、背景:EFS Provisioner 解决了什么问题
AWS EFS(Elastic File System)是亚马逊提供的共享文件存储服务,天然支持 NFS 协议。Kubernetes 官方项目(kubernetes-incubator/external-storage)提供了一个 EFS provisioner,用于"根据 PersistentVolumeClaim 的创建动态地在 EFS 文件系统上划分目录,并生成对应的 PersistentVolume",从而让集群内的工作负载能够以 PVC 的方式透明使用 EFS 存储。
按图表 README 中的描述:该 provisioner 由"一个能够访问 AWS EFS 资源的容器"构成,容器读取包含EFS 文件系统 ID、AWS 区域、provisioner 名称的配置(在本图表中通过环境变量注入),其中 provisioner 名称会在后续创建 StorageClass 时使用。其核心工作流程为:
- 用户创建带
storageClassName的 PersistentVolumeClaim; - EFS Provisioner 监听到 PVC 创建事件;
- Provisioner 在 EFS 文件系统中为 PVC 创建一个独立文件夹;
- Provisioner 自动创建对应的 PersistentVolume,并完成 PVC 与 PV 的绑定;
- 容器即可将 EFS 卷挂载进 Pod。
需要强调的是,"持久卷是以 AWS EFS 文件系统内的文件夹形式创建的",多个 Pod 可共享同一 EFS 文件系统下的不同子目录,且 StorageClass 默认使用ReadWriteMany访问模式,适合多副本共享读写的应用场景。
从 deployment.yaml 的模板实现可以看到,Provisioner 容器自身正是通过挂载一个 NFS 类型的pv-volume(指向 EFS 的 DNS 地址、path: /)来访问 EFS 根目录,并通过subPath: {{ trimPrefix "/" .Values.efsProvisioner.path }}将 PVC 数据统一落盘到 EFS 的指定子路径下,挂载点为/persistentvolumes。
二、前置条件:安装前必须完成的 AWS 侧准备
README 明确指出,EFS 文件系统与挂载端点需要由使用者自行提前创建,图表本身不负责创建:
- 创建 EFS 文件系统:需提前在 AWS 控制台或通过 CLI 创建 EFS 文件系统,并记录其文件系统 ID(形如
fs-12345678)。 - 创建并配置挂载目标(Mount Targets / Endpoints):EFS 的挂载端点必须能够被集群节点访问到。这通常意味着挂载目标所在的子网与集群节点子网互通,或在同一 VPC 内。
- 节点具备 NFS 挂载权限:集群节点需要安装 NFS 客户端(如
nfs-utils),并具备挂载 EFS 文件系统的网络与安全组(Security Group)放行条件。EFS 挂载目标默认使用 2049 端口(NFS),安全组需允许相应流量。
只有满足以上条件,Provisioner 容器(以及后续挂载 PV 的应用 Pod)才能成功 mount 上 EFS 文件系统。若跳过该步骤,Provisioner 会因无法挂载而无法进入健康的运行状态。
三、快速安装:两条命令起步
图表 README 给出的最小安装方式,只需提供 EFS 文件系统 ID 与 AWS 区域:
helm install stable/efs-provisioner --set efsProvisioner.efsFileSystemId=fs-12345678 --set efsProvisioner.awsRegion=us-east-2所有可配置项均可通过helm inspect values查看:
helm inspect values stable/efs-provisioner也可以直接阅读仓库中的 values.yaml,两者内容一致。关于图表版本信息,Chart.yaml 记录了当前图表版本为0.13.2,appVersion为v2.4.0(对应镜像quay.io/external_storage/efs-provisioner:v2.4.0),并已标记deprecated: true——该图表随 Helm Charts 仓库归档而停止更新,生产使用请自行评估。
关于"占位 ID"的细节
注意 deployment.yaml 中的一处关键实现细节:只有当efsFileSystemId不等于默认占位值fs-12345678、或者显式设置了dnsName时,模板才会真正渲染 Deployment。注释明确说明,这是为了防止 Helm 集成测试在无法访问真实 AWS EFS 资源的环境中,渲染出一个永远无法进入干净运行状态的 Deployment。因此,如果你在安装时保留默认的fs-12345678而不做任何设置,将不会得到任何 Deployment——这提醒我们efsFileSystemId是必须由用户真实提供的参数。
四、配置参数详解:从 values.yaml 到模板渲染
以下参数全部来自 values.yaml,并对照模板说明其作用。
4.1 全局与部署基础
| 参数 | 默认值 | 说明 |
|---|---|---|
global.deployEnv | dev | 部署环境标签(如 dev/test/prod),会作为env标签写入所有资源 |
replicaCount | 1 | Deployment 副本数;由于 provisioner 需要以Recreate策略运行(见 deployment.yaml),一般保持单副本 |
revisionHistoryLimit | 10 | Deployment 保留的历史版本数量 |
image.repository/image.tag/image.pullPolicy | quay.io/external_storage/efs-provisioner/v2.4.0/IfNotPresent | Provisioner 容器镜像配置 |
image.pullSecrets | 空 | 访问私有镜像仓库所需的 Secret 列表 |
busyboxImage.* | gcr.io/google_containers/busybox:1.27 | 用于创建 EFS 子路径的 init 容器镜像 |
extraEnv/envFrom | [] | 额外注入的环境变量 / 从 ConfigMap、Secret 批量注入的环境变量(渲染进容器env/envFrom) |
annotations | {} | 部署等资源的注解 |
4.2 efsProvisioner:核心供给配置
| 参数 | 默认值 | 说明 |
|---|---|---|
efsProvisioner.efsFileSystemId | fs-12345678 | 必填,EFS 文件系统 ID;模板用它拼出 NFS server 地址{fsId}.efs.{region}.amazonaws.com |
efsProvisioner.awsRegion | us-east-2 | AWS 区域,用于构造 EFS 挂载域名 |
efsProvisioner.dnsName | 空(注释示例my-custom-efs-dns.com) | 可选;设置后使用自定义 DNS 或 IP 连接 EFS,此时优先于efsFileSystemId拼接出的域名 |
efsProvisioner.path | /example-pv | Provisioner 在 EFS 中存放 PVC 数据的根子路径 |
efsProvisioner.provisionerName | example.com/aws-efs | Provisioner 标识名,StorageClass 的provisioner字段会使用它 |
这些参数在模板中的落地位置非常清晰(见 deployment.yaml):
FILE_SYSTEM_ID←efsFileSystemIdAWS_REGION←awsRegionPROVISIONER_NAME←provisionerNameDNS_NAME←dnsName(仅当设置了dnsName时注入)
4.3 storageClass:动态供给的入口
| 参数 | 默认值 | 说明 |
|---|---|---|
efsProvisioner.storageClass.name | aws-efs | StorageClass 名称,PVC 通过它引用 |
efsProvisioner.storageClass.isDefault | false | 是否设为集群默认 StorageClass;为true时模板会写入注解storageclass.kubernetes.io/is-default-class: "true"(见 storageclass.yaml) |
efsProvisioner.storageClass.gidAllocate.enabled | true | 是否启用 GID 自动分配,解决 EFS 上不同 PV 间权限隔离问题 |
efsProvisioner.storageClass.gidAllocate.gidMin/gidMax | 40000/50000 | GID 分配区间 |
efsProvisioner.storageClass.reclaimPolicy | Delete | PV 回收策略;Delete表示 PVC 删除时 PV 及对应 EFS 数据一并回收 |
efsProvisioner.storageClass.mountOptions | [] | 额外 NFS 挂载选项(如tcp、nfsvers=4.1),会渲染为 StorageClass 的mountOptions列表 |
storageclass.yaml 展示了gidAllocate的渲染逻辑:启用时写入gidAllocate: "true"、gidMin、gidMax三个参数;禁用时仅写入gidAllocate: "false"。reclaimPolicy直接透传,mountOptions为空数组时整个字段不会被渲染。
4.4 RBAC、ServiceAccount 与安全
| 参数 | 默认值 | 说明 |
|---|---|---|
rbac.create | true | 是否创建 ClusterRole 与 ClusterRoleBinding |
serviceAccount.create | true | 是否创建专用 ServiceAccount;为false时回退使用default或serviceAccount.name指定的已有账户 |
serviceAccount.name | "" | 自定义账户名;为空且create: true时按 fullname 模板自动生成(见 _helpers.tpl) |
serviceAccount.annotations | {} | ServiceAccount 注解,典型用途是注入 EKS IRSA 角色 ARN(如eks.amazonaws.com/role-arn) |
podSecurityPolicy.enabled | true | 是否创建 PodSecurityPolicy;podSecurityPolicy.annotations可附加自定义注解 |
ClusterRole 的权限集(见 clusterrole.yaml)精确对应 provisioner 的工作对象:对persistentvolumes具备 get/list/watch/create/delete,对persistentvolumeclaims具备 get/list/watch/update,对storageclasses具备 get/list/watch,并拥有events与endpoints的读写权限(provisioner 通过 Endpoints 做 leader election 与信息发布)。启用 PSP 时,还会额外授予对该 PSP 的use权限。
PodSecurityPolicy 本身(见 podsecuritypolicy.yaml)以最小权限为原则:privileged: false、禁止提权、丢弃全部 capabilities、禁止 hostNetwork/hostIPC/hostPID,卷类型仅允许configMap、secret、nfs,根文件系统只读(readOnlyRootFilesystem: true),runAsUser与seLinux使用RunAsAny,supplementalGroups 与 fsGroup 限定在 1~65535 区间。
4.5 调度与资源
| 参数 | 默认值 | 说明 |
|---|---|---|
podAnnotations | {} | Pod 注解,注释示例为注入 IAM 角色(iam.amazonaws.com/role: efs-provisioner-role) |
podLabels | {} | Pod 标签 |
nodeSelector | {} | 节点选择器 |
affinity | {} | 亲和性配置 |
tolerations | {} | 容忍配置 |
resources | {} | 资源请求与限制(注释示例给出cpu: 100m~200m、memory: 128Mi) |
priorityClassName | "" | Pod 优先级类名 |
上述调度与资源参数在 deployment.yaml 中均按"配置了才渲染"的方式处理。
五、模板实现细节:子路径初始化与 NFS 挂载
deployment.yaml 中还包含两个值得注意的实现细节:
1. NFS 卷的 server 地址构造(L97-L105):
volumes: - name: pv-volume nfs: {{- if .Values.efsProvisioner.dnsName }} server: {{ .Values.efsProvisioner.dnsName }} {{- else }} server: {{ .Values.efsProvisioner.efsFileSystemId }}.efs.{{ .Values.efsProvisioner.awsRegion }}.amazonaws.com {{- end }} path: /即默认使用 AWS 标准的 EFS 挂载域名格式{filesystem-id}.efs.{region}.amazonaws.com;若配置了dnsName则完全由自定义地址接管。
2. init 容器创建子路径(L85-L96):当efsProvisioner.path不为/时,模板会渲染一个名为init-path的 busybox init 容器,执行mkdir -p /efs-vol-root/<path>,提前在 EFS 根目录下创建好供给数据所在的子目录,避免 Provisioner 主容器启动时目录尚不存在。
六、使用:通过 PVC 申请 EFS 存储
安装完成后,NOTES.txt 会输出一个可直接套用的 PVC 示例:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: my-efs-vol-1 annotations: volume.beta.kubernetes.io/storage-class: aws-efs spec: storageClassName: aws-efs accessModes: - ReadWriteMany resources: requests: storage: 1Mi其中storageClassName对应efsProvisioner.storageClass.name的实际取值(默认aws-efs)。创建该 PVC 后,EFS Provisioner 会自动完成"建目录 → 创建 PV → 绑定 PVC"的全流程,随后即可在 Deployment/StatefulSet 中通过该 PVC 挂载 EFS 共享存储,满足多 Pod 读写同一份数据的场景(如共享缓存、上传目录、协同编辑类应用)。
accessModes: ReadWriteMany与 EFS 的 NFS 特性天然匹配——这正是 EFS 相比 EBS(仅单节点读写)的核心差异,也是选择 EFS 方案的首要理由。
七、注意事项与弃用声明
- 本图表位于
stable目录,但已在 README.md 与 Chart.yaml 中明确标记DEPRECATION NOTICE:图表已弃用、不再受支持。这是 Helm Charts 官方仓库整体归档(2020-11-13 起不再更新)的一部分,请结合后续维护方案使用。 - 安装前务必核对:EFS 文件系统 ID 是否为真实 ID(避免默认占位值导致 Deployment 不渲染)、挂载端点与集群网络是否互通、节点是否具备 NFS 挂载能力。
- 若集群启用了 PodSecurityPolicy 准入控制,
podSecurityPolicy.enabled: true会随之创建 PSP 并绑定权限,此时需确保集群支持policy/v1beta1资源。 - 若在 EKS 中使用 IRSA,可在
serviceAccount.annotations中注入eks.amazonaws.com/role-arn,为 provisioner 提供访问 EFS 所需的 IAM 权限(EFS 客户端需要权限完成挂载目标访问)。
结语
通过本文,你已经掌握 efs-provisioner 图表从"前置准备 → 参数配置 → 模板渲染 → PVC 使用"的完整链路。核心要点可概括为三条:efsFileSystemId与awsRegion是安装的必填项;provisionerName决定了 StorageClass 与 provisioner 的绑定关系;gidAllocate与mountOptions决定了 EFS 上多租户数据隔离与挂载行为。结合仓库中的 values.yaml 与 templates 源码,你可以进一步按需裁剪 RBAC、PSP 与调度参数,将其适配到自己的集群环境。
【免费下载链接】charts
⚠️(OBSOLETE) Curated applications for Kubernetes
相关推荐
使用 Helm 在 Kubernetes 上部署 Apache Druid:完整配置与实战指南
使用 Helm 在 Kubernetes 上部署 Apache Druid:完整配置与实战指南 Apache Druid 是一款高性能的实时分析数据库,本指南基
PyPTO 系统访问变量实战指南:get_block_idx / get_block_num / get_subblock_idx / get_subblock_num 多核编程完全解析
PyPTO 系统访问变量实战指南:get_block_idx / get_block_num / get_subblock_idx / get_subblock
使用 Helm Chart 在 Kubernetes 上部署 Istio 0.2.12:安装、RBAC 与配置实战
使用 Helm Chart 在 Kubernetes 上部署 Istio 0.2.12:安装、RBAC 与配置实战 Istio 是一个为微服务提供统一连接、管理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考