本文将介绍 Docker 容器的常用概念和配置使用方法。

如需了解 Docker 资源隔离、容器间组网和镜像编辑等配置,见其他博文。

常用概念

Docker:一个开源的容器虚拟化平台。

Docker 镜像:Docker 容器运行时的只读模板,每个镜像由一系列的层 (Layers) 组成。镜像的修改可以理解为是对层的更换。

Docker 容器:容器是一个特定的程序运行环境,环境内容由镜像规定。容器可以运行、开始、停止、移动和删除。

Docker 容器仓库:存放容器镜像的代码仓库。私有仓库由用户自行创建,公共仓库特指 Docker Hub 仓库,这是一个开放的分布式容器仓库。

使用容器

Docker 使用命令做管理操作,该命令一般由程序名(docker)、命令(Command)、选项(Option)和参数(ARG)构成。

输入程序名 docker,可以获取其全部命令的列表,详见本文末命令帮助。

获取当前 docker 程序版本,使用 docker version 命令。

了解容器状态

查看容器,可以使用 docker ps 命令,该命令仅支持查看当前正在工作的容器。

查看包括正在运行和结束运行的全部容器,可以在上述命令后追加 -a 选项。

使用该命令后的返回信息如下:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
28faba7558fb        hello-world         "/hello"            7 seconds ago       Exited (0) 7 seconds ago                       boring_minsky

返回信息包含容器ID、使用的镜像、工作命令、创建时间、工作状态、端口信息和容器名。

停止一个容器,使用 docker stop 容器名/ID 命令,如停止上述的容器:

$ docker stop 28faba7558fb
28faba7558fb

启动一个容器,使用 docker start 容器名/ID 命令,如启动上述的容器:

$ docker start 28faba7558fb
28faba7558fb

基本镜像管理

查看本地仓库镜像,使用 docker images 命令。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              48b5124b2768        3 months ago        1.84 kB

该命令返回(用户名/)镜像源名、标签(版本分支)、镜像ID、创建时间和容量。

如本地仓库没有所需镜像,可以使用 docker search 命令,在公共镜像仓库中查找相关的镜像。如这个示例,在镜像库中查询 web应用框架:

$ docker search webapp
NAME                        DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
training/webapp                                                             57                   [OK]
automodeling/webapp         Web App for visualize the results               1                    [OK]
wrmarchetto/webapp          Webapp                                          0                    [OK]
···

查询到这个框架的信息后,使用 docker pull (作者名/)镜像源名(:版本分支) 命令下载所需镜像到本地。

$ docker pull training/webapp:latest
···

需要注意的是,如果没有提供标签(版本分支),将自动下载容器的 latest 版本。

使用镜像构建容器

一般的,有两种构建容器的方式,使用镜像构建容器和使用 Dockerfile 构建容器。在这里介绍的是使用镜像构建容器的常规操作。关于 Dockerfile 构建容器的方式,见其他博文。

从镜像构建容器,使用 docker run 镜像名 执行语句 命令。

$ docker run -d -p 8080:5300 seanhuai/docker-flask-example python app.py
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
dfe80cbfd640        seanhuai/docker-flask-example     "python app.py"     9 seconds ago       Up 8 seconds        0.0.0.0:8080->5300/tcp   serene_boyd

本例是 Python Flask 应用程序框架的容器构建。-d 选项表示在生成的容器在后台运行,容器的输出内容将不会打印在当前命令行中,也不会对当前命令行做监听。-p 选项用于设置该容器的端口映射。

本例中的设置 -p 8080:5000 用于将容器内的 TCP 5000端口映射到本地任意 IP 的8080端口,这里是默认将单端口映射到本地的情形,除此之外可以使用类似 -p 127.0.0.1:8080:5000 的写法,将容器内端口绑定到指定 IP 的端口上,如写作 -p 127.0.0.1::5000 被视为将容器内端口绑定到指定 IP 的随机空余端口上,这与使用 -P 选项功能基本一致。

这里默认是 TCP 端口映射,如使用 UDP 映射,可在端口后写明类型,如 -p 8080:5000/udp

容器的端口映射信息可以在 docker ps 命令中查看,但是随着容器数量的增加,显示的信息数量也会有明显增加,会造成识别上的不便,所以还可使用 docker port 容器ID/容器名 命令查看指定容器的端口映射信息。

探访容器内部

容器在运行中,可以使用 docker exec 容器ID/容器名 执行语句 对容器工作情况进行追加操作。

在实际使用中,为了更加直观的了解到容器内部的情况,可以使用这个命令访问到容器内部,直接对其执行操作。

$ docker exec -it dfe80cbfd640 /bin/bash
root@dfe80cbfd640:/opt/webapp# 
root@dfe80cbfd640:/opt/webapp# ls
app.py tests.py
···

本例中使用 docker exec 进入上文构建的 Flask 框架容器内部进行直接操作。

-i 选项是选择交互式(interactive)操作,-t 选项是选择使用伪虚拟终端(TTY)进行显示。默认的,容器内的操作使用的是 root 权限,容器中另有声明的除外。操作后可以键入 exit 退出当前终端。

需要了解的是,-it 选项可以直接用于 docker run 命令中。

管理容器数据

数据卷是独立于容器结构的持久化存储,用于实现容器和本地设备的数据交换、容器间的数据共享等操作。

