【重识云原生】第二章计算第一节——计算虚拟化技术总述-程序员宅基地

技术标签: 云原生  Xen  原力计划  VMare  云原生-IaaS专栏  云计算  

云平台计算领域知识地图:

楔子:计算虚拟化技术算是云计算技术的擎天之柱,其前两代技术的演进一直引领着云计算的发展,即便到了云原生时代,其作用依然举足轻重。

一、计算虚拟化技术总述

1.1 虚拟化技术定义与术语

1.1.1 虚拟化技术定义

        援引《虚拟化技术发展编年史》的定义:在计算机科学中,虚拟化技术(Virtualization)是一种资源管理(优化)技术,将计算机的各种物理资源(e.g. CPU、内存以及磁盘空间、网络适配器等 I/O 设备)予以抽象、转换,然后呈现出来的一个可供分割并任意组合为一个或多个(虚拟)计算机的配置环境。虚拟化技术打破了计算机内部实体结构间不可切割的障碍,使用户能够以比原本更好的配置方式来应用这些计算机硬件资源。而这些资源的虚拟形式将不受现有架设方式、地域或物理配置所限制。虚拟化技术是一个广义的术语,根据不同的对象类型可以细分为:

  • 平台虚拟化(Platform Virtualization):针对计算机和操作系统的虚拟化。
  • 资源虚拟化(Resource Virtualization):针对特定的系统资源的虚拟化,如内存、存储、网络资源等。
  • 应用程序虚拟化(Application Virtualization):包括仿真、模拟、解释技术等,如 Java 虚拟机(JVM)。

        本文主讲计算领域的虚拟化技术按照上述分类属于平台虚拟化技术,简单来说,就是将一台物理服务器的资源虚拟并组合为多台逻辑服务器(即虚拟机),虚拟机共享物理机的 CPU、内存、IO 硬件等资源,但虚拟机之间逻辑隔离,可运行不同操作系统,从而使不同应用程序能并行运行而彼此不受影响。此类物理服务器,在云计算领域一般称为宿主机(Host),宿主机中运行的虚拟机称为客户机(Guest),或者直称云主机。

1.1.2 主要技术名词概念

  • VM,Virtual Machine,虚拟机,即Guest客户主机;
  • VMM,Virtual Machine Monitor,虚拟机监控器;
  • VMCS,在VT-x环境中,引入了VMCS(Virtual Machine Control Structure,虚拟机控制结构),以便更好的支持CPU虚拟化。VMCS用于保存虚拟CPU需要的相关状态,比如:CPU在根模式和非根模式下的寄存器的值、VM-Exit的原因等,当CPU发生VM-Exit和VM-Entry时,会自动查询和更新VMCS,VMM也可以通过配置VMCS控制CPU的行为。
  • 全虚拟化技术,Full-virtualization,指为客户机提供完整的虚拟X86平台, 包括处理器、 内存和外设等功能部件全面虚拟化的技术, 支持运行任何理论上可在真实物理平台上运行的操作系统,为VMare研发的第一代x86架构的虚拟化技术。
  • 半虚拟化技术,Para-virtualization,在全虚拟化技术基础上,将客户机操作系统做一定程度的定制修改,使其对硬件资源的访问可直接向VMM申请使用,以大幅提升虚拟机性能的第二代虚拟化技术,以Xen为典型实现。
  • 硬件辅助虚拟化技术,HVM,在全虚拟化技术基础上,通过物理平台本身(主要是CPU)提供对特殊指令截获和重定向的硬件增强虚拟化的技术,以Intel VT-x技术与AMD-V技术为代表。
  • VMX root operation,硬件辅助虚拟化技术Intel VT-x技术中,专为宿主机运行而增设的运行态权限模式。
  • VMX non-root operation,硬件辅助虚拟化技术Intel VT-x技术中,为虚拟机运行的常规运行态权限模式。
  • VMare,全球云基础架构和移动商务解决方案领导厂商,为企业客户提供基于VMware虚拟化技术解决方案的IT服务商,在虚拟化和云计算基础架构领域处于全球领先地位,拥有 400,000多家客户和55,000多家合作伙伴。
  • Xen,由剑桥大学计算机实验室开发的一个开源虚拟化项目,可直接运行于硬件层,属于type-I型虚拟化系统,通过定制虚拟机操作系统来实现虚机对硬件资源的直接访问,以高性能、占用资源少著称,赢得了IBM、AMD、HP、Red Hat和Novell等众多世界级软硬件厂商的高度认可和大力支持,已被国内外众多企事业用户用来搭建高性能的虚拟化平台。
  • KVM,全称Kernel-based Virtual Machine,是基于Linux内核的第三代开源虚拟化解决方案,依托硬件辅助虚拟化技术,提供CPU虚拟与内存虚拟化能力,并结合经过特殊改造后的Qemu(Qemu-kvm)来实现完整的平台虚拟化功能,目前主流云厂商的技术虚拟化技术均基于此。
  • Intel VT-x,Intel公司的硬件辅助虚拟化技术实现,通过增加新的指令集与root operation运行模式,拦截VMM(Virtual Machine Monitor,虚拟机监视器)参与虚拟机“中断”请求的处理与特定指令的执行,从而大幅提升虚拟机运行性能、可靠性和安全性的硬件虚拟化增强技术统称。
  • AMD-V,AMD公司实现的与Intel VT-x类似的HVM技术。
  • VMExit,在VT-x环境中,非根模式下(即Guest中),执行敏感指令触发的“陷入”称为VM-Exit。VM-Exit发生时,CPU自动从非根模式切换到根模式下,然后就可以由VMM对触发VM-Exit的敏感指令做进一步处理或模拟。
  • VMEntry,与VM-Exit对应的是VM-Entry,此操作由VMM发起,通常是VMM调度某个Guest(或VCPU)运行时引起,此时CPU自动由根模式切换为非根模式。
  • I/O through,I/O透传技术,指将宿主机host中的IO物理设备直接穿过宿主机、虚拟化层而直接分配给虚拟机使用的一类I/O虚拟化技术,可以获取近乎native的性能;
  • VMare GSX,VMare推出服务器虚拟化第一款产品,基于软件全虚拟化技术实现;
  • VMware ESX,2009年VMware推出的第二款虚拟化产品,可将ESX直接安装在物理计算机上,但是ESX并不能完全地摒弃宿主操作系统,而是将虚拟化主程序写入到linux的操作系统内核中,通过linux系统的Servers Console来运行,而资源和虚拟机的管理工作则通过合作代理伙伴程序和编写脚本来执行,基本属于Type-I型虚拟机技术。
  • VMware ESXi,2011年VMware推出的第三款虚拟化产品,也是当前应用最广泛的虚拟化产品,同样是裸机安装,其改进之处是将虚拟化层中linux层剔除,只保留VMkernel虚拟化内核对资源进行管理,同时将控制台从虚拟化程序中移除,变成一个独立的组件,即Vsphere Client,使得管理工作更加便捷。
  • VMare vSphere,即由VMware ESXi、vCenter Server以及其他功能组件一起包装而成的整体虚拟化解决方案。

