本文是阅读《深入浅出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容器标准

  1. OCI规范了什么?

    规范了容器镜像标准和容器运行时标准,两者通过一个文件系统包(filesystem bundle)来连接

  2. filesystem bundle有什么作用?

    将镜像解包成bundle,bundle包含了一个config.json配置文件和一个根文件夹,Docker引擎会识别这个bundle来运行容器

    config.json的结构包含公共部分和平台适配部分

    公共部分包含了版本信息、rootfs等等,平台部分则是对系统底层的适配,比如Linux的配置是cgroup和namespaces,Windows则是hypervisor

    可以看到Docker是怎么实现跨平台的

  3. 镜像规范规范了什么?

    规定了镜像的构建系统需要输出的内容和格式,并且可以被解包成bundle

    主要包含了以下几种

    1. 文件系统:一个镜像由多个层叠加组成,文件系统负责维护这些层的变更集
    2. manifest:记录层和配置文件的定位信息
    3. 配置文件:记录镜像运行时相关的参数和根目录的变更
    4. image index:记录不同平台的manifests配置

    下边是实例



    关于镜像的组成下文会继续探索

  4. 容器规范规范了什么?什么是容器运行时(runtime)?

    容器规范标准了容器的配置、运行环境和生命周期

    配置文件就是通过解包镜像获得的config.json,并通过这个文件获取支持的平台和创建容器需要的字段

    容器运行时负责运行容器的所有部分,但是实际上并不止运行程序本身;容器运行时负责:通过读取bundle里的配置文件,来准备容器所需要得环境和资源,然后创建容器并且管理他的生命周期

    容器运行时有多种实现,但大多都包含lower-levelhigher-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组成原理的更多相关文章

  1. Docker个人理解总结

    最新在学习Docker,记录下自己对Docker的理解. 一.Docker是什么? 1. Docker是一个能够把开发的应用程序自动部署到容器的开源引擎. 2.Docker使用Google公司推出的G ...

  2. 说透 Docker:虚拟化

    本章内容将讲解 Docker 虚拟化.虚拟化本质.namespace.cgroups. Docker 虚拟化 关于Docker 本小节将介绍 Docker 虚拟化的一些特点. Docker 是一个开放 ...

  3. docker——容器安装tomcat

    写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...

  4. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  5. Docker 第一篇--初识docker

    已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...

  6. 在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 ...

  7. docker for mac 学习记录

    docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...

  8. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  9. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

随机推荐

  1. 帝国CMS实现栏目批量修改:是否生成

    帝国cms实现栏目批量修改 是否生成:不生成栏目页, 不生成内容页, 不生成JS调用, 标签不调用的修改方本文关键字词:栏目批量设置第一步./e/admin/SetMoreClass.php中查找: ...

  2. Unity通过脚本创建Mesh(网格)

    ##1.创建一个带Mesh的物体 Unity中的网格作为组件不能脱离物体单独存在 新建脚本CreateMesh public class CreateMesh: MonoBehaviour { voi ...

  3. vue--vuex 中 Modules 详解

    前言 在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理.于是Vuex中就存在了另 ...

  4. 【GPLT】 紧急救援(c++)

    题目: 本题使用Dijkstra算法,但在模板上进行了一定的扩展,是一道不错的最短路题目. AC代码: 1 #include<iostream> 2 #include<cmath&g ...

  5. 面渣逆袭:Spring三十五问,四万字+五十图详解

    大家好,我是老三啊,面渣逆袭 继续,这节我们来搞定另一个面试必问知识点--Spring. 有人说,"Java程序员都是Spring程序员",老三不太赞成这个观点,但是这也可以看出S ...

  6. 通过源码了解Java的自动装箱拆箱

    什么叫装箱 & 拆箱? 将int基本类型转换为Integer包装类型的过程叫做装箱,反之叫拆箱. 首先看一段代码 public static void main(String[] args) ...

  7. Python 中删除列表元素的三种方法

    列表基本上是 Python 中最常用的数据结构之一了,并且删除操作也是经常使用的. 那到底有哪些方法可以删除列表中的元素呢?这篇文章就来总结一下. 一共有三种方法,分别是 remove,pop 和 d ...

  8. MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的“放大镜”式投影程序

    最近刚好因为一些原因整理这方面的内容,所以还是把这篇鸽了一年多的博客顺手写出来了∠( ᐛ 」∠)_.因为是当时课程设计的一部分,程序上难免会有一些不足和bug,在这里将设计的思路分享给大家. 本篇博客 ...

  9. mybatis混淆概念

    1.resultMap与resultType <mapper namespace="com.dao.FilmMapper"> <resultMap id=&quo ...

  10. Vue 学习之路(一)- 创建脚手架并创建项目

    安装脚手架 命令 npm install -g @vue/cli 打开 cmd 窗口输入以上命令.当出现以下界面即表示安装完成. 查看已安装脚手架版本 命令 vue -V 在 cmd 窗口输入以上命令 ...