python创建虚拟环境venv,python venv 部署

  python创建虚拟环境venv,python venv 部署

  主要介绍了Pythonvenv虚拟环境跨设备迁移的实现,通过示例代码进行了非常详细的介绍,对大家的学习或工作有一定的参考价值。有需要的朋友下面跟边肖学习。

  00-1010后台python加载lib库的顺序。详细操作。打包相关的glibc库迁移包,并在目标Centos 6系统上执行。我们希望扩展一些第三方扩展包,并重新定位新添加的第三方库,如flask、requests和psutil。结束!

  

目录

  我们通常会遇到这样的情况,我们想方便地将一台设备的python开发环境迁移到另一台设备上,但是可能我们另一台设备本身的python环境,包括系统环境,是不可控的。我在这里遇到的是将python开发环境从centos7迁移到centos6。Centos7自带的python环境是2.7.5版本,一些依赖的文件库也适配了2.7.5及以上版本,导致我们把环境迁移到centos6默认的python2.6.6环境时会出现很多错误。下面的文档记录了我遇到的错误和解决方法,提供了一个轻松解决环境迁移问题的完美方法。

  

背景

  环境

  制作python虚拟环境设备:

  版本:centos 7python版本:python2.7.5迁移的目标设备:

  系统:centos 6python版本:python2.6.6

  

python加载lib库的顺序

  安装虚拟

  [centos 7] # pip安装virtualenv

  创建python venv环境

  [centos 7]# mkdir-p/opt/python _ venv _ test

  [centos 7]# virtualenv-p/usr/bin/python 2.7-copies/opt/python _ venv _ test

  参数- copies的意思是尽量不要为/opt/python_venv_test的文件创建软链接。如果不指定这个参数,我们可以看到/opt/python_venv_test目录下的一些文件是这样的:

  [centos 7]# ll/opt/python _ venv _ test/lib 64/python 2.7/*

  lrwxrwxrwx 1 root root 32 Apr 26 20:24/opt/python _ venv _ test/lib 64/python 2.7/lib-dyn load-/usr/lib 64/python 2.7/lib-dyn load

  lrwxrwxrwx 1 root root 26 Apr 26 20:24/opt/python _ venv _ test/lib 64/python 2.7/OS . py-/usr/lib 64/python 2.7/OS . py

  lrwxrwxrwx 1 root root 27 Apr 26 20:24/opt/python _ venv _ test/lib 64/python 2.7/OS . pyc-/usr/lib 64/python 2.7/OS . pyc

  -rw-r-r-1 root root 6978 Apr 26 20:24/opt/python _ venv _ test/lib 64/python 2.7/site . py

  /opt/python _ venv _ test/lib 64/python 2.7/config :

  总计0

  lrwxrwxrwx 1 root root 36 Apr 26 20:24 Makefile-/usr/lib 64/python 2.7/config/Makefile

  /opt/python _ venv _ test/lib 64/python 2.7/site-packages 3360

  总计0

  您可以看到,在原始python环境中,许多文件直接软链接到lib库中的文件。如果我们此时将它们打包并移植到另一个设备上,所有这些文件都将被清空,因此我们必须添加参数- copies。添加- copies参数后,看起来像这样:

  [c

  entos 7] # ll -d /opt/python_venv_test/lib64/python2.7/*

  drwxr-xr-x 2 root root 4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/config

  drwxr-xr-x 2 root root 4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/lib-dynload

  -rw-r--r-- 1 root root 25769 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/os.py

  -rw-r--r-- 1 root root 25557 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/os.pyc

  drwxr-xr-x 2 root root 4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/site-packages

  -rw-r--r-- 1 root root 6978 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/site.py

  可以看到没有软链接了,那么我们这个环境就是完全独立的,这时候我们的python venv环境就已经生成了。

  

  

打包依赖的glibc库

  我们的python环境为python2.7.5版本,比较推荐的是使用glibc-2.17版本,下载地址为:glibc下载地址 ,里面有各个版本的glibc文件。

  为什么这里要打包依赖的glibc库呢?

  我把虚拟环境目录移植到目标的centos6机器上测试了一下,如果上面的这些库文件在新的设备上没有,那么就会报错,这里我遇到的报错就是:

  

/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

  ./bin/python: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /usr/lib64/libpython2.7.so.1.0)

  

  这两个报错都是很有可能会命中的,提示我们缺少库文件,没有办法运行python binary。

  那么到底缺少哪些库文件呢?我们可以通过readelf -d /opt/python_venv_test/bin/python 命令检查python binary的依赖文件:

  

