RHEL7系统使用cpanm安装Perl模块报错找不到模块求助
RHEL7环境下迁移Docker部署的Perl项目故障排查方案
问题概述
- 需将原Docker容器化部署的Perl项目改造为物理机/虚拟机直接运行模式,原容器基于Ubuntu 20.04(focal)构建,当前部署环境为RHEL7
- 已尝试按原Dockerfile中Ubuntu的包名安装基础依赖,执行cpanm安装Perl模块时失败,典型报错如下:
[root@npcrver01 home]# cpanm Log::Log4perl ! Finding Log::Log4perl on cpanmetadb failed. ! cannot open file '/root/.cpanm/sources/http%www.cpan.org/02packages.details.txt.gz': No such file or directory opening compressed index ! Couldn't find module or a distribution Log::Log4perl ()
- 原项目Dockerfile逻辑如下:
FROM ubuntu:focal-20200703 as ubuntu FROM ubuntu as mytool ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y -qq build-essential libssl-dev tzdata bash curl wget perl cpanminus libcrypt-ssleay-perl libnet-ssleay-perl RUN cpanm -n Data::Printer \ Log::Log4perl \ List::Util \ Test::More \ JSON \ JSON::XS \ YAML \ YAML::XS \ GitLab::API::v4 \ IO::Socket::SSL \ HTML::HashTable \ REST::Client \ MIME::Base64 \ File::Spec \ File::Basename \ File::Path \ List::MoreUtils \ DateTime::Format::ISO8601 \ Digest::MD5 ENV TZ=Pacific/Auckland RUN echo $TZ > /etc/timezone && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime COPY docker/context/usr/local/bin/entrypoint.sh /usr/local/bin/entrypoint.sh COPY docker/context/usr/local/etc/mytool/mytool.env.ctmpl /usr/local/etc/mytool/mytool.env.ctmpl RUN mkdir -p /usr/local/bin /usr/local/bin/cache.d WORKDIR /usr/local/bin COPY mytool /usr/local/bin/ COPY lib/ /usr/local/bin/lib # Container pilot obligatory parameters START ENV SERVICE_NAME=mytool ENV SERVICE_PRE_EXEC=/bin/true ENV SERVICE_HEALTHCHECK_EXEC="test -f /usr/local/etc/mytool/mytool.env" ENV SERVICE_TEMPLATE_CONFIG_PAIRS=/usr/local/etc/mytool/mytool.env.ctmpl:/usr/local/etc/mytool/mytool.env EXPOSE 8080 ENTRYPOINT [""] CMD ["/usr/local/bin/entrypoint.sh"] # Container pilot obligatory parameters END
故障根因
- 两个发行版包命名规则完全不同,直接照搬Ubuntu的apt包名安装,会缺失大量编译Perl模块必需的系统依赖
- 默认cpanm配置使用海外CPAN源,受网络策略、防火墙限制无法拉取索引文件,且本地已生成损坏的缓存文件
- RHEL7默认源不带cpanminus包,手动安装的cpanm版本可能存在兼容问题
修复步骤
- 安装RHEL7适配的系统依赖
不要使用Ubuntu的包名,执行以下命令安装所有系统级依赖:# 安装编译工具链(对应Ubuntu的build-essential) yum groupinstall -y "Development Tools" # 安装EPEL扩展源获取cpanminus包 yum install -y epel-release # 安装所有编译、运行必需的系统包 yum install -y openssl-devel perl-devel perl-CPAN zlib-devel wget curl tzdata bash perl-App-cpanminus - 清理损坏缓存,重新安装Perl模块
先删除旧的损坏cpanm缓存,指定可正常访问的CPAN镜像安装模块:# 清理旧缓存 rm -rf /root/.cpanm # 批量安装所有需要的Perl模块 cpanm --mirror https://mirrors.aliyun.com/CPAN/ -n Data::Printer \ Log::Log4perl \ List::Util \ Test::More \ JSON \ JSON::XS \ YAML \ YAML::XS \ GitLab::API::v4 \ IO::Socket::SSL \ HTML::HashTable \ REST::Client \ MIME::Base64 \ File::Spec \ File::Basename \ File::Path \ List::MoreUtils \ DateTime::Format::ISO8601 \ Digest::MD5 - 对齐容器内的目录与配置
按照Dockerfile的路径映射规则,在服务器上创建对应目录、放置项目文件:# 创建所需目录 mkdir -p /usr/local/bin/cache.d /usr/local/etc/mytool # 按原Dockerfile的COPY路径放置对应文件 # 把entrypoint.sh放到/usr/local/bin/,加执行权限 chmod +x /usr/local/bin/entrypoint.sh # 把mytool.env.ctmpl放到/usr/local/etc/mytool/ # 把主程序mytool放到/usr/local/bin/ # 把项目lib目录放到/usr/local/bin/下 # 配置时区 timedatectl set-timezone Pacific/Auckland - 运行验证
直接执行/usr/local/bin/entrypoint.sh启动脚本,无模块缺失、路径报错即为正常。原Dockerfile里的Container pilot相关配置是容器环境专用,物理机运行不需要部署,只要保证脚本运行时能正常生成/usr/local/etc/mytool/mytool.env配置文件即可,后续可自行配置systemd服务实现开机自启。
内容的提问来源于stack exchange,提问作者usert4jju7
相关产品推荐
相关产品推荐