容器使用数据,一般有三种方式,其一是直接在容器上挂载数据卷,其二是生成数据卷容器并挂载,其三是使用隧道传递信息的容器链接。本文将介绍前两种数据使用方式。

挂载数据卷

直接在容器上挂载数据卷,需要在构建容器同时完成,通过在执行 docker run 命令时附加 -v 选项实现数据卷的挂载。

$ docker run -d -v /code:/webapp seanhuai/docker-flask-example app.py

本例新建了一个 Flask 框架容器,并在构建时挂载本地 /code 目录到容器内 /webapp 位置。这样的操作将允许开发人员在本地修改工作目录代码,并通过 web 框架容器得到当前的实时效果。需要注意,本地目录路径必须完整输入

默认的,容器对容器内数据卷具有读写权限,在挂载时使用类似 -v /code:/webapp:ro 的写法,将限制容器的写权限,仅允许容器对容器内数据卷具有只读权限。

仅使用选项 -v /webapp,将在容器工作目录位置挂载一个数据卷。

挂载数据卷容器

数据卷容器是一种默认支持容器间数据共享的数据使用方式,数据卷容器是链式调用的,具有极大的扩展性。

$ docker run -d -v /data --name app1 seanhuai/docker-flask-example app.py

本例构建了一个挂载了 /data 目录的 Flask 框架容器,该容器命名为 app1

在其他需要该数据卷的容器构建时,使用 --volumes-from 选项,实现挂载。

$ docker run -d --volumes-from app1 --name app2 seanhuai/docker-flask-example app.py

这一挂载行为可以由已挂载的容器向下继承,即后续的容器可以从已挂载的容器上获得所需的数据卷,而不依赖最初挂载的原始容器。

$ docker run -d --volumes-from app2 --name app3 seanhuai/docker-flask-example app.py

数据卷可以脱离原始容器,也可以脱离任意已挂载的容器。只要还有挂载它的容器存在,数据卷即存在,除非在仅存最后一个挂载的容器上,执行显式删除数据卷操作。

命令帮助

$ docker 

Commands:
    attach    Attach to a running container                 
              # 当前 shell 下 attach 连接指定运行镜像
    build     Build an image from a Dockerfile              
              # 通过 Dockerfile 定制镜像
    commit    Create a new image from a container's changes 
              # 提交当前容器为新的镜像
    cp        Copy files/folders from the containers filesystem to the host path
              # 从容器中拷贝指定文件或者目录到宿主机中
    create    Create a new container                        
              # 创建一个新的容器,同 run,但不启动容器
    diff      Inspect changes on a container's filesystem   
              # 查看 docker 容器变化
    events    Get real time events from the server          
              # 从 docker 服务获取容器实时事件
    exec      Run a command in an existing container        
              # 在已存在的容器上运行命令
    export    Stream the contents of a container as a tar archive   
              # 导出容器的内容流作为一个 tar 归档文件[对应 import ]
    history   Show the history of an image                  
              # 展示一个镜像形成历史
    images    List images                                   
              # 列出系统当前镜像
    import    Create a new filesystem image from the contents of a tarball  
              # 从tar包中的内容创建一个新的文件系统映像[对应 export]
    info      Display system-wide information               
              # 显示系统相关信息
    inspect   Return low-level information on a container   
              # 查看容器详细信息
    kill      Kill a running container                      
              # kill 指定 docker 容器
    load      Load an image from a tar archive              
              # 从一个 tar 包中加载一个镜像[对应 save]
    login     Register or Login to the docker registry server   
              # 注册或者登陆一个 docker 源服务器
    logout    Log out from a Docker registry server         
              # 从当前 Docker registry 退出
    logs      Fetch the logs of a container                 
              # 输出当前容器日志信息
    port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
              # 查看映射端口对应的容器内部源端口
    pause     Pause all processes within a container        
              # 暂停容器
    ps        List containers                               
              # 列出容器列表
    pull      Pull an image or a repository from the docker registry server
              # 从docker镜像源服务器拉取指定镜像或者库镜像
    push      Push an image or a repository to the docker registry server
              s# 推送指定镜像或者库镜像至docker源服务器
    restart   Restart a running container                   
              # 重启运行的容器
    rm        Remove one or more containers                 
              # 移除一个或者多个容器
    rmi       Remove one or more images                 
              # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需-f 强制删除]
    run       Run a command in a new container
              # 创建一个新的容器并运行一个命令
    save      Save an image to a tar archive                
              # 保存一个镜像为一个 tar 包[对应 load]
    search    Search for an image on the Docker Hub         
              # 在 docker hub 中搜索镜像
    start     Start a stopped containers                    
              # 启动容器
    stop      Stop a running containers                     
              # 停止容器
    tag       Tag an image into a repository                
              # 给源中镜像打标签
    top       Lookup the running processes of a container   
              # 查看容器中运行的进程信息
    unpause   Unpause a paused container                    
              # 取消暂停容器
    version   Show the docker version information           
              # 查看 docker 版本号
    wait      Block until a container stops, then print its exit code   
              # 截取容器停止时的退出状态值

Run 'docker COMMAND --help' for more information on a command.

了解命令选项设置,可以在命令后附 --help 获取帮助。