在Windows平台上实现云自动化

ny8p 9年前


对于如今的Windows自动化领域来说,可以以几种不同的方式来看待它的发展。一种方式是将Windows自动化目前的状况与五年之前进行比较,这种方式或许会令人对于这门技术的发展深受鼓舞,并对未来的发展充满乐观。另一种方式是将如今的Windows自动化生态系统与基于Linux的基础设施中所用的工具进行比较。一眼看上去它们似乎没什么不同,但随着你更深入的观察与更多的实践之后,你开始意识到真实的情况,不可否认,Windows自动化的成熟度与Linux相比确实存在着差距。

这两种比较方式都与当前的Windows自动化状况背后的故事相关。在本文中,我将通过对当今实际应用中的Windows自动化场景的观察,深入探索这两种比较方式的意义。Windows自动化在2014年的发展情况如何?痛点在哪里?它与Linux平台有着怎样的不同?Windows和Linux 是否会最终形成一种近似的自动化方式,还是说它们依旧水火不容,各自在自己的市场中占据一席之地?

你采用的Windows自动化方式可能与我的不同

实现Windows自动化的方式多种多样,不过这些方式最终可以归结为这三类:

首先看一下第一种方式,用户选择不断重复琐事并决定不采用自动化。第二种方式能够提供漂亮的报表,但要经过无数次的点击,可能还会提供一个功能有限的可编程API界面。第三种方式通过原始代码的集成提供了极大的灵活性,但往往提供的文档很有限,并且需要编写大量的自定义代码才能够创建一个完整的端到端解决方案。本文主要专注于第三种方式,因为我个人对这种方式最有经验。

设置

首先让我们来讨论一下设置。虽然设置Windows环境的方式有很多,但我所展示的方式是我们在CenturyLink Cloud平台上所应用的流程。由于我们的环境中混合使用了Linux与Windows服务器,因此需要一种能够集成这两种操作系统的解决方案。我们最终决定使用Chef作为配置管理工具,并且成为它们的机器资源产品 —— Chef Metal的beta版本的早期使用者。我们所使用的主要虚拟平台是VMware vSphere。现在让我们看一看这些技术是通过怎样的方式结合在一起,对Windows和Linux机器进行设置的:

如图所示,我们通过一个设置器节点保存着某个数据中心所有服务器的目录(由Chef服务器提供),如果它察觉某个服务器没有被正确设置,并且它存在于这个目录之中,那么设置器就会使用Chef Metal对该节点进行设置。Chef Metal为Chef生态环境提供了一种新的“资源”,即机器资源。这种资源的定义包括核的数量、内存、VM镜像的模板等属性。

machine 'web' do     machine_options :memory_mb => 4096, :num_cpus => 2     recipe 'active_directory'  end

Chef Metal本身了解在Chef中的机器的通信情况,但它并不了解VMware的存在。使用者可以利用Chef Metal的插件模型创建一个驱动程序,它知道如何与ruby vSphere SDK(rbvmomi)进行交互,并且能够将Chef Metal的高层次抽象转换为实际的VM、数据存储、集群、操作系统自定义模板等等。

驱动程序代码在Chef Metal中表现为一种计算资源,Chef Metal从而了解如何在Chef客户端中引导这一实例,并将其转换为在我的配置中所定义的角色,它可以是一个web服务器、一个活动目录服务器、一个文件服务器或其它任何角色。

总的来说,这套方案是可行的,但或许你只是希望能够设置一台Windows服务器,尽量避免搭建其它服务器,以及编写自定义ruby代码的复杂性。这种情况下可以采取一些其它轻量级的方式,我将为你展示其中的几种。

Windows Azure PowerShell Cmdlets

如果你拥有一个Azure帐号,只需下载Azure PowerShell模块,就能够将在Azure web门户网站上可进行的一切操作进行自动化,比如只需一行代码就能够创建一个Azure IaaS虚拟机:

$cred=Get-Credential AzureAdmin  New-AzureQuickVM –ServiceName ServiceTest1 -Windows -Name MyVM `     -ImageName 3a50f22b388a4ff7ab41029918570fa6__Windows-Server-2012-Essentials-20131217-enus `     -Password $cred.GetNetworkCredential().Password -AdminUsername $cred.UserName `     -Location "West US" –WaitForBoot

Hyper-V PowerShell 模块

如果你的膝上电脑安装了Windows 8专业版,那么就可以通过其中自带的hypervisor实现Windows设置的自动化。如果你还没有完成这一步,请按照以下方式打开这一功能:

dism.exe /Online /Enable-Feature:Microsoft-Hyper-V /All  dism.exe /Online /Enable-Feature:Microsoft-Hyper-V-Management-PowerShell

随后创建你的VM:

New-VM -Name "myVM" -MemoryStartupBytes 1GB -NewVHDPath "D:\VHDs\w81.vhdx" -NewVHDSizeBytes 60GB  Set-VMDvdDrive -VMName myVM -Path "C:\ISOs\EVAL_EN-US-IRM_CENA_X64FREE_EN-US_DV5.iso"  Start-VM "myVM"

无需许可

手头上碰巧没有可用的Windows ISO?不要紧。你可以从微软的TechNet或MSDN网站下载Windows免费评估版本的ISO或VHD文件。这些镜像在几个月之后才会过期,当然不要在生产环境中使用这些镜像,但我一直使用它们进行测试。

关于Windows更新的提示

将Windows更新预先安装在你的基础镜像文件中,这可以省去你几个小时的时间用于等待更新完成。你需要一种自动化流程,能够对这些镜像文件进行日常更新。我强烈建议你研究一下某些工具的使用,例如packer.io。Packer在Linux世界中已经广为人知,不过近期在Windows社区中也得到了一定的关注。它是一种用于创建基础VM镜像的工具,通过一个配置文件告诉packer如何创建这个镜像。这种方式很像配置管理,但操作的对象是镜像,而不是机器。实际上packer能够与许多流行的配置管理工具进行集成,例如Chef,从而利用配置管理解决方案中提供的DSL创建你所需的镜像。

打造新的Windows实例

现在你有了一个空的Windows VM,那么接下来呢?正如我之前所指出的,我们使用Chef在CenturyLink Cloud平台上创建Windows机器。从技术层面上说,你需要编写一些Ruby代码,但多数情况下只需使用DSL就够了,对于 Ruby的专业知识要求几乎没有。Chef将组成一台服务器的多种通用抽象概念以构建块的形式进行公开,它们被称为资源。你可以将它们组合成为更大的资源,在Chef的术语中称为recipe及cookbook。

以下代码表现了一个注册表键的资源:

# Disable the ServerManager.  registry_key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager' do     values [{       :name => 'DoNotOpenServerManagerAtLogon',       :type => :dword,       :data =>  0x1       }]  end

以下代码将某个用户加入一个组资源中:

group "administrators" do     action :modify     members node['platform_ftp']['fileshare_user']     append true  end

顺便说一句,这种方式在Windows或Linux上都能够运行。实际上大多数资源都是平台无关的,只依靠于某个底层提供者模型,它将具体实现委托给特定的平台。

资源的概念不仅仅限于Chef

资源这种抽象概念并非Chef所独有的,在其它配置管理工具中也使用了相同的术语,例如流行的Puppet和在PowerShell 4及更高版本中内置的微软DSC(期望状态配置)。PowerShell团队还有许多地方需要向Puppet、Chef、CFEngines等工具看齐,但他们追赶的脚步非常快,现已推出了可用于Windows上的新资源可供下载,名为资源wave包,最新的版本是wave 7

在许多配置管理工具中,除了资源之外还有许多复杂的工作。例如报表、版本控制、节点引导、打包等等。实际上,像Chef这样的工具已经围绕着自身打造了一个完整的开源生态系统,为测试、依赖管理和各种小型插件提供了额外的工具,能够填补Windows服务器本身与各种特定的业务需求之间的差距。微软已认识到这种差距的存在,于是和Chef等产品进行了紧密合作,并通过Chef recipe将它的DSC资源进行公开。这也意味着,一方面能够利用由DSC资源所提供的某些特别的Windows自动化能力,同时也能够利用Chef的跨平台功能,包括它的报表、企业服务器特性,甚至能够与它的开源社区完全实现对接。

如果想了解关于在Chef中实现DSC,以及使用基于PowerShell的测试工具对自动化过程进行测试的详细内容,请阅读这一篇博客文章,它将一步步地带你了解这一主题

获取Chocolaty

如果你无意克服配置管理工具那陡峭的学习曲线,而只是想通过它完成几个应用的自动化,那么你可以对Windows在包管理方面所提供的功能进行一番调查。

多年以来,Windows包格式的事实标准是MSI文件,但说句实话,它的功能无法与apt-get或yum相提并论。几年之前,我的朋友Rob Reynolds就意识到,人们需要一些更简单,并且能够更好地支持http的工具,因此他开始开发Chocolatey。虽说我遇到的Windows技术专家中有许多人从没有听说过Chocolatey,这一点总是让我感觉很吃惊,但它已经在Windows高级用户群体中获得了很高的流行度,甚至微软PowerShell团队也在最新版本的PowerShell中创建了一个Chocolatey客户端。没错,下个版本的Windows将自带Chocolatey。

让我们观察一下这些命令:

cinst googlechrome  cinst git  cinst ruby  cinst vagrant  cinst VisualStudio2013ExpressWeb

它们的作用是在后台安装所列出的各种软件,而无需图形用户界面的介入,不必一路点击“下一步”、“下一步”、“完成”。正如apt-get一样,你能够发现、下载并升级你最常用的Windows应用。

虽然Chocolatey的技术没得说,并且开发工作也十分活跃,但它最大的弱点在于它的生态系统。请不要误解我的意思,和Windows OSS一样,Chocolatey的社区同样十分活跃。但与apt-get等工具不同的是,Chocolatey包多数是由社区进行开发及维护的,而不是由包软件作者本人进行维护,当然也有一些例外。这意味着有些情况下,包或许没有得到及时更新,或者会试图从失效的URL中下载软件。在多数情况下这种情况并不严重,但有时经常会遇到这种问题。

不过,正如我们已经看到DSC的崛起使得配置管理技术成为了Windows的主流,我敢打赌,在包管理方面也会看到同样的进展。一旦在 Windows中出现了这种工具,并且能够让Windows用户通过TechNet上的白皮书开始学习示例,那么让包管理工具成为日常工具的日子也就不远了。

使用Boxstarter进行Chocolatey风格的机器构建

继续回到刚才的话题,怎样能够创建一个Windows环境,而又避免使用繁重的配置管理工具呢?让我们快速地浏览一下这个工具,它利用了 Chocolatey的功能,并且能够解决在搭建新的Windows环境时在机器引导时所经常遇到的各种痛苦。首先我要曝光一点:我就是这个工具的作者。

Boxstarter为Chocolatey包加入了重启后自动恢复的功能,并且提供了一些额外的命令,它能够增加底层的功能并且进行自定义。避免在安装类似SQL Server、Visual Studio等应用,或是在打开Windows特性以及安装Windows更新时经常出现的机器构建错误。

Boxstarter与Chocolatey接受同样的安装命令字符串,它能够检测到等待重启的情况、自动进行重启、在必要时重新登录用户,并返回包的安装过程。Boxstarter最受欢迎的特性之一在于,你无需创建一个包、也不必安装Chocolatey、Boxstarter或其它任何先决条件,就能够实现这一功能,通过一个URL就能够完成一切操作。举例如下 :

http://boxstarter.org/package/nr/url?https://gist.githubusercontent.com/mwrock/  8518683/raw/43ab568ff32629b278cfa8ab3e7fb4c417c9b188/gistfile1.txt

以上链接将提供一个微软ClickOnce风格的应用作为引导程序,以提供Boxstarter的安装,随后将紧随Boxstarter URL 后的gist URL中的内容进行打包。你也可以选择安装Boxstarter PowerShell模块,使用这些模块通过Chocolatey设置远程Windows环境。它依然能够优雅地对重启进行处理,并允许你使用在本地常用的PowerShell搭建环境。

你也许不会仅仅通过Boxstarter或Chocolatey用于设置和管理运行中的服务器,但对于每个开发者机器来说是非常优秀的工具。

SSH在哪里?

如果你曾经在Unix或Linux中进行过实战,你也许会认为Windows已经默认实现了SSH服务器的功能。虽然从技术上来说它并不是SSH,但其概念是相同的。许多人对于微软没有从一开始就使用SSH感到困惑不解,如果你想知道微软为什么不使用SSH,请听一下这个播客音频、PowerShell的作者Jeffrey Snover对此进行了深入探讨。

为了获得与SSH相近似的功能,Windows使用了winrm(Windows 远程管理),这是一个基于SOAP的web service,能够通过HTTP(s)发送或获取消息,并将其转换为本地命令行。这一功能最早出现于PowerShell v2.0中,在随后的每个新版本中都对功能进行了增强(当前的PowerShell版本是beta v5),用户可以使用“PowerShell Remoting”,它的功能建立于winrm之上,并且提供了一个互动性的远程控制台,与SSH会话的使用几乎没有差别。

现在我已经远程连接到某一台Azure VM:

有人可能会争辩(包括我自己在内)道,远程PowerShell的功能比起SSH更为先进,因为它在远程与本地shell之间提供了更高精度的通信与操作能力。

我个人的体验是,远程PowerShell的主要缺点在于它不像SSH那么容易顺利上手,尤其是在老版本的Windows系统上,但即使在近期的系统,例如Windows 2008 R2上也不那么容易使用。在获得授权的Linux机器上,SSH可以直接使用,而在Windows系统上则需要进行适当的配置。在Windows 2012 R2上虽然不必再进行任何配置,但前提是已经满足了某些条件,例如已经加入了域、在同一个子网中,或是需要其它某些组策略设置。

如果你打算尝试从非Windows平台上远程访问Windows系统,那么即使使用远程PowerShell也无能为力,你唯一的选择就是直接调用winrm web service。不过还有一些跨平台的API可以选择,用Ruby开发的WinRM就是一个流行的选择,我个人也经常使用它,Shawn Neal也非常积极地维护着这个项目。

require 'winrm'  endpoint = 'http://mywinrmhost:5985/wsman'  krb5_realm = 'EXAMPLE.COM'  winrm = WinRM::WinRMWebService.new(endpoint, :kerberos, :realm => krb5_realm)  winrm.cmd('ipconfig /all') do |stdout, stderr|     STDOUT.print stdout     STDERR.print stderr  end

我难道不能够使用Vagrant吗?

简短的回答是:可以!如果你还不熟悉Vagrant,就先简单介绍一下:Vagrant是一种对虚拟化进行抽象的工具,能够简化个人机器设置的过程,通常用于开发或测试目的,可以在团队成员之间很方便地进行共享。如果你还没有使用过Vagrant,很难用语言有效地表现出它的功能与简易性。许多不熟悉它的人会表示,“我很满意目前使用的 hypervisor(VMware、virtual box、Hyper-V等等),为什么还要引进其它工具?” Vagrant能够很方便地共享一个1K左右大小的单一文件(通常在源代码控制系统中管理),它能够以一种易读的DSL表示在何处获取初始的VM镜像、如何配置网络,以及如何为基础镜像加入额外的自动化能力。在你的团队中或许有成员使用了不同的虚拟化技术,但“vagrantfile”通过抽象消除了它们之间的差异。

VAGRANTFILE_API_VERSION = "2"  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|      config.vm.box = "mwrock/Windows8.1-amd64"     config.vm.box_url = "https://wrock.blob.core.Windows.net/vhds/win8.1-vbox-amd64.box"     config.vm.guest = :Windows      config.winrm.username = "vagrant"     config.winrm.password = "vagrant"     config.winrm.port = 55985  end

这是一个非常简单的vagrantfile示例,它的作用是设置一个Windows 8.1的vagrant环境。从URL就可以看出来,这个基础镜像是由我的Windows Azure Storage帐号提供的。Vagrant会将所有对端口号55985的请求转发到vitual box VM上“真正”的winrm端口号5985。

Vagrant最近刚刚对Windows实现了第一等的支持,我个人的感觉是Vagrant对Linux系统的支持更好,但这种情况在每次发布后都有所改善。为了演示通过Vagrant设置Windows系统有多方便,首先下载vagrant,然后执行以下命令:

vagrant init mwrock/Windows8.1-amd64  vagrant up

这个命令将设置一个Windows系统,无论你使用的是VirtualBox或是Hyper-V(你至少需要用到其中一种技术)。如果你还没有获取基础镜像,那么不必麻烦,在调用这段命令时会自动下载该镜像。在这里你实际上已经开始感觉到它应用在Windows系统中的不便了,典型的Windows 基础镜像经过压缩后约为3.5GB,这个文件尺寸非常大,通常来说比Linux镜像大30倍以上。不过,这个下载过程通常是一次性的,Vagrant会将它缓存在本地,因此无需进行重复下载。

容器化

如果不谈谈容器化技术或是Docker,我就无法结束这个话题。Docker能够明显减少设置一个计算实例所需的时间,并且它承诺能够充分简化打包应用的过程。

目前在Windows系统上还不存在容器。对于某些人来说,这一事实就足以让他们决定远离Windows,或开始从Windows环境中向外迁移。在CenturyLink Cloud环境中,我们将所有基于Linux的基础设施都通过Docker进行了初始化服务器构建测试。而团队中的每个人都会告诉你,对Windows服务器的自动化进行测试与调整远比Linux麻烦得多,其原因就是在Windows环境中无法使用Docker这一事实。

有一家公司对于如何将容器化特性引入Windows环境投入了巨大的调研力量,那就是spoon.net。早在虚拟桌面领域中,他们就开始投入这一概念的研发了,但很快他们就在服务器环境中加速了这一进程。你可以创建一个spoon容器,它提供了一个隔离的文件系统以及注册表,其命令行界面也很有Docker的风格。目前在服务与网络功能上还存在着一些不足,但许多问题在本文发布时或许已经得到解决了。我的期望是有一天能够将Windows容器与我的Chef自动化工作流整合在一起。

Spoon的CEO Kenji Obata最近在推ter上的一篇帖子中发布了关于容器化Chef客户节点的几张截图。

自从这篇帖子最初发布之后,关于在Windows上实现容器化的进程出现了更有趣的变化,微软刚刚宣布将与Docker展开合作,将Windows容器引入Docker生态系统。至于什么时候能够实现,以及它的工作方式如何还不清楚。不过微软能够公开性地做出这一承诺,这一点确实很令人振奋。看起来,Windows容器将来必将以某种方式出现在我们面前。

先锋时代已来临

对于Windows自动化来说,现在正是一个非常激动人心的时刻。当我最近刚刚离开微软加入CenturyLink,开始完全进入跨平台之旅时,我感觉似乎自己似乎已经站上了一个高点,正准备目击一个服务器自动化文明的出现。虽然有多种方式能够描述这一景象,但我喜欢想象为自己已经大踏步迈进了西大荒准备进行开垦。虽然前进的道路并不平坦,但我感觉Windows自动化的时机和创新条件已迈向成熟。我非常期待着看到它能够将我们带往何处。

关于作者

Matt Wrock在设计大规模、分布式、高流量的web应用程序的架构以及自动化环境设置及部署方面已经具有超过15年的经验。不久之前,Matt在软件担任高级软件工程师。如今他到了CenturyLink Cloud开展工作,专注于数据中心的自动化。Matt也是http://boxstarter.org项目的创始人,以及http://chocolatey.org的代码贡献者。你可以在推ter上通过@mwrockx关注他,或是阅读他的博客hurryupandwait.io

查看英文原文:Cloud Automation in a Windows World