[centos 7] # readelf -d /opt/python_venv_test/bin/python

  Dynamic section at offset 0xdd8 contains 29 entries:

    Tag        Type                         Name/Value

   0x0000000000000001 (NEEDED)             Shared library: [libpython2.7.so.1.0]

   0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]

   0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]

   0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]

   0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]

   0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

   0x000000000000000c (INIT)               0x4005e0

   0x000000000000000d (FINI)               0x4007a4

   0x0000000000000019 (INIT_ARRAY)         0x600dc0

   0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)

   0x000000000000001a (FINI_ARRAY)         0x600dc8

   0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)

   0x000000006ffffef5 (GNU_HASH)           0x400298

   0x0000000000000005 (STRTAB)             0x400478

   0x0000000000000006 (SYMTAB)             0x4002f8

   0x000000000000000a (STRSZ)              218 (bytes)

   0x000000000000000b (SYMENT)             24 (bytes)

   0x0000000000000015 (DEBUG)              0x0

   0x0000000000000003 (PLTGOT)             0x601000

   0x0000000000000002 (PLTRELSZ)           48 (bytes)

   0x0000000000000014 (PLTREL)             RELA

   0x0000000000000017 (JMPREL)             0x4005b0

   0x0000000000000007 (RELA)               0x400598

   0x0000000000000008 (RELASZ)             24 (bytes)

   0x0000000000000009 (RELAENT)            24 (bytes)

   0x000000006ffffffe (VERNEED)            0x400578

   0x000000006fffffff (VERNEEDNUM)         1

   0x000000006ffffff0 (VERSYM)             0x400552

   0x0000000000000000 (NULL)               0x0

  我们可以在两台机器上查看一下到底有没有库文件,以及库文件产出自哪个rpm包:

  目标 centos 6机器没有找到libpython2.7.so.1.0库文件, 而/lib64/libc.so.6文件版本较低,没有达到glibc-2.14版本:

  

[centos 6] #  whereis libpython2.7.so.1.0

  libpython2.7.so.1:

  [centos 6] # whereis /lib64/libc.so.6

  libc.so: /lib/libc.so.6 /lib64/libc.so.6 /usr/lib64/libc.so

  [centos 6] # rpm -qf /lib64/libc.so.6

  glibc-2.12-1.80.el6.x86_64

  我们回到centos 7机器看看,可以看到有libpython2.7.so.1.0这个文件,而且/usr/lib64/libc.so.6的版本也大于glibc-2.14版本。

  

[centos 7] # whereis libpython2.7.so.1.0

  libpython2.7.so.1: /usr/lib64/libpython2.7.so.1.0

  [centos 7] #  rpm -qf /usr/lib64/libpython2.7.so.1.0

  python-libs-2.7.5-68.el7.x86_64

  [centos 7] #  whereis /lib64/libc.so.6

  libc.so: /usr/lib/libc.so.6 /usr/lib64/libc.so /usr/lib64/libc.so.6

  [centos 7] #  rpm -qf /usr/lib64/libc.so.6

  glibc-devel-2.17-260.el7_6.3.x86_64

  好了, 我们回归正题,我们现在要解决上面这些问题。

  首先,在centos 7机器上,下载及安装glibc-2.17:

  

[centos 7] # wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.xz -O /tmp/

  [centos 7] # cd /tmp/; tar xf glibc-2.17.tar.xz; cd /tmp/glibc-2.17

  [centos 7] # mkdir build; cd build

  [centos 7] # ../configure --prefix=/opt/python_venv_test/glibc-217

  [centos 7] # make -j4

  [centos 7] # make install

  以上操作完成后,我们就可以在/opt/python_venv_test/glibc-217目录下看到glibc-2.17的所有文件都在里面了。然后我们把发现的不属于glibc但又需要的库文件libpython2.7.so.1.0移植进来glibc-2.17的lib目录里:

  

[centos 7] # cp -ar /usr/lib64/libpython2.7.so.1.0 /opt/python_venv_test/glibc-217/lib/

  除了glibc这个基础库,还需要python本身的基础库,是运行binary python时需要加载的模块,比如os等,这个库一般是在系统的/usr/lib64/python2.7/目录,我们把它移植到我们的虚拟环境目录下(这个地方如果我们本地的/usr/lib64/python2.7 过大,可以考虑起一个可运行干净的python环境centos 7虚拟机,把它的/usr/lib64/python2.7拷贝过来,这样就能保证它是最小的包量):

  

[centos 7] # rm -rf /opt/python_venv_test/lib64/python2.7

  [centos 7] # cp -ar /usr/lib64/python2.7 /opt/python_venv_test/lib64/python2.7

  如果上面这个操作你没有做,可能就会遇到这样的报错:

  

[centos 7] # ./bin/python
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site

  

  当你把$PYTHONHOME设置完成后,或者会遇到这样的报错(总之就是找不到基础库文件):

  

[centos 7] # ./bin/python
Traceback (most recent call last):
File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 190, in <module>
main()
File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 18, in main
rewrite_standard_library_sys_path()
File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 97, in rewrite_standard_library_sys_path
import os
ImportError: No module named os

  

  改写环境加载文件/opt/python_venv_test/pyvenv.cfg,这样我们就不需要依赖移植后目标centos 6系统本身的lib库了,以免造成版本冲突:

  

