在 Windows 平台上实现云自动化

阅读数:2732 2015 年 6 月 19 日

话题:云计算DevOps语言 & 开发架构

对于如今的 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最近在 Twitter 上的一篇帖子中发布了关于容器化 Chef 客户节点的几张截图。

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

先锋时代已来临

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

关于作者

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

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