社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

生信猿的docker入门课2

生信媛 • 4 年前 • 514 次点击  

背景

小师妹突然找到我,问我是否知道怎么做singularity或者docker镜像。细问之下了解到,她的文章在投,因为涉及她自己写的一个工具以及数据分析,编辑要求她提供镜像。原因在上一篇推文其实提到过,总的来说,只提供分析源码和数据本身并不能保证分析的可重复性。因为还有依赖的库以及软件版本改变带来的隐忧。

也许,容器技术在生信领域已经成为其中一种标准了。

这篇推文主要介绍一下2种生成docker镜像的方法。

镜像封装

打包镜像的方法有2种:

  1. 以某个基础镜像,比如centos7,为基础,运行docker容器,在容器内将所有需要安装的安装完毕后,以该容器为基础生成一个新的镜像。
  2. 使用dockerfile生成镜像。

我自己的习惯是,先在容器内将需要安装的软件安装一遍,测试所需要安装的工具怎么装,以及是否有需要额外安装的依赖包等等,然后写成Dockerfile再生成新镜像。

对于需要安装的软件包,我们可以直接下载到本地,再使用某些方式放到容器内(后边会细说),也可以联网下载。

方式1:基于容器

先获取1个基础镜像并启动为容器。

docker run -it --name sxydemo --hostname sxy -v $PWD:/docker centos:7
  • docker run 其实本质上是docker pull(拉取镜像)+ docker start(启动容器)。拉取镜像是从Docker-Hub上。镜像相关信息也可以从上边获取。

  • -it,其实是-i 和 -t 的组合,一般一起使用,就是开启了一个伪终端,让你可以在终端输入命令进行交互

    Name, shorthandDefaultDescription
    --interactive , -i
    Keep STDIN open even if not attached
    --tty , -t
    Allocate a pseudo-TTY
  • -v 挂载卷。这里我的当前路径就是放了很多需要安装软件的路径。在容器中,对应该卷路径为根目录下的docker目录。

  • --name 给容器命名,可选。这个参数不加对我们后续没有影响

  • --hostname 加了以后,容器内部的hostname就设定为你指定的这个,不加则为容器id。这个参数不加对我们后续没有影响

docker run后我们就进入了容器了。我们来看看挂载的情况:



docker目录下的东西跟我们本地的被挂载路径的东西是一模一样的。因为本质上,这俩就是同一个卷。通过这种方式,你在容器内分析的数据就可以存储到服务器上了。

你可以自己尝试在容器内创建一个空文件,在容器外部也会看到的。

因为我们拉取的是一个linux系统的基础镜像,因此在进入容器以后,我们就跟在一个linux的终端上体验没区别了。安装软件也完全一样的。并且原先你习惯用conda来安装软件,在docker内也是一样一样的。

来装2个软件试试。下载安装的方式以perl为例。使用已经下载好的安装包进行安装则以samtools为例。但其实二者没什么太大区别,完全使用前一种方法的话,无需挂载路径。而后者需要将能访问到软件包的路径挂载到容器内(注意,可以是软件包所在路径,也可以是其上级目录)。仅此而已。

perl

  • perl5.16.3源码地址:https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2

在正式开始之前,先装几个要用到的软件。

  • perl的源码是bz2压缩格式,需要bzip2
  • perl的编译需要gcc和make(或者gmake)
yum -y install bzip2 gcc make less

在这个镜像里面没有预装wget,我们用curl来下载。

mkdir /src && cd /src
curl -OL https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2
tar -jxvf perl-5.16.3.tar.bz2
cd perl-5.16.3
# -d use defaults for all answers.否则一项项地确认好麻烦。
./Configure -d 
make
make install


plink

解压zip需要unzip工具:

yum install -y unzip

为了避免出现读写权限问题,将/docker下的plink拷贝到/src下再进行后续操作.

cp /docker/plink_linux_x86_64.zip /src
unzip plink_linux_x86_64.zip -d ./plink
ls plink
# LICENSE  plink  prettify  toy.map  toy.ped

因为这里只有2个可执行文件,我将plink和prettify直接拷贝到其中一个PATH路径下。

查看:

echo $PATH        
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

拷贝:

cp ./plink/{plink,prettify} /usr/local/bin

其他的软件安装方法都是跟linux下一样的(因为是基于centos7镜像),不再赘述了。

将容器打包成镜像:

docker commit sxydemo sxydemo:20201126

sxydemo是docker的名称,你也可以用容器id。二者是一样的。




    
docker images|head -2


我们使用新打包好的镜像生成容器,然后简单验证一下:

docker run -it --rm -u $(id -u):$(id -g) sxydemo:20201126

另外,我们挂载的容器内路径还在,但是内容是空的(因为我们这次没挂载了)。而拷贝到容器内的目录下的文件还会在。为了使得我们最后打包的镜像体积小一点,其实在安装后无用的文件我们都应该清除。

另外,我们可以看到,这次因为我使用了-u命令进入容器,因此此时,对于docker容器内部,我是一个普通的用户身份。

--rm:当我退出容器的时候,便将容器销毁。这个命令在我们频繁使用docker进行数据分析的时候很有必要加上。

方式2:基于dockerfile

将上述过程,整理成dockerfile的形式,打包镜像。

FROM centos:7
ADD . /src
RUN yum install -y bzip2 gcc less unzip
RUN cd /src && curl -OL https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2 && \
  tar -jxvf perl-5.16.3.tar.bz2 && \
  cd perl-5.16.3 && \
  ./Configure -d -e && \
  make && make install && \
  rm -rf /src/perl-5.16.3*

RUN cd /src && unzip plink_linux_x86_64.zip -d ./plink && \
  cp ./plink/{plink,prettify} /usr/local/bin && \
  rm -rf /src/plink*

CMD ["/bin/bash"]

将上述文件名字命名为Dockerfiledocker build的时候会自动去找指定路径下的这个名称的文件,然后根据描述去构建镜像。你也可以更改名字,只要在docker build的时候用--file或者-f指定一下就好了。

docker build -t sxydemo:20201126 .

这里多说一句,为什么两次RUN我都需要cd /src,上一次进入这个路径以后,不是应该就在这个路径下了吗?但是对于Dockerfile打包镜像的时候,每一行命令都是基于上一个打包好的基础上作为一个新的docker启动的,因此每次都是回到某个设定好的最初进入的路径(比如你在linux下每次登陆进去都是进入你的home目录),可以使用WORKDIR进行设置进入docker后的路径是哪里。

另外,Docker镜像是一层一层的,容器只是在镜像最上边加了一层读写层。而每一层需要删除的东西得在这一层进行删除(比如第2个和第3个RUN命令),在下一层删除是没有意义的,它其实仍然存在,只是对你不可见了而已,这样镜像打包后大小并不会改变。

同样,打包完自行检查一下软件等是不是都正确能使用了。

docker run -it --rm -u $(id -u):$(id -g) sxydemo:20201126

如果需要将这个镜像分享给别人,可以使用下边命令打包成tar文件:




    
docker save -o /YOUR/PATH/docker_tar/sxydemo_20201126.tar sxydemo:20201126

参考资料

  • docker命令行使用文档
  • Dockerfile reference


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/99573
 
514 次点击