home = /opt/python_venv_test/

  implementation = CPython

  version_info = 2.7.5.final.0

  virtualenv = 20.13.0

  include-system-site-packages = false

  base-prefix = /opt/python_venv_test/

  base-exec-prefix = /usr

  base-executable = /opt/python_venv_test/bin/python

  我们还得改写一下/opt/python_venv_test/bin/activate 文件,这个文件是我们在移植后目标centos 6系统加载python虚拟环境的入口,我们在这里面加一条对LD_LIBRARY_PATH环境变量的局部重写(红色字体部分,第一条是为了退出环境变量时,下掉alias的绑定,第二条是开始加载activate环境时对LD_LIBRARY_PATH环境变量的局部重写):·

  

··········

  deactivate () {

      unalias python >/dev/null 2>&1

      unset -f pydoc >/dev/null 2>&1 true

  ·············

  # Make sure to unalias pydoc if its already there

  alias pydoc 2>/dev/null >/dev/null && unalias pydoc true

  alias python="${VIRTUAL_ENV}/glibc-217/lib/ld-2.17.so --library-path ${VIRTUAL_ENV}/glibc-217/lib:/lib64 ${VIRTUAL_ENV}/bin/python"

  ·················

  然后,我们就可以打包了:

  

[centos 7] # cd /opt/

  [centos 7] # tar -czf python_venv_test.tar.gz python_venv_test

  

  

移植包到目标Centos 6系统上执行

  首先在centos 7 系统上我们scp压缩包到目标机器

  

[centos 7] # cd /opt/

  [centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

  然后我们在centos 6上解压压缩包:

  

[centos 6] # cd /opt/

  [centos 6] # tar xf python_venv_test.tar.gz

  这时候就可以虚拟环境目录运行python了

  

[centos 6] # cd /opt/python_venv_test

  [centos 6] # souce bin/bin/activate

  [centos 6] # python

  Python 2.7.5 (default, Apr 11 2018, 07:36:10)

  [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

  Type "help", "copyright", "credits" or "license" for more information.

  >>>

  

  

我们要扩充一些第三方扩展包

  回到centos7机器

  

  

搬迁新增的flask、requests、psutil等第三方库

  我们还是先回到我们的虚拟环境目录/opt/python_venv_test下面,先使用bin目录下的pip安装flask

  

# ./bin/pip install flask requests psutil

  打压缩包,并拷贝压缩包到centos 6目标系统上

  

cd /opt/

  tar -czf python_venv_test.tar.gz python_venv_test/

  [centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

  回到centos6 机器上,解压缩包,并运行python看看有没有什么问题

  

cd /opt/python_venv_test/

  # source bin/activate

  # python

  Python 2.7.5 (default, Apr 11 2018, 07:36:10)

  [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

  Type "help", "copyright", "credits" or "license" for more information.

  >>> import flask

  bash: /opt/bsc_python_venv/glibc-217/lib/libssl.so.10: No such file or directory

  报错显示缺少libssl.so.10文件,我们看看这个文件分别在两台测试机的哪里:

  centos 6机器情况:

  

# whereis libssl.so.10

  ld-2.17:

  centos 7机器情况,并且要确定的是它不是一个软链接:

  

# whereis libssl.so.10

  libssl.so: /usr/lib64/libssl.so.10 /usr/lib64/libssl.so

  # ll -d /usr/lib64/libssl.so.10

  lrwxrwxrwx 1 root root 16 Jan 21  2021 /usr/lib64/libssl.so.10 -> libssl.so.1.0.2k

  # ll -d /usr/lib64/libssl.so.1.0.2k

  -rwxr-xr-x 1 root root 470360 Mar 12  2019 /usr/lib64/libssl.so.1.0.2k

  我们再把centos7 的 /usr/lib64/libssl.so.1.0.2k 这个文件给放到虚拟环境glibc-217目录,然后做成压缩包,传到centos6机器上,再来试试

  

# cp -ar /usr/lib64/libssl.so.1.0.2k /opt/python_venv_test/glibc-217/lib/libssl.so.10

  # cd /opt/

  # tar -czf python_venv_test.tar.gz python_venv_test/

  [centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

  我们再在centos 6的机器上把原来的文件删除,解压缩,再试试import flask、requests、psutil这三个库文件,就不会再报刚才那个错了:

  

cd /opt/python_venv_test/

  # source bin/activate

  # python

  Python 2.7.5 (default, Apr 11 2018, 07:36:10)

  [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

  Type "help", "copyright", "credits" or "license" for more information.

  >>> import flask

  >>> import requests

  >>> import psutil

  

  

结束!

  本文设计的内容较多,如果有一些细节不太懂的地方,建议自行搜索,再回来反复查看本文档。

  到此这篇关于Python venv虚拟环境跨设备迁移的实现的文章就介绍到这了,更多相关Python venv迁移内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: