背景
最近开发用到了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-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脚本的
从异常分析是应用在启动的时候,对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,多思考找解决办法。