zoukankan      html  css  js  c++  java
  • docker入门教程(三)Docker 镜像

    ps:镜像是Docker容器的基石,容器是镜像的运行实例,有了镜像才能启动容器。

    1.11 hello-world ------- 最小的镜像

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

    通常来说,我们希望镜像能提供一个基本的操作系统环境,用户可以根据需要安装和配置软件。

    这样的镜像我们称作 base 镜像。

    1.12 base镜像

    base 镜像有两层含义:(1)不依赖其它镜像,从secrch 构建;

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

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

    我们以 CentOS 为例考察 base 镜像包含哪些内容。

    下载镜像

    docker pull centos 

    查看镜像信息:如图

    镜像大小不到200MB.

    平时我们安装一个CentOS至少几个GB,怎么才200MB! 下面我们来解释这个问题

    Linux操作系统由内核空间和用户空间组成,如图

    1.rootfs

    内核空间是kernel,Linux刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。

    用户空间的文件系统是 rootfs,包含我们熟悉的 /dev ,proc,/bin 等目录。

    对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

    而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令,工具和程序库就可以,

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

    CentOS 镜像的 Dockerfile 的内容如下

    FROM scratch

    ADD centos-7docker.tar.xz /

    CMD ["/bin/bash"]

    第二行 ADD 指令添加到镜像的tar包就是CentOS 7 的rootfs。在制作镜像时,这个tar包会自动解压到 / 目录下,生成/dev,/proc,/bin 等目录

    3.支持运行多种 Linux OS

    不同 Linux 发行版本的区别主要就是 rootfs。

     比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包;而 Centos 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel 差别不大。

    所以 Docker 可以同时支持多种 Linux 镜像,模拟初多种操作系统环境,如下图所示

    上图 Debian 和 BusyBox(一种嵌入式 Linux)上层提供各自的 rootfs,底层共用 Docker Host 的 Kernel。

    这里需要说明的是:

    1)base镜像只是在用户空间与发行版一致,Kernel 版本与发行版本是不同的。
    例如 CentOS 7 使用3.x.x的kernel,如果Docker Host 是 Ubuntu 16.04,那么在 CentOS容器中使用的实际上是Host 4.x.x的kernel
    root@ubuntu: ~# uname -r
    4.4.0-31-generic    ①
    root@ubuntu: ~#
    root@ubuntu: ~# docker run -it centos    ②
    [root@231ad31 /]# cat /etc/redhat-release 
    CentOS Linux release 7.5.1804 (Core)    ③
     [root@231ad31 /]# uname -r
    4.4.0-31-generic

    ①.Host Kernel 4.4.0-31
    ②.启动并进入容器。
    ③.验证容器是 CentOS 7。
    ④.容器的 Kernel 版本与 Host 一致
    (2)容器只能使用 Host 的 Kernel,并且不能修改
    ps:所有容器都共用 host 的 Kernel,在容器中没办法对nKernel 升级

    3.1.3 镜像的分层结构

    Docker 支持通过扩展现有镜像,创建新的镜像。

    实际上,Docker Hub中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。比如我们现在构建一个新的镜像,Dockerfile如下

    FROM debian    ①
    RUN apt-get install emacs    ②
    RUN apt-get install apache2    ③
    CMD ["/bin/bash"]    ④
    ①.新镜像不再是从 scratch 开始,而是直接在 Debian base 镜像上构建。
    ②.安装 emacs
    ③.安装 apache2.
    ④.容器启动时运行 bash

     新镜像是从 base 镜像一层层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

     为什么Docker镜像要采用这种分成结构呢?

     最大的一个好处就是:共享资源。

     比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只加载一份 base 镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享

     如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如/etc 下的文件,这是其他容器的 /etc 是否也会被篡改?

     答案是不会!!! 

     修改会被限制在单个容器内

     容器的 Copy-on-Write特性:

     可写的容器层

    当启动容器时,一个新的可写层被加载带镜像的顶部。

    这一层通常被称作"容器层","容器层" 之下的都叫 “镜像层” 如下图:

    所有对容器的改动,无论添加,删除,还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

    下面我们深入讨论容器层的细节。

    镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统
    (1.) 添加文件。在容器中创建文件时,新文件被添加到容器层中。
    (2.) 读取文件。在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存
    (3.) 修改文件。在容器中修改已存在的文件时,Docker 会从上往下依次在各个镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之
    (4.) 删除文件。在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作。
    只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-write。可见,容器层保存的时镜像变化的部分,不会对镜像本身进行任何修改
    这样就解释了之前的问题,容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享
  • 相关阅读:
    kubernetes之手动部署k8s 1.14.1高可用集群
    db2 常用配置
    db2 常用命令
    linux 常用命令
    linux for 使用
    图解Python 【第六篇】:面向对象-类-进阶篇
    图解Python 【第五篇】:面向对象-类-初级基础篇
    图解Python 【第一篇】:Python基础1
    图解Python 【第三篇】:Python-函数
    图解Python 【第二篇】:Python基础2
  • 原文地址:https://www.cnblogs.com/mclzy/p/9214165.html
Copyright © 2011-2022 走看看