内容提要
本文介绍 Flink on Kubernetes 的持久化存储配置:通过 NFS 挂载 NAS 等弹性文件系统,保存 checkpoint、savepoint 和高可用数据。需在 flink-conf.yaml 中配置状态后端、存储目录及 Kubernetes 高可用,并创建 PV/PVC 挂载到 Pod。由于 Flink 以 9999 用户运行而 NAS 目录属 root,需用 Init 容器执行 chown 初始化权限;Job Manager 与 Task Manager 的挂载路径必须一致,否则会导致 checkpoint 堆积。
延伸解读
为什么选择云上弹性文件系统而非自建 HDFS
文章指出,在 k8s 上部署 Flink 时,除了沿用 HDFS 持久化 checkpoint,还可以直接使用云上弹性分布式文件系统(如阿里云 NAS、AWS EFS)。这些文件系统通过 NFS 协议挂载到 Pod,使用体验接近本地文件,省去了在 k8s 中自建和维护 HDFS 的复杂度。对于已经运行在云上的 Flink 集群,这种方案能降低存储层运维负担,但前提是集群节点能访问对应的 NFS 服务。
权限初始化是持久化配置中最常见的启动障碍
Flink 官方镜像以 UID 9999 的 flink 用户运行,而 NAS 目录默认属主为 root,导致任务进程无法写入 checkpoint 和高可用目录。文章给出的典型报错是“Mkdirs failed to create file:/nas/flink/recovery/default”,Job Manager 会因此反复重启。解决方案是用 Init 容器在应用容器启动前执行 chown -R 9999:9999 /nas/flink,并同样挂载该 NAS 目录。这比直接用 root 运行 Pod 更安
挂载路径不一致会导致 checkpoint 堆积
文章强调 Job Manager 与 Task Manager 的 NAS 挂载路径 mountPath 必须一致。若不一致,两边的 checkpoint 文件会写入不同目录,即使设置了 state.checkpoints.num-retained,Flink 也无法自动清理多余文件,最终占满磁盘。排查时除了检查该参数是否过大,更应优先核对 Job Manager 和 Task Manager 的 YAML 中 volumeMounts 的 mountPath 是否相同。
Q&A
Flink on k8s 为什么需要配置持久化存储?
为了实现任务高可用,需要将 checkpoint、savepoint 以及 Job Manager 元数据等数据持久化存储下来,而不是存储在单个 Node 上,这样任务异常后可以通过持久化的 checkpoint 恢复。
在 k8s 上为 Flink 配置持久化存储,除了 HDFS 还有什么更简单的方案?
可以直接使用云上的弹性分布式文件系统,比如阿里云 NAS、AWS EFS,这些文件系统可以通过 NFS 协议挂载到 Pod 中,使用起来像读写本地文件一样方便。
flink-conf.yaml 中需要配置哪些关键项来实现高可用和 checkpoint 存储?
需要配置 state.backend: rocksdb、state.checkpoint-storage: filesystem、state.checkpoints.dir、state.savepoints.dir、state.backend.incremental: true、kubernetes.cluster-id、high-availability: org.apache.flink.kubernetes.highavailability.KubernetesHaServicesFactory 以及 high-availability.storageDir。
如何解决 Flink 任务没有权限写 NAS 目录的问题?
可以通过 Init 容器在应用容器启动前执行 chown -R 9999:9999 /nas/flink 命令,将 NAS 目录的所有者改为 flink 用户(ID 9999),从而让 flink 任务有权限读写。
Job Manager 和 Task Manager 的 NAS 挂载路径不一致会导致什么问题?
会导致 checkpoint 文件存储到不同的目录中,即使设置了 state.checkpoints.num-retained,Flink 也无法自动清理多余的 checkpoint 文件,最终导致 checkpoint 文件堆积、占满磁盘空间。
Flink 任务启动时报错“Mkdirs failed to create file:/nas/flink/recovery/default”是什么原因?
根本原因是 flink 任务进程没有权限写 /nas/flink/recovery/default 目录,因为 NAS 目录默认所有者是 root,而 flink 任务以 ID 9999 的用户运行,需要通过 Init 容器修改目录权限。