到底什么是Unikernel?

本文讲的是到底什么是Unikernel,【编者的话】本文介绍了一种新的应用虚拟化技术,它让应用及其所依赖的运行环境、甚至是连内核一起打包,直接运行在硬件或是Hypervisor上,从而更加高效的利用计算机资源。非常有意思,推荐给大家。

如果你持续关注DevOps周刊,DevOps主题的会议或是对技术真正感兴趣,你也许已经听说Unikernel很多次了。在过去的几个月,它似乎越来越受关注。

然而,究竟什么是Unikernel? 它是我想要的东西吗?

我纠结这个问题许久。不知如何定义Unikernel以及它存在的意义?

什么是Unikernel?

真相的来源仅仅是Wikipedia上的一段晦涩的解释,我们先看看:

Unikernel是通过使用专门的库操作系统来构建的单地址空间机器镜像。开发者通过选择栈模块和一系列最小依赖库来运行应用,而这些栈和库对应于操作系统中运行应用所必需的依赖。

这些库负责应用和配置代码编译,构建成封闭的、固定用途的镜像(Unikernel)可以直接在虚拟机管理程序(hypervisor)或硬件上运行,不需要类似Linux或Windows的操作系统介于其中。
---- 维基百科:Unikernel

都清楚了,对吗?

好吧,如果是我,或许以上并没有说太多。接下来是我对Unikernel的解释。

首先让我们跟着这里例子回顾一下。假设你是一个开发者在写PHP应用。当你运行你的PHP(其他Ruby、Node、Perl均类似)应用,你本质上是在运行:

  • 语言解释器:PHP、Perl、Ruby、...
  • 调用操作系统中系统级别的API
  • 其中的一些API调用需要不同级别的权限,强制切换应用程序的上下文...(用户空间 vs. 内核空间)
  • 所有运行在操作系统上,例如CentOS、Debian、Ubuntu、...
  • 或许是运行在VM上,例如VMware、Xen、KVM、...
  • 或许是运行在自己的虚拟化管理系统上,例如ESXi、Xen Hypervisor...
  • 依次运行在硬件上
  • 通过BIOS或UEFI来引导

说老实话,如果你在抽象一个应用程序构建所需的所有层次,这会是一个奇迹般的工作。

但是他们做到了。并且做得非常好,有较好的性能。但是你必须认识到,在提供应用运行环境的硬件到应用程序本身存在许多层。

那就是Unikernel试图解决的:删除应用与硬件中间臃肿的部分。让最“精简”的操作系统运行你的代码。

这里有一篇论文总结得非常好: 

Unikernel的愿景:当你看到云客户端时就像看到单应用硬件一样。

The Rise and Fall of the Operating System

Unikernel试图抹去现代操作系统带来的一些复杂性。因为“通用”的操作系统(就像任何Linux和Windows的发行版),通常会伴随着带来一些对你的应用来说并不需要的驱动、依赖包、服务、等等,但这些对每一个操作系统来说某种程度上又是必需的。

甚至是在Linux内核的核心模块都并不是需要每一次都完全加载。像USB驱动这类东西在虚拟化的“云”环境被认为是无用的,但仍然会被包含在内核中。

相比容器和虚拟化,Unikernel所呈现的演进如下图:

