数人云上海&深圳两地“容器之 Mesos/K8S/Swarm 三国演义”的嘉宾精彩实录第四弹!小数已经被接连不断的干货搞晕了,沉浸技术的海洋好幸福~Windows container 在国内的实践还比较少,携程做为.Net 大户,率先进行了调研和实践应用,将其中的成果与你们分享。java
罗勇,携程云平台开发经理
主要负责携程云平台建设和维护,熟悉 OpenStack , Docker , Linux/Windows Container 等技术领域python
今天的主题是 Windows 容器。今年下半年携程开始了对 Windows container 的调研工做,目前已经有一些成果和实际应用案例,与你们分享一下,主要内容有:linux
携程为何要使用 Windows container
(可能国内大部分的人了解 Windows container 少一些,特别是具体的实践,分享重点会偏 Windows container 细节)web
传统.Net 应用容器化实践shell
容器存储&网络&编排安全
携程是.Net 应用大户,由技术栈决定的,早期携程整个应用架构都放在该平台上,线上跑了 3000 多个核心应用,覆盖了 20 多个 BU (业务部门),这让咱们不得不关注这一庞大的系统。服务器
平台要往 java 方面转,去分享 java 的红利,可是.Net 线上应用不可能都重写;网络
.Net 的应用目前 90%左右的应用都跑在虚拟机上,从虚拟机自身来看,粒度太粗,对资源的使用率还不是很好。架构
持续发布,应用上线,从拿到机器环境准备好环境上线生产,虚拟机模式下周期长,扩容慢。工具
新一代发布平台的需求,但愿缩短环境准备时间,作到秒级部署, Linux 平台的应用很是容易作到,可是 Windows .Net 应用在这方面支持比较难,另外,为了确保生产和测试环境高度一致,但愿应用发布是单一应用、单一镜像的,最好是一个容器尽可能少的包含系统进程,这样能够把资源隔离的粒度控制在小范围内,尽可能榨取宿主机的资源,同时但愿 Linux 容器和 Windows 容器的方案尽量接近,好比网络、存储,不须要两套不同的方案或是有大的有变化。
最开始的时候携程用物理机部署应用,为了保证互不冲突,用户在一个物理机上只部署一个应用。后来认为此举太浪费,就部署了多个应用,可是为管理带来了麻烦,应用之间有必定的冲突或者相互影响。以后有了虚拟机,虚拟机上能够部署更多的应用,并且隔离比较好,不过虚拟机资源隔离的粒度太粗了,因而容器走了过来,能作到把一个应用打到包里,这个包涵盖了环境配置等, run 起来能够只是一个进程,又具有必定的隔离性,同时把资源使用的粒度控制足够的细。
Windows container 目前支持的系统是 Windows server 2016 ,这个版本是去年 10 月份正式发布的(携程是国内比较早的一批拿到了他们的 RTM 版本),支持两类 server ,一类是 server core ,另外一类是 nano server 。 nano server 是微软比较推荐的一类服务器系统,启动很是快,能够大幅度缩短计划内维护宕机时间,一般几秒钟就起来了,不包含硬件检测的时间,几十秒都可以起来。这块携程尚未用于生产环境,目前只测试了用 server core 做为容器宿主机的系统的状况。须要着重提一下的是,若是宿主机打了补丁或者升级,容器也要对应的作补丁或者升级。固然不必定说立马作补丁升级,但必定要比较精确的找到对应的版本作升级。
Windows container 有两种 container 类型,这两种容器都是跑到 Windows servrer 2016 的,但还有一种容器的玩法是在 Liunx 平台跑.Net core ,这种方案咱们也看过,你们很容易想到它的局限,其实只能跑到用.Net 技术开发的 Windows 的应用,一些非.Net 的应用不支持,所以这个方案被 Pass 了。直接在 Windows server 跑容器的方案更为靠谱,该方案有两种类型, Windows server 和 hyper - v container 。
有人会问, hyper-v 不就是一个虚拟机的技术吗?对,其实它有点像虚拟机,可是 hyper - v 的技术略有不一样,速度会明显比虚拟机快不少,只是在申请资源或者获取资源时,比 Windows server Container 的速度稍稍慢一点点, Windows server container 可能 3 秒,它可能 4 、 5 秒。可是资源的隔离度比较好一些,相似于虚拟机,微软公有云 Azure 的容器服务也是采起这种容器类型,他们的考虑是公有云上面部署的应用不是受信任的,相互之间有可能“打架”的状况发生,他想隔离好一些。
另外一个区别, Windows server Container 的内核是共享的,能够在宿主机上看到每一个容器里面的进程,这与 Linux 容器类似,能够直接 kill 掉。 hyper-v container 宿主机是看不见容器内进程的,像一个虚拟机同样。此外,内存资源隔离不一样, Windows server Container 内存能够 share , hyper-v container 不能 share , hyper-v container 一旦分配就不能从新进行修改。对系统应用是信任的,这种比较适合作私有云的一些产品,由于在应用上跑的什么东西,这个应用能干什么坏事或者是相互之间有没有影响,均可以控制,可是公有云不能这样作,应用使用率很高,会把别的容器影响到。启动速度上也会有差异,一个启动快,一个启动慢一点,固然并非特别慢。
容器镜像,这个和 Linux 容器的镜像相似,能够分层。最下面一层是基础镜像,可是基础镜像和 Linux 有区别。 Linux 镜像能够本身搞,弄一个系统把它作成镜像,可是微软没有办法本身作一个 Windows container base 镜像。或者说如今只是 Windows server 2016 的镜像,想跑一个 2012 的系统是不行的。当前系统内核只能支持 win10 ,在上面能够继续安装想要的东西,好比接着安装 Framework ,而后在最上面装应用。
镜像构建也是同样, Windows container 容器和 Docker 集成比较好,能够用 Docker 工具的一些命令进行 build ,用 Dockerfile 来 Build 一个镜像。 registry 是镜像能够直接 push 到一个平台或者是私有的 registry 上面去,经过 Docker pull 方式拉下来, Docker run 跑起来。
Windows container 的镜像,能够在 Docker 网站上能够找到关于 Windows container 的一些 base image, pull 下来大概有 8G 左右,在外网上下载可能要两天。你们能够尝试一下。也能够建私有的 registry ,携程采用的 VMware 开源的 Harbor 方案,自己没有作太多的修改,直接能够用。和携程的 AD 整合之后基本上能用了, registry 能够把 Linux 和 Windows 的镜像都放在一块儿,两边都能用,都能管,这部分省掉了不少的内容,不须要作额外的开发,这样 Windows 和 Linux 的平台的 image 管理方案是一致的。
以前提到携程有 3000 多个.Net 应用,这些应用天天要不停的发布、测试、编译打包,是一项很大的繁琐工程,有个叫“ build ”的项目负责这个事情。最初这些跑在虚拟机里,资源使用率很低,白天很忙,晚上使用率很低,有必定的资源浪费,且构建环境也常常不一致。为了积攒容器应用使用的经验,咱们考虑把 build 项目先容器化,也就意味着.Net 应用本身的编译在容器里面编译,看能撞出来什么样的火花。
原来写几千个应用的编译脚本,若是改了一些东西,变动维护的代价是很是大的,尽可能这个方案不要用到原来以往用的工具和使用方式,不去动它,最好可以拿过来不怎么修改,就跑起来。另外,重点看一下像 vs2010 和 vs201 这样的工具能不能在容器里跑,实践证实是能够的。而后看 MSBuild 在容器里面是否兼容,支持不一样的.Net Framework 版本,这些都是比较通用的软件,结果是这些功能都可以支持,另外也包括 python 、 MVC 、 GIT 等等。
首先环境,编译的环境高度一致,每一个环境没有太多的区别,容器拉起来直接跑,提升了编译成功率。
其次资源利用率提升了,咱们把虚拟机资源砍掉了一半,就只须要两台宿机机搞定整个携程 3000 多个.Net 应用的编译。
编译时长也缩短了,原来用一次构建平均要几分钟,如今 90 秒左右基本上能构建完成。
图形不支持,这个是某些企业想用 Windows container 的大问题,它自己图形不支持。后台程序没有太大问题,不过有一些依赖图像工具比较难支持。
旧应用兼容不是很好。好比遇到 MGwin 编译出来的包,一旦代码中有调用标准输出的语句程序直接就挂了,遇到这类问题,须要把源码拉下来从新编译,比较有难度。
不支持 RDP ,远程桌面是不能用的,那怎么作到远程访问呢? 还好 Windows 如今支持 SSHD 安装了,只须要容器内装一个 SSHD ,而后远程 SSH 去,固然能够用 powershell 远程的登陆方式,两种方案均可以用, SSH 方案更统一一些, 若是用户当前正在 Linux 平台上工做,忽然想登一个 Windows 的容器怎么办?固然也能够用 linux 平台的 powershell 工具实现远程登录容器。
不支持 D 盘。携程迁移过来不少老的应用是要装在 D 盘的,容器拉起来没有 D 盘,只有一个 C 盘。自己 Docker 有一个 volume 功能,能够挂一个数据的盘,问题是这样会致使在宿主机上留下一些东西,和宿主机产生耦合,若是容器删除或者迁移,宿主机上就留下了脏数据。后来咱们为 D 盘作一个 link ,至关于 D 盘能够快捷的方式连到 C 盘,映射到 C 盘的某个目录,这样数据都是落地到在容器的磁盘上,若是想在别的地方拉起来这个容器,能够直接 push register ,就能够在别的地方部署且环境同样。
接下来 Windows container 容器的存储,网络,编排方面的技术与你们分享一下。
Windows container 资源的隔离方式和配置管理 API 是借用 Docker 规范,设计理念和 Linux Container 相似,也支持 CPU share 的这种方式去控制资源的分配。内存能够经过 quota 的方式去分配内存, Disk 也可以充分应用到 IO 的带宽,这一块尚未作很是多严格的测试。关于网络的支持,携程作了不少测试,总体来说比较不错,问题较少。性能也知足需求,多个容器在一个同一个宿主机上也能尽可能用到整个宿主机的带宽。
存储有三种:一种是镜像,镜像自己是一个存储,设计之初定义就不是一个永久的存储,当前容器存储拉掉那个存储就没有了,也不是设计安全的。另一种存储是 volume (卷) ,能够挂一个数据盘到某一个容器上,在容器里扩展存储空间。同时多个容器也能够挂载宿主机上的一个同一个 volume (卷目录),这样你们能够实现 NFS 同样的效果。最后一类存储是网络存储,好比能够用 SMB 的方式挂网络盘在容器里面使用,里面若是有万兆的带宽支持还能够玩一下,若是没有万兆带宽的话就不要玩了,它只能放一些冷数据。
相对来说复杂一些, Windows 支持有四种网络模型,第一种 NAT 模式你们比较熟悉,起一个本地或者是数据本地的 IP 地址,若是你想外网访问的话,把 Docker 映射出来,这种方式比较适合作一个 JOB 类型的应用在上面,不须要外边能够访问它,可是容器里面能够去下载东西。以前讲的 build 项目就是用这个网络模型,很是简单,不须要考虑太多网络的模型就能够直接用。
第二种是 transparent 网络模型,这种模型是如今主要用于生产的模型,首先它是经过 mac 地址假装实现数据透传,对网络的性能自己折损也比较少,它也支持把多个工做网卡绑到一个交换机上,而后把这个交换机给容器用。网络模型在容器宿主机之外的机器上看到 Windows 容器和一台物理机没有什么区别。
还有一种是 L2 bridge 这种采用 openstack 网络的 Flat 模式,所用的网络跟宿主机的网络是同样的,和宿主机在同一个网段,这样有很大的局限性,网络和宿主机混在一块儿没有办法作到多租户隔离,而后网段用光了就完了,适用于比较小的集群。
最后一种是 Tunnel mode ,没有太多研究这一种,可是微软 Azure 用的这一种网络模型。自己携程为了和虚拟机的不少的品牌网络模型一致,因此这一种没有那么快的推动。
Hyper-v 宿主机是 2012 上面 hyper-v 的网络模型,以前要求一台宿主机尽可能要 4 块网卡,为何要用 4 块网卡?两块给虚拟机用,另外两块作一些管理,好比对存储用,虚拟机迁移等,能够作宿主机的管理。另外一种方式, 2016 建议的一种网络方式,这里面有一个叫作 embed team ,内嵌交换机,它的好处是把下面不管是两块仍是 N 块网卡均可以绑在一个 bound ,而后把这个 bound 放在一个交换机里面,每一个容器 port 所有放在交换机里面,而后容器给 port 打相应的 vlan tag ,这样容器的网就通了。
embed team 的好处是不须要要求宿主机必定要有这么多的网卡才能够用,另外一个好处是对这些不一样的 vlan 之间作一些流量的控制,携程的 container 的网络模型也是基于嵌入式交换机上实现的。把宿主机至少两块网卡作了 bound ,放在一个 embed team 里面去,另外加一个 port 给宿主机作管理网卡。容器宿主机相比虚拟机宿主机简单,没有存储和迁移的需求,就不要以额外的划分网络了,若是须要为容器的存储单独挂一个网络的话能够加一个 Port 作这个事情。不一样的网段的这种容器在上面能够再建立不一样的 Docker ,加不一样的 port ,而后容器在里面能够互通,这样的好处就是既实现了多租户、实现了网络隔离,同时和虚拟机包括 Linux 上面的网络模型是一致的。
编排这块一般一个容器部署到多个宿主机上,同时一套应用下来有数据层、业务层、也有 web 层,这些应用要分开放,它们中间放在哪里须要有一个地方,把整个管起来,也但愿这个东西能自动化,自己作编排这些,不管是 Swarm 、 K8S 、 Mesos 都是须要解决的问题。一种方案是用 Docker compose 这种方式,适合于单宿主机管理。想编排一下容器,看如何跑,这种方式用 Docker compose 就能解决。固然,微软如今对 Docker Swarm 支持好一些,实现成本比较低,基本上能管,可是性能方面没有作太多的测试,目前一些基本的调度、主机分类等等都能用。
由于携程的 Linux 平台用的也是这套方案作的编排相关的管理,但愿有一套方案可以尽可能两种容器一致,因而咱们的方案采用 Mesos 加上 Marathon 对它进行管理,自己它也有一些现成的工具,好比 UI 等现成的工具均可以用,这部分还在进行测试和研究中。官方下来的包不能直接跑到 Windows server 上面,要拿下来从新编译才能用。最终携程是想作到这么简单的一个容器的管理的架构,就是说但愿 Mesos 在里面可以同时管 Linux 容器和 Windows 容器,对它进行统一的调度,最大限度的优化这种调度策略,提高使用率,这是最终总体的设计理念。
有一些急迫解决的问题,与你们交流一下。首先 Windows container 的镜像比较大,在生产环境,若是批量 pull base image ,网络的带宽会很快被打满,会对业务带宽形成影响。咱们须要有一套方案来解决这个问题, 如何可以比较“经济”的方式把 Based image 或者变动的 Layer 文件下发下去,是后续要解决的问题。
Windows container 的监控日志,没有现成的方案,我也有与微软团队交流过,这部分文档很是少,携程以后也会重点解决监控问题。
推行单容器、单应用的发布方式,但愿后面可以把各类 FAT/UAT/Prod 环境之间打通,均可以经过 Windows 容器方式,秒级发布。
携程有 3000 多个应用,一旦容器跑起来了,宿主机的规模仍是比较可观的,这种状况下,大规模容器如何管理好?这也是后面须要解决的问题。
这是我今天给你们分享的主要的内容,谢谢你们!