Docker组成原理
本文是阅读《深入浅出Docker》的相关学习笔记
起初简单的以为Docker和容器是一种东西,后来才发现Docker是实现了Linux容器技术(LXC,可以提供轻量级的虚拟化)的一种实现
LXC技术使用Linux 内核和内核功能(Cgroups 和Namespaces)来分隔进程,以便各进程相互独立运行
于是好像有了一个定义:容器是一个相互隔离的和资源受限制的进程
当启动Docker时,会通过Namespaces和Cgropus来创建一个资源隔离的环境,然后将打包的应用程序和关联的文件复制到 Namespace 内的文件系统中
Docker引擎
Docker 引擎是用来运行和管理容器的核心软件
基于OCI标准,采用的模块化结构
主要结构:客户端、守护进程(docker daemon)、containerd和runc
他们共同负责容器的创建和运行
早期的Docker引擎结构由Docker daemon和LXC组成
Docker daemon负责创建容器和运行容器,功能都耦合在一块了
而LXC技术,使用其提供的Namespace和Cgroup来启动容器
为了摆脱LXC的依赖,解决跨平台和核心功能依赖外部工具的问题
Docker公司开发了名为Libcontainer的自研工具,用于替代LXC。Libcontainer的目标是成为与平台无关的工具,可基于不同内核为Docker上层提供必要的容器交互功能
后续Docker公司对Docker daemon进行了重构,将容器执行、容器运行是等功能做成小组件的方式
伴随着重构的进行,Docker公司也在推进着OCI标准(容器开放标准)即规范容器运行时标准(runtime-spec)和容器镜像标准(image-spec)
OCI容器标准
OCI规范了什么?
规范了容器镜像标准和容器运行时标准,两者通过一个文件系统包(filesystem bundle)来连接
filesystem bundle有什么作用?
将镜像解包成bundle,bundle包含了一个config.json配置文件和一个根文件夹,Docker引擎会识别这个bundle来运行容器
config.json的结构包含公共部分和平台适配部分
公共部分包含了版本信息、rootfs等等,平台部分则是对系统底层的适配,比如Linux的配置是cgroup和namespaces,Windows则是hypervisor
可以看到Docker是怎么实现跨平台的
镜像规范规范了什么?
规定了镜像的构建系统需要输出的内容和格式,并且可以被解包成bundle
主要包含了以下几种
- 文件系统:一个镜像由多个层叠加组成,文件系统负责维护这些层的变更集
- manifest:记录层和配置文件的定位信息
- 配置文件:记录镜像运行时相关的参数和根目录的变更
- image index:记录不同平台的manifests配置
下边是实例
关于镜像的组成下文会继续探索容器规范规范了什么?什么是容器运行时(runtime)?
容器规范标准了容器的配置、运行环境和生命周期
配置文件就是通过解包镜像获得的config.json,并通过这个文件获取支持的平台和创建容器需要的字段
容器运行时负责运行容器的所有部分,但是实际上并不止运行程序本身;容器运行时负责:通过读取bundle里的配置文件,来准备容器所需要得环境和资源,然后创建容器并且管理他的生命周期
容器运行时有多种实现,但大多都包含
lower-level
和higher-level
,需要注意的是,lower-level和higher-level得职责不同,解决不同的问题lower-level需要提供容器所需要得资源(如namesapece和cgroup)
higher-level负责传输和管理镜像,解包镜像并将命令传递给low-level,hight-level还对外提供Api
runc和containerd就是从docker中分离出来的low-level和hight-level
镜像
镜像只会包含必要的应用和服务以及所需要的依赖,以保持较小的体积
镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象
当拉取镜像的时候,可以看到这和镜像需要哪些层,结构如下图
也可以使用docker image inspect 镜像 -f "{{.RootFS}}"
命令来查看镜像里的分层,可以看到分层都是使用了sha256来散列过的
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层
当添加一个补丁,会继续增加新的分层,因为分层式只读的,不过上层的修改会覆盖下层的
镜像的层会共享,当拉取镜像的时候,Docker可以识别出要拉取的镜像中,哪几层已经在本地存在
启动流程
可以看出Docker将创建和管理容器的逻辑都从Docker daemon中移除,意味着容器运行时与Docker daemon是解耦的,有时称之为“无守护进程的容器(daemonlesscontainer)”,如此,对Docker daemon的维护和升级工作不会影响到运行中的容器
Docker daemon收到请求后会将命令传递给Containerd,Containerd会把镜像解包,将bundle传递给runc,注意到runc之上还有一个shim
shim的作用是允许runc创建完容器后退出,避免每一个容器都创建一个runc,此时会创建一个shim进程,再由shim来调用runc来创建容器、
当runc创建完容器退出后,shim就会成为容器进程的父进程
参考
https://www.qikqiak.com/post/containerd-usage/
https://www.cnblogs.com/michael9/p/13039700.html
https://iximiuz.com/en/posts/container-learning-path/
https://www.modb.pro/db/145438
https://www.waynerv.com/posts/container-fundamentals-learn-container-with-oci-spec/
https://iximiuz.com/en/posts/container-learning-path/
Docker组成原理的更多相关文章
- Docker个人理解总结
最新在学习Docker,记录下自己对Docker的理解. 一.Docker是什么? 1. Docker是一个能够把开发的应用程序自动部署到容器的开源引擎. 2.Docker使用Google公司推出的G ...
- 说透 Docker:虚拟化
本章内容将讲解 Docker 虚拟化.虚拟化本质.namespace.cgroups. Docker 虚拟化 关于Docker 本小节将介绍 Docker 虚拟化的一些特点. Docker 是一个开放 ...
- docker——容器安装tomcat
写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- Docker 第一篇--初识docker
已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...
- 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)
环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...
- docker for mac 学习记录
docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...
- scrapy爬虫docker部署
spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...
- [原][Docker]特性与原理解析
Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...
随机推荐
- 帝国CMS实现栏目批量修改:是否生成
帝国cms实现栏目批量修改 是否生成:不生成栏目页, 不生成内容页, 不生成JS调用, 标签不调用的修改方本文关键字词:栏目批量设置第一步./e/admin/SetMoreClass.php中查找: ...
- Unity通过脚本创建Mesh(网格)
##1.创建一个带Mesh的物体 Unity中的网格作为组件不能脱离物体单独存在 新建脚本CreateMesh public class CreateMesh: MonoBehaviour { voi ...
- vue--vuex 中 Modules 详解
前言 在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理.于是Vuex中就存在了另 ...
- 【GPLT】 紧急救援(c++)
题目: 本题使用Dijkstra算法,但在模板上进行了一定的扩展,是一道不错的最短路题目. AC代码: 1 #include<iostream> 2 #include<cmath&g ...
- 面渣逆袭:Spring三十五问,四万字+五十图详解
大家好,我是老三啊,面渣逆袭 继续,这节我们来搞定另一个面试必问知识点--Spring. 有人说,"Java程序员都是Spring程序员",老三不太赞成这个观点,但是这也可以看出S ...
- 通过源码了解Java的自动装箱拆箱
什么叫装箱 & 拆箱? 将int基本类型转换为Integer包装类型的过程叫做装箱,反之叫拆箱. 首先看一段代码 public static void main(String[] args) ...
- Python 中删除列表元素的三种方法
列表基本上是 Python 中最常用的数据结构之一了,并且删除操作也是经常使用的. 那到底有哪些方法可以删除列表中的元素呢?这篇文章就来总结一下. 一共有三种方法,分别是 remove,pop 和 d ...
- MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的“放大镜”式投影程序
最近刚好因为一些原因整理这方面的内容,所以还是把这篇鸽了一年多的博客顺手写出来了∠( ᐛ 」∠)_.因为是当时课程设计的一部分,程序上难免会有一些不足和bug,在这里将设计的思路分享给大家. 本篇博客 ...
- mybatis混淆概念
1.resultMap与resultType <mapper namespace="com.dao.FilmMapper"> <resultMap id=&quo ...
- Vue 学习之路(一)- 创建脚手架并创建项目
安装脚手架 命令 npm install -g @vue/cli 打开 cmd 窗口输入以上命令.当出现以下界面即表示安装完成. 查看已安装脚手架版本 命令 vue -V 在 cmd 窗口输入以上命令 ...