第2章
Linux虚拟化:构建Linux工作环境
本章内容提要
发现正确的虚拟化技术
使用Linux软件仓库管理器
使用VirtualBox构建有效的环境
使用LXC构建容器
如何以及何时严密地管理虚拟机(VM)
虚拟化是最近几乎所有服务和产品交付方式改进背后最重要的技术。这不仅使从云计算到自主驾驶汽车的所有产业成为可能,也更引人注目。好奇吗?你从一开始就需要了解关于虚拟化的两个事实:
Linux在虚拟空间占据绝对的主导地位。
虚拟化使得对任何技术的学习都变得更加简单。
本章介绍当前使用的主流企业虚拟化技术。但更确切地讲,本章也会使你能够使用虚拟化环境,在那里你可以安全地学习Linux管理技能。为什么要在本书中这么早地阐述如此复杂的技术呢?原因在于,这将让你更加轻松地完成后续章节的学习。
需要一个新的、干净的操作系统(OS)来尝试新的技术吗?那就花一点时间创建一个吧。发生了让你不能进入机器的配置错误吗?没问题。将其删除并重新启动一个。沿着这条道路,你将学会如何使用Linux包管理器下载、安装并管理你需要的全部软件(如VirtualBox和LXC)。
2.1 什么是虚拟化
以前,当你想用一台新的服务器为公司或公司客户提供web服务器或文档共享服务时,你需要先进行研究、申请预算、协商、订购、安全安装和配置,之后启动一个崭新的计算机。从开始到结束的整个过程可能花费数月(请相信我—我曾经经历过)。当增加的服务需求远超过服务器的能力时,你就要再次重复上述过程,并且希望最终能够平衡能力与需求。
常见的情形是,公司常常会提供多个相互依赖的服务,并将其部署在分布式的硬件上。试想部署一个有后端数据库的前端web服务器。然而,当一切完成时,通常你会发现,一台服务器未被充分利用而另一台服务器(通常在机柜中的一侧)却无法满足要求。但是,再来设想你可以在多个服务之间安全地共享一台高性能服务器的计算、内存、存储和网络资源。想象一下,通过在物理服务器上创建多个仅需分配所需资源的虚拟服务器实例,之后及时调整资源分配来满足不断变化的需求是多么方便。
现在,设想能够将一组运行多个操作系统的虚拟计算机有效地打包部署到一台裸机服务器上,由此,绝对不会存在任何浪费。再设想一下,当前面的物理服务器满负载时,虚拟机(Virtual Machine,VM)将会被自动部署到后续的其他物理服务器上。再来设想一下,杀死一个故障的或者需要更新的虚拟机是非常方便的,甚至快速地进行替代以致用户感知不到任何变化。在你的脑海中已经出现这样的情景了吗(希望如此,类似于图2-1所示的内容)?你正在设想的便是虚拟化(virtualization)。图2-1非常具有吸引力,现在已经成为企业计算领域的主流。在这点上,我怀疑本地服务器或基于云的服务器有许多负载剩余,它们没有运行在某种虚拟化技术上。而且,运行绝大多数虚拟负载的操作系统正是Linux。
顺便说一下,亚马逊Web服务(Amazon Web Service,AWS)允许客户租用(Linux)服务器上的服务能力,这些服务器运行数百万计的虚拟机,而这些虚拟机则运行着无数的负载,包括诸多最流行的在线服务。图2-2给出了AWS弹性计算云(Elastic Compute Cloud,EC2)实例如何作为各种存储、数据库和网络化工具的服务枢纽。
如果还不清楚AWS的某些细节,请不要担心,无论如何它都并非本书的主题。但如果你确实想学习关于亚马逊Web服务的更多内容,可以阅读我写的《Learn Amazon Web Services in a Month of Lunches》一书(Manning出版社,2017年)。那关于虚拟化呢?请阅读我写的《Teach Yourself Linux Virtualization and High Availability》一书(LULU出版社,2017年)。
下一个简短的章节可能会有些令人头疼,但是它会为那些有兴趣了解后台运行原理的读者提供一些有用的信息。成功的虚拟化在物理计算机上使用了可以安装客体操作系统的某种隔离空间,并且客体操作系统误以为是在自己的计算机上独自存在。客体操作系统之间可以共享网络连接,从而使其管理员都可以远程登录(将在第3章讨论),并且像在传统计算机上一样正确地完成工作。这些统一的共享网络连接允许你使用虚拟机来提供网站等公共服务。总体而言,当前有两种虚拟化方法:
- 管理程序(Hypervisor,也称为虚拟机管理器)—在某种程度上控制宿主系统的硬件,为每个客户操作系统提供所需的资源(如图2-3所示)。客户计算机以系统进程的形式运行,但是可以虚拟地访问硬件资源。例如,AWS服务器早已构建在开源的Xen管理程序技术上(尽管他们近期开始将部分服务器切换到同等开源的KVM平台)。其他同样重要的管理程序平台还包括VMware ESXi、KVM和微软的Hyper-V。
- 容器(Containers)—非常轻量级的虚拟服务器,它们并不以完整操作系统的方式运行,而是共享宿主操作系统的底层内核(如图2-4所示)。容器可以由纯文本的脚本来构建,在数秒时间内完成创建并启动,并可以简单又可靠地在网络上进行共享。当前最有名的容器技术当属Docker。本章中,我们将要使用的Linux容器(LXC)项目就来源于Docker最初的灵感。
没有一种技术可以适用于所有项目。但是,如果你决定学习本章的后续内容,你需要学习如何以及为何要使用两种虚拟化技术:VirtualBox(一个II型虚拟机),以及我之前提及的LXC(一种容器管理器)。
设计注意事项
我可不想你在学完这本书的时候还没有掌握选择虚拟化技术的一些基本指导原则,所以这里给出一些建议:
像Xen和KVM这样完整的虚拟机管理器(通过像Libvirt这样的管理前端)通常用于企业级Linux虚拟机部署,涉及大量的Linux虚拟机。
VirtualBox(以及VMware Player)在采用现有操作系统进行测试和实验是很好的,一次一个或两个,且无须将其安装到实际的计算机上。但它们相对较高的上限使得它们并不适合于大多数产品环境。
像LXC和Docker这样的容器技术是轻量级的,且可以在数秒内完成配置和启动。LXC容器特别适合于运用新技术和安全地构建操作系统的软件栈。Docker是当前运行无数动态的、集成的容器集群的技术,它是大量微服务体系结构的一部分(我将在第9章深入讨论微服务)。
2.2 使用VirtualBox
用Oracle的开源软件VirtualBox可以做很多事情。你可以将其安装在任何操作系统(包括Windows)中,在台式机或笔记本电脑上运行,或者使用该软件在几乎所有的宿主操作系统上托管运行一组虚拟机实例。
在Windows计算机上安装VirtualBox
想在Windows计算机上试验该工具吗?请前往VirtualBox的网站(https://www.virtualbox.org/wiki/Downloads )并下载可执行文件。点击已下载的文件,然后执行安装步骤(默认值都应该有效)。安装最终将会询问你是否可以重置网络接口,之后,是否想安装VirtualBox。由你来操作。
VirtualBox提供了一个环境,你可以在其中启动物理系统资源所能支持的尽可能多的虚拟机。同时,对于安全地测试和学习新的管理技能(这是当前我们的主要目标),它也是一个特别有用的工具。但在所有这些之前,你需要知道如何在Linux系统中下载和安装软件。
2.2.1 使用Linux包管理器
将VirtualBox恰当地安装在Ubuntu计算机上实际非常简单。执行如下两条命令:
注意:请记住#提示符意味着该命令需要管理员权限,该权限通常通过在命令前加sudo来获取。
然而,在我们的示例中会发生什么呢?这一切都围绕着名为高级软件包工具(Advanced Package Tool,简称APT,通常称为apt)的软件包管理器。在Linux的世界里,包管理器将计算机与成千上万个软件应用构成的大量在线软件仓库连接起来,这些软件应用大都是免费和开源的。Linux中默认安装的管理器具有如下一些功能:
维护一个本地索引来跟踪软件仓库及其内容;
跟踪安装在本地机器上的所有软件的状态;
确保所有可用的更新在已安装的软件上都已更新;
确保在新的应用被安装之前,软件依赖性(即正在安装的软件包所需的其他软件包和配置参数)是满足的;
处理安装和卸载软件包。
图2-5说明了在线软件仓库及Linux计算机上运行的包管理器之间既有关系中的一些元素。
该系统运行得很好,出于历史和市场原因,在Linux世界之外没有什么能比它更好了。但问题是,你使用的管理器将依赖于特定的Linux版本。总体而言,如果你的版本是Debian/Ubuntu系列,你需要使用APT。红帽系列中的成员会使用RMP管理器及Yum(或者其新的替代品DNF)。表2-1给出了一个相关的版本列表。
除了使用包管理器从远程软件仓库中安装软件,你可能还需要从网站下载软件。通常,你将会发现一旦使用后端工具从命令行安装后,由开发人员格式化封装的软件包就可以使用APT或Yum了。也就是说,例如,你想要使用Skype。转到其下载页(如图2-6)将可以为Linux下载一个DEB格式或RPM格式的Skype软件包。如果你正在使用基于Debian的版本及APT,就应该选择DEB格式,或者,如果你正在使用钟爱Yum的红帽系列,就应该选择RPM。
使用Debian包管理器
一旦下载了这个文件,你就可以在命令行中使用dpkg来进行安装。使用-i标志(表示安装)。你将需要确保你正在skypeforlinux-64文件所在的目录中运行dpkg命令。以下示例假设你将软件包保存到了你的用户账户下的Downloads目录中:
dpkg命令应该会为你处理依赖项。但如果不做处理,其输出通常会提供足够的信息让你了解当前发生了什么。
“-64”是什么?
与其他基于x86体系的操作系统一样,Linux也存在64位和32位两种版本。近10年来制造和销售的大量计算机大都是更快的64位架构。因为仍然存在更老的或者面向开发的硬件,所以有时你需要运行32位的系统,而且你会想让你安装的软件在这样的系统上运行。
你可以通过在命令行运行arch命令来检查系统版本。除非你知道你正在老旧的硬件上运行(顺便说一下,Linux在旧硬件上也运行得非常好),你可以放心假设你是一名64位的用户。
为RPM包管理器安装VirtualBox
之前,我介绍了apt update和apt install virtualbox命令。那么这些简洁的命令到底完成了什么工作?为了进行解释,我将在运行Fedora Linux发行版的机器上安装相同的VirtualBox软件。因为我将使用红帽的DNF包管理器,所以它会要求一些额外的步骤—这是件好事,执行这些步骤将说明这个过程如何运行。该过程部分有点复杂,因此表2-2列举出了这些步骤。
注意:这些步骤是为Fedora 25版本设计并在其上进行测试的,很好地说明了包的管理过程。不过,在最近的Fedora版本中,这一切都可能更加流畅。
回到Ubuntu系统,当我将virtualbox添加到install命令时,APT明白我想做什么。因为VirtualBox包在APT熟悉的在线软件仓库中。然而,红帽及其衍生版本(如CentOS和Fedora)并非如此,至少不是立即可用的,因此,我将需要把virtualbox软件仓库添加到Yum中。
在前一章中,你将记住第三方软件配置文件通常保存在/etc/目录中,而且,yum/DNF在这方面也没有什么不同。软件仓库的信息被保存在/etc/yum.repos.d/目录中,因此,你应该切换到这个目录。在这个目录中,你将使用wget程序(通常是默认安装的)来下载.repo文件。以下是如何做到这一切的方法:
在Linux上安装软件
安装Linux软件的具体方法,包括诸如较早前我使用的精确URL等细节,几乎都可以在网上找到。你可以在软件开发人员自己的网站上或免费提供的指南中找到这些信息。互联网是你的好朋友。
请确保在任何必要的搜索引擎词组中指定Linux版本、发布版本以及体系结构(32位或64位)。我通过自己喜欢的搜索引擎获得本项目所需具体软件包的细节—你也理应如此。
在你告诉RPM有什么变化之前,将.repo文件放到正确的目录下并不会有太大的作用。你可以通过运行update命令来进行操作。update命令同时对本地软件仓库的索引及其在线版本进行对照检查,以判断是否存在你想要了解的任何新变化。无论你使用的是何种管理器,在安装新的软件之前更新repo信息通常都是一个好主意:
下一步是安装VirtualBox正确运行所需的所有软件依赖项。依赖项(dependency)是为了让新的软件包能够运行而必须事先安装的软件。回到Ubuntu系统,APT无形地处理了这些重要的细节;Yum通常也会处理诸多的后台细节。但如果没有处理,你就必须手动操作,如前所述,可以从相同的在线资源中获取相关细节。这里给出一个简略版本,内容如下:
这是一个稍微漫长的过程,但是你终于准备好在你的Red Hat、CentOS或Fedora机器上安装VirtualBox了。本示例中我使用的版本号来自之前使用的在线指南。当然,在你尝试这一方法的时候,它可能已经不再是5.1版本了:
VirtualBox附加组件
你应该意识到Oracle为VirtualBox提供了一个扩展包,它为现有的启动选项添加了诸如USB支持、硬盘加密等一些可选项。如果在运行标准包时遇到了死胡同,请考虑使用这些工具。
你也可以通过VBox客体系统扩展包的CD-ROM映像(VBox Guest Additions CD-ROM image)在VirtualBox虚拟机及它们的宿主机之间增加额外的文件系统和设备集成。例如为你提供共享剪切板和拖拽等功能。如果Vbox功能扩展包在你的主机上还不可用,那么在Ubuntu系统上使用如下命令安装扩展包:
sudo apt install virtualbox-guest-additions-iso
随后,将其作为虚拟光驱添加到正在运行的虚拟机中。请搜索关于在宿主操作系统上运行所需要的任何附加软件包的在线文档。
在继续实际使用VirtualBox这样的虚拟化工具之前,我应该给你留下一两个提示来寻找你可能需要的其他仓库软件包。APT系统允许你使用apt search命令搜索可用的软件包。以下示例搜索那些可能有助于你监视系统健康状态的软件包,之后使用apt show命令显示软件包的完整信息:
安装完成后,Aptitude程序是一个半图形化的shell环境,你可以在其中探索和管理可用的和已经安装的软件包。如果你离不开鼠标,那么考虑Synaptic,它是一个用于桌面环境的全图形化的软件包管理器。而且,Yum世界也是完全可以搜索的,如下所示:
2.2.2 定义虚拟机
我不确定你曾经是否组装过一台计算机,但可能会涉及。在VirtualBox中定义一台新虚拟机的工作方式与之相差不多。唯一显著的差别在于,虚拟机不需要你用牙齿咬着手电筒然后跪在地上用手将RAM和存储驱动器安装到机箱中,而是让你通过点击鼠标的方式来定义虚拟机的“硬件”规格。
在VirtualBox界面中点击New(新建)按钮之后,你可以给将要创建的虚拟机一个描述性名称。如图2-7所示,该软件应该能自动地为Type(类型)和Version(版本)字段填写正确的内容。这里所选的Type和Version并不会安装一个实际的操作系统,而是用于申请一些适当的硬件模拟设置。
在下一个界面中,你要给虚拟机分配RAM(内存)。除非你计划做一些具有特殊要求的事情,如托管一个容器群或者运行一个重负载的Web服务器,否则默认容量(768 MB)应该就可以了。如有必要,你当然可以分配更多的RAM,但不要忘了,要为宿主计算机及可能已经在其中运行的其他虚拟机留下足够的空间。如果你的宿主机只有4 GB的物理RAM,你可能就不想将其中的一半分配给虚拟机了。
如果你最终决定要一次运行多个虚拟机就要注意这些限制,这对进行本书后续内容中的项目实验将是有用的。即使每个虚拟机都仅使用默认的内存容量,两三个虚拟机也可能会逐渐消耗掉宿主机正常操作所需的RAM。
接下来,VirtualBox设置过程会询问是否要为虚拟机创建新的虚拟硬盘或者使用已存在的虚拟硬盘(如图2-8)。没有硬盘驱动器的计算机会是什么样的?有时你可能希望在两个虚拟机之间共享一个硬盘,但是对于这个练习,我猜你会希望从头开始。选择“Create a Virtual Hard Disk Now”(现在创建一个虚拟硬盘)。
下一个界面(如图2-9所示)让你选择即将要创建的硬盘文件类型格式。除非你正在计划将该盘最终导出并用于其他虚拟环境,否则,默认的VirtualBox硬盘映像(VirtualBox Disk Image,VDI)格式就可以很好地工作。
我也从未后悔过使用默认的动态分区选项(如图2-10所示)作为虚拟驱动器消耗主机硬盘空间的方式。这里,动态(dynamic)意味着主机存储盘上的空间将仅在需要时分配给虚拟机。如果虚拟机硬盘的使用率很低,那么将会为其分配更少的宿主机空间。
另一方面,无论实际使用多少空间,一个固定大小的虚拟硬盘都会被立即分配最大的空间容量。固定大小的唯一优势是应用的性能。因为通常我只使用VirtualBox虚拟机进行测试和实验,所以我很好地避免了这种情况。
因为环境知道你运行的是Linux,并且Linux对存储空间的利用非常高效,因此,VirtualBox在下一个界面中将可能只提供总计8 GB的硬盘大小(如图2-11所示)。除非你对虚拟机有着不寻常的大计划(例如,你将处理一些复杂的数据库操作),否则这应该是没有问题的。另一方面,如果你已经选择了Windows操作系统,那么默认选项将会是
25 GB—这是有充分理由的:Windows并不羞于索取大量的资源。这也很好地说明,Linux非常适合于虚拟环境。
注意:如果你愿意,你也可以在文件位置和空间大小(FileLocation and Size)界面为VirtualBox设置名字及其在硬盘上的位置。
当完成这些工作后,点击Create(创建),新建的虚拟机将会出现在VirtualBox管理器左侧的虚拟机列表中。但是,工作还没有完成:这只是一台虚拟机。现在,你需要一个操作系统赋予这台虚拟机生命。
2.2.3 安装操作系统
现在你已经定义了新建虚拟机的虚拟硬件配置,以下是需要继续完成的工作:
1.下载一个包含所要使用的Linux发行版映像的文件(ISO格式的);
2.使用包含下载的ISO文件的虚拟DVD设备引导新的虚拟机;
3.执行标准的操作系统安装过程;
4.引导虚拟机并启动刚刚安装的操作系统。
一旦确定了发行版,你就需要下载一个包含操作系统文件及安装程序的.ISO文件。查找合适的文件通常就是用发行版本名和关键字下载(download)在互联网上进行搜索。在使用Ubuntu的情况下,可以选择前往主页https://ubuntu.com page 并点击Downloads(下载)选项卡,如图2-12所示。请注意,Ubuntu存在多种版本。如果你打算用虚拟机来管理任务,那么轻巧且快速的服务器(Server)版本可能比桌面(Desktop)版本更好。
在下载过程中,大文件有时可能会出现损坏。即使.ISO文件只有一个字节发生了改变,安装也可能无法完成。因为你应该不会花费时间和精力来查找下载中出现的问题,通常,快速计算出你所下载的.ISO文件的校验和(或哈希,hash)来确认没有发生任何改变会是一个更好的选择。为此,你将需要获取合适的SHA或MD5校验和,这看上去就像如下形式的一个字符串:
你应该能够从获取.ISO文件的相同位置获取到该字符串。在使用Ubuntu的情况下,可以前往主页http://releases.ubuntu.com/ ,点击与所下载操作系统版本相匹配的目录,之后,点击其中的一个链接来获取校验和(例如,SHA1SUMS)。你应该把从该主页获取的特定字符串与在.ISO下载目录中用命令计算出的结果进行比较,计算命令类似如
下形式:
如果两者匹配,你下载的操作系统就没有问题。如果不匹配(而且你已经再次确认版本是正确的),你可能就不得不再次下载这个.ISO文件。
注意:你应该知道有多种哈希算法。多年来,MD5SUM算法一直占主导地位,但SHA256(具有更长的256位哈希值)现在正变得越来越流行。实际上,对于大型操作系统映像文件,哪种方法好还不一定呢。
一旦.ISO文件准备就绪,请回到VirtualBox。在左侧面板中高亮显示的新创建的虚拟机上,点击应用顶部绿色的Start(开始)按钮。此时,将提示你从文件系统中选择一个.ISO文件用作虚拟DVD驱动器。理所应当地,你会选择你下载好的文件。新的虚拟机将读取该DVD驱动器并启动操作系统安装。
安装过程在大多数时间内都运行良好;然而,要阐述每个可能出错的小问题的解决方案则会需要几个完整的章节。如果你确实遇到了麻烦,可以查阅Linux发行版中的文档及指南,或者将你的问题发布在曼宁网站上的Linux in Action论坛,让其他人来帮忙。
当每件事情都很好地完成后,在能够成功引导虚拟机之前仍然会有一些事情需要考虑。高亮选中你的虚拟机,点击黄色的Settings(设置)图标。在这里,你可以对虚拟机的环境及硬件设置进行操作。例如,点击Network(网络)可以定义网络连接。如果你想让虚拟机能够通过主机的网络接口完全接入互联网,那么,如图2-13,你可以从Attached to下拉框中选择桥接适配器(Bridged Adapter),进而选择主机适配器的名字。
注意:使用桥接适配器可能并非总是你的首选,而且它有时可能会带来安全风险。实际上,选择NAT网络(NAT Network)是为虚拟机提供互联网接入的一个更为常见的方式。因为本书的很多练习实践都要求在多个虚拟机之间进行网络连接(使用NAT时更加复杂),所以现在我将使用桥接方法。
你可能永远不需要如下这条信息,但是如果你知道,你将会感到万幸。在某些情况下,为了让虚拟机以正确的方式进行引导启动,你还需要将DVD从驱动器中移除,就像“真正的”物理安装过程一样。你可以点击Storage选项来进行操作。点击列出的第一个硬盘,随后点击底部的Remove Disk(删除硬盘)图标(如图2-14所示)。请一定要确保没有意外删除掉你的硬盘!
你有时也会需要挂载一个DVD(或.ISO文件)并让VirtualBox识别它。选中Controller: IDE行后,点击 + 图标来选择一个文件作为虚拟光驱。
2.2.4 克隆和共享VirtualBox虚拟机
本节是一点额外的收获,谁不喜欢免费的东西呢?我将告诉你们两个相关的技巧:如何组织VirtualBox虚拟机尽可能快地运行以及如何使用命令行在网络上共享虚拟机。
克隆虚拟机以快速启动
使用虚拟机最为明显的优势之一就是能够快速访问一个新的、干净的操作系统环境。但是,如果访问这个环境需要经历完整的安装过程,那如果你不采用克隆的方法,我们也感受不到它有多快。为什么不将原始虚拟机保持在安装后的干净状态,并在任何需要实际使用的时候创建一个相同的克隆呢?
这很简单。再来看看VirtualBox的应用程序。选择你想用作主副本的(停机的)虚拟机,点击Machine菜单项,之后点击Clone按钮。你要给克隆的虚拟机设定名称,接下来,在点击Next后,无论你是要创建一个完全克隆(表示将为新建虚拟机创建完整的新文件副本)还是一个链接克隆(表示该新建虚拟机会共享主虚拟机的所有基础文件,但会独立地开始你的新工作)。
注意:选择Linked选项将会执行得非常快速,同时占用硬盘上更少的空间。唯一的缺点在于,之后你无法将这个特定的克隆移动到另一台计算机上。如何选择取决于你。
现在,请点击Clone,在虚拟机面板中将出现一个新的虚拟机。以正常的方式启动该虚拟机,然后用主虚拟机上设置的认证信息登录该虚拟机。
从命令行管理虚拟机
VirtualBox带有其自己的命令行shell,可以用vboxmanage进行调用。为什么要麻烦命令行呢?因为除了其他优点,命令行还允许你在远程服务器上工作,这可以大大增加可能项目的使用范围。要想知道vboxmanage如何工作,请使用list vms来列出当前系统中所有可用的虚拟机:
vboxmanage clonevm将完成之前我用图形界面描述的相同类型的克隆操作。这里,我要创建Kali Linux模板虚拟机的一个克隆,并命名为newkali:
你可以通过再次运行vboxmanage list vms来验证它是否正常工作。
在本地计算机上使用这个新虚拟机的效果很好,它就会很好地工作。但是假设我希望团队的其他成员能够运行该虚拟机的一个精确副本,由此他们可以测试我正在做的一些事情。为此,我需要把该虚拟机转换为某种标准的文件格式。以下是我如何将一个本地虚拟机导出为一个使用开放虚拟化格式(Open Virtualization Format,OVF)文件的操作:
接下来,你需要将这个.OVA文件拷贝到同事的计算机上。请记住,从任何层次来说,该文件都不会被认为是小巧的。如果你没有剩余的网络带宽来进行几个GB的数据传输,那么就考虑使用USB设备来移动文件。但如果你确实采用了网络路由,完成这项工作的最佳工具就是安全拷贝工具(secure copy,scp)。以下是该工具的使用方式示例:
如果整个scp命令的操作看上去有点晦涩,也请不要担心:后续就会有帮助。scp命令将会被作为OpenSSH内容的一部分完全包括在第3章中。与此同时,仅当两台计算机上都安装了OpenSSH,以及你在远程计算机上具有访问授权且从本地计算机可以访问到该远程计算机时,scp命令才能工作。
当传输完成时,剩下的事情就是从远程计算机将该虚拟机导入到该计算机的VirtualBox中。该命令非常简单,如下:
使用list vms命令来确认导入操作已经执行,接着从桌面尝试启动该虚拟机,命令如下:
如果你不需要特别地远程访问,你也可以用GUI来共享虚拟机。高亮显示要共享的机器,点击VirtualBox中的File菜单,之后点击Export Appliance(导出设备)。
2.3 使用Linux容器
要执行需要Linux内核访问的操作(就像使用SELinux这样的安全产品一样,具体请参见第9章),或者需要GUI桌面会话的时候,或者用于测试Windows这样的操作系统时,VirtualBox都是非常好的。但是,如果你需要快速访问一个干净的Linux环境并且不寻求任何特定的发行版本,那么,你将很难不选用LXC。
注意:类似于任何复杂系统,LXC并不能在所有的硬件体系结构上都良好地运行。如果你在启动一个容器时遇到困难,请考虑出现兼容性问题的可能。互联网,应该一如既往地被求助作为更深层信息的有益来源。
LXC容器会有多快?你将马上亲眼看到它会足够快。但是,因为这些容器巧妙地在宿主机和其他容器之间共享了很多系统资源,它们仅使用最小的存储空间及内存,却可以像全功能的独立服务器那样运行。
2.3.1 LXC入门
要在你的Ubuntu工作站上安装LXC吗?这是轻而易举的事情:
如果是在CentOS上安装呢?是的,依然非常简单,但需要多做一点处理。在一定程度上是因为,Ubuntu是面向且基于Debian构建的。无论如何,请在CentOS上试一试这个方法,但我不保证一定能成功。首先,你将需要添加一个新的软件仓库,即企业版Linux附加软件包(Extra Packages for Enterprise Linux,EPEL),随后,安装LXC及一些依赖项,如下:
就是这样。你已经准备好着手处理业务了。基本的LXC技能集实际上是非常简单的。我将向你展示三、四个需要让其全部运行起来的命令,之后给出一个内部提示,即一旦你明白了LXC是如何组织其自身的,你会恍然大悟。
2.3.2 创建第一个容器
为什么不立即行动创建你的第一个容器呢?-n参数的值设置了容器的名字,-t参数则告诉LXC使用Ubuntu模板来创建容器,命令如下:
注意:你可能会开始看到与相对较新的LXD容器管理器相关的另一组lxc命令的替代引用。LXD在后台仍然使用LXC工具,只是其使用了一个稍有不同的接口。举例说明,使用LXD之前的命令可能是这种形式:lxc launch ubuntu:16.04 myContainer。这两个命令集都将被继续广泛地使用。
如你从/usr/share/lxc/templates/目录列表中所看到的,确实存在相当数量的可用模板,如下:
警告:并不能保证所有这些模板都立即可用。一些只用于实验,一些还在不断完善中(works in progress)。在Ubuntu主机上坚持使用Ubuntu的模板应该是一个更安全的选择。正如我说的,出于历史原因,LXC在Ubuntu主机上一直运行良好。当涉及其他发行版时,情况会有所不同。
也就是说,如果你决定要创建一个CentOS容器,那么你就应该记下最后几行的输出内容,因为它包含了登录时要用到的密码信息:
你将使用root用户名及存放在tmp_root_pass文件中的密码进行登录。另一方面,如果你的容器使用了Ubuntu模板,那么你要使用ubuntu作为用户名和密码。当然,如果你计划将该容器用于任何要求严格的事情,你会希望立即修改密码,操作如下:
顺便说一下,该命令使用了缩写passwd而非password。我猜passwd程序的设计者不喜欢打字吧。现在,使用lxc-ls --fancy命令检查容器的状态:
很好,该容器已经存在了,但显然它还需要启动。如前所述,-n指定想要启动的容器的名字。-d表示分离(detach),意味着你不希望在容器启动时被自动放入一个交互式会话中。交互式会话并没有什么问题:实际上,我的一些好朋友就是互动的。但在这种情况下,运行没有-d参数的lxc-start命令将意味着离开的唯一方法是关闭容器,这可能并非是你想要的:
现在,列举出你的容器应该会类似地显示出如下信息:
这一次,容器正在运行且已经获取到一个IP地址(10.0.3.142)。你可以用这个地址及一个安全的shell会话来登录,但要在阅读第3章之后。现在,你可以使用lxc-attach在一个运行的容器中启动一个root的shell会话,如下:
你可能想花几分钟来看看相关的信息。例如,ip addr将列出该容器的网络接口。这种情况下,eth0接口被分配了一个IP地址10.0.3.142,其与较早前从lxc-ls --fancy获取的IPV4值相符,详细信息如下:
查看完新容器后,你可以运行exit命令来注销,同时保持容器继续运行,命令如下:
或者使用shutdown -h now命令来关闭容器。但在该操作之前,让我们先来看看LXC容器的速度有多快。之前我为shutdown添加的-h标志表示停机(halt)。如果我使用了r标志,容器不会关闭,而是重启。我们来运行reboot,之后再次立即登录,看看容器的恢复需要花费多长时间:
情况如何?我打赌在你尝试重新输入lxc-attach命令的时候,myContainer容器已经唤醒并就绪。你是否知道在Bash中按下向上箭头按键会在命令行中列出之前的命令?这种方式会让登录请求变得相当快。在我的示例中,没有明显的时延。容器在小于2秒的时间内关闭并完全重启!
LXC容器在系统资源上运行也很轻松。不像我之前使用VirtualBox虚拟机的体验,并发运行三个服务器已经开始严重影响8 GB宿主工作站的性能,然而我可以启动各种LXC容器,且速度不受影响。
你说的是什么?我答应过你的内部提示呢?好极了。我可以看出你的专注。请回到主机上的终端(注意不是容器),你将需要用sudo su打开一个管理员shell。由此开始直至输入exit,你将一直处于sudo状态:
现在,切换到/var/lib/lxc/目录并列举出其内容。你会看到一个以容器命名的目录,如下所示。如果你在系统中还有其他容器,它们也会拥有自己的目录:
切换到你的容器目录并列出其内容。目录下有一个名为config的文件及一个名为rootfs的目录(fs表示文件系统):
请随意浏览一下config文件:容器基础环境的值在这里被设置。一旦你对LXC的工作方式有了一些了解,你可能会希望使用该文件来调整容器的运行方式。但是,我真正想要说明的是rootfs目录,如下:
rootfs目录下的所有子目录看上去熟悉吗?它们都是Linux文件系统层级标准(Filesystem Hierarchy Standard,FHS)的一部分。这是容器的根目录(/),但包含于主机的文件系统中。只要你拥有主机的管理员权限,你就可以浏览这些目录并编辑任何文件—即使是在容器没有运行的时候。
你可以用这种访问方式做各种各样的事情,但这里有一种方法,它可能在某一天挽救你(职业)生涯。假设你把自己锁在一个容器外。通过这种方式没有什么可以阻挡你操纵文件系统,修复你搞砸的配置文件,并重新开始工作。来吧,告诉我这并不酷。但它确实变得更好了。
的确,自从Docker的生态系统在几年前从LXC的阴影中走出来后,他已经获得了许多层次的特性和复杂性。然而,在底层,它依然建立在一个基础结构范式上,任何熟悉LXC的人都能够立即识别它。这意味着,如果你倾向于使用十年来发展最快的虚拟化技术来试水,那么你已经在竞争中占有一席之地了。
2.4 小结
像VirtualBox这样的虚拟机管理器提供了虚拟操作系统这样能够安全访问硬件资源的环境,而轻量级的容器则共享了它们主机上的软件内核。
像APT和RPM(Yum)这样的Linux软件包管理器使用一个定期更新的索引反应远程软件仓库的状态,从而由托管的在线软件仓库监督软件的安装与管理。
在VirtualBox中运行一个虚拟机需要定义其虚拟硬件环境,下载一个操作系统映像并在虚拟机上安装该操作系统。
你可以从命令行简单地克隆、共享并管理VirtualBox虚拟机。
LXC容器的构建需要预先声明并指定发行版模板。
LXC数据存储在主机文件系统中,这使得容器的管理更加方便。
主要名词
- 虚拟化(Virtualization)是计算、存储、网络资源在多个进程之间的逻辑分享,允许每个进程像在独立的物理计算机上运行。
- 虚拟机管理器(hypervisor)是一个运行在主机上的软件,它将系统资源暴露给某个层次的一个客户机,允许启动和管理全栈式的客户虚拟机。
容器(container)是存在于宿主机核心操作系统内核上的一个非全栈式虚拟机。由于其主要面向短期需要,容器的启动和销毁非常容易。
VirtualBox中动态分配(dynamically allocated)的虚拟驱动器只会在物理驱动器上占用虚拟机实际需要的空间。而固定大小(fixed-size)的驱动器则会占用最大数量的空间,无论实际需要多少。
软件仓库(software repository)是一个可以存储数字资源的位置。仓库对于软件包的协作和分配都特别有用。
安全最佳实践
允许一个官方的包管理器在你的Linux系统上安装和维护软件是优先于手动操作的方式。在线的软件仓库更为安全,同时,下载过程是恰当加密的。
要经常扫描对比已下载文件的校验和哈希值与正确的哈希值,这不仅因为软件包在下载过程中可能损坏,也因为它们有时会被中间人攻击者修改。
命令行回顾
apt install virtualbox命令使用APT从远程软件仓库安装一个软件包。
dpkg -i skypeforlinux-64.deb命令在Ubuntu机器上直接安装一个下载的Debian软件包。
dnf update、yum update或apt update命令用在线软件仓库中的索引信息同步本地软件索引。
shasum ubuntu-16.04.2-server-amd64.iso命令计算已下载文件的校验和,以确认其值与所提供的值相符。这意味着文件的内容在传输中没有损坏。
vboxmanage clonevm Kali-Linux-template --name newkali命令使用vboxmanage工具克隆一个已存在的虚拟机。
lxc-start -d -n myContainer命令启动一个已存在的LXC容器。
ip addr命令显示系统各个网络接口上的信息(包括它们的IP地址)。
exit命令离开shell会话而不关闭虚拟机。
自测题
1.容器和虚拟机管理器共享了如下哪一种特性?
a.它们都允许虚拟机在宿主操作系统上独立运行。
b.它们都依赖于宿主机的内核,以进行基础操作。
c.它们都允许非常轻量级的虚拟机。
d.它们都允许极为高效地使用硬件资源。
2.如下哪项不是Linux软件包管理器的功能?
a.用远程软件仓库同步本地索引。
b.扫描已安装软件中的恶意软件。
c.对已安装的软件进行更新。
d.确保所有的软件包依赖项都已安装。
3.在Ubuntu系统上,你将使用如下哪个命令来直接安装下载的软件包?
a. dpkg -i
b. dnf --install
c. apt install
d. yum -i
4.在VirtualBox上创建一个虚拟机时,要先进行哪个步骤?
a.选择一个硬盘文件类型。
b.在动态分配和固定大小之间进行选择。
c.从驱动器中移除虚拟DVD。
d.配置网络接口。
5.操作系统映像可以使用如下哪种格式?
a. VDI
b. VMI
c. ISO
d. VMDK
6.如下哪条命令可以将一个虚拟机保存到.OVA格式的文件中?
a. vboxmanage export
b. vboxmanage clonevm
c. vboxmanage import
d. vboxmanage clone-ova
7.如下LXC命令行标志中,哪一个启动容器且不自动打开一个新的shell会话?
a. lxc-start –t
b. lxc-start –a
c. lxc-start –d
d. lxc-start –n
8.默认地,如下哪一个目录中可以找到容器的文件系统?
a. /usr/share/lxc/
b. /etc/share/lxc/
c. /usr/lib/lxc/
d. /var/lib/lxc/
答案
1.d 2.b 3.a 4.a 5.c 6.a 7.c 8.d