技术冲浪: 拥抱 OCI(容器)时代

1,055 阅读10分钟

前言

X公司会议室里人声鼎沸, 项目部老大吼道:你们程序员不是天天吹我司的拳头产品是跨平台运行的吗?为什么每次部署到客户服务器上都要花上一周时间?上线后还有各种兼容bug, 等着修复, 你们知道上线晚一天, 客户会 找多少理由卡回款吗?,

实施部老大看情况不对连忙劝道: 咱们拳头产品的客户远至新疆,云南,近至北上广深, 还偶尔要出差去国外部署, 部署的服务几十个, 中间件几十个, 服务器类型覆盖了 Linux, unix, Win server 各个版本, 开发也不容易啊! 要是把项目 SAAS化实施工作也会轻松很多.

技术部老大赶紧借坡下驴道: 我司的拳头产品都是管理用户核心资产, 客户根本不可能愿意SAAS化! 部署遇到的问题也是技术问题, 我听说OCI容器化可以解决服务器兼容性的问题, 实施部和技术部都出些人组织建设下我们公司的OCI吧!

项目部老大闻听问题有了转机道: 技术升级上的事情项目部会大力支持, 但是无论如何不能因为兼容性再被卡回款了!

会后, X公司决定让技术部老鸟程序员 张大胖牵头搞OCI容器化!

张大胖接到任务的时候犯迷糊, 来回确定了下OCI的概念, 心想: 早就听说大厂都在用 K8S,Docker了, OCI还是头一回听说! 总之先搞个Demo吧.

OCI 浅探

Open Container Initiative (OCI 开放容器倡议) 是一个轻量级的开放治理结构(项目),在 Linux 基金会的主持下形成,其明确目的是围绕容器格式和运行时创建开放的行业标准。 OCI 于 2015 年 6 月 22 日由 Docker、CoreOS 和其他容器行业的领导者发起。

OCI 目前包含两个规范:

  • 镜像规范(image-spec)

    • 为了支持这种 UX,OCI 镜像格式包含足够的信息以在目标平台上启动应用程序(例如命令、参数、环境变量等)。
    • 该规范定义了如何创建 OCI 镜像,一般由构建系统完成,并输出镜像清单、文件系统(层)序列化和镜像配置. 在较高级别上,镜像清单包含有关镜像内容和依赖关系的元数据,包括一个或多个文件系统序列化档案的内容可寻址身份, 这些档案将被解包以构成最终的可运行文件系统。镜像配置包括应用程序参数、环境等信息。镜像清单、镜像配置和一个或多个文件系统序列化的组合称为 OCI 镜像。
    • github.com/opencontain…
  • 运行时规范(runtime-spec)

    • 运行时规范概述了如何运行在磁盘上解压的“文件系统包”。
    • 在高层次上,OCI 实现会下载一个 OCI 镜像,然后将该image 解压缩到一个 OCI 运行时文件系统包中。 此时,OCI Runtime Bundle 将由 OCI Runtime 运行。
    • github.com/opencontain…
  • 更多参考:

  • opencontainers.org/about/overv…

  • github.com/opencontain…

  • github.com/opencontain…

OCI 镜像规范以及实现

在顶层设计上,镜像清单包含有关镜像内容和依赖项的元数据,包括一个或多个文件系统层变更集档案的内容可寻址身份,这些档案将被解包后构成最终的可运行文件系统。 镜像配置包括应用程序参数、环境等信息。镜像索引是更高级别的清单,它指向清单和描述符列表。 通常,这些清单可以提供图像的不同实现,可能因平台或其他属性而异

github.com/opencontain…

根据上述网址得知, 规范包含以下8点.

  • 符号约定- 命名约定
  • Image Index 图像清单的注释索引
  • Image Layer 表示图像内容的文件系统布局
  • Image Config 确定适合转换为运行时包的图像的层顺序和配置
  • Image Manifest 描述构成容器镜像的组件文档
  • 文件系统层 描述容器文件系统的变更集
  • 转换 描述如何进行转换的文件
  • Descriptor 描述被引用内容的类型、元数据和内容地址的引用

关于 OCI 镜像实现

在Java 生态中 jib 可以不依赖 Dockerfile 构建容器.

jib 插件配置

<plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>${jib-maven-plugin.version}</version>
        <configuration>
          <to>
            <image>gcr.io/REPLACE-WITH-YOUR-GCP-PROJECT/image-built-with-jib</image>
          </to>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

执行 buildTar 命令根据配置项编译OCI镜像. 无需安装 docker.

mvn jib:buildTar

一旦构建了 OCI 映像,就可以通过名称发现、下载、通过哈希验证、通过签名信任并解压缩到OCI 运行时包中。

解压打包后的文件目录

  • manifest.json
    • Image Manifest 描述构成容器镜像的组件文档
  • config.json
    • Image Config 确定适合转换为运行时包的图像的层顺序和配置
  • 86973f6e6360a4c8bb5f26f181be.tar.gz
    • Image Layer 表示图像内容的文件系统布局
  • 89973f6e6360a4c8bb5f2612378U.tar.gz
    • Image Layer 表示图像内容的文件系统布局
  • ...
  • ...

这是符合 OCI 镜像规范的, 可以被符合 OCI 运行时规范的实现运行

OCI 运行时规范以及实现

定义一个称为标准容器的软件交付单元。标准容器的目标是以自描述和可移植的格式封装软件组件及其所有依赖项,以便任何兼容的运行时都可以在没有额外依赖项的情况下运行它,而不管底层机器和容器的内容如何.

标准容器规范定义:

  • 配置文件格式
  • 一组标准操作
  • 一个执行环境

