微软在2014年秋宣布,计划在Windows Server 2016中增加对Docker容器的支持。这个声明进一步强调了微软对Linux和开源工具的日益关注。在接下来的几个月,.NET Core开放了源码,微软和红帽结成联盟,并宣布了计划将SQL Server移植到Linux上。Windows社区对容器的支持近在眼前,那就让我们深入探索SQL Server容器的使用。
容器与虚拟机容器的概念已经存在了数十年(记得BSD Jails大致发布于2000年),但现在都涌入了采用Docker公司开源项目的主流中。Docker的设计包含一个优雅的应用打包方法以及一个对容器进行管理的服务器端API。该设计的核心是通过将软件依赖内嵌在容器镜像内来解决“依赖地狱”的应用打包方式。通过使用Docker容器,开发人员可以确保在笔记本上开发的应用能在一个共享测试服务器或公有云上运行。
正如Win32 API控制着桌面应用领域,Docker正快速地成为事实上的容器打包工业标准API。微软正在为Windows Server 2016实现一个Docker API的子集,从而通过开放容器计划(Open Container Initiative)参与到这个标准化过程中。用户可以从Docker对业界的支持中获益,这些支持包括AWS、Azure的主机服务、云服务以及第三方监控、日志、集群等管理工具。
容器有高速、轻量以及提升资源利用的优势。容器只需要数秒就可以启动,且往往对主机只有很小的增量负载。在一个共享的开发、测试服务器上运行大量的容器也很寻常。而另一方面,虚拟机却需要数分钟来启动,并且只有较低(10-15%)的资源利用率。容器在开发和测试环节的盛行正是由于它在创建环境时的高速和灵活,以及相应对虚拟机使用(或维护)需求的明显减少。
容器镜像和仓库容器提供用户和进程的隔离来保护应用免收其他容器的不良操作。.Net和SQL Server容器也都提供有效的命名空间隔离。业界极度关注提升容器的安全性,主要云提供商(Azure、AWS)将容器包装在虚拟机中来保证其安全使用。容器也有方法来管理资源使用,比如限制CPU、磁盘和网络使用。
容器是通过Docerfile来构建的。Docerfile是一个包含一系列构建容器命令的文本文件。Dockerfile从一个基础镜像开始,向容器内增加代码、数据。容器可以被保存并且作为“镜像”被复用。镜像可以保存在一个共享的仓库中。
关系型
数据库容器和SQL ServerMySQL和Postgres属于Docker Hub中最受欢迎的容器镜像之列。数据库容器被用来构建相同的、隔离的、沙箱化的环境来进行开发、测试。数据可以放在容器内,也可以挂载(mount)上去。SQL Server容器是基于微软共享DLL架构的SQL Server实例,这个架构在过去十年中为同一个主机上运行多SQL Server实例提供支持。容器提供额外的进程和用户隔离和SQL Server配置,用户可以通过SQL Management Studio或其他工具来访问。一旦构建完成,容器可以保存为镜像,使用镜像来帮助团队在一个共享主机上构建多个相同实例。容器特有的优势包括:
速度:SQL Server容器可以在数秒内提供服务,并为经常需要停用和快速替换实例的开发和测试人员提供有效的支持。
高效:多个SQL Server容器可高效地在同一共享主机上运行,并且支持合并多个虚拟机为单个共享虚拟机来提供给开发测试团队,这相应节省了许可证(license)和维护的成本。
持续集成(CI)、持续交付(CD)支持:SQL Server容器提供自动增加挂载(mount)数据库的支持、构建时运行配置脚本、以及持续集成和持续发布过程所需要的自动化构建支持。
高可用(HA)、灾备(DR)支持:SQL Server容器支持集成管理数据库副本、快照、镜像的第三方系统,并花费大量工作来证明一系列操作的效用。下面会详细介绍。
微软在2016年下半年准备实现Windows Server对Docker的支持。微软所设计的特点是可以支持Windows Server 2016“内核”或无输出界面的Nano服务器。有趣的是微软闭口不言Windows Server 2016对SQL Server容器的支持,今年春天演示的第一个SQL Server容器也是运行在将来的SQL Server的Linux移植版上的!这意味着SQL Server可能倾向于支持Linux主机而不是Windows容器。这可以理解,毕竟微软选择实现Linux风格的容器和应用配置。
微软的Windows Server 2016容器被设计为兼容.NET、Windows控制台应用和服务所在的shell容器。然而,SQL Server和其他Windows应用并不适合在shell中进行管理。Windows Server 2016上的SQL Server容器会需要使用SQL Management Studio或其他工具来运行脚本或增加、挂载数据库。简单来说,SQL Server容器需要这些手动操作,阻碍了容器所提供的的高速和自动化。
幸运的是,对基于Docker的开源项目移植的SQL Server容器感兴趣的开发人员可以找到微软之外的实现。WinDocks是一个由前微软工程师组建的初创组织,他们已经为Windows 8、Windows 10、Windows Server 2012、Windows Server 2016发布了Docker开源项目的移植版。WinDocks支持SQL Server 2008(及r2)、2012、2014和2016的所有版本。WinDocks为Windows添加容器的支持,使用户可以在容器中使用SQL Server的许可证。本文以WinDocks社区版本为基础,可以免费获得这个版本。
数据持久化和SQL Server容器
SQL Server容器和SQL Server实例在使用上没有区别,所以需要选择本地数据或挂载的数据库。WinDocks SQL Server 容器支持使用ADDDB命令来复制一个数据库到容器中,而MOUNTDB命令支持挂载本地或网络上的数据库。
ADDDB复制数据库(Primary、Secondary和日志文件)到容器中,并在容器启动时追加,在容器停止时剥离。SQL Server容器提供命名空间隔离,所以多个相同实例可以在相同主机上的容器中运行而无需考虑命名和用户冲突。
一旦创建完成,容器和其追加的数据库可以被保存为新镜像,之后开发和测试人员可以方便地根据需求生成实例。容器可以在数秒内实例化,具体速度取决于数据库的大小和数量。这是支持开发和测试的一种常用方式,一些用户在容器中增加30个或更多的数据库也能拥有良好的性能。
“容器内”数据和本地添加到实例中的数据是一样的。容器拥有这些数据,并将它们持久化在容器的文件系统中,同时受到容器宕机的影响。数据库可以通过SQL Server Management Studio或其他标准工具来访问。
下面是一个DockerFile使用ADDDB的例子,它由两个命名的数据库组成,包含一个primary数据库文件和多个secondary数据库文件:
FROM MSSQL-2016
ADDDB dbname Primarydb.mdf Secondarydb.ndf Secondarydb.ndf
ADDDB dbname2 Primarydb.mdf Secondarydb.ndf
ADDDB将数据库复制到容器内,MOUNTDB支持挂载本地或网络上的数据库。WinDocks支持容器独立生成的挂载点。在这方面,WinDocks反映了将来Docker设计的方向。
使用MOUNTDB让数据库在容器启动时挂载并追加,并在容器停止时卸载并剥离。每个数据库只支持一次挂载。与容器使用ADDDB不同,挂载的数据库不会被放入SQL Server容器镜像中。为了支持挂载在多个容器上,数据库必须建立副本并创建或克隆多个挂载点。
下面是MOUNTDB使用本地和网络数据库的一个例子:
FROM MSSQL-2016
MOUNTDB dbname c:pathPrimarydb.mdf
MOUNTDB dbname2 networkpathdbname2.mdf networkpathdbname2.ndf
构建SQL Server
容器下面的例子描述了使用ADDDB构建SQL Server容器的过程:
第一步:打开一个新的命令行窗口
第二步:输入 >docker build c:WindockssamplesTest1 WinDocks客户端返回包含容器ID、端口和SQL Server sa密码的字符串。
第三步:>docker start ,其中containerID可以只使用容器ID的一部分。
Docker命令和返回输出如下图所示。每个容器都是完全隔离的SQL Server实例,并且有命名空间隔离,可以通过SQL Server Management Studio访问。在这个例子中,数据库Adventureworks被复制到容器内,并在容器启动时被追加。
数据库的schema和设计可以被更新,一个新的SQL Server镜像会在容器停止后被创建。整个团队可以在一个共享的WinDocks主机上使用这个SQL Server镜像。
这个流程展示了在相同独立容器中快速共享SQL Server实例的普及。一个SQL Server变更脚本可以根据需求被导出,用来更新源数据库。
容器和数据库克隆在使用大型数据库时数据库克隆非常有用,它支持发布多个挂载了克隆数据库的容器,用来开发或测试(一些克隆数据库还是可写的)。WinDocks是一个可扩展的系统,它支持管理进程介入创建快照和克隆过程。
对增加快照和克隆的支持是由管理员提供的,管理员可以选择在WinDocks的node.cfg文件中启用“特权”命令。在下面的例子中我们使用一个简单的“copy”命令来展示这个过程。
Dockerfile可以定义包含挂载了克隆数据库的SQL Server容器。注意容器中环境变量的使用。
今年早些时候WinDocks与NetApp合作探索使用容器来集成NetApp的SnapClone进程(SDCLI.exe)。结果令人满意,仅一步就在50秒内部署了挂载750G克隆数据库的SQL Server容器!
SQL Server容器对遗留项目的支持
用户对Windows容器的兴趣正快速上涨,一个针对WinDocks社区版下载者的调查显示了一个惊人的使用范围,最流行的还是用它来进行开发和测试,但是为了支持遗留项目如SAP和微软Dynamics的情况也有很多。在这些案例中,SQL Server后端被容器化,并且相关支撑环境也被简化。
集成SQL Server和.Net容器以及现存架构
幸运的是,容器对.Net应用提供完美支持,并且集成SQL Server和.Net容器环境是很直截了当的。ASP.NET架构定义了XML文件、web.config的使用,从而定义.NET应用和SQL Server容器间的配置和链接字符串。
这里我们使用WinDocks中位于windockssamplestestdotnet目录的示例.NET应用来举个例子。使用记事本打开web.config,配置“连接字符串”,指向SQL Server容器的主机地址、端口和SQL认证信息。
使用运行中的SQL Server容器信息修改主机名(如果需要),端口和SQL Server sa密码。保存并关闭文件(检查下,不要保存成.txt文件)。并运行:
打开浏览器,访问主机地址和端口来查看集成的应用。
还有另一种方法集成容器和DNS命名服务。这个方法是在构建时使用Windows NETSH工具将容器动态分配到已知IP地址。
结论SQL Server容器利用经过微软验证的共享DLL架构来提供在共享主机上SQL Server实例的实践支持。流行的用例是在开发和测试环节,但有部分是用来使用容器化SQL Server后端来测试遗留项目(主要是SAP和微软Dynamics)。对虚拟机需求数量的降低各有不同,但用户报告平均能有3-5x的减少,同时也显著节省许可证和主机维护的开销。由于更新会在容器刷新时自动传播,主机的维护也得到简化。
这里提到的例子关注于数据库引擎,若要探索容器对SSIS和其他SQL Server服务的支持,仍需做更多的工作。
其他正在探索的有前景的使用场景包括迁移工作负荷、高可用、以及灾难恢复。容器的速度和可移植性使得这些更加可行、可实践、也更容易被测试。额外的时间和测试也会有助于回答SQL Server容器是否做好了运行在生产环境的准备。
鉴于微软没有明确计划,SQL Server容器在Windows Server 2016不太可能得到实践级支持。既然Windows Server 2016不支持,那么理想的容器支持会是将来的SQL Server的Linux移植版,我们期待在2017中的进展。