1.2 虚拟化技术发展编年史

​ 此图援引自《虚拟化技术发展编年史》

        虚拟化的概念最早出现于1959年,克里斯托弗 在《大型高速计算机中的时间共享》一文中首次提出了“虚拟化”的概念,还论述了什么是虚拟化技术,由此拉开了虚拟化技术发展的帷幕。

        1964年,IBM 推出了著名的 System/360,其上运行的TSS(Time Sharing System, 分时共享系统),允许多个用户远程共享同一高性能计算设备的使用时间,这被认为是最原始的虚拟化技术。

        1972年,IBM发布了可用于创建灵活、大型虚拟机的虚拟机技术,可以根据用户动态的应用需求来调整和支配资源,使昂贵的大型机资源可以得到尽可能的充分使用。虚拟机进入了大型机的时代。

        1999年,VMware 公司在X86平台上推出可流畅运行的商业虚拟化软件VMaware Workstation,虚拟化计算从此走下大型机的神坛,向PC机领域大跨步迈进,虚拟化技术进入第一代全软件虚拟时代。

        2003 年,英国剑桥大学计算机实验室开发发布了开源虚拟化项目 Xen,标志着虚拟化技术进入第二代半虚拟化技术时代。

        2004年,企业级虚拟化走向主流,微软发布Virtual Server 2005计划,象征了“虚拟化正在从一个小石城向主流市场转变”。此后, AMD, Oracle, Redhat, 思科,惠普等先后进军虚拟化市场。

        2006 年,Intel 和 AMD 等厂商相继将对虚拟化技术的支持加入到 x86 体系结构的中央处理器中(AMD-V,Intel VT-x),使原来纯软件实现的各项虚拟化功能可以借助硬件实现提速,标志着第三代基于硬件辅助的全虚拟化技术时代的到来。

        2007 年 2 月,Linux Kernel 2.6.20 合入了由以色列公司 Qumranet 开发的虚拟化内核模块 KVM(Kernel-based Virtual Machine,基于内核的虚拟机),KVM虚拟机进入大众视野,支持 KVM 的前提是 CPU 必须要支持虚拟化技术。

        2014 年 6 月,Docker 发布了第一个正式版本 v1.0。同年,Redhat 和 AWS 就宣布了为 Docker 提供官方支持,容器化时代正式到来。

        2015 年 7 月 21 日,Kubernetes v1.0 发布,从此云计算世界进入3.0时代——云原生时代。

     

        特别说明:从上文约定可以看到,本文所述虚拟化技术主要指1999年起从VMare虚拟化技术演进以来的x86体系的三代虚拟化技术。

1.3 虚拟机两大Hypervisor模型

        1974 年,Gerald J. Popek(杰拉尔德·J·波佩克)和 Robert P. Goldberg(罗伯特·P·戈德堡)在合作论文《可虚拟第三代架构的规范化条件》(Formal Requirements for Virtualizable Third Generation Architectures)中提出了一组称为虚拟化准则的充分条件,又称波佩克与戈德堡虚拟化需求(Popek and Goldberg virtualization requirements)即:虚拟化系统结构的三个基本条件。满足这些条件的控制程序才可以被称为虚拟机监控器(Virtual Machine Monitor,简称 VMM):

  1. 资源控制(Resource Control)。控制程序必须能够管理所有的系统资源。
  2. 等价性(Equivalence)。在控制程序管理下运行的程序(包括操作系统),除时序和资源可用性之外的行为应该与没有控制程序时的完全一致,且预先编写的特权指令可以自由地执行。
  3. 效率性(Efficiency)。绝大多数的客户机指令应该由主机硬件直接执行而无需控制程序的参与。

        该论文尽管基于简化的假设,但上述条件仍为评判一个计算机体系结构是否能够有效支持虚拟化提供了一个便利方法,也为设计可虚拟化计算机架构给出了指导原则。同时,Gerald J. Popek 和 Robert P. Goldberg 还在论文中介绍了两种 Hypervisor 类型,分别是类型 I 和 类型 II。

1.3.1 Type-II型(寄居或托管 Hypervisor)

        VMM 运行在传统的操作系统上,就像其他计算机程序那样运行。

主要特点:

        VMM 作为应用程序运行在主操作系统环境内运行效率一般较类型 I 低。

实现案例:

  • VMware 5.5 以前版本
  • Xen 3.0 以前版本
  • Virtual PC 2004

1.3.2 类型 I(原生或裸机 Hypervisor)

        这些虚拟机管理程序直接运行在宿主机的硬件上来控制硬件和管理客户机操作系统。

 特点:

        需要硬件支持VMM 作为主操作系统运行效率高

实现案例:

  • VMware 5.5 及以后版本
  • Xen 3.0 及以后版本
  • Virtual PC 2005
  • KVM

