note
  • 个人笔记
  • 理解 Cilium 系列文章
    • (1) 初识 Cilium
    • (2) 理解网络数据包的流转过程
    • (3) ebpf
    • (4) ebpf Map
    • (5) ebpf 辅助函数
    • (6) XDP
    • (7) cilium 原理解析
  • linux
    • 内存
    • network
      • Linux虚拟网络之 tun/tap、ipvlan/macvlan、ipvtap/macvtap
      • socket
        • image
    • 文件系统
    • 详解Cgroup V2
    • ebpf
  • go
    • map
  • 平台
    • 关于函数冷启动
    • 镜像预热
    • 网关
    • Serverless平台遇到的问题⭐️⭐️ ⭐️⭐️⭐️
  • 工具合集
    • 压测 hey
    • 调试 pod
  • kubernetes
    • oci
      • OCI 和 runc
    • 容器网络
      • iptables ipvs
      • 如何实现一个 Kubernetes 网络插件
      • 性能提升40%: 腾讯 TKE 用 eBPF 绕过 conntrack 优化 K8s Service
    • CRI
    • 调度
    • kubectl top
    • 容器中的单进程和 k8s 中的 Pause 容器
    • Docker entrypoint 和 kubernetes 容器启动命令
  • 开发相关
    • 如何利用 Google 开源工具 Ko 在 kubernetes 上构建并部署 Go 应用
  • serverless
    • serverless 趋势解读
    • 有状态函数
  • 公众号内容
    • 题材列表
    • 内容
      • 为 Serverless 平台插上腾飞的翅膀--自定义 Faas 事件驱动事件源
      • 容器镜像按需加载
      • 【图解 Knative】解密 Eventing Broker-Trigger实现原理
      • 图解 kubectl 命令
      • Serverless 2021 最新调查报告
      • 典型的 Serverless 架构是怎样的
  • 容器技术
    • Docker 存储驱动
    • Docker overlay2 分层原理1
    • Docker overlay2 分层原理2
  • 操作系统
    • 第二章 中断,异常,系统调用
    • 第三章 计算机体系结构和 内存层次结构
  • 虚拟化
    • kvm与 qemu关系
    • kvm
  • 负载均衡
    • 负载均衡相关文章
Powered by GitBook
On this page
  • 1、镜像知识点回顾
  • 1.1、镜像技术
  • 1.2、存储驱动

Was this helpful?

  1. 公众号内容
  2. 内容

容器镜像按需加载

1、镜像知识点回顾

1.1、镜像技术

1.1.1. Images & layers

Docker image 是由一组上下有序的只读 layer 构建出来的,当用 Dockerfile 构建 image 时,Dockerfile 中每个命令就代表着一个 layer。每一个 layer 都只包含了相比于下一层的 layer 不同的内容,最后所有的 layer 堆叠起来就是一个新的 image。

以下面这个 Dockerfile 为例,它以 Ubuntu15.04 的 image 为基础 image ,加入一个 App 后构建出一个新的 image:

FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py

通过docker file制作镜像,每行命令产生了一个image layer。可以通过docker history {image_id}查看制作过程、命令和对应那一个layer。

$ docker build .
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM ubuntu:15.04
 ---> d1b55fd07600
Step 2/4 : COPY . /app
 ---> 31603973c835
Step 3/4 : RUN touch /app/test
 ---> Running in f5b9db5b7e18
Removing intermediate container f5b9db5b7e18
 ---> 4c95aef72941
Step 4/4 : CMD python /app/app.py
 ---> Running in 5a45dcd707cb
Removing intermediate container 5a45dcd707cb
 ---> f6509acd680a
Successfully built f6509acd680a

