Docker-原理之写实复制(cow)

作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们在上一章,讲了虚拟化,虚拟化是把硬件虚拟化,然后创建出来的虚拟机完全隔离,而Docker则是软件(内核)虚拟化,他的隔离性会低于虚拟机。我们将通过3-4周来讲解Docker相关内容,由于涉及到内容较多,就不一一列出来具体的细节,主要从以下几个方面来讲解:

Docker基本情况

Docker基本命令

Dockerfile

Docker镜像

Docker仓库

Docker原理(本小节属于)

Docker网络&存储&日志

Docker-Compose

Docker番外篇

基于我们对联合文件的理解,我们来讲解写实复制(cow),其实在讲kvm-外部快照的时候也提到了这个技术。

当 Docker 第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层之上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。由此,该文件的只读版本依然存在于只读层,只是被读写层的该文件副本所隐藏。该机制则被称之为写时复制(Copy on write)。下面就是几种文件操作的具体流程。

添加文件

在容器中创建文件时,新文件被添加到可读写层中。

容器里面创建新目录

csharp 复制代码
[root@localhost ~]# docker exec -it df3 bash
[root@df36a78f937e /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@df36a78f937e /]# mkdir -p eee

UpperDir同步存在

这2个文件的inode都是一样的(本质上他们就是一个文件),有兴趣可以下去对比下。

读取文件

在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件。如果这个文件存在于下面的只读层中,Docker直接从该只读层读取文件内容,不涉及任何复制操作。这是因为读操作不会改变文件内容,所以可以安全地与其它容器共享。

修改文件

在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之。举例来说,就是如果编辑一个已经存在的文件,当保存以后,UpperDir里面就会出现同路径下的的同名文件,以后的读写操作的就是这个文件。

但是这个实际显示和理解的逻辑出现了一点误差,比如我在容器里面查看一个文件,那么这个时候我看到应该是LowerDir的内容,他的inode是固定的不会变的,可以在LowerDir层和MergeDir层看到他的inode都是一样的,可以确认是一个文件。当我对这个文件进行修改以后,UpperDir层出现文件以后,他有新的inode,到这里都是没问题的。但是这个时候在去看MergeDir的inode还是没有变化,按照联合文件系统来解释,MergeDir=LowerDir+UpperDir,当文件冲突的时候以UpperDir为准,从内容来看是没问题的,但是inode这个时候应该是MergeDir和UpperDir一样才对,但是实际是MergeDir层的inode并没有发生改变。

删除文件

在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作,原始文件不会被删除,此为白障(whiteout)这个白障我们通过例子来讲解。

perl 复制代码
#我们进入容器删除了3个文件
[root@e8bd94fb3082 bin]# pwd    
/bin
[root@e8bd94fb3082 bin]# ll |grep kill
-rwxr-xr-x 1 root root   33608 Sep 30  2020 kill
-rwxr-xr-x 1 root root   28336 Sep 30  2020 pkill
-rwxr-xr-x 1 root root   24184 Sep 30  2020 skill
[root@e8bd94fb3082 bin]# rm -rf kill skill pkill
[root@e8bd94fb3082 bin]# ll |grep kill
[root@e8bd94fb3082 bin]# 

#UpperDir,这里就显示了3个特殊的文件,就是我们删除的3个文件
root@localhost bin]# docker inspect e8bd |grep -i UpperDir
                "UpperDir": "/var/lib/docker/overlay2/5b817c1abadb32403449f9123c13c2d8b0f95ee9f402444e23e344b466b1b4ca/diff",
[root@localhost bin]# cd /var/lib/docker/overlay2/5b817c1abadb32403449f9123c13c2d8b0f95ee9f402444e23e344b466b1b4ca/diff
[root@localhost diff]# ls
usr
[root@localhost diff]# cd usr/bin/
[root@localhost bin]# ll
total 0
c--------- 1 root root 0, 0 Dec  5 09:57 kill
c--------- 1 root root 0, 0 Dec  5 09:57 pkill
c--------- 1 root root 0, 0 Dec  5 09:57 skill

运维小路

一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!

关注微信公众号《运维小路》获取更多内容。

相关推荐
运维&陈同学4 分钟前
【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
大数据·运维·elk·elasticsearch·微服务·云原生·logstash
会飞的爱迪生6 分钟前
nginx反向代理+缓存
运维·nginx·缓存
有一只柴犬21 分钟前
Nginx实现接口复制
运维·nginx·lua
KXue070329 分钟前
【Linux 之一 】Linux常用命令汇总
linux·ubuntu·shell
diaya1 小时前
clickhouse 离线包安装(ubuntu)
linux·服务器·网络
练小杰1 小时前
Linux 文件的特殊权限—ACL项目练习
android·linux·运维·服务器·经验分享·学习
AI青年志1 小时前
【服务器】ubuntu20.04安装cuda12.01(使用runfile安装)
linux·运维·服务器
wanhengidc1 小时前
高防服务器对于网络攻击是怎样进行防御的?
运维·服务器
叶 落2 小时前
Centos 修改 yum 源为阿里云
linux·阿里云·centos·yum
玖石书2 小时前
[c++]Linux平台下的动态库加载技术详解
linux·c++·算法