Docker架构&&虚拟化原理
Docker简介
Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和 基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。
Docker的优点如下:
1、简化程序
Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放入Docker中进行管理。方便快捷已经是 Docker的最大优势,过去需要用数天乃至数周的 任务,在Docker容器的处理下,只需要数秒就能完成。
2、避免选择恐惧症
如果你有选择恐惧症,还是资深患者。Docker 帮你 打包你的纠结!比如 Docker 镜像;Docker 镜像中包含了运行环境和配置,所以 Docker 可以简化部署多种应用实例工作。比如 Web 应用、后台应用、数据库应用、大数据应用比如 Hadoop 集群、消息队列等等都可以打包成一个镜像部署。
3、节省开支
一方面,云计算时代到来,使开发者不必为了追求效果而配置高额的硬件,Docker 改变了高性能必然高价格的思维定势。Docker 与云的结合,让云空间得到更充分的利用。不仅解决了硬件管理的问题,也改变了虚拟化的方式。
Docker的架构
- Docker daemon( Docker守护进程)
Docker daemon是一个运行在宿主机( DOCKER-HOST)的后台进程。可通过 Docker客户端与之通信。
- Client( Docker客户端)
Docker客户端是 Docker的用户界面,它可以接受用户命令和配置标识,并与 Docker daemon通信。图中, docker build等都是 Docker的相关命令。
- Images( Docker镜像)
Docker镜像是一个只读模板,它包含创建 Docker容器的说明。它和系统安装光盘有点像,使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行 Docker镜像中的程序。
- Container(容器)
容器是镜像的可运行实例。镜像和容器的关系有点类似于面向对象中,类和对象的关系。可通过 Docker API或者 CLI命令来启停、移动、删除容器。
- Registry
Docker Registry是一个集中存储与分发镜像的服务。构建完 Docker镜像后,就可在当前宿主机上运行。但如果想要在其他机器上运行这个镜像,就需要手动复制。此时可借助 Docker Registry来避免镜像的手动复制。
一个 Docker Registry可包含多个 Docker仓库,每个仓库可包含多个镜像标签,每个标签对应一个 Docker镜像。这跟 Maven的仓库有点类似,如果把 Docker Registry比作 Maven仓库的话,那么 Docker仓库就可理解为某jar包的路径,而镜像标签则可理解为jar包的版本号。
Docker Registry可分为公有Docker Registry和私有Docker Registry。 最常⽤的Docker Registry莫过于官⽅的Docker Hub, 这也是默认的Docker Registry。 Docker Hub上存放着⼤量优秀的镜像, 我们可使⽤Docker命令下载并使⽤。
Docker虚拟化原理
传统虚拟化和容器技术结构比较:传统虚拟化技术是在硬件层面实现虚拟化,增加了系统调用链路的环节,有性能损耗;容器虚拟化技术以共享宿主机Kernel的方式实现,几乎没有性能损耗。
docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。避免了寻址、加载操作系统内核这些比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
Docker是如何将机器的资源进行隔离的?
答案是联合文件系统,常见的有AUFS、Overlay、devicemapper、BTRFS和ZFS等。
以Overlay2举例说明,Overlay2的架构图如下:
原理:overlayfs在linux主机上只有两层,一个目录在下层,用来保存镜像(docker),另外一个目录在上层,用来存储容器信息。在overlayfs中,底层的目录叫做lowerdir,顶层的目录称之为upperdir,对外提供统一的文件系统为merged。当需要修改一个文件时,使用COW(Copy-on-write)将文件从只读的Lower复制到可写的Upper进行修改,结果也保存在Upper层。在Docker中,底下的只读层就是image,可写层就是Container。
写时复制 (CoW) 技术详解
所有驱动都用到的技术—写时复制,Cow全称copy-on-write,表示只是在需要写时才去复制,这个是针对已有文件的修改场景。比如基于一个image启动多个Container,如果每个Container都去分配一个image一样的文件系统,那么将会占用大量的磁盘空间。而CoW技术可以让所有的容器共享image的文件系统,所有数据都从image中读取,只有当要对文件进行写操作时,才从image里把要写的文件复制到自己的文件系统进行修改。所以无论有多少个容器共享一个image,所做的写操作都是对从image中复制到自己的文件系统的副本上进行,并不会修改image的源文件,且多个容器操作同一个文件,会在每个容器的文件系统里生成一个副本,每个容器修改的都是自己的副本,互相隔离,互不影响。使用CoW可以有效的提高磁盘的利用率。所以容器占用的空间是很少的。
查看容器占用磁盘大小指令:
# 查看所有容器的大小
cd /var/lib/docker/containers # 进入docker容器存储目录
du -sh * # 查看所有容器的大小
du -sh <容器完整id> #查看某一个容器的大小
用时分配 (allocate-on-demand)
用时分配是针对原本没有这个文件的场景,只有在要新写入一个文件时才分配空间,这样可以提高存储资源的利用率。比如启动一个容器,并不会因为这个容器分配一些磁盘空间,而是当有新文件写入时,才按需分配新空间。
docker中的镜像分层技术的原理是什么呢?
docker使用共享技术减少镜像存储空间,所有镜像层和容器层都保存在宿主机的文件系统/var/lib/docker/中,由存储驱动进行管理,尽管存储方式不尽相同,但在所有版本的Docker中都可以共享镜像层。在下载镜像时,Docker Daemon会检查镜像中的镜像层与宿主机文件系统中的镜像层进行对比,如果存在则不下载,只下载不存在的镜像层,这样可以非常节约存储空间。
docker镜像层会生成一个UUID ,会根据镜像的名称,镜像版本生成不同的UUID
最后附一个查看容器资源使用情况的指令:
docker stats # 返回容器资源的实时使用情况,1秒刷新一次
docker stats --no-stream # 返回容器当时的资源使用情况
默认情况下,stats 命令会每隔 1 秒钟刷新一次输出的内容直到你按下 ctrl + c。下面是输出的主要内容:
[CONTAINER]:以短格式显示容器的 ID。
[CPU %]:CPU 的使用情况。
[MEM USAGE / LIMIT]:当前使用的内存和最大可以使用的内存。
[MEM %]:以百分比的形式显示内存使用情况。
[NET I/O]:网络 I/O 数据。
[BLOCK I/O]:磁盘 I/O 数据。
[PIDS]:PID 号。
docker run -m 500M redis #限制容器的最大使用内存为500M
docker run -d --memory 100M --name tomcat1 tomcat #内存限制
docker run -d --cpu-shares 10 --name tomcat2 tomcat #cpu限制
相关文章
- X86&ARM @Linux平台cache eviction功能测试
- memtester && s-tui cputest编译测试
- 在CentOS/RHEL/Scientific Linux 6 & 7 上安装Telnet
- [转]深入理解Docker ulimit(docker容器启动报错library initialization failed - unable to allocate file descriptor table - out of memory问题解决)
- Docker服务启动报错:Job for docker.service failed because the control process exited with error code
- 【前端学习之HTML&CSS】-- HTML第五篇 -- 文本元素
- scenes & segues within storyboards
- Windows下启动Docker容器遇到Error invoking remote method ‘docker-start-container‘: Error解决办法
- Docker - docker镜像的制作
- 华为HMS Core全新推出会员转化&留存预测模型
- 汇编子程序模块化(near&far)
- 使用 Rust & Warp 和 Docker 构建安全的 WebSocket 服务器
- Docker环境搭建与使用:docker常用的命令
- Spring MVC的Post请求参数中文乱码的原因&处理
- Swift的 convenience && designated init
- Docker容器重启策略以及docker run的--restart选项详解
- js的=,==,===,||,&&,三元表达式等等运算符
- 浅析如何解决终端输入长命令不换行覆盖(Docker容器内输入长命令折行覆盖)问题:如何设置docker容器tty终端窗口大小-Linux stty命令设置串口终端行列数
- SQL INSERT INTO & UPDATE & DELETE
- AT&T联盟Ubuntu,开放网络大步走
- 学习笔记(08):Python网络编程&并发编程-实现服务端可以对多个客户端提供服务
- 学习笔记(07):Python网络编程&并发编程-客户端与服务端代码bug修复
- CTSC&APIO&THUPC2018颓废记
- php中引用&的真正理解-变量引用、函数引用、对象引用
- torch中的几种乘法:torch.mm, torch.mul, torch.matmul &&矩阵相乘和矩阵点乘