$ docker history f6509acd680a
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
f6509acd680a        About a minute ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "pyth…   0B
4c95aef72941        About a minute ago   /bin/sh -c touch /app/test                      0B
31603973c835        About a minute ago   /bin/sh -c #(nop) COPY dir:8b4813429364f8894…   73B
d1b55fd07600        5 years ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0B
<missing>           5 years ago          /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   1.88kB
<missing>           5 years ago          /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli…   701B
<missing>           5 years ago          /bin/sh -c #(nop) ADD file:3f4708cf445dc1b53…   131MB

1.1.2. Container and layers

容器 = 镜像 + 读写层

通过镜像启动容器时,docker 将会在这些只读 layer 的顶部添加一个 writable layer ,也叫作 container layer,container 运行时的所有修改都会写到这个 writable layer 中,包括创建新文件、修改存在的文件、删除文件(Copy On Write)等。Docker 用 storage driver 负责处理各个 layer 之间的交互,docker 目前支持的 storage driver 有 overlay、aufs、zfs、btrfs、devicemapper 等,这些其实都是一些不同类型的联合文件系统。

Container 和 image 之间最大的不同就是顶层的那个 writable layer。Container 删除后,这个 writable layer也会被删除,底层的 image不会发生任何变化。因为所有的修改都写到了writable layer,所以多个container可以共享部分甚至全部的只读layer(底层image),

Copy-on-write 写时复制,顾名思义,在写数据的时候再对源数据进行拷贝,它将共享和拷贝文件的效率最大化。在 container 中,如果要修改一个在只读 layer 中已经存在的文件,这个文件会先被拷贝到writable layer,然后将修改写入 writable layer 中的文件副本。在build image的过程中,某一层要 layer 修改底层 layer 的文件,流程一样如此。

1.2、存储驱动

Docker 的存储驱动称为 graph driver 或 storage driver ,containerd 的存储驱动称为 snapshotter。不论是docker 还是 containerd 的存储驱动,作用都是将从远程存储把镜像下载下来,然后以各种存储驱动特有的方式将镜像转换为一个文件目录的形式,用作容器启动的 rootfs。

1.2.1. 基于目录Union mount的驱动:aufs, overlay, overlay2

文件级存储驱动一般使用一种 union mount 的方法,依赖文件语义实现镜像的分层和 COW,包括 aufs,overlay 和 overlays2。文件级存储驱动将多个文件系统目录根据层级关系整合为一个,特点如下:

  • 在 image 的各个 layer 中查找目标文件;

  • 将目标文件复制至容器的 writable layer;

  • 在 writable layer 修改目标文件,这样镜像各个 layer 中的原文件将不会被读到。

  • 优点:内存利用率高;

  • 缺点:多写场景下 writable layer 会越来越大;

1.2.2. 基于块级快照的驱动: btrfs, zfs 和 devicemapper

块级存储驱动则一般基于内核对存储。比如基于btrfs、ZFS的快照特性。块级镜像方案有如下特点:

  • 多写场景下性能更好;

  • btrfs 和 ZFS需要更多内存;

  • ZFS适用场景:高密度的PaaS集群;

下图对比了几种驱动的性能[15]:

1.2.3. 配置方法

下面以docker为例介绍使用方法[10-12]:通过docker info查看当前的存储驱动

$ docker info 
 
Containers: 0 
Images: 0 
Storage Driver: overlay2 
 Backing Filesystem: xfs 
<output truncated>
# /etc/docker/daemon.json
{ 
  "storage-driver": "overlay2" 
}

Previous为 Serverless 平台插上腾飞的翅膀--自定义 Faas 事件驱动事件源Next【图解 Knative】解密 Eventing Broker-Trigger实现原理

Last updated 3 years ago

Was this helpful?

Docker所支持的存储驱动 overlay2 是当前 docker 默认的存储驱动,linux 支持度比较广泛。配置Docker 存储驱动除系统默认支持的文件系统,其他存储驱动需要将docker的工作目录/var/lib/docker/改成对应的文件系统(具体方法参考官网 ),然后更改 dockerd 配置文件。

https://docs.docker.com/storage/storagedriver/select-storage-driver/