• OSTree 官网文档


    本文是直接翻译了ostree官网文档。在正文之前,先将ostree的优点列出:

    • 可以进行分布式版本控制。跟git类似,可以根据分支、commit提交时的sha1码、提交时的log等,找到自己想要升级的软件版本
    • 增量下载。下载软件包时,只会下载更新了的部分,而不会全部下载,效率高,快
    • 可以回滚。升级失败时,自动回到升级前的版本
    • 支持从本地更新。可以部署在USB、SD、EMMC等本地存储介质上,但是一般用ostree都是远程升级。

    第一章 OSTree 概述

    简介

    OSTree是基于Linux的操作系统的升级系统,它对完整的文件系统树执行原子升级。它不是一个包系统(package system);相反,这是为了补充它们。主要模型是在服务器(server)上编写包,然后将它们复制到客户端(client)。
    底层架构可以概括为“操作系统二进制文件的git”。它在用户空间中运行,可以在任何Linux文件系统上运行。其核心是一个类似git的内容寻址对象仓库(object store),带有分支(branch 或“refs”)以跟踪仓库中有意义的文件系统树。跟git类似,您可以checkout 或 commit 这些branch 。
    最上层是bootloader配置、/etc目录下的管理和其他一些负责升级的功能(升级并不单纯是复制文件)
    您可以在纯复制模型中单独使用OSTree,但另一种方法是在顶部添加包管理器,从而创建混合树/包系统。

    使用示例

    OSTree主要是作为库去使用,这里也可以通过CTL工具(基本指令)来了解下ostree基本的工作方式。

    1. 创建ostree仓库

    ostree --repo=os_repo init //执行成功后,会在当前目录下新建ostree仓库:os_repo

    • ostree仓库有五种不同的模式:

    (1)bare。//裸机。 存储常规文件,用来存放硬链接。如果要存放root用户拥有的文件,就要以root权限运行ostree
    (2) bare-splt-xattrs //裸机拆分xattrs。
    (3) bare-user //裸机用户。
    (4) bare-user-only //仅裸机用户。
    ** (5) archive : //**归档。通过普通HTTP传输,可以被非root用户读写(最常用,主控升级采用这种方式)

    1. 向ostree仓库的某一个分支导入数据

    ostree --repo=repo commit --branch=foo tree/ 把tree目录下的内容导入到foo分支

    1. 查看repo仓库有什么分支

    ostree --repo=repo refs

    1. 查看foo分支下有什么内容

    ostree --repo=repo ls foo

    1. 从仓库检出(获取)某个分支的具体内容

    ostree --repo=repo checkout commit

    与传统包管理器的区别

    OSTree是为部署核心操作系统而设计的,在这里与dpkg和rpm包管理器做一个比较。传统上,包(package)是由附加了元数据和脚本的部分文件系统树组成的,这些文件系统树在依赖关系解析过程之后在客户机上动态组装。也就是说,dpkg和rpm不会更新整个文件系统,它只会更新对应的软件包,它可以由客户端检查完一个软件包中各个组件的依赖关系后,动态组装。

    而OSTree只支持记录和部署完整的(可引导的)文件系统树。它没有内置的关于给定文件系统树是如何生成的、单个文件的来源或者没有关于单个组件的依赖关系识。换句话说,OSTree只处理交付和部署;您可能仍然希望在每个树中包含关于进入树的各个组件的元数据。例如,系统管理员可能想知道您的树中包含了什么版本的OpenSSL,因此您应该支持等效的rpm-q或dpkg-L。
    OSTree核心强调通过HTTP复制只读操作系统树,其中操作系统包括(如果需要)一个完全独立的机制来安装应用程序,如果它们是系统全局的,则应用程序(app)存在/var中,如果是给指定用户安装应用程序,则存于/home中。所以我们必须先安装这个独立的机制,也就是ostree本身,再在此基础上安装app。示例应用机制是http://docker.io/
    除了更新整个文件系统外,Ostree也可以基于当前的文件系统,安装或者更新包。做法:把要更新或者新增的包放在一个基本树的顶部,将其记录在本地OsTree存储库中,然后为下一次引导进行设置。这样就不会更新整个运行中的文件系统,而是等下一次重启时,把新的包给装上。这种更新模式需要依赖一个C共享库:introspectable

    与 block/image 镜像复制的区别

    OSTree有些地方跟“dumb”复制和“stateless”无状态部署类似。,比如云部署中常见的模型就是节点从只读磁盘启动,用户数据保存在不同的卷上。OSTree和云模型共享的“哑”复制的优点是它可靠且可预测。
    但与许多默认的基于image映像的部署不同,OSTree只有两个目录在升级过程中是持久可写的:/etc和/var。

    因为OSTree在Unix文件系统层运行,所以它可以在任何文件系统或块存储布局上工作;可以将给定的文件系统树从OSTree存储库复制到纯ext4、BTRFS、XFS,或者任何支持硬链接的Unix兼容文件系统。注意:如果OSTree部署在上面,它将透明地利用一些BTRFS功能。

    “裸机”配置的用户会发现OSTree模型最有用。

    并行可安装只读文件系统树之间的原子转换

    包管理器和复制 image 映像之间的另一个根本区别是:OSTree旨在并行安装多个独立操作系统的多个版本。OSTree依赖于一个新的顶级OSTree目录;它可以并行安装在当前正在占用/root 目录的操作系统或者ostree分支上。

    在每台客户机上,都有OSTree存储库放在在/OSTree/repo中,**主控板上有两个ostree仓库:/ostree/repo_os和/ostree/repo_app ,分别存放ostree本身,和实际的应用程序app. **还有一组“部署”存储在/ostere/deploy/ S T A T E R O O T / STATEROOT/ STATEROOT/CHECKSUM中。每个部署主要由一组到存储库的硬链接组成。这意味着每个版本都进行了重复数据消除;升级过程只需要与新文件成比例的磁盘空间,外加一些恒定的开销。

    OSTree模型强调的是,操作系统只读内容保存在经典的Unix/usr中;它附带了创建Linux只读绑定挂载的代码,以防止意外损坏。给定操作系统的每个部署之间正好共享一个/var可写目录。OSTree核心代码不涉及此目录中的内容;如何管理和升级状态取决于每个操作系统中的代码。

    第二章 OSTree 仓库解析

    核心objects(对象)类型和数据模型

    OSTree很像git,核心层就是是一个版本控制文件系统。它的object类型类似于git;有commit对象和内容对象,也就是说,他会检查当前ostree有没有新的提交,或者文件有没有被修改。Git有“tree”对象,而OSTree将它们拆分为“dirtree”和“dirmeta”对象。
    OSTree的校验和是SHA256。它的内容对象包括uid、gid和扩展属性(但仍然没有时间戳)。他不会因为时间戳改变而认为文件已经更新,而是根据拥有文件的用户、用户组、以及文件内容是否改变来判定是否更新。
    以下详细介绍各个Objects

    1. Commit objects

    包含元数据,如时间戳、日志消息,最重要的是,对描述文件系统根目录的dirtree/dirmeta校验和对的引用。OSTree 也可以向git那样管理commit。

    2.Dirtree objects

    dirtree 包含:
    (1)内容对象的排序数组,这个数组中是一个配对的信息<文件名,校验和>;
    (2)二级排序数组,<文件名,dirtree校验和,dirmeta校验和>

    3. Dirmeta objects

    在git中,tree objects 包含元数据,例如其子对象的权限。但是OSTree将其拆分为一个单独的对象,以避免重复扩展属性列表。这些类型的对象作为以.dirmeta结尾的文件存储在objects目录中。

    4.Content objects 内容对象

    一个需要升级的文件就对应一个objects。每一个objects包含以下信息:uid、gid、mode、符号链接目标、扩展属性,后面跟上这个文件的具体内容。
    每一个objects对象 以zlib方式压缩,后缀为.filez,这些文件是经过SHA256校验的,存储在/ostree/repo_XX/objects目录下

    5.Xattrs objects

    在某些ostree存储库模式下(例如bare-splt-xattrs),xattrs存储在它们所引用的内容对象的一侧。这是通过两种专用对象类型(文件xattrs和文件xattr链接)完成的。
    文件xattrs存储xattrs数据,编码为GVariant。每个对象都由xattrs内容的校验和进行键控,允许多个引用。
    文件xattrs链接是与文件对象关联的硬链接。每个对象都由相应文件对象的相同校验和进行键控。硬链接的目标是一个现有的文件xattrs对象。如果达到链接太多的限制,这个对象也可能是一个普通文件。

    repo仓库类型和位置

    • bare : 内容文件仅作为常规文件存储的存储库;它被设计成一个“硬链接农场”的来源,在那里,每个操作系统签出只是链接到它。如果要在此模式下存储由root等用户拥有的文件,则必须以root用户身份运行OSTree。
    • bare-split-xattrs: 类似于bare,但它将xattrs存储为单独的对象。这是为了避免与内核强制约束(例如SELinux标签)以及其他可能对xattr执行短暂更改的软件(例如容器运行时)发生冲突。
    • bare-user : 是后来添加的一个类似于裸用户的模式,因为文件被解压缩,但它可以(而且通常应该)被创建为非根用户。在这种模式下,扩展元数据(如所有者uid、gid和扩展属性)存储在扩展属性中,名称为user。ostremeta,但未实际应用。裸用户模式对于构建以非根用户身份运行但希望生成根用户拥有的内容的系统以及非根容器系统非常有用。
    • bare-user-only: 是bare-user的变体。与bare-user不同,既不存储所有权也不存储扩展属性。这些存储库应该在 user 模式下 checkout(带有-U标志),在这种模式下,无论如何都不会应用此信息。因此,此模式可能会丢失元数据。bare-user-only 的主要优点是,存储库可以存储在不支持扩展属性的文件系统上,如tmpfs
    • archive: 通过普通HTTP传输数据。与tar文件一样,它可以由非root用户读写。

    在OSTree部署的系统上,“系统存储库”是/ostree/repo。它可以由任何uid读取,但只能由root写入。默认情况下,ostree命令将在系统存储库上运行;您可以提供–repo参数来覆盖它,或者设置$OSTREE_repo环境变量。主控板上,ostree命令就是在系统存储库 /ostree/repo_os 或 /ostree/repo_app上运行

    第四章 原子升级

    _一、_可以随时关机

    如果系统崩掉或断电,会升级到新版本,或保持旧版本

    二、通过HTTP进行简单升级

    OSTree支持的最基本模型是通过HTTP从服务器复制预先生成的文件系统树,只跟踪一个ref,也就是只下载一个指定的分支,该ref存储在.origin文件中用于部署。

    1. OSTree从远程服务器的.origin文件中获取ref的内容,当前正在运行的/etc 和 ref 指定的 文件系统中 /etc 内容会合并。
    2. 把要升级的objects pull 到主控上,只下载更改后的文件(zlib压缩),每个objects都经过校验和(SHA256)的验证,并存储在/ostree/repo/objects/中

    拉动完成后,我们已经下载了执行部署(升级)所需的所有objects。

    三、通过外部工具升级(eg. 包管理器)

    如介绍中所述,OSTree还允许在客户端计算文件系统树的模型。这些树是如何生成的,这是完全不可知的;它们可以用传统的包、顶部有部署后脚本的包来计算,或者由开发人员直接从本地版本控制中构建,等等
    目前大多数包管理器(dpkg和rpm)都在当前启动的文件系统上“实时”运行。他们可以使用OSTree的方法是,在当前启动的树中获取已安装包的列表,并从中计算一个新的文件系统。后面的一章将更详细地描述如何实现这一点:调整现有系统。
    为了本节的目的,让我们假设我们在repo中存储了一个新生成的文件系统树(它与现有的引导树共享存储空间)。

    四、组装新的部署目录origin

    指定要部署的commit(也就是要升级到哪个commit),OSTree首先为其分配一个目录。它的格式为/boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf$serial通常为0,但如果一个给定的commit 已经部署了多次,它将递增。同一个 commit 有可能会部署(更新)多次,因为之前的部署可能在 /etc 中有我们不想使用或覆盖的配置。

    现在我们有了一个部署目录,在当前启动的部署的/etc、ostree的默认配置和新部署(/usr/etc)之间执行三路合并。
    它的工作原理是:
    当前的/etc目录中,已经被 /usr/etc更改过的文件保持不变;没有被/usr/etcg

    1. 当前启动的部署(正在运行)的/etc中的文件将保留,这些文件是从默认的/usr/etc(同一部署的)修改而来的。
    2. 当前启动的部署/etc中未从默认/usr/etc(同一部署)修改的文件将从新部署的/usr/etc升级为新的默认文件。
    3. 粗略地说,这意味着一旦您在/etc中修改或添加了一个文件,该文件将永远按原样传播(尽管有一种极端情况,如果您的修改最终与未来的默认文件完全匹配,那么该文件将从那时起返回到后续的默认更新)。

    可以使用 ostree-admin-config-diff 来查看启动部署的/etc 和 ostree默认值之间的差异。

    五、原子交换boot配置

    此时,已经创建了一个新的部署目录作为 hardlink farm;正在运行的系统 和 bootloader配置 都没有受到影响。我们要将此部署添加到“部署列表”(deployment list)中。
    OSTree支持任意部署集之间的原子转换,但有一个限制,即当前启动的部署必须始终在新的部署集中。在正常情况下,我们只有一个部署,就是正在被boot加载的哪个,我们希望将新的部署添加到列表中。一个更复杂的命令可能允许创建100个部署,作为一个原子事务的一部分,这样就可以建立一个自动化系统,将它们一分为二。

    六、boot版本

    Ostree可以通过在/boot目录中实现“交换目录模式”,来实现新boot配置替换旧boot配置。
    我们通过一个软链接指向需要执行的boot. 如果当前正在运行的boot是 /ostree/boot.0, 我们就创建/ostree/boot.1,用新的内容去填充。然后让软链接指向/ostree/boot.1,此时 /ostree/boot.0就没用了,可以被废弃掉。

    第六章 OSTree数据格式

    一、关于“smart servers”

    OSTree和git之间的最关键的区别是git有一个“smart servers”。git 即使在通过https://获取数据时,http 也不仅仅是一个静态Web服务器,而是会为客户端动态计算和压缩packegs。
    相比之下,OSTree的作者认为,对于操作系统更新,许多部署都希望使用简单的静态Web服务器,这是大多数包系统设计使用的目标。主要优点是安全性和计算效率。像Amazon S3和CDN 也是静态nginx服务器。

    二、archive 格式

    只需gzip压缩每个content objects。元数据对象未压缩存储。这就很容易通过静态HTTP提供服务。注意:repo配置文件使用 archive-z2 模式。
    提交新内容时,可以看到objects/目录中生成了 新的 .filez文件

    三、archive 优缺点

    1. archive的优点:
    • 易于理解和实施
    • 可以由静态Web服务器直接通过纯HTTP提供服务
    • 客户端可以增量下载/解压缩
    • 节省服务器空间
    1. 缺点:
    • 客户端下载文件的时候,每一个需要更新的文件都要对一个HTTP请求
    • 下载之前,不知道文件大小

    第七章 管理OSTree仓库中的内容

    –depth=-1 检索所有commit的历史记录;–depth=3 检索最后3次commit。

  • 相关阅读:
    P4 开发实践 — NG-SDN Tutorial — Exercise 5: IPv6 Routing
    为什么在springboot中使用thymeleaf无法实现网络请求
    队列(JAVA)
    多数之和问题
    15、网站统计数据
    题解 [Codeforces1156D] 0-1-Tree
    InnoDB数据存储结构
    java实战:Redis实现查找附近的人
    Win Docker Desktop + WSL2 部署PyTorch-CUDA服务至k8s算力集群
    大数据技术Hive详解
  • 原文地址:https://blog.csdn.net/m0_37983106/article/details/127928822