ps:这里我特意将类型 I 和 II 的顺序调转,至于为什么,从编年史案例可以看出类型 I 已然是时代的选择。

1.4 X86架构运行态权限模型以及全虚拟化(Full virtualization) 技术诞生背景

        在x86架构CPU技术体系下,虚拟化技术的共同目标就是将 x86 架构转变为通用的共享硬件基础架构,使应用程序运行环境在隔离性、移动性和操作系统类型方面都有选择的空间。

        CPU 为了保证程序代码执行的安全性、多用户的独立性以及保证操作系统的稳定性,提出了 CPU 执行状态的概念。它有效的限制了不同程序之间的数据访问能力,避免了非法的内存数据操作,同时也避免了应用程序错误操作计算机的物理设备。Intel x86架构使用了4个级别来标明不同的执行状态权限级别。最高级别R0实际就是内核态,拥有最高权限。而一般应用程序处于R3状态(即用户态)。在Linux中,还存在R1和R2两个级别,一般归属驱动程序的级别。在Windows平台则没有R1和R2两个级别,只用R0内核态和R3用户态。在权限约束上,高权限等级状态可以阅读低等级状态的数据,例如进程上下文、代码、数据等等,但是反之则不可。

  •  Ring0 核心态(Kernel Mode):是操作系统内核的执行状态(运行模式),运行在核心态的代码可以无限制的对系统内存、设备驱动程序、网卡接口、显卡接口等外部设备进行访问。显然,只有操作系统能够无限制的访问内存、磁盘、鼠键等外围硬件设备的数据,因为操作系统就是作为计算机硬件资源管理器而存在的,操作系统就是为了让多个普通应用程序可以更简单、安全的运行在同一台计算机上而存在的 “特殊的应用程序”。
  • Ring3 用户态(User Mode):运行在用户态的程序代码需要受到 CPU 的检查,用户态程序代码只能访问内存页表项中规定能被用户态程序代码访问的页面虚拟地址(受限的内存访问),而且还只能访问 I/O Permission Bitmap 中规定的能被用户态程序代码访问的端口,不能直接访问外围硬件设备、不能抢占 CPU。

        所有应用程序都应该运行在用户态中。当应用程序需要访问外围硬件设备时,CPU会通过特别的接口去调用核心态的代码,以这种旁路的方式来处理应用程序对硬件设备的调用。如果用户态的应用程序直接调用硬件设备的话,就会被操作系统捕捉到并触发异常,弹出警告窗口。

        由此可见,x86 架构与以往大型机不同,当时的 x86 体系结构缺乏必要的针对虚拟化的硬件支持,难以直接满足波佩克与戈德堡的虚拟化系统架构要求,所以 x86 架构天然不是一个可虚拟化的架构。具体而言,x86 架构的 CPU 中有 17 条指令成为了虚拟化最大的障碍,错误执行这些指令会导致操作系统显示警告、终止应用程序甚至完全崩溃。当时 VMware 提出了解决这个问题的思路——在虚拟机生成这些特殊的指令时将它们 “困住”,然后将它们转换成可虚拟化的安全指令,同时保证其他所有的指令不受到干扰地执行。这样就产生了一种与主机硬件匹配并保持软件完全兼容性的高性能虚拟机。这就是全虚拟化(Full virtualization)技术诞生的背景,当然此方案必须使用纯软件实现的 VMM。VMware 首创了这项技术,并以此一举稳坐虚拟化龙头老大。

1.5 虚拟化主要突破方向(CPU、内存、网络、IO)

1.5.1 CPU虚拟化技术实现

一)全虚拟化和半虚拟化

1)Full-virtualization(全虚拟化)

        全虚拟化为客户机提供了完整的虚拟X86平台, 包括处理器、 内存和外设, 支持运行任何理论上可在真实物理平台上运行的操作系统, 为虚拟机的配置提供了最大程度的灵活性。不需要对客户机操作系统做任何修改即可正常运行任何非虚拟化环境中已存在基于X86平台的操作系统和软件,这也是全虚拟化无可比拟的优势。

        在全虚拟化情况下,虚拟机并不知道自己运行在虚拟化环境下,是无感知的,安装使用时跟在物理机上没有什么区别。但是这种完全虚拟化中间需要软件做支撑的,需要软件去模拟提供所有的硬件资源,至少是这个CPU的特权指令需要用软件去模拟的,因为你要让各Guest并不知道自己运行在虚拟环境中,那么你就必须要提供一个带有特权指令的CPU。

        在虚拟化环境中,通常虚拟跟模拟是两个概念,VMWare的动态二进制翻译技术(BT)是虚拟的而QEMU软件技术是模拟的。最大的区别在于,模拟通过软件实现时需要模拟CPU ring 0-3,也就是需要转换CPU ring 0-3所有的指令,而虚拟只需要转换CPU ring 0特权指令即可。

       当然不管上面说到的BT技术还是QEMU还是硬件辅助虚拟化技术都属于完全虚拟化技术,都是需要指令转换的,都是需要复杂的步骤才能完成的,如果我们能够精简这其中的步骤那么虚拟机的性能一定会有提升的。那么怎么精简呢?这就是下面会展开说的第二代半虚拟化技术以及第三代硬件辅助虚拟化技术。

