当前位置: 首页 > news >正文

Docker迁移以及环境变量问题

问题一描述

将docker容器通过docker export命令打包,传输到另外的服务器,再通过docker import命令导入后,发现原来docker容器中的环境变量失效了。

解决方案

1. 【无效方案】直接在docker容器中通过export命令设置环境变量。

export LD_LIBRARY_PATH=/home/shared/TensorRT-8.2.4.2/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64

显然,export命令配置的环境变量只能临时生效,重新进入容器后环境变量失效。

2. 【无效方案】在docker容器的/etc/profile中配置环境变量。

a. 在docker容器中,在/etc/profile的末尾添加环境变量配置:

export LD_LIBRARY_PATH=/home/shared/TensorRT-8.2.4.2/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64

b. 然后执行环境变量刷新:

source /etc/profile

在/etc/profile中配置环境变量是令环境变量永久生效的通用做法,但对于docker,这一做法失败了,表现为,重新进入docker后,环境变量失效,并且重启docker容器同样无效。

3. 【有效方案】在docker容器的/root/.bashrc中配置环境变量。

在docker容器中,在/root/.bashrc的末尾添加环境变量配置:

export LD_LIBRARY_PATH=/home/shared/TensorRT-8.2.4.2/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64

重新进入容器,可以发现环境变量保持生效。

4. 【有效方案】该方案为方案2的改进版。

在docker容器的/etc/profile中配置环境变量,然后在/etc/bash.bashrc或/etc/bashrc中增加环境变量刷新命令。

a. 在docker容器中,在/etc/profile的末尾添加环境变量配置:

export LD_LIBRARY_PATH=/home/shared/TensorRT-8.2.4.2/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64

b. 在/etc/bash.bashrc或/etc/bashrc的文件末尾增加环境变量刷新命令:

source /etc/profile

问题二描述

将docker容器通过docker export命令打包,传输到另外的服务器,再通过docker import命令导入后,发现在docker容器外部无法执行docker容器中的命令,而原始的,export之前的docker,则不存在此问题。

例如:在docker容器中,可以正常执行python、ll等命令,但在dockers外部,则会出现command not found错误。

docker exec gpu21 /bin/bash -c"ll"

/bin/bash: ll: command not found

docker exec gpu21 /bin/bash -c "cd/home/server && ./start.sh"

/bin/bash: python: command not found

解决方案

1. 【有效方案】直接在docker容器中对应的脚步中通过export命令设置环境变量。

简单分析可以认为,在docker容器中,bash能够正常找到执行程序,而在docker外部,bash找不到执行程序,所以还是环境变量的PATH变量的问题,并且是PATH变量的值在容器中是正确的,而在容器外部调用bash执行命令时,PATH变量失效。

暂时能想到的解决方案是,直接在docker中需要执行的脚本里边再次设定环境变量。例如,对于以下执行需求:

docker exec gpu21 /bin/bash -c "cd/home/server && ./start.sh"

/bin/bash: python: command not found

我们可以直接进入容器,查看PATH变量的值:

echo $PATH

/root/anaconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

以及查看在容器外部执行时PATH变量的值:

docker exec gpu21 /bin/bash -c "echo$PATH"

/usr/local/cuda-11.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

可以发现两者并不一致,这也正是问题所在。我们可以改写start.sh脚本,在脚本的开始处添加设置环境变量的内容,使得在容器外部时PATH变量的值与docker容器内部一致。

在start.sh文件的开头处添加以下内容:

exportPATH=/root/anaconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

再次在容器外部执行start.sh,发现可以成功执行了:

docker exec gpu21 /bin/bash -c "cd/home/server && ./start.sh"

终极解决方案

在传递docker镜像时,请避免使用

docker export

命令;请改用

docker save

命令,已避免可能出现的环境变量问题。

两者区别在于:

docker export命令针对容器执行,对应的,导入命令为:

docker import

docker save命令针对镜像执行,对应的,导入命令为:

docker load

容器迁移步骤

以如下容器为例:

b379e350987d vsr_trt "/bin/bash" 6 weeks ago Up 6 weeks enhancefox

容器名称为enhancefox,其镜像为vsr_trt,迁移镜像的操作步骤如下:

1. 通过容器创建新的镜像。

如果容器在原镜像的基础之上有变更,需提交变更,创建一个新版本的镜像。

docker commit enhancefox vsr_trt:20230215

这里我们将容器enhancefox在通过原镜像vsr_trt创建之后可能产生的变更进行提交,创建版本号为20230215的新镜像。

2. 保存镜像。

docker save vsr_trt:20230215 > /home/vsr_trt_20230215_save.tar

3. 传递镜像和容器。

将保存的镜像传递至新的服务器,在新的服务器上执行:

scp -P 22 dancen@10.17.1.11:/home/vsr_trt_20230215_save.tar/home/vsr_trt_20230215_save.tar

打包容器相关文件等:

cd /mnt/data

tar -czvf enhancefox.tar enhancefox

scp -P 22 dancen@10.17.1.11:/mnt/data/enhancefox.tar/mnt/data/enhancefox.tar

4. 导入镜像并创建容器。

在新服务器上导入镜像:

docker load -i /home/vsr_trt_20230215_save.tar

解压容器相关文件等:

cd /mnt/data

tar -xvf enhancefox.tar

创建新容器:

docker run -itd --gpus all --ipc=host--network host -p 9501:9501 -v /mnt/data/enhancefox:/home/server -v/etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime --name enhancefoxvsr_trt:20230215

http://www.lryc.cn/news/7924.html

相关文章:

  • Sphinx文档生成工具(二)
  • Python快速上手系列--JSON--入门篇
  • axios中的GET POST PUT PATCH,发送请求时params和data的区别
  • hume项目k8s的改造
  • MACD红二波选股公式,选出MACD二次翻红的标的
  • mac上安装mysql
  • Django 模型继承问题
  • Vue3篇.01-简介及基本使用,项目创建方式, 模板语法, 事件监听, 修饰符
  • 别学英语了,真的
  • CRM系统五大技巧集成Excel为销售流程赋能
  • 交通部互通互联码的根证书规则
  • Map和Set(Java详解)
  • Vue 3的响应式机制
  • 30岁了,说几句大实话
  • AsyncTask使用及源码查看Android P
  • 花2个月面过华为测开岗,拿个30K不过分吧?
  • JAVA练习51-最大子数组和
  • Inception Transformer
  • 10分钟学会数据库压力测试,你敢信?
  • 论文阅读 | Video Super-Resolution Transformer
  • 7-6 带头节点的双向循环链表操作
  • npm publish 、 npm adduser 提示 403 的问题
  • Java 8的函数式接口使用示例
  • 2023年企业如何改善员工体验?为什么员工体验很重要?
  • 设计模式:桥接模式让抽象和实现解耦,各自独立变化
  • C++学习记录——십 STL初级认识、标准库string类
  • 【redis】redis缓存与数据库的一致性
  • XCP实战系列介绍12-基于Vector_Davinci工具的XCP配置介绍(一)
  • Unity Material详解
  • 碰撞检测算法分类