Jenkins自动化执行时无法向现有目录结构写入文件如何解决?
问题原因与解决方案
最常见原因:目标目录是Docker Volume挂载点
官方JMeter镜像默认会把/opt/apache-jmeter-*/lib目录声明为匿名VOLUME,Dockerfile构建阶段写入VOLUME目录的所有操作都会被丢弃,只有容器运行时的写入才会持久化。你在Dockerfile里执行的解压、mv/cp操作都是构建阶段执行的,所以看起来执行成功实际文件根本没写进去,这正好符合你能创建子目录但实际写入文件不生效的表现。
解决方法:
- 不要在Dockerfile里直接往VOLUME目录写文件,改成把jar包放到其他目录,再用ENTRYPOINT脚本在容器启动时复制到lib目录
- 自定义构建镜像时先取消VOLUME声明,写入完成后再按需声明VOLUME
第二个可能:目录被设置了不可变属性
root用户也无法直接写入设置了i(不可变)属性的目录,ls -l命令不会显示该属性,需要执行:
lsattr /opt/$JMETER_VERSION/lib
如果输出里有i标记,执行以下命令解除后再操作:
chattr -i /opt/$JMETER_VERSION/lib
第三个可能:强制访问控制规则限制
如果你的Docker宿主机开启了SELinux或者AppArmor,即使目录权限、用户都正确,也可能拦截容器内root的写入操作:
- SELinux环境下可以在挂载目录时加
z/Z参数,或者临时关闭SELinux测试 - AppArmor环境下可以给容器加
--security-opt apparmor=unconfined参数测试
第四个可能:tar命令参数/源文件路径错误
你可以先把tar包解压到/tmp目录,再手动cp到目标目录看报错信息,替换原有tar命令为以下逻辑排查具体错误:
# 先解压到临时目录 mkdir -p /tmp/mysql-connector tar -xzvf /tmp/mysql-connector.tar.gz -C /tmp/mysql-connector # 手动复制并打印报错 cp -v /tmp/mysql-connector/mysql-connector-java-6.0.3/mysql-connector-java-6.0.3-bin.jar /opt/$JMETER_VERSION/lib/ # 执行后查看目标目录是否存在文件 ls -l /opt/$JMETER_VERSION/lib/ | grep mysql
内容的提问来源于stack exchange,提问作者Ray D
相关产品推荐
相关产品推荐

