升级Flink-1.4.0至1.4.2后遇HDFS写入权限问题
结合你的环境(Flink 1.4.2、Hadoop 2.6.0-cdh5.13.0无安全机制、Ubuntu 16.04、Java 8)和报错信息,我之前处理过类似的升级后权限问题,大概率是Flink 1.4.2在Hadoop客户端集成的用户上下文逻辑上做了调整,下面是一步步的排查和解决思路:
1. 先验证基础权限是否真的存在问题
首先排除HDFS本身的权限配置问题,用运行Flink的用户xng在任意集群节点执行以下命令:
hadoop fs -mkdir -p /你的目标写入路径 hadoop fs -touchz /你的目标写入路径/test.txt
- 如果命令失败:说明HDFS路径确实没有给
xng用户写入权限,直接调整路径权限即可(比如hadoop fs -chmod 775 /目标路径或者把xng加入对应用户组)。 - 如果命令成功:问题出在Flink的运行上下文和Hadoop客户端的交互上,继续往下排查。
2. 检查Flink的Hadoop依赖适配
Flink 1.4.2对Hadoop客户端的依赖细节和1.4.0有差异,即使你用的是CDH版本的Hadoop,也要确认Flink的依赖包是否匹配:
- 查看Flink安装目录下的
lib文件夹,检查flink-shaded-hadoop-2相关jar包的版本是否和你的CDH5.13.0兼容。如果不匹配,建议替换成你集群的Hadoop客户端jar包(需要替换hadoop-common.jar、hadoop-hdfs.jar等核心依赖,注意要删除原有冲突的jar包)。 - 确保Flink能读取到集群的Hadoop配置:在
flink-conf.yaml中添加env.hadoop.conf.dir: /你的Hadoop配置目录路径,让Flink加载集群的hdfs-site.xml和core-site.xml。
3. 确认Flink的用户上下文一致性
虽然Hadoop没开启安全,但Flink 1.4.2修改了UserGroupInformation的初始化逻辑,可能导致提交任务的用户和TaskManager运行时的用户上下文不一致:
- 检查TaskManager的启动用户:查看TaskManager的日志开头,确认是否是
xng用户启动的。如果是其他用户(比如默认的flink用户),需要调整TaskManager的启动脚本,用xng用户启动。 - 在
flink-conf.yaml中添加配置:security.kerberos.login.contexts: Client,KafkaClient,即使没开Kerberos,这个配置会强制Flink保持用户上下文的传递,避免TaskManager用其他用户身份访问HDFS。
4. 调整任务中的HDFS写入代码
如果你在任务中直接使用Hadoop原生API操作HDFS(比如FileSystem.get(new Configuration())),建议换成Flink提供的文件系统API:
import org.apache.flink.core.fs.FileSystem; import org.apache.flink.core.fs.Path; // 获取Flink的FileSystem实例,自动继承当前任务的用户上下文 FileSystem fs = FileSystem.get(new Path("/目标路径").toUri()); // 后续写入操作使用这个fs实例
Flink的FileSystem会自动处理用户上下文的传递,避免原生API可能导致的权限上下文丢失问题。
补充:报错信息参考
你遇到的核心报错应该是类似这样的:
WARN org.apache.hadoop.security.UserGroupInformation: PriviledgedActionException as:xng (auth:SIMPLE) cause:org.apache.hadoop.security.AccessControlException: Permission denied: user=xng, access=WRITE, inode="/target/path":hdfs:supergroup:drwxr-xr-x
这个报错说明TaskManager在尝试写入HDFS时,用的xng用户确实没有路径的写入权限,但如果手动验证权限没问题,那一定是上下文传递的问题。
内容的提问来源于stack exchange,提问作者Abareghi




