想让代码运行起来,首先需要干什么?配环境
程序依赖很多(Python库、linux包、C++库等)、版本又各不相同而且,可能面临开发在windows、部署在linux这种尴尬而且,你刚配好环境,boss又给你两台新机器,让你再配一遍 1、虚拟机
将程序和环境封装到虚拟机
用VMware,在windows系统下装个Ubuntu然后在Ubuntu里配好环境,保存快照以后就用此快照,在任意机器的VMware里还原环境
虚拟机好像挺美,But,面临很多问题
资源占用多虚拟机自己的启动就需要几百兆内存;虚拟机会独占一部分内存和硬盘空间,即便程序仅仅是个hello world; 冗余步骤多
虚拟机是完整的操作系统,系统级别的操作无法跳过,比如用户登录 启动慢
启动虚拟机,就像电脑开机,需要几分钟时间 2、Docker(简单版的虚拟机)
如logo所示,Docker就是一个集装箱,将程序及其环境打包在一起;
相比于虚拟机,docker容器是一种非常轻量的虚拟化技术;
一台主机运行成百上千个Docker容器是家常便饭;
Docker概念:
镜像(image):一个静态文件,里面保存了代码及其环境;容器(image):运行镜像,产生容器,容器里面就可以跑我们的程序;(多次运行同一个镜像产生多个容器,可用于多进程并发)仓库(registry):托管镜像文件的网站,
公开的 https://hub.docker.com/私有的 每个公司有自己的dockerhub 二、Docker标准工作流
编写Dockerfile文件,指定基础镜像、依赖安装、添加代码、服务启动命令等
# 声明基础镜像版本,选择pytorch官方镜像(执行容器或创建容器的时候会从hub.docker网站将镜像拉取下来)# 如果base镜像pull得很慢,可以更新国内的镜像源,比如:https://reg-mirror.qiniu.comFROM pytorch/pytorch:1.3-cuda10.1-cudnn7-runtime# 声明维护者MAINTAINER old-wei # 首先拷贝requirements.txt进dockerCOPY ./requirements.txt /requirements.txt# 安装python依赖(如果安装较慢,请更换国内pip源:-i https://pypi.douban.com/simple/)RUN pip install -r /requirements.txt# 将当前目录里的所有代码拷贝到目标docker容器对应的data/app目录COPY 、/data/app# 设置默认的工作目录WORKDIR /data/app# 设置系统编码为utf-8,防止中文乱码ENV LANG C.UTF-8# 设置暴露8000端口EXPOSE 8000# CMD(command命令)启动http服务,(也可以选择启动rpc服务,或者两个同时启动)CMD cd /data/app/scripts && sh start_http_server.sh
测试不利用缓存:将安装requirements.txt放到COPY 代码之后
# 声明基础镜像版本,选择pytorch官方镜像FROM pytorch/pytorch:1.3-cuda10.1-cudnn7-runtime# 声明维护者MAINTAINER old-wei # 将当前目录里的所有代码拷贝到目标docker容器对应的data/app目录COPY 、/data/app# 首先拷贝requirements.txt进dockerCOPY ./requirements.txt /requirements.txt# 安装python依赖(如果安装较慢,请更换国内pip源:-i https://pypi.douban.com/simple/)# RUN pip install -r /requirements.txt -i https://pypi.douban.com/simple/RUN pip install -r /requirements.txt# 设置默认的工作目录WORKDIR /data/app# 设置系统编码为utf-8,防止中文乱码ENV LANG C.UTF-8# 设置暴露8000端口EXPOSE 8000# CMD(command命令)启动http服务,(也可以选择启动rpc服务,或者两个同时启动)CMD cd /data/app/scripts && sh start_http_server.sh
1.2 编写build.sh基于Dockerfile,通过docker build命令构建镜像;
img_name=api-segment # 镜像名,即项目名img_tag=`date '+%Y%m%d_%H%M%S'` # 声明镜像tag为 日期+时间(实践中需要关联上git的commit-id)docker build -f Dockerfile -t ${img_name}:${img_tag} .
运行sh build.sh,构建镜像
1.3 上传自定义的docker镜像通过docker push,将镜像推到dockerhub;
1.4 手动docker run,测试服务hello路由docker run ****************************
默认执行Dockerfile文件中的CMD命令。
2、部署阶段 确保镜像已在本地,从远程pull镜像;
docker run命令,输入服务名、镜像名、端口映射、目录挂载、环境变量等;
待容器内服务启动成功,访问http接口
可以docker exec进入容器,排查问题;
可将容器当成一个简单版的虚拟机,执行各种linux命令;
3、使用经验 镜像是分层构建的,善于利用缓存,加快构建速度;当前层及以前,命令或内容不变,则利用缓存base镜像,推荐官方提供的基础镜像,方便、靠谱;比如pytorch或tensorflow官方的base镜像容器即服务,将容器就等同于服务:容器起来,服务起来;容器退出,服务退出容器是单进程模式,不推荐使用多进程;如需使用多进程并发,推荐起多个容器;容器无状态,重要的数据或模型要挂载出来,防止数据丢失 三、构建dev镜像dev镜像的主要目的是为了【跑测试】和【开发调试】
1、编写docker/Dockerfile.devFROM pytorch/pytorch:1.3-cuda10.1-cudnn7-runtimeMAINTAINER old-wang COPY ./requirements.txt /requirements.txtRUN pip install -r /requirements.txt# 安装ssh,用于远程debug(在本地运行服务器上的的python解释器,需借助ssh)# 实际工作中,本地环境一般不具备各种gpu硬件资源,无法运行gpu方面的程序。此时必须借助远程debug。RUN apt-get update --fix-missing && apt-get install --fix-missing -y openssh-serverRUN mkdir -p /var/run/sshdRUN echo 'root:root' | chpasswdRUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_configRUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_configRUN sed 's@sessions*requireds*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshdENV NOTVISIBLE "in users profile"RUN echo "export VISIBLE=now" >> /etc/profileCOPY 、/data/appWORKDIR /data/appENV LANG C.UTF-8EXPOSE 8000CMD cd /data/app/ && python tests/unit_tests/env/run_unit_tests.py
2、构建测试镜像build_dev.sh
img_name=api-segment:devdocker build -f docker/Dockerfile.dev -t ${img_name} .
四、Docker总结 Docker就是一个集装箱,将程序及其环境打包在一起;相比于虚拟机,docker容器是非常轻量,一台主机运行成百上千个容器是家常便饭;镜像:保存代码及其环境的文件;容器:运行镜像,产生容器,容器里跑我们的程序;仓库:托管镜像文件的网站;熟练掌握docker run、docker exec、docker build等基本命令