Docker使用笔记

作者: 井底蛙蛙呱呱呱 | 来源:发表于2018-09-05 14:36 被阅读53次

    Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

    Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

    总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

    一、安装

    详细安装过程可参照官网

    1.1 若以前有安装过旧版本,先移除旧版本:
    $ sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-selinux \
                      docker-engine-selinux \
                      docker-engine
    
    1.2 安装依赖
    $ sudo yum install -y yum-utils \
      device-mapper-persistent-data \
      lvm2
    $ sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    $ sudo yum-config-manager --enable docker-ce-edge
    $ sudo yum-config-manager --enable docker-ce-test
    
    1.3 安装免费版docker

    默认安装最新版docker

    $ sudo yum install docker-ce
    
    1.4 启动docker
    $ sudo systemctl start docker
    
    1.5 查看docker是否安装成功
    $ sudo docker run hello-world
    
    1.6 加入docker用户组

    Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组(官方文档)。

    $ sudo groupadd docker
    $ sudo usermod -aG docker $USER
    

    检查一下,不使用sudo来运行docker:

    [09:40 sxuan@hulab ~]$ docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    9db2ca6ccae0: Pull complete
    Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/engine/userguide/
    
    1.7 使用Docker 中国官方镜像加速

    通过 Docker 官方镜像加速,中国区用户能够快速访问最流行的 Docker 镜像。该镜像托管于中国大陆,本地用户现在将会享受到更快的下载速度和更强的稳定性,从而能够更敏捷地开发和交付 Docker 化应用。
    Docker 中国官方镜像加速可通过 registry.docker-cn.com 访问。该镜像库只包含流行的公有镜像。私有镜像仍需要从美国镜像库中拉取。

    您可以使用以下命令直接从该镜像加速地址进行拉取:

    $ docker pull registry.docker-cn.com/myname/myrepo:mytag
    # 如下例子:
    $ docker pull registry.docker-cn.com/library/ubuntu:16.04
    

    当然,更简单的方法是更改配置文件,一劳永逸。修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值:

    {
      "registry-mirrors": ["https://registry.docker-cn.com"]
    }
    
    1.8 设置docker开机启动
    # systemd
    $ sudo systemctl enable docker
    # upstart
    $ echo manual | sudo tee /etc/init/docker.override
    #chkconfig
    $ sudo chkconfig docker on
    

    二、使用Docker

    2.1 简单使用

    下面,我们通过最简单的 image 文件"hello world",感受一下 Docker。

    $ docker image pull library/hello-world
    

    上面代码中,docker image pull是抓取 image 文件的命令。library/hello-world是 image 文件在仓库里面的位置,其中library是 image 文件所在的组,hello-world是 image 文件的名字。

    由于 Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略。因此,上面的命令可以写成下面这样。

    $ docker image pull hello-world
    

    抓取成功以后,就可以在本机看到这个 image 文件了。

    docker image ls
    

    现在,运行这个 image 文件。

    $ docker container run hello-world
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/engine/userguide/
    

    输出这段提示以后,hello world就会停止运行,容器自动终止。
    值得注意的是docker container run命令是新建容器,每运行一次,就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用docker container start命令,它用来启动已经生成、已经停止运行的容器文件。

    $ docker container start [containerID]
    

    有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。

    $ docker container run -it ubuntu bash
    

    对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止。

    $ docker container kill [containID]
    

    docker container kill命令终止容器运行,相当于向容器里面的主进程发出 SIGKILL 信号。而docker container stop命令也是用来终止容器运行,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号。
    这两个信号的差别是,应用程序收到 SIGTERM 信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到 SIGKILL 信号,就会强行立即终止,那些正在进行中的操作会全部丢失。

    2.2 容器文件

    image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
    简单的理解就是image就是没有运行的container,container就是运行image运行生成的容器,只有运行时才能进行一些操作。

    # 列出正在运行的容器
    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUSPORTS               NAMES
    # 列出本机所有容器,包括终止运行的容器
    $ docker container ls --all
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS           PORTS               NAMES
    0e3d2c90f5a4        hello-world         "/hello"            About an hour ago   Exited (0) About anhour ago                       gracious_hermann
    a5c267eb9afc        hello-world         "/hello"            2 hours ago         Exited (0) 2 hours ago                             boring_stonebraker
    
    # 查看本机已有的镜像
    $ docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              2cb0d9787c4d        7 weeks ago         1.85kB
    pkrusche/hap.py     latest              f69ea1624f20        15 months ago       2.16GB
    
    # 删除镜像
    $ docker rmi [image ID]
    # 若出现Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container a5c267eb9afc is using its referenced image 2cb0d9787c4d 类似的报错,可加-f参数强制删除
    $ docker rmi -f [image ID]
    
    2.3 一个简单的实战

    现在利用一个docker打包好的软件来分析本地数据。这里较为重要的一部就是将数据映射到容器中的某个目录下以方便分析。

    2.3.1 拉取所用到的docker镜像

    利用docker pull命令可以方便的从远程仓库中拉取所需要的软件镜像,这个命令跟git clone有些许相似。

    $ docker pull pkrusche/hap.py
    
    2.3.2 运行镜像生成容器

    直接使用docker run命令来运行镜像:

    $ docker run -it --rm -v `pwd`:/data -v /DataBase/Human/GATK_bundle/b37:/data/b37 f69ea1624f20 /bin/bash
    
    • -it 容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
    • --rm 默认情况下,每个容器在退出时,它的文件系统也会保存下来,这样一方面调试会方便些,因为你可以通过查看日志等方式来确定最终状态。另外一方面,你也可以保存容器所产生的数据。但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望Docker能在容器结束时自动清理其所产生的数据。
    • -v 从主机挂载单个文件或目录到容器中
    • /bin/bash为运行的容器执行的第一个命令
    2.3.3 运行程序

    在使用hap.py程序之前我们需要先配置程序运行所需文件:

    $ export HGREF=/data/b37/human_g1k_v37_decoy.fasta
    

    接下来就可以进行运行程序了:

    $ /opt/hap.py/bin/hap.py \
         /data/highconf_variation/HG001.highconf_SNP.vcf.gz \
         /data/init_fq/gatk_call/variation_b37/raw_snp/HG001.raw_SNP.vcf.gz \
         -f /data/rawdata/HG001.Hiseq.b37.bed -o HG001
    [I] Total VCF records:         3258078
    [I] Non-reference VCF records: 3258078
    [I] Total VCF records:         50167
    [I] Non-reference VCF records: 50167
    Benchmarking Summary:
    Type Filter  TRUTH.TOTAL  TRUTH.TP  TRUTH.FN  QUERY.TOTAL  QUERY.FP  QUERY.UNK  FP.gt  METRIC.Recall  METRIC.Precision  METRIC.Frac_NA  METRIC.F1_Score  TRUTH.TOTAL.TiTv_ratio  QUERY.TOTAL.TiTv_ratio  TRUTH.TOTAL.het_hom_ratio  QUERY.TOTAL.het_hom_ratio
     SNP    ALL        42825     40024      2801        50140     10116          0    212       0.934594          0.798245               0         0.861055                2.543807                2.391331                   1.567034                   1.646584
     SNP   PASS        42825     40024      2801        50140     10116          0    212       0.934594          0.798245               0         0.861055                2.543807                2.391331                   1.567034                   1.646584
    
    

    为了更方便以后运行程序而不必每次运行程序都要再次导入设置环境变量,有两种方法可以保存现有容器的状态:其一为运行镜像时候不使用--rm命令,下次使用时继续使用此容器,使用docker start命令;其二是使用commit提交生成新的镜像,以后每次运行新的镜像生成容器即可。

    方法1:

    # 第一次使用
    $ docker run -it -v `pwd`:/data -v /DataBase/Human/GATK_bundle/b37:/data/b37 f69ea1624f20 /bin/bash
    # 配置环境变量
    root@f08af3e1ac90:/# echo "export HGREF=/data/b37/human_g1k_v37_decoy.fasta" >> ~/.bashrc && source ~/.bashrc
    # 退出
    root@2deb07b46456:/# exit
    
    # 查看container ID
    $ docker container ls --all
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS  PORTS               NAMES
    f08af3e1ac90        f69ea1624f20        "/bin/bash"         About a minute ago   Exited (0) 28 seconds ago                      focused_kare
    # 继续使用刚刚的容器
    $ docker start -ai f08af3e1ac90
    # 进入容器后直接运行
    root@f08af3e1ac90:/# /opt/hap.py/bin/hap.py \
          /data/highconf_variation/HG001.highconf_SNP.vcf.gz \
          /data/init_fq/gatk_call/variation_b37/raw_snp/HG001.raw_SNP.vcf.gz \
          -f /data/rawdata/HG001.Hiseq.b37.bed -o HG001
    

    方法2:

    # 第一次使用容器
    $ docker run -it -v `pwd`:/data -v /DataBase/Human/GATK_bundle/b37:/data/b37 f69ea1624f20 /bin/bash
    # 配置环境变量
    root@f08af3e1ac90:/# echo "export HGREF=/data/b37/human_g1k_v37_decoy.fasta" >> ~/.bashrc && source ~/.bashrc
    # 退出
    root@f08af3e1ac90:/# exit
    
    # 将容器进行commit生成新的镜像
    $ docker commit -m="built env hap.py" --author="shexuan" f08af3e1ac90 hap.py/built_env
    # 查看镜像
    [12:08 sxuan@hulab ~/WES]$ docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hap.py/built_env    latest              fb593adbe750        About an hour ago   2.19GB
    pkrusche/hap.py     latest              f69ea1624f20        15 months ago       2.16GB
    # 使用新的镜像生成容器
    $ docker run -it --rm -v `pwd`:/data -v /DataBase/Human/GATK_bundle/b37:/data/b37 fb593adbe750 /bin/bash
    root@52d0e50f8f0c:/# /opt/hap.py/bin/hap.py \
    >      /data/highconf_variation/HG001.highconf_SNP.vcf.gz \
    >      /data/init_fq/gatk_call/variation_b37/raw_snp/HG001.raw_SNP.vcf.gz \
    >      -f /data/rawdata/HG001.Hiseq.b37.bed -o HG001
    

    可以看到两种方法是都可以正常运行的。
    docker commit为使用一个配置发生改变的的容器生成新的镜像,用法如下:
    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

    • -a, --author= 添加作者信息
    • -c, --change=[] 使用Dockerfile指令来创建镜像
    • -m, --message= 提交时的说明文字
    • -p, --pause=true 在commit时,将容器暂停

    一般来说是不推荐直接使用commit来生成新的镜像的,更推荐使用更改dockerfile来生成新的镜像。

    三、 一些其他的常用命令

    docker ps [OPTIONS] 列出容器。

    • -a :显示所有的容器,包括未运行的
    • -f:根据条件过滤显示的内容
    • --format :指定返回值的模板文件
    • -l :显示最近创建的容器
    • -n :列出最近创建的n个容器
    • --no-trunc :不截断输出
    • -q :静默模式,只显示容器编号
    • -s :显示总的文件大小

    docker top [OPTIONS] CONTAINER [ps OPTIONS] 查看容器中运行的进程信息,支持 ps 命令参数。
    容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程。

    docker logs [OPTIONS] CONTAINER 获取容器的日志。

    • -f : 跟踪日志输出
    • --since :显示某个开始时间的所有日志
    • -t : 显示时间戳
    • --tail :仅列出最新N条容器日志
    # 例子
    $ docker logs 52d0e50f8f0c
    root@52d0e50f8f0c:/# /opt/hap.py/bin/hap.py \
    >      /data/highconf_variation/HG001.highconf_SNP.vcf.gz \
    >      /data/init_fq/gatk_call/variation_b37/raw_snp/HG001.raw_SNP.vcf.gz \
    >      -f /data/rawdata/HG001.Hiseq.b37.bed -o HG001
    [I] Total VCF records:         3258078
    [I] Non-reference VCF records: 3258078ll/variation_b37/raw_snp/HG001.raw_SNP.vcf.gz
    [I] Total VCF records:         50167
    [I] Non-reference VCF records: 50167
    Benchmarking Summary:
    Type Filter  TRUTH.TOTAL  TRUTH.TP  TRUTH.FN  QUERY.TOTAL  QUERY.FP  QUERY.UNK  FP.gt  METRIC.Recall  METRIC.Precision  METRIC.Frac_NA  METRIC.F1_Score  TRUTH.TOTAL.TiTv_ratio  QUERY.TOTAL.TiTv_ratio  TRUTH.TOTAL.het_hom_ratio  QUERY.TOTAL.het_hom_ratio
     SNP    ALL        42825     40024      2801        50140     10116          0    212       0.934594          0.798245               0         0.861055                2.543807                2.391331                   1.567034                   1.646584
     SNP   PASS        42825     40024      2801        50140     10116          0    212       0.934594          0.798245               0         0.861055                2.543807                2.391331                   1.567034                   1.646584
    

    docker cp [OPTIONS] CONTAINER:SRC_PATH [DEST_PATH] 用于容器与主机之间的数据拷贝。

    • -L :保持源目标中的链接
    # 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下
    $ docker cp /www/runoob 96f7f14e99ab:/www/
    #将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www
    $ docker cp /www/runoob 96f7f14e99ab:/www
    # 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中
    docker cp  96f7f14e99ab:/www /tmp/
    

    docker history [OPTIONS] IMAGE 查看指定镜像的创建历史。

    • -H :以可读的格式打印镜像大小和日期,默认为true
    • --no-trunc :显示完整的提交记录
    • -q :仅列出提交记录ID
    $ docker history -H hap.py/built_env
    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    fb593adbe750        2 hours ago         /bin/bash                                       36.4MB              built env hap.py
    f69ea1624f20        15 months ago       /bin/sh -c rm -rf /opt/hap.py-source            0B
    <missing>           15 months ago       /bin/sh -c #(nop) WORKDIR /                     0B
    <missing>           15 months ago       /bin/sh -c bin/test_haplotypes                  0B
    <missing>           15 months ago       /bin/sh -c #(nop) WORKDIR /opt/hap.py           0B
    <missing>           15 months ago       /bin/sh -c python install.py /opt/hap.py --w…   370MB
    <missing>           15 months ago       /bin/sh -c #(nop) WORKDIR /opt/hap.py-source    0B
    <missing>           15 months ago       /bin/sh -c #(nop) ENV PATH=/usr/local/sbin:/…   0B
    <missing>           15 months ago       /bin/sh -c wget http://archive.apache.org/di…   36.6MB
    <missing>           15 months ago       /bin/sh -c #(nop) WORKDIR /opt                  0B
    <missing>           15 months ago       /bin/sh -c #(nop) WORKDIR /opt/hap.py-data      0B
    <missing>           15 months ago       /bin/sh -c mkdir -p /opt/hap.py-data            0B
    <missing>           15 months ago       /bin/sh -c #(nop) COPY dir:9d3c8f8028e03cbcc…   453MB
    <missing>           15 months ago       /bin/sh -c mkdir -p /opt/hap.py-source          0B
    <missing>           15 months ago       /bin/sh -c echo oracle-java8-installer share…   387MB
    <missing>           15 months ago       /bin/sh -c pip install bx-python                11.1MB
    <missing>           15 months ago       /bin/sh -c apt-get clean -y                     0B
    <missing>           15 months ago       /bin/sh -c apt-get install software-properti…   51.7MB
    <missing>           15 months ago       /bin/sh -c apt-get install python2.7 python2…   312MB
    <missing>           15 months ago       /bin/sh -c apt-get install git bzip2 wget -y    32.6MB
    <missing>           15 months ago       /bin/sh -c apt-get install build-essential z…   266MB
    <missing>           15 months ago       /bin/sh -c apt-get update && apt-get upgrade…   111MB
    <missing>           23 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
    <missing>           23 months ago       /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
    <missing>           23 months ago       /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   1.9kB
    <missing>           23 months ago       /bin/sh -c rm -rf /var/lib/apt/lists/*          0B
    <missing>           23 months ago       /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   745B
    <missing>           23 months ago       /bin/sh -c #(nop) ADD file:cd937b840fff16e04…   127MB
    

    参考:
    Docker 命令大全
    Docker 入门教程
    官方文档

    相关文章

      网友评论

        本文标题:Docker使用笔记

        本文链接:https://www.haomeiwen.com/subject/ndnwwftx.html