举个例子: 运输行业使用的物理集装箱。运输集装箱是基本的交付单元,可以提升、堆叠、锁定、装载、卸载和贴标签。 不管它们的内容如何,通过标准化容器本身,它允许定义一致、更精简和更有效的流程集。对于软件,标准容器作为软件包的基本、标准化交付单元提供了类似的功能。

github.com/opencontain…

根据上述网址得知, 规范包含以下5点.

  • 符号约定 - 命名约定
  • 标准容器的 5 个原则
  • 文件系统包
  • 运行时和生命周期
  • 特定配置

关于 OCI 运行时实现

Docker 将其容器格式和运行时 runC 捐赠给 OCI,作为 OCI 的基石 。

感兴趣的可以去看看: github.com/opencontain…

更多实现

  • alibaba/inclavare-containers - 用于机密计算的 Enclave OCI 运行时
  • containers/crun - C 中的运行时实现
  • containers/youki - Rust 中的运行时实现
  • opencontainers/runc - OCI 运行时的参考实现
  • projectatomic/bwrap-oci - 将 OCI 规范文件转换为用于bubblewrap的命令行

OCI 与 Docker/K8s/OpenStack 之间的关系

  • docker
    • 简介: Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker 允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。
    • 定位: 主要针对 Paas 平台,是以应用为中心
  • k8s
    • 简介: Kubernetes(常简称为K8s)是用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。 它支持一系列容器工具,包括Docker等。
    • 定位: 主要针对 Paas 平台, 是以跨主机集群的自动部署、扩展以及运行应用程序容器的应用为中心
  • OpenStack
    • 简介: OpenStack是一个自由、开源的云计算平台。它主要作为基础设施即服务(IaaS)部署在公用云和私有云中,提供虚拟服务器和其他资源给用户使用。该软件平台由相互关联的组件组成,控制着整个数据中心内不同的厂商的处理器、存储和网络资源的硬件池。 用户可以通过基于网络的仪表盘、命令行工具或RESTful网络服务来管理。
    • 定位: 主要针对 Iaas 平台,以资源为中心,可以为上层的 PaaS 平台提供存储、网络、计算等资源。

docker 与 K8s 都可以运行在OpenStack 的内部云上, OpenStack 上可以将docker 与 K8s制作为镜像, 基于相关api进行扩展. 反之 OpenStack 上可将必要的中间件全都由支持OCI标准的实现运行。

  • docker与OCI生态
    • 特点
      • 导入符合OCI标准的镜像, 基于符合OCI标准的运行时启动
      • win/mac/linux 容器跨平台运行
      • 提供官方的镜像注册中心, 以及私服镜像注册中心, 用于远程加载镜像创建容
      • docker-swarm 支持跨机器部署
      • Docker 是使用最广泛的容器实现, 并不等于OCI。
    • 如何封装OCI生态
      • Linux namespace 八种资源隔离 (linux core 5.6)
        • Mount: 隔离文件系统
        • UTS: 隔离主机的 Hostname, Domain name
        • PID: 隔离进程编号, 无法看到其他名称空间的 PID, 意味着无法对其他进程产生影响
        • NetWork: 隔离网络资源, 如网卡,网络栈, ip 地址,端口等
        • User: 隔离用户和用户组
        • Cgroup: 隔离 cagoups 信息,进程有自己的 cgroups 的根目录视图(在 /proc/self/cgroup 不会看到整个系统的信息).
        • Time: 隔离系统时间, 2020 年 3 月最新的 5.6 版内核开始支持进程独立设置系统时间
      • 基于 runc 作为 OCI 容器运行时
      • Hook 容器生命周期并执行诸如设置和/或清理网络之类的事情的地方。
      • OCI镜像提供注册中心, 自动检查安全漏洞

  • K8s与OCI生态
    • 特点
      • 导入符合OCI标准的镜像, 基于符合OCI标准的运行时启动
      • win/mac/linux 容器跨平台运行
      • 服务发现和负载均衡
      • 存储编排
      • 自动部署和回滚
      • 自我修复
    • 如何封装OCI生态
      • Kubernetes 使用Container Runtime Interface解耦运行时实现。简单来说,CRI 定义了创建、启动、停止和删除容器的接口。它允许 Kubernetes 的可插拔容器运行时,您不必锁定到一个特定的运行时。目前有几种实现方式,例如cri-containerdand cri-o,它们最终都会使用oci/runc.
      • Linux namespace 八种资源隔离 (linux core 5.6)
        • ...
      • 基于 runc 作为 OCI 容器运行时
      • Hook 容器生命周期并执行诸如设置和/或清理网络之类的事情的地方。
      • OCI镜像提供注册中心, 自动检查安全漏洞

  • OpenStack与OCI生态
    • 特点
      • 支持 KVM、Xen、Lvc、Docker 等虚拟机软件或容器,默认为 KVM
      • 通过安装驱动,也支持 Hyper-V 和 VMware ESXi
      • OpenStack 社区和 Docker 联系紧密

更多参考: www.alibabacloud.com/blog/open-c…

PS: 打破 Dev/Ops

dev/ops 是 开发与运维的意思, 一般开发上线项目都是交给运维部署, 然后上线后再去测试那里领bug。 而打破 Dev/Ops 的意思是, 开发基于DevOps 生态的组件让项目持续交付, 不需要全部借助运维, 甚至在部署前自动检查一些bug。

  • devops 组件
  • 交付物料
  • 容器
  • 镜像私服
  • 容器运行时
  • War/Jar 编译后的包
  • 测试环境
  • 部署环境
  • ci
  • cd
  • 代码托管平台
  • 服务监控