2)Para-virtualization(半虚拟化)

        软件全虚拟化可以在缺乏硬件虚拟化支持的平台上完全通过VMM软件来实现对各个虚拟机的监控,以保证它们之间彼此独立和隔离。 但是付出的代价是软件复杂度的增加和性能上的巨大损失。一种优化方案就是修改Guest操作系统,使它知道自己运行在虚拟环境下,从而使其能够与虚拟机监控机协同工作,这种技术就叫半虚拟化(para-virtualization)技术。

        虚拟机内核明确知道自己是运行在虚拟化之上的,对于硬件资源的使用不再需要BT而是自己直接向VMM申请使用,如对于内存或CPU的使用就是直接向VMM申请使用,而非BT翻译。就算对于I/O设备的使用,它也可以通过Hyper Call(Hypervisor提供的系统调用)直接跟硬件打交道,减少中间的翻译步骤提升性能。据说这种半虚拟化方式能够让虚拟化达到物理机90%的性能。

        本质上,半虚拟化弱化了对虚拟机特殊指令的被动截获要求,将其转化成客户机操作系统的主动通知。但是,半虚拟化需要修改客户机操作系统的源代码来实现主动通知。Xen是开源半虚拟化技术应用非常成功的一个项目,操作系统作为虚拟服务器在Xen Hypervisor上运行之前,它必须在内核层面进行某些改造。也因此,Xen仅适用于BSD、Linux、Solaris及其他开源操作系统,但不适合像Windows这类专有闭源操作系统——因为其不公开源代码,无法改造其内核。

3)总结

        因其相较于软件全虚拟化技术的性能优势,Xen项目在相当长一段时间深受开源市场的欢迎。然而,随着硬件辅助虚拟化的出现,使得完全虚拟化路线在性能上也得到了大幅提升,并且相比半虚拟化而言,完全虚拟化使用上更加简单,虚拟过程对于Guest完全透明,并能支持闭源操作系统,所以更加符合市场需求,在Intel VT-x与AMD-V等CPU硬件虚拟化技术出现后,完全虚拟化方案又重新成为市场主流选择,并得到进一步发展,比如后面会提到的KVM虚拟机。

二)软件虚拟化和硬件虚拟化

        VMare第一代全虚拟化技术方案与半虚拟化方案均是典型的软件虚拟化方案,而随着CPU厂商对虚拟机技术的支持,硬件辅助虚拟化方案逐渐成为市场主流。

1)纯软件虚拟化方案

        纯软件虚拟化, 顾名思义, 就是用纯软件的方法在现有的物理平台上(往往并不支持硬件虚拟化) 实现对物理平台访问的截获和模拟。常见的软件虚拟机例如QEMU,它是通过纯软件来仿真X86平台处理器的取指、解码和执行,客户机的指令并不在物理平台上直接执行。由于所有的指令都是软件模拟的,因此性能往往比较差,但是可以在同一平台上模拟不同架构平台的虚拟机。

        VMWare的软件虚拟化则使用了动态二进制翻译(BT)的技术,与QEMU这种模拟的方式不同,BT是一种加速虚拟化的方案(另一种常见的虚拟化加速方案就是硬件辅助虚拟化技术)。BT就是在VMM可控制的范围内,允许客户机的指令在物理平台上直接运行。但是,客户机指令在运行前会被VMM扫描,其中突破VMM限制的指令会被动态替换为可以在物理平台上直接运行的安全指令,或者替换为对VMM的软件调用。这样做的好处是比纯软件模拟技术在性能上有大幅的提升, 但是也同时失去了跨平台虚拟化的能力。

        有了BT技术后,Guest的用户空间运行在CPU Ring 3上,而Guest的内核空间运行在了CPU Ring 1上,Host的内核空间运行在CPU Ring 0上。BT就监控在CPU Ring 1上,随时将Guest内核的调用给转换为特权指令调用。当然CPU Ring 1并没有被使用,BT这种技术让虚拟化性能得到了大大的提升。但是BT有一个很大的缺点就是无法跨平台,使用QEMU这种模拟器则不管底层硬件是什么,均能模拟各种CPU架构平台,如PowerPC、ARM等,但是BT无法做到这点,BT强烈依赖底层架构,比如底层是X86的那么只能创建X86 CPU的虚拟机。

        在纯软件虚拟化解决方案中,VMM在软件套件中的位置是传统意义上操作系统所处的位置,而Guest操作系统的位置是传统意义上应用程序所处的位置, 这种转换必然会增加系统的复杂性。软件堆栈的复杂性增加意味着——这些环境更难于管理,因而会加大确保系统可靠性和安全性的困难。

核心技术原理: vCPU机制

                                                                 vCPU调度机制

        对虚拟机来说,不直接感知物理CPU,虚拟机的计算单元通过vCPU对象来呈现。虚拟机只看到VMM呈现给它的vCPU。在VMM中,每个vCPU对应一个VMCS(Virtual-Machine Control Structure)结构,当vcpu被从物理CPU上切换下来的时候,其运行上下文会被保存在其对应的VMCS结构中;当vcpu被切换到pcpu上运行时,其运行上下文会从对应的VMCS结构中导入到物理CPU上。通过这种方式,实现各vCPU之间的独立运行。

        从虚拟机系统的结构与功能划分可以看出,客户操作系统与虚拟机监视器共同构成了虚拟机系统的两级调度框架,如图所示是一个多核环境下虚拟机系统的两级调度框架。客户操作系统负责第2 级调度,即线程或进程在vCPU 上的调度(将核心线程映射到相应的虚拟CPU上)。虚拟机监视器负责第1 级调度, 即vCPU在物理处理单元上的调度。两级调度的调度策略和机制不存在依赖关系。vCPU调度器负责物理处理器资源在各个虚拟机之间的分配与调度,本质上即把各个虚拟机中的vCPU按照一定的策略和机制调度在物理处理单元上可以采用任意的策略来分配物理资源, 满足虚拟机的不同需求。vCPU可以调度在一个或多个物理处理单元执行(分时复用或空间复用物理处理单元), 也可以与物理处理单元建立一对一固定的映射关系(限制访问指定的物理处理单元)。

