先描述一下场景,公司Jboss服务端的一个功能需使用salt方式调用一台centos7.3机器上面的python脚本,python版本为3.7,脚本执行完成会回调一个http接口反馈执行结果。在测试环境,我有linux机器的root权限,完成python安装以及依赖模块的安装,测试本地执行py脚本正常,jboss salt调用也正常。发布生产后发现调用发出后无回调,于是开始定位问题。
生产环境配置时,已经手动执行python脚本,确认脚本可正常执行。首先确认命令确实被发送到linux服务器上面了,监听/var/log/messages 日志,可以看到执行失败的salt调用内容:
其中有报错原因:salt-minion: ModuleNotFoundError: No module named 'openpyxl', 这就很奇怪,直接在机器上面执行,所有的依赖都是有的,为什么salt调用就失败呢?于是开始各种百度,发现这方面资料不少但是直接相关的不多,要么是解决python模块安装的方法,要么是salt stack调用python出现salt相关的包缺失的问题,无法解决我的问题。
跟同事沟通后,同事怀疑是linux机器上面不同用户pip安装模块的路径不同导致的,我在生产环境无root权限,这是跟测试环境最显著的区别。根据这个思路,我首先查询了一下pip3安装的模块存放的路径:
果然模块都存放在当前用户的私有路径下,同时当我想要sudo执行pip3安装时,发现系统提示命令不存在,并且执行python脚本出现了和messages日志中同样的报错信息:
$ sudo -H python3 static_analyzer.py
File "static_analyzer.py", line 7, i <module>
import openpyxl
ModuleNotFoundError: no module named 'openpyxl'
$ sudo -H pip3 install openpyxl -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com --user
sudo:pip3: command not found
这个思路靠谱,于是我又找了pip安装模块各个用户共享或者最起码让root用户可以共享的方法。根据命令不存在这个提示,发现一篇博文给出了简单的解决方法,即直接挂软连接让root用户可以找到python3 和 pip3:
#如下软连接是为了使命令在root用户下 也能正常使用
sudo ln -snf /usr/local/python3/bin/python3 /usr/bin/python3
sudo ln -snf /usr/local/python3/bin/pip3 /usr/bin/pip3
果然,软连接之后,sudo模式就可以正常使用python3和pip3命令:
sudo -H pip3 install openpyxl -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com --user
根据这个思路,我们使用sudo模式运行python脚本,验证一下,当前环境root用户是否能够正常执行:
sudo -H python3 python_script.py
结果完全正常。而如果未进行上述软连接,同样的命令,也会出现messages日志中出现的ModuleNotFoundError,那么到此为止,我们就顺利解决了pip3安装的模块root用户无法找到的问题。
最后的最后,通过jboss生产环境的服务页面提交请求,整个流程顺利完成,完美!
参考文献:
查看Linux下使用pip install 安装python模块的路径
解决pip3命令把安装包安装到home下的.local/lib/python3.5/dist-packages目录下的问题