docker启动flink报没有权限

1,310 阅读3分钟

背景

最近开发用到了flink要从x86环境迁移到国产麒麟ARM64,因为是离线环境下载依赖包不方便,因此就考虑整个环境都用docker镜像来做。

安装

按照网上的,在hub.docker.com 下载ARM架构flink镜像,我下载的是java8,然后编写docker-compose.yaml配置

version: "2.1"
services:
  jobmanager:
    image: flink
    expose:
      - "6123"
    ports:
      - "8081:8081"  # 暴露访问端口
    command: jobmanager  # 启动jobmanager服务
    environment:
      - JOB_MANAGER_RPC_ADDRESS=jobmanager
  taskmanager:
    image: flink
    expose:
      - "6121"
      - "6122"
    depends_on:
      - jobmanager
    command: taskmanager  # 启动taskmanager服务
    links:
      - "jobmanager:jobmanager"
    environment:
      - JOB_MANAGER_RPC_ADDRESS=jobmanager

熟悉docker-compose的可以自己修改配置,当然也可以使用docker run来创建容器,并设置相关环境变量,然后满怀期待的运行了 docker-compose up -d 访问 http://ip:881 果不其然没那么顺利 [因为是内网环境只能拍照]

docker_flink_error.jpg

错误示范

说下我的解决思路 查看报错 docker-compose up 不加-d,直接输出,或者也可以后台启动,用docker logs --tail="400" 容器ID 来查看容器启动最后的日志。

刚开始我以为是libjemalloc.so的问题,因为我环境是ARM64的,而这个包看路径在x86下面。于是我以为是环境问题,就条件反射的找包,装包,找了半天发现,我在其它环境都能启动,说明不是包的问题,果不其然在这个问题后面有个 ignore 。也就是说这个不影响,启动,这是个警告信息。

好吧那就来继续看报错问题,提示不能加载/opt/flink/conf/flink-conf.yaml 文件 Permission denied,我第一反应就是权限不够,用户权限,docker权限,docker-compose,docker-socket权限等等以前遇到过的,最后检查了一遍,我是root,什么权限都是最高的,docker这些都是预装的都是有权限的。那肯定不是这个问题了。

查了半天,那我想的就把这个flink-conf.yaml文件,通过docker -v 或者docker-compose的 volumes 给挂载出来,结果神搓搓的,jobmanager和taskmanager挂载到了同一个目录,导致文件被占用还是启动不起来,就以为不是权限问题,就各种百度,google,发现都没有出现这个问题。最后回归本质。

最终解决办法

docker镜像中容器启动会执行docker-entrypoint.sh脚本,使用 docker inspect 可查看,有的镜像是自定义入口sh脚本的

docker-flink-inspect.png 从异常分析是应用在启动的时候,对flink-conf.yaml没有读取权限,那么我们在外部环境权限一切ok的情况下,只有内部解决了,因此我们可以在入口sh脚本,进行赋权限。 创建容器启动失败后,容器还是创建了,因此我们可以通过docker cp将 docker-entrypoint.sh 复制出来 docker cp 容器id:/docker-entrypoint.sh docker-entrypoint.sh 最后在docker-entrypoint.sh入口加入赋权的代码 chmod +x ${FLINK_HOME}/bin/*.sh。最后再通过 docker cp docker-entrypoint.sh 容器id:/docker-entrypoint.sh 覆盖掉容器的docker-entrypoint.sh,然后docker start 容器,启动,发现启动正常。

总结

这个问题网上没有查到相关出现的场景,我觉得应该是跟环境相关,因为我在其它环境下装都没出现过,因此想要记录下来。再一次证明了遇到问题不要急躁,太依赖百度、google,多思考找解决办法。