2)硬件辅助虚拟化方案

        硬件辅助虚拟化(HVM)技术,简而言之,就是物理平台本身提供了对特殊指令的截获和重定向的硬件支持,甚至,新的硬件会提供额外的资源来帮助软件实现对关键硬件资源的虚拟化,从而提升性能。

        以Intel VT-x技术为例(AMD-V技术类似),通过引入新的指令和运行模式,使VMM和Guest OS分别运行在不同模式(ROOT模式和非ROOT模式)下,且Guest OS运行在Ring 0下。通常情况下,Guest OS的核心指令可以直接下达到计算机系统硬件执行,而不需要经过VMM,减少了VMM对I/O处理的管理,从而不但加速数据传输,且消除了大部分性能开销。当Guest OS执行到特殊指令的时候,系统会切换到VMM,让VMM来处理特殊指令。CPU硬件辅助虚拟化技术简要流程如下图:

        效法IBM 大型机,VT-x提供了2 个运行环境:根(Root)环境和非根(Non-root)环境。根环境专门为VMM准备,很像原来没有VT-x 的x86,只是多了对VT-x 支持的几条指令。非根环境作为一个受限环境用来运行多个虚拟机。

         如上图所示,根操作模式与非根操作模式都有相应的特权级0至特权级3。VMM运行在根模式的特权级0,GuestOS的内核运行在非根模式的特权级0,GuestOS的应用程序运行在非根模式的特权级3。运行环境之间相互转化,从根环境到非根环境叫VMEntry;从非根环境到根环境叫VMExit。VT-x定义了VMEntry操作,使CPU由根模式切换到非根模式,运行客户机操作系统指令。若在非根模式执行了敏感指令或发生了中断等,会执行VMExit操作,切换回根模式运行VMM。根模式与非根模式之问的相互转换是通过VMX操作实现的。VMM 可以通过VMXON 和VMXOFF打开或关闭VT-x。

        通过以上实现,VMM会很容易将客户机置于一种受限制的模式下运行,一旦客户机试图访问物理资源,硬件会暂停客户机的运行,将控制权交回给VMM处理。VMM还可以利用硬件的虚拟化增强机制,将客户机在受限模式下对一些特定资源的访问,完全由硬件重定向到VMM指定的虚拟资源,整个过程不需要暂停客户机的运行和VMM软件的参与。

        由于虚拟化硬件可提供全新的架构,支持操作系统直接在上面运行,无需进行二进制转换,减少了相关的性能开销,极大简化了VMM 设计,进而使VMM能够按通用标准进行编写, 性能更加强大。需要说明的是, 硬件虚拟化技术是一套解决方案,完整的情况下,需要CPU、主板芯片组、BIOS和软件一起支持才能真正发挥其最大优势。当然,即使只是CPU支持虚拟化技术,在配合VMM软件的情况下,也会比完全不支持虚拟化技术的系统有更好的性能。

        鉴于虚拟化的巨大需求和硬件虚拟化产品的广阔前景,Intel一直都在努力完善和加强自己的硬件虚拟化产品线。自2005年末,Intel便开始在其处理器产品线中推广应用Intel Virtualization Technology(IntelVT)虚拟化技术,发布了具有IntelVT虚拟化技术的一系列处理器产品,包括桌面的Pentium和Core系列,还有服务器的Xeon至强和Itanium安腾。Intel一直保持在每一代新的处理器架构中优化硬件虚拟化的性能和增加新的虚拟化技术。而AMD 从 2006 年也开始致力于硬件辅助虚拟化技术的研究,并已经发布了支持AMD Virtualization Technology(AMD-V)虚拟化技术的一系列处理器产品,包括Socket S1接口的Turion 64 X2系列以及Socket AM2接口的Athlon 64 X2系列和Athlon 64 FX系列等等,并且绝大多数的AMD下一代主流处理器,包括即将发布的Socket F接口的Opteron都将支持AMD VT虚拟化技术。

1.5.2 内存虚拟化技术实现

        说完虚拟化技术中最重要的CPU虚拟化相关技术,下面再来说说计算机五大部件中的第二大部件存储器(内存)的虚拟化技术。

        其实,内存的地址映射与分页机制的实现本身就有类似于虚拟化的技术实现,其通过虚拟地址对外提供服务,所有的进程都以为自己可以使用所有的物理内存。如下图提供了在非虚拟化中和虚拟化中寻址方式。

1)No Virtualation

        在非虚拟化环境中,系统把物理地址通过虚拟地址的方式(一个个页表项)提供给进程使用,每个进程都以为自己使用所有的物理内存。相应的,在CPU中有一个称为MMU(memory management unit)的管理单元,当某个进程想要访问自己的虚拟线性地址中的某段数据时,此进程将虚拟地址传给CPU并发送读取数据请求。CPU通过MMU将此虚拟地址转换为对应物理地址来进行数据访问。基于此设计,一般进程所得到的虚拟内存地址空间是一个连续的地址空间,但真正的物理存储空间一般都不会是连续的地址空间。

