• 操作Docker容器


    容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行态环境和其他系统环境)和跑在上面的应用,那么Docker容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。

    创建容器

    对容器进行操作就跟直接操作应用一样简单、快速。Docker容器实在太轻量级了,用户可以随时创建或删除容器。

    1.新建容器

    可以使用docker create命令新建一个容器,例如:

    $ docker create -it ubuntu:latest

    $ docker ps -a

    使用docker create命令新建的容器处于停止状态,可以使用docker start命令来启动它。

    create命令和后续的run命令支持的选项都十分复杂,主要包括如下几大类:与容器运行模式相关、与容器和环境配置相关、与容器资源限制和安全保护相关。

    create命令与容器运行模式相关的选项:

    create命令与容器环境和配置相关的选项:

    create命令与容器资源限制和安全保护相关的选项:

     

    其他比较重要的选项还包括:

    ·-l,--label=[]:以键值对方式指定容器的标签信息;

    ·--label-file=[]:从文件中读取标签信息。

    2.启动容器

    使用docker start命令来启动一个已经创建的容器,例如启动刚创建的ubuntu容器:

    $ docker start containerId

    $ docker stop containerId

    3.新建并启动容器

    除了创建容器后通过start命令来启动,也可以直接新建并启动容器。所需要的命令主要为docker run,等价于先执行docker create命令,再执行docker start命令。

    例如,下面的命令输出一个“Hello World”,之后容器自动终止:$ docker run ubuntu  /bin/echo 'Hello world'

    这跟在本地直接执行/bin/echo'hello world'几乎感觉不出任何区别。

    当利用docker run来创建并启动容器时,Docker在后台运行的标准操作包括:

    1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
    2. 利用镜像创建一个容器,并启动该容器;
    3. 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
    4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中;
    5. 从网桥的地址池配置一个IP地址给容器;
    6. 执行用户指定的应用程序;
    7. 执行完毕后容器被自动终止。

    下面的命令启动一个bash终端,允许用户进行交互:

    $ docker run -it ubuntu:14.04 /bin/bash

    root@af8bae53bdd3:/#

    其中,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。

    更多的命令选项可以通过man docker-run命令来查看。在交互模式下,用户可以通过所创建的终端来输入命令。

    在容器内用ps命令查看进程,可以看到,只运行了bash应用,并没有运行其他无关的进程。

    对于所创建的bash容器,当使用exit命令退出之后,容器就自动处于退出(Exited)状态了。这是因为对Docker容器来说,当运行的应用退出后,容器也就没有继续运行的必要了。

    某些时候,执行docker run会出错,因为命令无法正常执行容器会直接退出,此时可以查看退出的错误代码。

    默认情况下,常见错误代码包括:

    ·125:Docker daemon执行出错,例如指定了不支持的Docker命令参数;

    ·126:所指定命令无法执行,例如权限出错;

    ·127:容器内命令无法找到。

    命令执行后出错,会默认返回错误码。

    4.守护态运行

    更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。此时,可以通过添加-d参数来实现。

    例如下面的命令会在后台运行容器:

    $ docker run -d ubuntu  /bin/sh -c "while true; do echo hello world; sleep 1; done"

    ce554267d7a4c34eefc92c5517051dc37b918b588736d0823e4c846596b04d83

    容器启动后会返回一个唯一的id,也可以通过docker ps命令来查看容器信息

    此时,要获取容器的输出信息,可以如下使用docker logs命令:$ docker logs containerId

    终止容器

    可以使用docker stop来终止一个运行中的容器。该命令的格式为docker stop [-t|--time[=10]] [CONTAINER...]。

    首先向容器发送SIGTERM信号,等待一段超时时间(默认为10秒)后,再发送SIGKILL信号来终止容器:$ docker stop containerId

    docker kill命令会直接发送SIGKILL信号来强行终止容器。

    此外,当Docker容器中指定的应用终结时,容器也会自动终止。例如对于上一节中只启动了一个终端的容器,用户通过exit命令或Ctrl+d来退出终端时,所创建的容器立刻终止,处于stopped状态。

    可以用docker ps -qa命令看到所有容器的ID。例如:$ docker ps -qa

    处于终止状态的容器,可以通过docker start命令来重新启动:$ docker start containerId

    docker restart命令会将一个运行态的容器先终止,然后再重新启动它:$ docker restart containerId

    进入容器

    在使用-d参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进行操作。

    这个时候如果需要进入容器进行操作,有多种方法,包括使用官方的attachexec命令,以及第三方的nsenter工具等。

    1.attach命令

    attach是Docker自带的命令,命令格式为:

    docker attach [--detach-keys[=[]]] [--no-stdin] [--sig-proxy[=true]] CONTAINER

    支持三个主要选项:

    ·--detach-keys[=[]]:指定退出attach模式的快捷键序列,默认是CTRL-p CTRL-q;

    ·--no-stdin=true|false:是否关闭标准输入,默认是保持打开;

    ·--sig-proxy=true|false:是否代理收到的系统信号给应用进程,默认为true。

    下面示例如何使用该命令:$ docker run -itd ubuntu

    $ docker ps

    CONTAINER ID   IMAGE           COMMAND     CREATED            STATUS            PORTS   NAMES

    243c32535da7   ubuntu:latest  "/bin/bash"    18 seconds ago   Up 17 seconds               nostalgic_hypatia

    $ docker attach nostalgic_hypatia

    root@243c32535da7:/#

    但是使用attach命令有时候并不方便。当多个窗口同时用attach命令连到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

    2.exec命令

    Docker从1.3.0版本起提供了一个更加方便的exec命令,可以在容器内直接执行任意命令。该命令的基本格式为:

    docker exec [-d|--detach] [--detach-keys[=[]]] [-i|--interactive] [--privileged] [-t|--tty] [-u|--user[=USER]] CONTAINER COMMAND [ARG...]。

    比较重要的参数有:

    ·-i,--interactive=true|false:打开标准输入接受用户输入命令,默认为false;

    ·--privileged=true|false:是否给执行命令以高权限,默认为false;

    ·-t,--tty=true|false:分配伪终端,默认为false;

    ·-u,--user="":执行命令的用户名或ID。

    例如进入到刚创建的容器中,并启动一个bash:

    $ docker exec -it 243c32535da7  /bin/bash

    root@243c32535da7:/#

    可以看到,一个bash终端打开了,在不影响容器内其他应用的前提下,用户可以很容易与容器进行交互。

    通过指定-it参数来保持标准输入打开,并且分配一个伪终端。通过exec命令对容器执行操作是最为推荐的方式。

    3.nsenter工具

    在util-linux软件包版本2.23+中包含nsenter工具。如果系统中的util-linux包没有该命令,可以按照下面的方法从源码安装:

    $ cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;

    $ ./configure --without-ncurses

    $ make nsenter && cp nsenter /usr/local/bin

    为了使用nsenter连接到容器,还需要找到容器进程的PID,可以通过下面的命令获取:PID=$(docker inspect --format "{{ .State.Pid }}" )

    通过这个PID,就可以连接到这个容器:$ nsenter --target $PID --mount --uts --ipc --net --pid

    下面给出一个完整的例子,通过nsenter命令进入容器:

    $ docker run -idt ubuntu
    243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
    $ docker ps
    CONTAINER ID   IMAGE           COMMAND   CREATED           STATUS         PORTS     NAMES
    243c32535da7  ubuntu:latest   "/bin/bash"  18 seconds ago  Up 17 seconds  nostalgic_hypatia
    $ PID=$(docker-pid 243c32535da7)
    10981
    $ nsenter --target 10981 --mount --uts --ipc --net --pid
    root@243c32535da7:/#

    删除容器

    可以使用docker rm命令来删除处于终止或退出状态的容器,命令格式为docker rm[-f|--force][-l|--link][-v|--volumes]CONTAINER[CONTAINER...]。

    主要支持的选项包括:

    ·-f,--force=false:是否强行终止并删除一个运行中的容器;

    ·-l,--link=false:删除容器的连接,但保留容器;

    ·-v,--volumes=false:删除容器挂载的数据卷。

    例如,查看处于终止状态的容器,并删除:

    $ docker ps -a

    $ docker rm ce554267d7a4

    默认情况下,docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。

    如果要直接删除一个运行中的容器,可以添加-f参数。Docker会先发送SIGKILL信号给容器,终止其中的应用,之后强行删除,如下所示:

    $ docker run -d ubuntu:14.04  /bin/sh -c "while true; do echo hello world;sleep 1; done"
    2aed76caf8292c7da6d24c3c7f3a81a135af942ed1707a79f85955217d4dd594
    $ docker rm 2ae
    Error response from daemon: You cannot remove a running container. Stop the
    container before attempting removal or use -f
    2016/07/03 09:02:24 Error: failed to remove one or more containers
    $ docker rm -f 2ae
    2ae

    导入和导出容器

    某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用Docker的导入和导出功能。这也是Docker自身提供的一个重要特性。

    1.导出容器

    导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态,可以使用docker export命令。

    该命令的格式为docker export [-o|--output[=""]] CONTAINER。其中,可以通过-o选项来指定导出的tar文件名,也可以直接通过重定向来实现。

    首先查看所有的容器,如下所示:

    $ docker ps -a

    分别导出ce554267d7a4容器和e812617b41f6容器到文件test_for_run.tar文件和test_for_stop.tar文件:

    $ docker export -o test_for_run.tar ce5

    $ docker export e81 >test_for_stop.tar

    之后,可将导出的tar文件传输到其他机器上,然后再通过导入命令导入到系统中,从而实现容器的迁移。

    2.导入容器

    导出的文件又可以使用docker import命令导入变成镜像,该命令格式为:

    docker import [-c|--change[=[]]] [-m|--message[=MESSAGE]] file|URL|-[REPOSITORY[:TAG]]

    用户可以通过-c,--change=[]选项在导入的同时执行对容器进行修改的Dockerfile指令。

    下面将导出的test_for_run.tar文件导入到系统中:

    $ docker import test_for_run.tar - test/ubuntu:v1.0

    $ docker images

    REPOSITORY        TAG      IMAGE ID       CREATED              VIRTUAL SIZE

    test/ubuntu       v1.0     9d37a6082e97   About a minute ago   171.3 MB

    实际上,既可以使用docker load命令来导入镜像存储文件到本地镜像库,也可以使用docker import命令来导入一个容器快照到本地镜像库。

    这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。 

     

  • 相关阅读:
    LeeCode-Spiral Matrix II
    HDU1281(二分图最大匹配,棋盘建图,找关键点)
    HDU1083(二分图最大匹配vector实现)
    HDU2444(判断是否为二分图,求最大匹配)
    HDU1166(线段树单点更新区间查询)
    HDU1045(二分图经典建模)
    POJ1220(大数进制转换)
    POJ3466(01背包变形)
    POJ3180(有向图强连通分量结点数>=2的个数)
    POJ1236 (强连通分量缩点求入度为0和出度为0的分量个数)
  • 原文地址:https://www.cnblogs.com/wade-luffy/p/6497108.html
Copyright © 2020-2023  润新知