Heloowird

Docker 使用最佳指南

基本概念

  • 镜像(image)
  • 容器(container)

粗浅的理解: 镜像相当于一个类, 容器就是根据这个类创建的对象。详细参考Docker从入门到实践

镜像又分为远程镜像和本地镜像。这两个和git类似, 一个是远程, 一个是本地。

实践指南

  • 帮助命令

    1
    2
    3
    4
    5
    查看docker使用说明
    docker --help
    查看具体command 使用说明
    docker command --help
  • 常用命令集合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    # 1. 列出本地docker 镜像
    docker image ls
    # 2. 查看正在运行的容器
    docker ps
    # 3. 查看所有容器, 包括killed 状态的容器
    docker ps -a
    # 4. 启动一个新的容器
    docker run --it --name {container_name} -v {host_absolute_path}:{docker_absoulute_path} [{image_repo:image_tag}|{image_id}]
    # container_name 参数必须是唯一的, 不能和本地的其他容器名字同名. 在docker 其它命令中, 可以使用container_id 的地方也都可以使用container_name 代替, 方便记忆.
    # -v 用于指定挂载目录, 将宿主机器的目录映射到容器目录, 容器挂载目录下的所有数据实际存储在宿主机器目录下.
    # 本地docker 镜像既可以使用image_repo:image_tag, 可以通过image_id 来唯一标识
    # 一般地, 安装的软件放在非挂载目录下, 其他数据和开发脚本等最好放在挂载目录下。安装软件的命令可以写入新的docker file 或者临时的install_list.sh , 存在挂载目录下, 方便创建新的镜像/重新安装软件。
    # 重要: 启动之后, 推荐使用ctrl+p+q 快捷键, 让容器运行运行于后台。ctrl+p+q 的作用是让运行当前容器的线程脱离当前shell 的主线程, 当当前shell退出时, 容器仍保持后台运行。
    # 使用ctrl+p+q 让容器运行后台的前提是, docker run 启动时必须加上-i 参数
    # 5. 重新连接后台运行的容器
    # 方法一: 可用于连接killed 容器
    docker start -i {container_name|container_id}
    # 方法二: 推荐
    docker exec -it {container_name|container_id} [zsh|/bin/bash]
    # 方法一可以连接killed 容器, 缺点是exit 之后容器会进入killed 状态; 方法二只能连接运行状态的容器, exit 之后不会影响容器状态。
    # 方法一有一个重要的作用: 清理通过方法二启动但未exit 的进程。一般地, 方法二连接了一个容器, 当网断了该进程就会一直运行于后台, 长此以往就会有很多进程在后台连接该容器, 这样比较浪费机器资源. 通过docker top {container_name|container_id} 查看该容器相关的进程, 如果发现很多连接进程, 可以采取以下方法:
    # 1). 使用方法一连接容器, exit, 会使容器处于killed状态, 间接kill 掉与之连接的进程;
    # 2). 使用方法二连接容器, ctrl+p+q 使容器运行于后台即可;
    # 3). docker top {container_name|container_id} 查看容器相关进程。
    # 6. 查看正在运行容器的宿主机器进程
    docker top {container_name|container_id}
    # 同一个container 的父进程是一样的。
    # 7. 删除容器(慎用)
    docker rm {container_name|container_id}
    # 一般地, 如果启动容器后, 如果安装了安装耗时长且必备的软件, 建议创建一个新的dockerfile, 构建一个新的镜像
    # 如果安装一些小或者临时性的软件, 可以通过install_list.sh 记录下, 启动新的容器时, 可以sh install_list.sh 来快速安装, 如pip .
    # 可用于清理killed容器
    # 8. 建议把常用docker 相关命令通过alias 管理起来, 方便快速使用, 举个栗子:
    alias run_dc='docker run -it --name $(whoami) -v [your_machine_dir]:[your_docer_dir] image_id'
    alias list_dc='docker ps | grep $(whoami) | awk '\''ENGIN{print "CONTANINER_ID\tIMAGE"} {print $1"\t"$2}'\'''
    alias list_dead_dc='docker ps -a | grep "Exited" | grep $(whoami) | awk '\''ENGIN{print "CONTANINER_ID\tIMAGE"} {print $1"\t"$2}'\'''
    alias start_dc='docker start -i $(whoami)'
    alias connect_dc='docker exit -it $(list_dc | awk '\''NR==2{print $1}'\'') env LANG=C.UTF-8 /bin/bash'
  • 自定义镜像
    参考使用Dockerfile 定制镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # base image
    FROM base_image_repo:base_image_tag
    # set argument
    ARG OPENFST_VERSION="openfst-1.7.2"
    ARG SRILM_VERSION="srilm-1.7.2"
    # set work directory
    WORKDIR /root
    # copy your script
    COPY . .
    # install your software
    RUN set -ex \
    && apt-get update \
    && apt-get install -y git g++ make autoconf-archive libtool gfortran automake autoconf python-setuptools python-dev fontconfig \
    && cd /root \
    ...

参考资料

  1. Docker - 从入门到实践