镜像的内部结构

3.1.1   hello-world——最小的镜像

hello-world是Docker官方提供的一个镜像,用来验证Docker是否安装成功

hello-world的Dockerfile内容如下所示:

只有短短三条指令。

(1) FROM scratch镜像是从白手起家,从0开始构建。

(2) COPY hello/将文件“helo”复制到镜像的根目录。

(3)CMD["hel”容器启动时,执行helo

hello-world虽然是一个完整的镜像,但它并没有什么实际用途。通常来说,我们希望镜像能提供一个基本的操作系统环境,用户可以根据需要安装和配置软件。

输出Hello world

Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。

runoob@runoob:~$ docker run ubuntu:15.10 /bin/echo "Hello world"

Hello world

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run: 与前面的 docker 组合来运行一个容器。
  • ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
  • /bin/echo "Hello world": 在启动的容器里执行的命令

以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果。

运行交互式的容器

我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现"对话"的能力:

runoob@runoob:~$ docker run -i -t ubuntu:15.10 /bin/bash

root@0123ce188bd8:/#

各个参数解析:

  • -t: 在新容器内指定一个伪终端或终端。
  • -i: 允许你对容器内的标准输入 (STDIN) 进行交互。

第二行 root@0123ce188bd8:/#,此时我们已进入一个 ubuntu15.10 系统的容器

cat /proc/version   查看当前系统的版本信息

通过运行 exit 命令或者使用 CTRL+D 来退出容器。

启动容器(后台模式)

使用以下命令创建一个以进程方式运行的容器

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

2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63

在输出中,我们没有看到期望的 "hello world",而是一串长字符

2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。

首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:

runoob@runoob:~$ docker ps

CONTAINER ID        IMAGE                  COMMAND              ... 

5917eac21c36        ubuntu:15.10           "/bin/sh -c 'while t…"    ...

输出详情介绍:

  • CONTAINER ID: 容器 ID。
  • IMAGE: 使用的镜像。
  • COMMAND: 启动容器时运行的命令。
  • CREATED: 容器的创建时间。
  • STATUS: 容器状态。
    • 状态有7种:
    • created(已创建)
    • restarting(重启中)
    • running 或 Up(运行中)
    • removing(迁移中)
    • paused(暂停)
    • exited(停止)
    • dead(死亡)
  • PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
  • NAMES: 自动分配的容器名称。

runoob@runoob:~$ docker logs 2b1b7a428627    #在宿主主机内使用 docker logs 命令,查看容器内的标准输出

启动容器

以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:

$ docker run -it ubuntu

查看所有的容器:docker ps -a

启动一个已停止的容器: docker start 容器ID 

-d 指定容器的运行模式:docker run -itd --name ubuntu-test ubuntu /bin/bash

此时想要进入容器:docker exec -it 243c32535da7 /bin/bash 如果从这个容器退出,容器不会停止

停止容器:docker stop <容器 ID>

重启容器:systemctl start docker

导出容器:docker export 1e560fca3906 > ubuntu.tar   #导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。

导入容器:cat docker/ubuntu.tar | docker import - test/ubuntu:v1 #将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1

  • 可以通过指定 URL 或者某个目录来导入:

docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器:docker rm -f 1e560fca3906

清理掉所有处于终止状态的容器:docker container prune

删除所有未启动的容器:docker rm $(sudo docker ps -a -q)

杀死所有正在运行的容器:docker kill $(docker ps -a -q)

删除所有镜像:docker rmi $(docker images -q)

强制删除 无法删除的镜像

docker rmi -f <IMAGE_ID>

docker rmi -f $(docker images -q)

查看到容器的端口映射:docker ps

   docker port 容器名或ID 

查看web日志:docker logs -f beautiful_nash

查看容器内部运行的进程:docker top beautiful_nash

检查 WEB 应用程序:  docker inspect  beautiful_nash   查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

查询最后一次创建的容器:docker ps -l

重启正在运行的容器:docker restart beautiful_nash

搜索镜像:docker search httpd

下载镜像:docker pull httpd

使用镜像:docker run httpd

更新镜像:在运行的容器内使用 apt-get update 命令进行更新

列出镜像列表:docker images

  • 选项说明:

REPOSITORY 

  TAG

       IMAGE ID 

     CREATED   

    SIZE

镜像的仓库源

镜像的标签

镜像ID

镜像创建时间

镜像大小

  • 同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本
  • 如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:

runoob@runoob:~$ docker run -it ubuntu:15.10 /bin/bash

root@d77ccb2e5cca:/#

  • 如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。

删除镜像:docker rmi hello-world

列出本地进行的变更历史:docker history 镜像ID

容器和宿主机之间复制文件

docker cp 文件|目录 容器id:容器路径  #将宿主机的内容拷贝到容器指定路径

docker cp 容器id:容器路径 宿主机目录 #与上相反

数据卷(volume)实现与宿主机共享目录

docker run -v 宿主机路径|任意别名:容器内的路径 镜像名

注意:宿主机路径必须是绝对路径,宿主机目录会覆盖容器内目录内容

如果是别名则会在docker运行容器时自动在宿主机中创建一个目录,并将容器目录文件尖复制到宿主机中

3.1.2 base镜像

base镜像由两层含义:

(1)不依赖其他镜像,从scratch构建

(2)其他镜像可以以他为基础进行扩展

所以,能称作base镜像的通常都是各种 Linux发行版的 Docker镜像,比如 Ubuntu

Debian、 Centos等。

Linux OS由内核空间和用户空间组成

1.rootfs

  • 内核空间是 kernel, Linux刚启动时会加载 boots文件系统,之后 boots会被卸载掉。
  • 用户空间的文件系统是 rootfs,包含我们熟悉的/dev、/proc、/bin等目录。
  • 对于base镜像来说,底层直接用Host的 kernel,自己只需要提供 rootfs就行了。
  • 而对于一个精简的OS, rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以。

2.base镜像提供的是最小安装的Linux发行版

注:可在 Docker Hub的镜像描述页面中査看 Dockerfile

3.支持运行多种Linux OS

不同Linux发行版本的区别主要就是rootfs,Linux kernel差别不大。所以Docker可以同时支持多种Linux镜像

(1)base镜像只是在用户空间与发行版一致, kernel版本与发行版是不同的。

例如 Centos7使用3.xx的 kernel,如果 Docker Host是 Ubuntu16.04(比如我们的实

验环境),那么在 Centos容器中使用的实际上是Host 4.1xX的 kernel

① Host kernel为3.10.0

②启动并进入 Centos容器。

③)验证容器是 Centos7.