2)In Virtualation

        为了实现内存虚拟化,让客户机使用一个隔离的、从零开始且连续的内存空间,像KVM虚拟机引入一层新的地址空间,即客户机物理地址空间 (Guest Physical Address, GPA),这个地址空间并不是真正的物理地址空间,它只是宿主机虚拟地址空间在客户机地址空间的一个逻辑映射。对客户机来说,客户机物理地址空间都是从零开始的连续地址空间,但对于宿主机来说,客户机对应的实际物理地址空间并不一定是连续的,客户机物理地址空间有可能映射在若干个不连续的宿主机地址区间。

        从上图我们看出,在虚拟化环境中,由于客户机物理地址不能直接用于宿主机物理MMU寻址,所以需要先把客户机虚拟地址(Guest Virtual Address, GVA)转换为虚拟机物理地址GPA,再把虚拟机物理地址转换成宿主机上的虚拟地址 (Host Virtual Address, HVA),然后运行在硬件之上的Hypervisor再将宿主机虚拟地址HVA最终映射为真正宿主机物理地址 (Host Physical Address, HPA)以供上层虚拟机使用。显然,此种映射方式,虚拟机的每次内存访问都需要Hypervisor介入,并由软件进行多次地址转换,其效率是非常低的。

        因此,为了提高GVA到HPA转换的效率,目前有两种实现方式来进行客户机虚拟地址GVA到宿主机物理地址HPA的直接转换:第一种方案是基于纯软件的实现方式,也即通过影子页表(Shadow Page Table)机制来实现客户机虚拟地址到宿主机物理地址之间的直接转换(KVM虚拟机支持);第二种方案是基于硬件辅助MMU对虚拟化的支持来直接实现两者之间的转换。

        其中Shadow Page Table(影子页表)方案实现非常复杂,因为每一个客户虚拟机都需要有一个Shadow Page Table,并且这种情况会出现一种非常恶劣的结果——那就是TLB(Translation Lookaside Buffer,传输后备缓冲器)很难命中,尤其是由多个虚拟主机时,因为TLB中缓存的是GVA到GPA的转换关系,所以每一次虚拟主机切换都需要清空TLB,不然主机之间就会发生数据读取错误(因为各主机间都是GVA到GPA映射)。TLB是一种内存管理单元用于改进虚拟地址到物理地址转换后结果的缓存机制,而这种问题会导致虚拟机性能变得十分低下。

        因此便有了第二种硬件辅助支持方案,Intel的EPT(Extent Page Table) 技术和AMD的NPT(Nest Page Table) 技术都对内存虚拟化提供了硬件支持。这两种技术原理类似,都是在硬件层面上实现客户机虚拟地址到宿主机物理地址之间的直接转换,称为Virtualation MMU技术。当有了这种V-MMU虚拟化技术后,对于虚拟机进程来说还是同样把GVA通过内部MMU转换为GPA,保留了完全虚拟化的好处。但是,CPU同时会自动把GVA通过Virtualation MMU技术转换为真正的宿主机物理地址(HPA),此举显著减少了由GPA到HPA的映射转换过程时间,从而大幅提升虚拟机性能。

        同时,CPU厂商还提供了TLB硬件虚拟化技术,以前的TLB只是标记GVA到GPA的映射关系,只有两个字段,现在扩充为了三个字段,增加了一个主机字段,并且由GVA到GPA的映射关系变成了GVA到HPA的对应关系,明确说明这是哪个虚拟机的GVA到HPA的映射结果。        

3)总结

        由此看出,内存虚拟化,如果没有硬件做支撑,就只能使用Shadow Page Table(影子页表)技术,也就意味着TLB需要不断地进行清空,性能低下而不具备商业落地可能性。而有了硬件加持的内存虚拟机技术后,虚拟机的性能在某种程度上也得到了大大地提升,商业落地成为可能。

1.5.3 IO虚拟化实现

        从处理器的角度看,外设是通过一组I/O资源(端口I/O或者是MMIO)来进行访问的,所以设备的相关虚拟化被统称为I/O虚拟化,如:

1)外存设备:硬盘、光盘、U盘。

2)网络设备:网卡。

3)显示设备:VGA(显卡)。

4)键盘鼠标:PS/2、USB。

        还有一些如串口设备、COM口等等设备统称IO设备,所谓IO虚拟化就是提供这些设备的虚拟化支持,其思想就是VMM截获客户操作系统对设备的访问请求,然后通过软件的方式来模拟真实设备的访问效果。基于设备类型的多样化,I/O虚拟化的方式和特点纷繁复杂,我们挑一些常用IO设备来讲。

        一般IO虚拟化的实现方式有以下三种,如下图:

1)第一种模拟I/O设备

        完全使用软件来模拟,这是最简单但性能最低的方式,对于IO设备来说模拟和完全虚拟化没有太大意义上的区别。VMM给Guest OS模拟出一个IO设备以及设备驱动,Guest OS要想使用IO设备需要调内核然后通过驱动访问到VMM模拟的IO设备,然后到达VMM模拟设备区域。VMM模拟了这么多设备以及VMM之上运行了那么多主机,所以VMM也提供了一个I/O Stack(多个队列)用来调度这些IO设备请求到真正的物理IO设备之上。经过多个步骤才完成一次请求。例如Qemu、VMware Workstation均是此实现思路。

2)第二种半虚拟化

        半虚拟化比模拟性能要高,其通过系统调用直接使用I/O设备,跟CPU半虚拟化差不多,虚拟化明确知道自己使用的IO设备是虚拟出来的而非模拟。VMM给Guest OS提供了特定的驱动程序,在半虚拟化IO中我们也称为“前端IO驱动”。跟模拟I/O设备工作模式不同的是,Guest OS自己本身的IO设备不再需要处理IO请求,当Guest OS有IO请求时通过自身驱动直接发给VMM进行处理,而在VMM这部分的设备处理我们称之为“后端IO驱动”。典型实现例如Xen、Virtio。

3)第三种:I/O透传技术

        I/O透传技术(I/O through)比模拟和半虚拟化性能都好,性能几乎等价于硬件设备直通,Guest OS直接使用物理I/O设备,操作起来比较麻烦。其思想就是提供多个物理I/O设备,如硬盘提供多块、网卡提供多个,然后规划好宿主机运行Guest OS的数量,通过协调VMM来达到每个Guest OS对应一个物理设备。另外,要想使用I/O透传技术,不光提供多个I/O设备还需要主板上的I/O桥提供支持透传功能,一般Intel提供的这种技术叫VT-d,是一种基于北桥芯片的硬件辅助虚拟化技术,主要功能是用来提高I/O灵活性、可靠性和性能。

        为什么I/O透传还需要主板支持呢?每个虚拟机直接使用一个网卡不就可以了吗?主要是因为在我们传统的X86服务器架构上,所有的IO设备通常有一个共享或集中式的DMA(直接内存访问),DMA是一种加速IO设备访问的方式。由于是集中式的,所以在VMM上管理多块网卡时其实使用的还是同一个DMA,如果让第一个Guest OS直接使用了第一块网卡,第二个Guest OS直接使用第二块网卡,但使用的DMA还是同一个,DMA就无法区分哪个Guest OS使用的是哪块网卡。而像Intel的VT-d就是用来处理这些映射问题的,以及处理各主机中断。典型实现技术Intel VT-d。

        以上便是虚拟化技术的总览概述,接下来我们会详细介绍目前主流的三类虚拟化技术。

