本文是阅读《深入浅出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后台的采集功能是不能采集关键字的,那么老墨今天给大家说一个变通方法,让后台能采集关键字!方法如下: 1.系统设置--管理数据表--管理字段--增加字段(字段名:keywords字 ...

  2. openoffice将word转pdf中文乱码或消失的坑

    将windows系统下的中文字体文件(C:\Windows\Fonts),放到/usr/share/fonts下,必须重启openoffice.

  3. 地铁系统ajax人性化操作

    根据选择的城市不同,显示的地铁系统和线路图也不同

  4. js实时监听dom尺寸变化

    开发过程中总会遇到dom节点尺寸变化,去做一些相应的逻辑,第一想到的应该是用$(window).resize()去做,但是这个是监听浏览器窗口的所以这个时候要用 ResizeObserver Resi ...

  5. 缓存中间件-Redis(二)

    在上一篇中我们简单总结和介绍了Redis的几个方面 1.使用Redis背景 2.Redis通信多路复用的基本原理 3.Redis基本数据结构 4.Redis持久化方式 这一篇我们使用简单的业务场景来介 ...

  6. ASP.NET Core 6.0 添加 JWT 认证和授权

    序言 本文将分别介绍 Authentication(认证) 和 Authorization(授权). 并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能. 相关 ...

  7. python黑帽子(第五章)

    对开源CMS进行扫描 import os import queue import requests # 原书编写时间过于久远 现在有requests库对已经对原来的库进行封装 更容易调用 import ...

  8. ASP.NET和ASP.NETCore多环境配置对比

    前言 多环境配置应该都很熟悉了,最为常见的便是Debug和Release,例如下图是新建的一个asp.net项目,配置文件展开共有三个文件组成 据我所知,大多公司从来没编辑过Web.Debug.con ...

  9. SerialPort-4.0.+ 使用说明(Java版本)

    SerialPort-4.0.+ 项目官网 Kotlin版本使用说明 介绍 SerialPort 是一个开源的对 Android 蓝牙串口通信的轻量封装库,轻松解决了构建自己的串口调试APP的复杂程度 ...

  10. 【第六课】SHELL和计划任务(学习笔记)

    4月15日学习笔记