④容器的 kernel版本与Host一致。

(2)容器只能使用Host的 kernel,并且不能修改。

  • 所有容器都共用host的 kernel.,在容器中没办法对 kernel升级。如果容器对 kernel版本有要求(比如应用只能在某个 kernel版本下运行),则不建议用容器,这种场景虚拟机可能更

3.1.3 镜像的分层结构

  • 每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 容器存储层。

  • 容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
  • 有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

  • Docker支持通过扩展现有镜像,创建新的镜像。
  • 新镜像是从base镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的

基础上增加一层。

  • 为什么 Docker镜像要采用这种分层结构呢?
    • 最大的一个好处就是:共享资源。
  • 如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如/etc下的文件,这时其他容器的etc是否也会被修改?
    • 答案是不会!因为修改会被限制在单个容器内。

容器Copy-on-Write特性

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”

 

  • 所有对容器的改动,无论添加、删除,还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
  • 镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如a,上层的/a会覆盖下层的/a,也就是说用户只能访问到上层中的文件a。在容器层中,用户看到的是一个叠加之后的文件系统。

(1)添加文件。在容器中创建文件时,新文件被添加到容器层中。

(2)读取文件。在容器中读取某个文件时, Docker会从上往下依次在各镜像层中査找此文件。一旦找到,打开并读入内存

(3)修改文件。在容器中修改已存在的文件时, Docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之

(4)删除文件。在容器中删除文件时, Docker也是从上往下依次在镜像层中査找此文件。找到后,会在容器层中记录下此删除操作。

  • 只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Wite。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改

>>

容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值