参考链接

虚拟化技术发展编年史

Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3_weixin_30784501的博客-程序员宅基地

云计算技术 — 云计算技术发展编年史_烟云的计算-程序员宅基地_云计算编年史

虚拟化技术原理(CPU、内存、IO)_joneslee的博客-程序员宅基地_虚拟化原理

虚拟化原理介绍

虚拟化原理介绍 - 张朝锋 - 博客园

CPU硬件辅助虚拟化技术 

CPU硬件辅助虚拟化技术 - 又是火星人 - 博客园

五种主流的虚拟化技术_远有青山-程序员宅基地_虚拟化技术

Vmware虚拟化概念原理_曹世宏的博客-程序员宅基地_vmware虚拟化

Xen原理

Xen原理 - 张朝锋 - 博客园

Xen虚拟化技术原理_IT人生活的技术博客_51CTO博客

Xen虚拟化基本原理详解

Xen虚拟化基本原理详解 - stardsd - 博客园

Xen工作原理_为幸福写歌的博客-程序员宅基地_xen原理

Xen_百度百科

    《重识云原生系列》专题索引:

  1. 第一章——不谋全局不足以谋一域
  2. 第二章计算第1节——计算虚拟化技术总述
  3. 第二章计算第2节——主流虚拟化技术之VMare ESXi
  4. 第二章计算第3节——主流虚拟化技术之Xen
  5. 第二章计算第4节——主流虚拟化技术之KVM
  6. 第二章计算第5节——商用云主机方案
  7. 第二章计算第6节——裸金属方案
  8. 第三章云存储第1节——分布式云存储总述
  9. 第三章云存储第2节——SPDK方案综述
  10. 第三章云存储第3节——Ceph统一存储方案
  11. 第三章云存储第4节——OpenStack Swift 对象存储方案
  12. 第三章云存储第5节——商用分布式云存储方案
  13. 第四章云网络第一节——云网络技术发展简述
  14. 第四章云网络4.2节——相关基础知识准备
  15. 第四章云网络4.3节——重要网络协议
  16. 第四章云网络4.3.1节——路由技术简述
  17. 第四章云网络4.3.2节——VLAN技术
  18. 第四章云网络4.3.3节——RIP协议
  19. 第四章云网络4.3.4.1-2节——OSPF协议综述
  20. 第四章云网络4.3.4.3节——OSPF协议工作原理
  21. 第四章云网络4.3.4.4节——[转载]OSPF域内路由
  22. 第四章云网络4.3.4.5节——[转载]OSPF外部路由
  23. 第四章云网络4.3.4.6节——[转载]OSPF特殊区域之Stub和Totally Stub区域详解及配置
  24. 第四章云网络4.3.4.7节——OSPF特殊区域之NSSA和Totally NSSA详解及配置
  25. 第四章云网络4.3.5节——EIGRP协议
  26. 第四章云网络4.3.6节——IS-IS协议
  27. 第四章云网络4.3.7节——BGP协议
  28. 第四章云网络4.3.7.2节——BGP协议概述
  29. 第四章云网络4.3.7.3节——BGP协议实现原理
  30. 第四章云网络4.3.7.4节——高级特性
  31. 第四章云网络4.3.7.5节——实操
  32. 第四章云网络4.3.7.6节——MP-BGP协议
  33. 第四章云网络4.3.8节——策略路由
  34. 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
  35. 第四章云网络4.3.10节——VXLAN技术
  36. 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
  37. 第四章云网络4.3.10.3节——VXLAN隧道机制
  38. 第四章云网络4.3.10.4节——VXLAN报文转发过程
  39. 第四章云网络4.3.10.5节——VXlan组网架构
  40. 第四章云网络4.3.10.6节——VXLAN应用部署方案
  41. 第四章云网络4.4节——Spine-Leaf网络架构
  42. 第四章云网络4.5节——大二层网络
  43. 第四章云网络4.6节——Underlay 和 Overlay概念
  44. 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
  45. 第四章云网络4.7.2节——virtio网络半虚拟化简介
  46. 第四章云网络4.7.3节——Vhost-net方案
  47. 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
  48. 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
  49. 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
  50. 第四章云网络4.7.8节——SR-IOV方案
  51. 第四章云网络4.7.9节——NFV
  52. 第四章云网络4.8.1节——SDN总述
  53. 第四章云网络4.8.2.1节——OpenFlow概述
  54. 第四章云网络4.8.2.2节——OpenFlow协议详解
  55. 第四章云网络4.8.2.3节——OpenFlow运行机制
  56. 第四章云网络4.8.3.1节——Open vSwitch简介
  57. 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
  58. 第四章云网络4.8.4节——OpenStack与SDN的集成
  59. 第四章云网络4.8.5节——OpenDayLight
  60. 第四章云网络4.8.6节——Dragonflow
  61.  第四章云网络4.9.1节——网络卸载加速技术综述

  62. 第四章云网络4.9.2节——传统网络卸载技术

  63. 第四章云网络4.9.3.1节——DPDK技术综述

  64. 第四章云网络4.9.3.2节——DPDK原理详解

  65. 第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述

  66. 第四章云网络4.9.4.2节——智能网卡实现

  67. 第六章容器6.1.1节——容器综述

  68. 第六章容器6.1.2节——容器安装部署

  69. 第六章容器6.1.3节——Docker常用命令

  70. 第六章容器6.1.4节——Docker核心技术LXC

  71. 第六章容器6.1.5节——Docker核心技术Namespace

  72. 第六章容器6.1.6节—— Docker核心技术Chroot

  73. 第六章容器6.1.7.1节——Docker核心技术cgroups综述

  74. 第六章容器6.1.7.2节——cgroups原理剖析

  75. 第六章容器6.1.7.3节——cgroups数据结构剖析

  76. 第六章容器6.1.7.4节——cgroups使用

  77. 第六章容器6.1.8节——Docker核心技术UnionFS

  78. 第六章容器6.1.9节——Docker镜像技术剖析

  79. 第六章容器6.1.10节——DockerFile解析

  80. 第六章容器6.1.11节——docker-compose容器编排

  81. 第六章容器6.1.12节——Docker网络模型设计

  82. 第六章容器6.2.1节——Kubernetes概述

  83. 第六章容器6.2.2节——K8S架构剖析

  84. 第六章容器6.3.1节——K8S核心组件总述

  85. 第六章容器6.3.2节——API Server组件

  86. 第六章容器6.3.3节——Kube-Scheduler使用篇

  87. 第六章容器6.3.4节——etcd组件

  88. 第六章容器6.3.5节——Controller Manager概述

  89. 第六章容器6.3.6节——kubelet组件

  90. 第六章容器6.3.7节——命令行工具kubectl

  91. 第六章容器6.3.8节——kube-proxy

  92.  第六章容器6.4.1节——K8S资源对象总览

  93. 第六章容器6.4.2.1节——pod详解

  94. 第六章容器6.4.2.2节——Pod使用(上)

  95. 第六章容器6.4.2.3节——Pod使用(下)

  96. 第六章容器6.4.3节——ReplicationController

  97. 第六章容器6.4.4节——ReplicaSet组件

  98. 第六章容器基础6.4.5.1节——Deployment概述

  99. 第六章容器基础6.4.5.2节——Deployment配置详细说明

  100. 第六章容器基础6.4.5.3节——Deployment实现原理解析

  101. 第六章容器基础6.4.6节——Daemonset

  102. 第六章容器基础6.4.7节——Job

  103. 第六章容器基础6.4.8节——CronJob

  104. 第六章容器基础6.4.9.1节——Service综述

  105. 第六章容器基础6.4.9.2节——使用 Service 连接到应用

  106. 第六章容器基础6.4.9.3节——Service拓扑感知

  107. 第六章容器基础6.4.10.1节——StatefulSet概述

  108. 第六章容器基础6.4.10.2节——StatefulSet常规操作实操

  109. 第六章容器基础6.4.10.3节——StatefulSet实操案例-部署WordPress 和 MySQL

  110. 第六章容器基础6.4.10.4节——StatefulSet实操案例-使用 StatefulSet 部署Cassandra

  111. 第六章容器基础6.4.10.5节——Statefulset原理剖析

  112. 第六章容器基础6.4.11.1节——Ingress综述

  

