Docker 镜像

典型的 Linux 文件系统

bootfs(bootfilesystem)

  • Bootloader - 引导加载 kernel
  • Kernel - 当 kernel 被加载到内存中后 umount bootfs

rootfs(rootfilesystem)

  • /dev,/proc,/bin,/etc 等标准目录和文件

对于不同的 Linux 发行版,bootfs 基本是一致的,但 rootfs 会有差别

Docker 的文件系统如何启动

Linux

  • 在启动后,首先将 rootfs 置为 readonly,进行一系列检查,然后将其切换为“readwrite”共用户使用

Docker

  • 也是将 rootfs 以 readonly 方式加载并检查,然而接下来利用 union mount 将一个 readwrite 文件系统挂载在 readonly 的 rootfs 之上

  • 并且允许再次将下层的 file system 设定为 readonly 并且向上叠加

  • 这样一组 readonly 和一个 writeable 的结构构成一个 container 的运行目录,每一个被称作一个 Layer

AUFS

AUFS 是一种 Union File System,所谓 UnionFS 就是把不同物理位置的目录合并 mount 到同一个目录中。UnionFS 的一个最主要的应用是,把一张CD/DVD 和一个硬盘目录给联合 mount 在一起,然后,你就可以对这个只读的 CD/DVD 上的文件进行修改(当然,修改的文件存于硬盘上的目录里)

AUFS 是将多个目录合并成一个虚拟文件系统,成员目录称为虚拟文件系统的一个分支(branch),每个 branch 可以指定 readwrite/whiteout-able/readonly 权限,只读(ro),读写(rw),写隐藏(wo)。一般情况下,aufs 只有最上层的 branch 具有读写权限,其余 branch 均为只读权限。只读 branch 只能逻辑上修改,AUFS 每层branch 可以动态的增加删除,每增加一层,下层默认置为 ro,最上一层为 rw。删除 branch 是在 aufs 挂载点移除,并未删除挂载目录

AUFS 的文件读写与删除

当需要修改一个文件,而该文件位于低层 branch时,顶层 branch 会直接复制低层 branch 的文件至顶层再进行修改,而低层的文件不变,这种方式即是 CoW 技术(写复制),AUFS 默认支持 Cow 技术,当容器删除一个低层 branch 文件时,只是在顶层 branch 对该文件进行重命名并隐藏,实际并未删除文件,只是不可见,这种方式即 AUFS 的whiteout(写隐藏)

  • 添加文件:创建文件时,新文件被添加到branch中
  • 读取文件 :读取某个文件时,会从上往下依次在各镜像层中查找此文件。一旦找到,打开并读入内存。
  • 修改文件 :修改已存在的文件时,会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。
  • 删除文件 :删除文件时,也是从上往下依次在镜像层中查找此文件。找到后,会在branch中记录下此删除操作。

Docker 中的 AUFS

Docker 镜像(Image)是由一个或多个 AUFS branch 组成,并且所有的 branch 均为只读权限。简单来说,AUFS 所有 robranch 按照一定顺序堆积构成 Docker Image 镜像
在运行容器的时候,创建一个 AUFS branch 位于image 层之上,具有 rw 权限,并把这些 branch 联合挂载到一个挂载点下。这就是 Docker 能够一个镜像运行多个容器的原理所在

写时复制(Copy-on-Write)

  • 容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”
  • 所有对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中
  • 只有容器层是可写的,容器层下面的所有镜像层都是只读的
  • 只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分, 不会对镜像本身进行任何修改

AUFS 的好处

  • 节省存储空间:多个容器可以共享基础镜像(Base Image)存储
  • 快速部署:如果要部署多个容器,基础镜像(Base Image)可以避免多次拷贝
  • 内存更省:因为多个容器共享 Base Image,以及OS 的 Disk 缓存机制,多个容器中的进程命中缓存内容的几率大大增加
  • 允许在不更改基础镜像的同时修改其目录中的文件:所有写操作都发生在最上层的 writeable 层中,这样可以大大增加 Base Image 能共享的文件内容

镜像的定义

镜像(Image)就是一堆只读层(read-only layer)的统一视角
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是 Docker 内部的实现细节,并且能够在主机(译者注:运行 Docker 的机器)的文件系统上访问到。统一文件系统(union file system)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角

