Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1335607
  • 博文数量: 166
  • 博客积分: 46
  • 博客等级: 民兵
  • 技术积分: 4061
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-11 13:45
个人简介

现任职北京某互联网公司运维经理,高级架构师,涉足互联网运维行业已经超过10年。曾服务于京东商城,互动百科等互联网公司,早期运维界新星。 长期专研,C语言开发,操作系统内核,大型互联网架构。http://www.bdkyr.com

文章分类

分类: 虚拟化

2018-06-14 21:32:03

第四章 容器

      容器是Docker的另一个核心概念。

      简单地说,容器是镜像的一个运行实例,所不同的是,它带有额外的可写文件层。

      如果认为虚拟机是模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。那么Docker容器就是独立运行的一个或一组应用。以及它们的必须运行环境。

      本章将具体介绍容器的重要操作,包括创建一个容器、启动容器、终止一个容器、进入容器内执行操作、删除容器和通过导入导出容器来实现容器迁移等。

4.1 创建容器

     Docker的容器十分轻量级,用户可以随时创建或删除容器。

     新建容器

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

[root@dockers ~]# docker create -it centos

3d242b25e787fb4869bd1a4ad13c41e1f261cf5087f3d9831e9a7d5d9d1491e1

[root@dockers ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES

3d242b25e787        centos              "/bin/bash"              About a minute ago   Created                                         suspicious_kalam

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

新建并启动容器

    启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。所需要的命令主要为docker  run,等价于先执行docker  create命令,再执行docker start命令。

例如,下面的命令输出一个"Hello World”,之后容器自动终止:

[root@dockers ~]#docker run centos /bin/echo 'Hello world'

Hello world

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

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

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

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

docker run -t -i centos:6  /bin/bash

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

[root@dockers ~]# docker run -t -i -h docker001 centos:6 /bin/bash

[root@docker001 /]# ls

bin   dev  fastboot  lib         media  opt   root  sbin     srv  tmp  var

boot  etc  home      lost+found  mnt    proc  run   selinux  sys  usr

[root@docker001 /]# ps

  PID TTY          TIME CMD

    1 ?        00:00:00 bash

   17 ?        00:00:00 ps

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

用户可以按Ctrl+d 或输入exit命令来退出容器:

[root@docker001 /]# exit

exit

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

守护态运行

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

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

[root@dockers ~]# docker run -d -h docker001 centos:6 /bin/bash -c "while true; do echo hello world; sleep 1; done"

25db5ca2feed193224d07d82c141f8b4c300823fde3838ef86a4bc88c1ff6b28

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

[root@dockers ~]# docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES

25db5ca2feed        centos:6            "/bin/bash -c 'while "   8 seconds ago       Up 7 seconds                            drunk_lalande

要获取容器的输出信息,可以通过docker logs 命令:

[root@dockers ~]# docker logs 25db5ca2feed

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

4.2 终止容器

    可以使用docker  stop 来终止一个运行中的容器,命令的格式为docker stop [-t] --time [=10] 它会首先向容器发送SIGTERM信号,等待一段时间后(默认为10秒),再发送SIGKILL信号终止容器。

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

另外,可以使用docker  stop来终止一个运行中的容器:

[root@dockers ~]# docker stop 25db5ca2feed

[root@dockers ~]# docker ps -a -q

25db5ca2feed

b26c840c5896

3d242b25e787

32e7f9050246

3c1b69ba258c

47309b5dee4c

7ba09fc75f1d

f9ad9fdb59e7

03b5afee108c

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

[root@dockers ~]#docker start  03b5afee108c

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

[root@dockers ~]#docker restart  f9ad9fdb59e7

4.3 进入容器

    在使用-d 参数时,容器启动后会进入后台,用户无法看到容器中的信息。某些时候如果需要进入容器进行操作,有多种方法,包括使用docker  attach 命令,docker  exec命令,以及nsenter工具等。

attach命令

docker  attach 是Docker 自带的命令。下面示例如何使用该命令:

[root@dockers ~]# docker run -t -i -h docker001 centos:6 /bin/bash

[root@dockers ~]# docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

7d2c228aad49        centos:6            "/bin/bash"         12 seconds ago      Up 11 seconds                           dreamy_almeida

[root@dockers ~]# docker attach dreamy_almeida

[root@docker001 /]#

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

exec 命令

    Docker 自1.3版本起,提供了一个更加方便的工具exec,可以直接在容器内运行命令。例如进入到刚刚创建的容器中,并启动一个bash

[root@dockers ~]# docker exec -ti 14fcac75d16f  /bin/bash

[root@docker001 /]#

nsenter工具

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

[root@dockers ~]# cd /home/xuekun/

[root@dockers util-linux-2.24]# wget

[root@dockers util-linux-2.24]#./configure --without-ncurses

[root@dockers util-linux-2.24]#make nsenter && cp nsenter /usr/local/bin

为了使用nsenter连接到容器,还需要找到容器的进程的PID,可以通过下面的命令获取:

PID=$(docker inspec --format "{{ .State.Pid}}" )

通过这个PID,就可以连接到这个容器:

nsenter --target  $PID --mount --uts --ipc --net --pid

以下是完整例子:

[root@dockers util-linux-2.24]# PID=$(docker inspect --format "{{ .State.Pid }}" 7ba09fc75f1d )

[root@dockers util-linux-2.24]# echo $PID

3310

[root@dockers util-linux-2.24]# nsenter --target 3310 --mount --uts --ipc --net --pid

[root@docker001 /]#

4.4 删除容器

     可以使用docker  rm 命令删除处于终止状态的容器,命令格式为 docker rm [OPTIONS] CONTAINER  [CONTAINER ...]。支持的选项包括:

  • -f, --force=false 强制终止并删除一个运行中的容器。
  • -l, --link=false 删除容器的连接,保留容器。
  • -v, --volumes=false 删除容器挂载的数据卷。

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

[root@dockers ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES

14fcac75d16f        centos:6            "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                         berserk_bohr

7d2c228aad49        centos:6            "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                         dreamy_almeida

3057d687b207        centos:6            "/bin/bash"              19 hours ago        Exited (130) 19 hours ago                       happy_cray

[root@dockers ~]# docker rm 3057d687b207

3057d687b207

如果要删除一个运行中的容器,可以添加-f参数。Docker会发送SIGKILL信号给容器,终止其中的应用。

[root@dockers ~]# docker run -t -i -h docker001 centos:6 /bin/bash

[root@dockers ~]# docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

95e9ad2298fa        centos:6            "/bin/bash"         17 seconds ago      Up 16 seconds                           pensive_morse

[root@dockers ~]# docker rm 95e9ad2298fa

Error response from daemon: Cannot destroy container 95e9ad2298fa: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f

Error: failed to remove containers: [95e9ad2298fa]

[root@dockers ~]# docker rm -f 95e9ad2298fa

95e9ad2298fa

[root@dockers ~]#

4.5 导入和导出容器

导出容器

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

查看所有的容器如下所示:

[root@dockers ~]# docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES

14fcac75d16f        centos:6            "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                         berserk_bohr

7d2c228aad49        centos:6            "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                         dreamy_almeida

3057d687b207        centos:6            "/bin/bash"              19 hours ago        Exited (130) 19 hours ago                       happy_cray

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

[root@dockers ~]# docker export 14fcac75d16f >test_for_run.tar

[root@dockers ~]# ls

test_for_run.tar

[root@dockers ~]# docker export 7d2c228aad49 >test_for_stop.tar

[root@dockers ~]# ls

test_for_run.tar  test_for_stop.tar

可将这些文件传输到其它机器上,在其它机器上通过导入命令实现容器的迁移。

导入容器

    导出的文件又可以使用docker import命令导入,成为镜像,例如:

[root@dockers ~]# cat test_for_run.tar |docker import - centos1:v1.0

ee1bd65812b500e93553d1c80448132f8b97f0431f10069701075f4e9d927ab6

[root@dockers ~]# docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

centos1             v1.0                ee1bd65812b5        4 minutes ago       574.3 MB

    读者可能会记得,笔者在之前章节层介绍过使用aocker load命令来导入一个镜像文件。

    实际上,既可以使用docker  load命令来导入镜像存储文件到本地的镜像库,又可以使用docker import命令来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。


补充说明:
之所以选择原创标签,标识该文章是老薛自己学习验证后,逐行敲录的。感兴趣的朋友可以通过扫描如下二维码或者搜索“laoxue100”进行关注。
阅读(4001) | 评论(0) | 转发(0) |
0

上一篇:第三章 镜像

下一篇:没有了

给主人留下些什么吧!~~