《云原生进阶之容器》专题索引:

  1. 第一章Docker核心技术1.1节——Docker综述
  2. 第一章Docker核心技术1.2节——Linux容器LXC
  3. 第一章Docker核心技术1.3节——命名空间Namespace
  4. 第一章Docker核心技术1.4节——chroot技术
  5. 第一章Docker核心技术1.5.1节——cgroup综述
  6. 第一章Docker核心技术1.5.2节——cgroups原理剖析
  7. 第一章Docker核心技术1.5.3节——cgroups数据结构剖析
  8. 第一章Docker核心技术1.5.4节——cgroups使用
  9. 第一章Docker核心技术1.6节——UnionFS
  10. 第一章Docker核心技术1.7节——Docker镜像技术剖析
  11. 第一章Docker核心技术1.8节——DockerFile解析
  12. 第一章Docker核心技术1.9节——docker-compose容器编排
  13. 第一章Docker核心技术1.10节——Docker网络模型设计
  14. 第二章——Kubernetes概述
  15. 第二章Controller Manager原理剖析--2.1节Controller Manager综述
  16. 第二章Controller Manager原理2.2节--client-go剖析
  17. 第二章Controller Manager原理2.3节--Reflector分析
  18. 第二章Controller Manager原理2.4节--Informer机制剖析
  19. 第二章Controller Manager原理2.5节--DeltaFIFO剖析
  20. 第二章Controller Manager原理2.6节--Informer controller
  21. 第二章Controller Manager原理2.7节--Indexer剖析
  22. 第二章Controller Manager原理2.8节--Resync机制
  23. 第三章List-Watch机制3.1节-- List-Watch机制剖析
  24. 第四章Operator原理4.1节--定制资源(Custom Resource)
  25. 第四章Operator原理4.2节--CRD
  26. 第四章Operator原理4.3节--Operator模式
  27. 第四章Operator原理4.4节--Operator深入实践
  28. 第五章容器运行时5.1节--容器运行时总述
  29. 第五章容器运行时5.2节--容器运行时接口规范CRI
  30. 第五章容器运行时5.3.1--runC简介与使用
  31. 第五章容器运行时5.3.2--runC原理解读
  32. 第五章容器运行时5.4--容器运行时之Firecracker
  33. 第五章容器运行时5.5--容器运行时之Kata Container
  34. 第五章容器运行时5.6--容器运行时之gVisor
  35. 第六章容器网络6.1--Docker网络模型
  36. 第六章容器网络6.2--K8S网络模型
  37. 第六章容器网络6.3--CNI及各CNI网络解决方案简述
  38. 第六章容器网络6.4.1--Flannel组网方案综述
  39. 第六章容器网络6.4.2--Flannel的安装与部署
  40. 第六章容器网络6.4.3--Flannel网络模式
  41. 第六章容器网络6.5.1--Calico网络方案综述
  42. 第六章容器网络6.5.2--Calico网络架构详述
  43. 第六章容器网络6.5.3--Calico安装与部署
  44. 第六章容器网络6.6.1--Cilium网络方案概述
  45. 第六章容器网络6.6.2--Cilium部署
  46. 第六章容器网络6.7.1--阿里云Terway网络模式综述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/junbaozi/article/details/123384845

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签