镜像与分层

  1. Docker 镜像是多个的,堆叠的分层的只读文件系统
  2. 每一层的变化是基于下一层的
  3. 相邻层之间的改动是有延续性的
  4. 从 docker 1.10 之后,每个镜像层的由一致性的 hash 生成 id,取代了旧版使用随机生成的 UUID
FROM ubuntu:15.10
COPY . /app
RUN make /app
CMD python /app/app.py

镜像命名规则

registry.abc.net/orgname/imagename:tag

  • registry.abc.net:Remote registry 的地址
    -(docker.io,gcr.io)
  • orgname:(optional)组织区分的镜像集合
  • imagename:镜像名称
  • tag:标签

docker.io/oracle/mysql:v5.7.1
k8s.gcr.io/kube-apiserver-amd64:v1.11.0

小心 latest,千万别被 latest tag 给误导了。latest 其实并没有什么特殊的含义。当没指明镜像
tag 时,Docker 会使用默认值 latest,仅此而已,所以我们在使用镜像时最好还是避免使用 latest,明确指定某个 tag,比如 httpd:2.3

容器的定义

  • 容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,
    唯一区别在于容器的最上面那一层是可读可写的
  • 要点:容器 = 镜像 + 读写层,并且容器的定义并没有提及是否要运行容器

Dockerfile

dockerfile

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

构建过程如下图所示:


Dockerfile 是 docker 构建镜像的基础,也是 docker区别于其他容器的重要特征,正是有了 Dockerfile,docker 的自动化和可移植性才成为可能

编写Dockerfile命令:
FROM:从一个基础镜像构建新的镜像

  • FROM ubuntu

MAINTAINER:维护者信息

RUN:非交互式运行shell命令

  • RUN apt-get -y update
  • RUN apt-get -y install nginx

ENV:设置环境变量

  • ENV MYSQL 5.7

WORKDIR /path/to/workdir:设置工作目录

  • WORKDIR /var/www

USER:设置用户ID

  • USER nginx

VOLUME <#dir>:设置volume

  • VOLUME [‘/data’]

EXPOSE:暴露哪些端口

  • EXPOSE 80 443

ENTRYPOINT [‘executable’, ‘param1’,’param2’]:执行命令

  • ENTRYPOINT ["/usr/sbin/nginx"]

CMD [“param1”,”param2”]

  • CMD ["start"]

注意:

  • ENTRYPOINT 指令和 CMD 指令虽然是在 Dockerfile 中定义,但是在构建镜像的时候并不会被执行,只有在执行 docker run 命令启动容器时才会起作用
  • 在 Dockerfile 中,只能有一个 ENTRYPOINT 指令,如果有多个 ENTRYPOINT 指令则以最后一个为准
  • 在 Dockerfile 中,只能有一个 CMD 指令,如果有多个 CMD 指令则以最后一个为准
  • 在 Dockerfile 中,ENTRYPOINT 指令或 CMD指令,至少必有其一,如果设置了 ENTRYPOINT,则 CMD 将作为参数

Dockerfile 例子

Dockerfile Best Practices

  • 使用统一的base镜像 - Centos, Ubuntu
  • 使用小型基础镜像 - 生成镜像也较小
  • 动静分离 - 经常变化的内容和基本不会变化的内容要分开,把不怎么变化的内容放在下层, 创建出来不同基础镜像供上层使用。
  • 最小原则:只安装必需的东西
  • 一个原则:每个镜像只有一个功能 - 不要在容器里运行多个不同功能的进程,每个镜像中只安装一个应用的软件包和文件,需要交互的程序通过 pod 或者容器之间的网络进行交流。
  • 使用更少的层 - 尽量把相关的内容放到同一个层,使用换行符进行分割
  • 切勿映射公有端口 - 镜像应该可以多次运行在任何主机上
  • 不要在构建中升级软件版本 - 应在基础镜像中更新,类似于类的继承,在基类里实现
  • 利用 cache 来加快构建速度 - docker build --cache-from 参数可以手动指定一个镜像来使用它的缓存。
  • 版本控制和自动构建 - 最好把Dockerfile和对应的应用代码一起放到版本控制中,然后能够自动构建镜像。

Docker 镜像实操演示

参考 03 Docker 镜像实操演示

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,861评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,263评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,033评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,999评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,000评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,483评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,850评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,827评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,366评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,404评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,525评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,130评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,853评论 3 338
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,293评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,426评论 1 276
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,082评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,590评论 2 366