(来源:road_to_unikernels

Unikernel对比通用的操作系统例如Linux有许多优势;
• 安全性的提升:只运行操作系统的核心,废弃掉那些可能是干扰源的视频和USB驱动。
• 占用很小空间:想象一下能够抹去95%内核的大小,因为你的应用不需要那些。
• 定制的实现:深谙应用并且把内核精简调整到你想要的部分。
• 快速精准的运行Unikernel实例(就像运行一个Docker实例一样),启动时间少于1s。

这样我们非常自然的把Unikernel当作是微服务的备选方案。

用Unikernel抹去复杂的中间层

如果你运行应用之后想要它的开销是最小的,那你就可能要考虑制作一个Unikernel。

为此,要使用库操作系统(LibOS)。一个库操作系统会给你提供构建自己的Unikernel的方式。最值得关注的是MirageOS(术语“unikernel”的创造者)和Rump Kernels。两者本质上都是一系列标准化的驱动和库,这样你就不需要重复发明像TCP栈、持久存储层等这类东西。

Unikernel是用高级语言定制的操作系统内核,并且作为独立的软件构件。完整的应用(或应用系统)作为一个分布式系统运行在一套unikernels上。
MirageOS基于OCaml语言并且让unikernels运行在Xen hypervisor上。
-- queue.acm.org: Unikernels: Rise of the Virtual Library Operating System

目前最流行的用来写unikernel的语言是:
• Rust
• Go (or 'golang')
• OCaml
• Haskell

这些并不都是新的编程语言。除了Go和Rust,其他均有超过15年的历史。

为了使操作系统和应用运行得更加流畅,这些unikernel库需要使用内核部分尽可能小。

现在,由于虚拟化技术,像Xen或VMware这类虚机管理系统(注*:原Operating System)把异构的硬件设备抽象成一堆标准的虚拟化设备,unikernel也能为定制的虚拟设备而优化。

Unikernel利用虚拟化的优势创造出一种专属的经过优化的操作系统。

想要编译应用程序的“unikernel”,需要依赖MirageOS的库和OCaml语言,结果像这样:

编译器输出一个完全独立的内核取代Unix可执行文件。这些unikernels是只为满足特定的应用程序和配置文件而实现的库操作系统VM,并且会依赖hypervisor提供的资源复用和隔离。
--- queue.acm.org: Unikernels: Rise of the Virtual Library Operating System

最终你通过运行一个Unikernel,精简专属的操作系统,来运行你应用程序的一部分。如果你的应用和配置需要更新,你需要重新编译你的源码来生成新的Unikernel并部署新版本。如果是新的安全升级?也同样需要重新编译和部署。

这将使部署的协调和编排更加困难,但好处是运行应用程序更加高效。

构建不可变的基础设施架构的关键在于:应用程序不再保存状态,并且能方便地丢弃和重新构建。

一方面,我们可以让Unikernel运行在Docker容器中,但是是否应该尽量避免增加其他复杂的中间层?另一方面,Docker在使用和部署上的优势确实可以弥补这点中间层的开销。

谁应该使用Unikernel?

实话实说,这个问题的答案对我来说还并不明确。我认为说如果你现在是要在WordPress上部署web应用,使用Unikernel也许还有一定的鸿沟。

另一方面,Unikernel的好处是明显的,但需要一个完全不同的模式来管理你的基础设施,一组不同的技能来构建这类的应用和内核并且需要深谙目前对我们来说还完全陌生的一个概念:不可变的基础设施架构。

也许在今后的5至10年,我们会以新的规范一样来部署Unikernel。目前,我认为它针对一小部分想要相当专业和安全应用的用户。对于大多数普通用户,虚机(或是,如果你走在技术前沿一定会明白:Docker容器)或许才是你应该专注的。

更多Unikernel相关阅读:

如果您对这个主题感兴趣,推荐您一些相关链接:

• Unikernels: Rise of the Virtual Library Operating System
• The Rise and Fall of the Operating System (pdf)
• Presentation: The Road to Unikernels
• After Docker: Unikernels and Immutable Infrastructure
• Unikernels, meet Docker!

原文链接:What is a ‘unikernel’? (翻译:张怡)

===================
译者介绍
张怡,华南理工大学应届研究生。读研期间专注云计算领域,容器和虚拟化技术爱好者。

原文发布时间为:2015-11-26

本文作者:张怡 

本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。

原文标题:到底什么是Unikernel?

时间: 2024-11-10 07:54:31

到底什么是Unikernel?的相关文章

到底什么是 Unikernel?

到底什么是 Unikernel? 果你持续关注DevOps周刊,DevOps主题的会议或是对技术真正感兴趣,你也许已经听说Unikernel很多次了.在过去的几个月,它似乎越来越受关注. 然而,究竟什么是Unikernel? 它是我想要的东西吗? 我纠结这个问题许久.不知如何定义Unikernel以及它存在的意义? 什么是Unikernel? 真相的来源仅仅是Wikipedia上的一段晦涩的解释,我们先看看: Unikernel是通过使用专门的库操作系统来构建的单地址空间机器镜像.开发者通过选择

你知道到底什么是Unikernel吗

如果你持续关注DevOps周刊,DevOps主题的会议或是对技术真正感兴趣,你也许已经听说Unikernel很多次了.在过去的几个月,它似乎越来越受关注. 然而,究竟什么是Unikernel? 它是我想要的东西吗? 我纠结这个问题许久.不知如何定义Unikernel以及它存在的意义? 什么是Unikernel? 真相的来源仅仅是Wikipedia上的一段晦涩的解释,我们先看看: Unikernel是通过使用专门的库操作系统来构建的单地址空间机器镜像.开发者通过选择栈模块和一系列最小依赖库来运行应

DockerCon 2016:阿里专家解读unikernel

最近一段时间,unikernel这个词的曝光率越来越高,到处都可以看到,让人不禁好奇,unikernel到底是什么呢? Wikipedia上有定义,我们把第一段摘抄过来: Unikernels are specialised, single address space machine images constructed by using library operating systems. A developer selects, from a modular stack, the minim

Docker CTO Solomon说的LinuxKit到底是什么?

在奥斯汀举办的DockerCon17上,Docker公司的CTO Solomon宣布了一个新的开源项目LinuxKit .我们从几个方面出发研究下到底什么是LinuxKit. 1.Linuxkit是什么? LinuxKit是用来构建安全.可移植.精益的专门为容器服务的操作系统的工具集.(A toolkit for building secure, portable and lean operating systems for containers,https://github.com/linux

安全弹出USB到底有什么用?

  在弹出U盘时,出现"设备正在使用中"的提示时,通常是由于程序使用该设备中的文件所致.对此我们需要关闭正在使用U盘数据的程序或窗口,然后再尝试弹出U盘.但也有时候你会烦于等待时间过长,或是再三取消占用不成功,而将USB设备直接拔出来,安全弹出USB到底有什么用,下面就让我们一起来看看吧. 很久以前,操作系统曾经把磁盘当成一直陪在身边的信任对象.读取或是写入文件时,操作系统觉得,磁盘中的文件仍然可以访问,不会中途变卦忽然闪人.当你在电脑上打开了磁盘里的文件,读取程序就希望重回磁盘继续阅

upload-这到底报的是什么错误啊,看不懂啊

问题描述 这到底报的是什么错误啊,看不懂啊 解决方案 ChooseAreaActivity类找不到,检查是否存在以及路径是否正确 解决方案二: 请检查 cool/weather.app/com.coolweather.app.activity.ChooseAreaActivity 类的来源.你是否是引用了第三方的库?应该是指定的路径.或者包含的方法不对. 解决方案三: 看看是不是这个错误 今天调试程序的时候报了 java.lang.RuntimeException: Unable to inst

销毁链表到底有什么用,程序结束后不应该所有的内存都释放完了吗

问题描述 销毁链表到底有什么用,程序结束后不应该所有的内存都释放完了吗 销毁链表到底有什么用,程序结束后不应该所有的内存都释放完了吗 解决方案 是的,不管程序释放不释放,程序运行结束肯定释放.但是你写小程序要养成好习惯.不然大程序没有释放,这对于那种连续运行很久的程序来说就是一个灾难了. 解决方案二: C++还是java?C++是不会自动释放的.java大部分都 能自动释放,但也存在一些特例 解决方案三: c++ 程序结束后不释放? 链表就是结构体吗 没什么特殊的啊 解决方案四: 这个和申请变量

WiFi真正的商业价值到底在哪里

近日,一家名为WiFi共享精灵的企业获得千万美元融资的新闻引爆了互联网业界的关注,这也让外界开始掀开不为人知的WiFi争夺战的内幕. "商用WiFi,下一个移动入口"的提法被响亮推出,而在这个高达亿万级的市场里,运营商.互联网业界大佬.草根创业者均云集于此,试图掘金WiFi所蕴藏的无穷的商业价值. 相比此前炙手可热的智能家居的争夺,WiFi的争夺无疑意义更大.看看互联网世界的发展,人与信息的连接,人与交易的连接,人与信息的连接创造了BAT国内互联网界的三大巨头,而未来更大的蓝海在于人与

c++问题-在acm上刷题老是通不过,求大神指点一二,到底问题出在哪里。不胜感激!!!

问题描述 在acm上刷题老是通不过,求大神指点一二,到底问题出在哪里.不胜感激!!! #include #include using namespace std; int main() { int T; int k,t=0; int i, j, n1, n2; char a[1010], b[1010], c[1015]; string d[20], e[20], f[20]; cin>>T; for(k=1; k<=T; k++) { cin>>a>>b; d[