查看原文
其他

案例分享丨数据中心容器化改造

李绪亮 中国教育网络 2022-11-22

高校信息化部门在数字化转型浪潮中,首先要转变思路:技术固然重要,但它不是工作的目的。技术人员要摒弃“唯技术论”,跳出舒适圈,积极响应业务部门需求。

青岛大学(图源学校官网)

2019年底,青岛大学在数据中心改造时明确:支撑数字化转型高效、可靠、安全的应用交付,是高校数据中心存在的主要意义,任何技术创新都应围绕这个目标。

自2020年落实“十四五”规划的过程中,我们牢牢把握学校发展核心,尤其是注重疫情催生出的新的教学、科研、管理需求。结合IT行业的趋势进行研究,可知:

利用容器技术取代完整的操作系统,实现应用交付,是提高业务上线质量和速度、降低环境维护成本、增强网络安全的有效方法。

因此,我们将业务容器化改造写入“十四五”规划,并积极探索业务容器化的发展理念、生态培养、安全保障、支撑技术和落地工具。

2021年初,我们组织专家结合CentOS开源社区发生的重大变化[1]与我校数据中心实际进行分析和探讨,得出结论:

由于我校Linux系统管理成熟度低且CentOS 8只有少量部署,短期内社区变化对我们影响有限;但随着业务系统更新换代,此变化未来几年将对我校数据中心生态产生重大影响。

在金融、互联网等信息技术领先行业,容器应用成为“新常态”,高校和其他传统行业的数据中心,容器化应用相对较少。

我们应在研究容器技术的基础上,立即着手布局并推进云原生、容器化改造,这样既可在外部供应链变化时保证业务稳定运行,又可提升基础环境水平,为数字化转型消除部署运维障碍。

容器化改造策略

容器化初期,容器环境的应用交付还要依赖完善的虚拟化和现有的基础设施服务。随着容器化推进,会有越来越多(物理)服务器成为从属于容器平台的计算节点,运行Fedora CoreOS这类容器专用操作系统,虚拟化平台使用的(物理)服务器数量会减少。

绝大多数面向用户的应用和中间件完成容器化改造后,仍会有不适合容器环境的应用,只是两者相对地位会有变化,完整操作系统和容器共存局面将长期存在。

基于上述趋势判断,我们在完整操作系统和虚拟化环境中的投入,应以方便容器部署、简化运维复杂度、提高应用交付效率和安全性为目标,相应地减少对虚拟机资源调配、操作系统管理、文件系统管理、软件包管理等日常管理流程的优化。

考虑到基于Kubernetes的容器编排平台复杂性,加上目前高校场景下真正意义上的微服务架构业务应用还不丰富,我们初期还是会在Ansible +Podman[2]+systemd运行大部分应用,并将于容器化后期引入Kubernetes。

制度和培训方面,针对容器环境、云原生架构,我们将制定体现时代精神、顺应潮流的操作手册和规范。同时,积极引入社会力量,为部门自身和应用系统厂商技术人员提供学得会、记得住、用得好的培训,力求尽快形成战斗力。

我们虽然处于容器应用的初级阶段,但是对于容器支撑平台的IPv6支持和安全合规性的要求不能放松,必须明确拒绝没有考虑IPv6的产品,明确拒绝安全体系不完善的产品。

完整操作系统与

容器化优劣分析


完整操作系统的优劣

现阶段,从应用交付角度看,完整操作系统相比容器的优势,有以下两点需特别注意:

  1. 管理员对环境的熟悉:无需多年经验积累和深入学习,初级管理员也可以按照步骤完成复杂操作。

  2. 安全防护成熟:反病毒、防恶意软件、防木马、防篡改、操作审计等工具丰富。

与上述优势对应起来,完整操作系统环境主要有以下两大劣势:

  1. 操作系统环境入门容易,门槛很低,客观上使得大部分操作人员缺乏专业的系统管理知识和技能培训,遇到问题需求助公司的操作系统专家,或绕过系统管理流程,在网上搜一个“土办法”就把命令粘贴上,遵循“能用就行”的理念,为业务长期安全稳定运行留下严重隐患。

  2. 部分业务系统不遵循安全编码规范,不遵守应用部署安全准则(例如使用root身份运行的Web应用),使攻击者可以从Web端入侵,篡改业务应用、篡改操作系统关键文件和进程。许多没有遵循最小安装的操作系统,甚至变成攻击者的工作站,为攻击者在网络内横向移动大开方便之门。

上述问题根源是完整操作系统提供的自由度过高,为了应对这种隐患,才有了层出不穷的针对操作系统的安全工具。

日常工作中,虚拟化使得安装一个操作系统的难度,相比过去物理机部署大大降低。然而,完整操作系统在虚拟化环境中衍生出两个问题:

1.系统镜像更新不及时,留下存在安全漏洞的软件包

校方一般维护多个操作系统镜像模板,但是因为缺乏更新的机制和手段,存在安全隐患的镜像可能被持续使用。

部分商业系统没有可用的授权,无法从操作系统厂商处更新软件。许多高校环境的现实是业务上线到下线之间,操作系统没有接受过任何补丁。

2.没有手段保证统一的发行版、版本号及初始配置

业务系统厂商往往根据自身经验,指定一个Linux发行版或是特定版本的CentOS,很多时候并不是因为其应用的依赖足够复杂,只是因为在开发阶段选取了特定发行版或特定版本的系统。

到了部署的时候,如果是校方没有为特定发行版制作系统镜像,厂商往往会选择自己手工安装。手工安装会导致高校数据中心内没有两个完全一致的完整操作系统实例,这对于批量修改配置和安全加固都是巨大的挑战。本应该专注于应用交付的时间,就被浪费在处理不同虚拟机的个性化需求上了。

由此可见,数据中心环境中完整操作系统本身的劣势和衍生出的问题是极其严重的,要直接解决这些问题,需要投入大量的资金和技术,来建设完整的操作系统生命周期管理体系。然而,这与我们确立的“以应用交付为目标”的要求是相悖的。


容器环境的优劣

现阶段,从应用交付角度来看,容器相对于完整操作系统,有以下几个劣势:

  1. 部分情况下的IPv6支持不完善:例如Rootless模式的业务发布无法保留用户IPv6源地址。

  2. 许多技术人员对容器生态缺乏了解,无法在容器环境中排除应用故障。

  3. 部分应用设计时与操作系统特有能力紧密耦合,无法直接在容器中运行。

  4. 部分大型商业软件仅对部分操作系统发行版环境进行了认证,用户在容器中运行这些软件不会得到厂商技术支持。

显然,上述容器的劣势只是局部的、暂时的,相信随着容器技术的发展和普及,这些劣势将渐渐消失,目前容器技术社区和业务应用厂商正在积极解决这些问题,并有了一些初步成果。

容器相对完整操作系统的优势则是非常显著的:

1.开放性提升:容器镜像使用Dockerfile/Containerfile这种开放的描述式脚本构建,任何人都可以使用相同的Dockerfile构建完全一致的容器镜像。作为文本文件也方便纳入版本管理系统进行共享、协作、自动化集成和部署。

2.安全性增强:只要容器内的权限设定合理,容器中的进程不使用root身份运行,Web应用的漏洞难以修改容器镜像。如果Rootless模式(以受限用户身份启动)的单一容器出现安全问题,对宿主操作系统本身和之上承载的其他容器不会产生致命影响。容器内应用无法直接了解宿主操作系统的网络配置、存储配置和其他容器应用的配置。

3.故障恢复容易:依靠容器编排平台,单一服务器遇到故障或容器健康检查失败时,新的容器实例会迅速在其他服务器上启动,并利用容器存储接口(CSI)和数据库访问原来的业务数据。

4.代码与数据隔离:容器环境要求将业务数据与业务代码分开,业务数据单独存储,避免容器重建时丢失数据。一来架构变得更为清晰,方便开发和运维,二来业务逻辑和存储可以分别扩展,更容易获得性能优势。

5.资源利用率高:容器是轻量级的,启动时间以毫秒计,占用磁盘空间少,独占内存少,物理内存利用率高。同样配置的服务器如果不使用虚拟化而是容器技术的话,可以承载数十倍的应用。利用Control Groups v2可以实现细粒度的处理器和内存使用限制。

6.自包含:容器内应用所需的C语言库和其他软件运行时环境都包含在容器镜像内,不依赖宿主操作系统厂商提供,不同类型不同版本的运营时环境不会覆盖彼此文件。这就类似所谓“绿色软件”,不会修改宿主操作系统环境。

7.可移植性:容器镜像一旦构建,就可以在相同处理器架构的其他Linux发行版上运行容器。

8.支持云原生:由于容器的轻量级,大规模水平扩展和混合云环境中的迁移变得极为容易,容器技术成为云原生架构支撑技术的不二之选。

虚拟化应用交付与容器应用交付示意如图1、图2所示。

图1 虚拟化中的应用交付

图2 容器应用交付

容器化方案


容器化的不同阶段

1.探索阶段:将现有应用“搬”到容器内运行。不改变应用逻辑,只修改必需的配置。

2.完善阶段:打通各个环节,构建通用的容器化改造流程。减少不必要的重复劳动。

3.升华阶段:将独立运行的容器迁移到容器编排环境。进行水平扩展和高可用部署。

容器化改造不能一蹴而就。技术人员对容器工作方式、设计理念的理解需要过程,这个过程必须符合认知与实践规律。


容器化的准备工作

  1. 对生产环境中的业务进行收集、分类。首先排除淘汰的业务应用和容器迁移投入产出比低、风险高的业务应用,将剩下的业务按照重要性和复杂度分类,容器迁移要由易到难,从无状态应用到有状态应用,从较少依赖关系的应用到较复杂依赖关系的应用。

  2. 对生产环境业务配置功能和性能进行监控,便于比较迁移前后的可用性和性能,重点监控的指标:关键请求平均耗时,每秒请求数,每秒错误数。

  3. 为涉及到的服务配置双栈DNS记录,配置修改时将硬编码的IP地址换成DNS记录。

  4. 部署基于Git的源码管理系统,为Dockerfile,Ansible Playbook的开发协作提供环境。同时部署支持身份认证的Container Registry,为容器镜像的保存共享提供支撑。

  5. 确定迁移的时间窗口,提前通知相关用户,做好相关数据和环境备份,制定回滚策略。


现有业务容器化

将传统应用进行容器化改造分为两部分,一是将涉及的各个服务解耦,二是将静态的业务逻辑、配置与运行时的数据、日志等分离。

为了方便理解,我们以简单Web应用为例,一个简化的Web应用包括:运行业务逻辑代码的应用服务器,后端数据库服务,消息队列、内存数据库、缓存等服务,本地提供上传下载的文件目录。

遇到此经典结构,可以将数据库、缓存等服务独立出来。像数据库这种专业性强的业务,不再隐藏、分散在各个虚拟机中,方便专家进行性能调优、高可用配置、安全加固、备份、审计等,从长远看极大地提高了运维效率。

当业务依赖的后端服务被剥离、整合后,我们应分析业务应用与文件系统的耦合关系。此示例Web应用中,保存上传文件的目录是后端服务之外主要的持久化数据,因此我们将宿主操作系统中的一个目录在容器启动时映射到容器内的上传目录。这样,当我们从容器镜像重建容器实例时,上传的数据不会丢失。

同样的,应用运行时产生的文本日志,也可以映射到宿主操作系统的目录中。除了使用本地目录作为持久化存储,还可以使用提供容器存储接口(CSI)供应商的服务,例如开源的Ceph CSI和一些闭源商业产品。

运行业务代码的应用服务器有自己的配置,一些配置是文件形式,我们可以像映射上传目录一样,将配置文件映射到容器内,实现配置与逻辑解耦。还有一些配置短小灵活,可以在容器启动时以环境变量的形式传递给应用。

从业务环境中剥离依赖的服务、持久化数据、日志、配置后,构建的容器镜像中应当只包含业务逻辑代码和应用服务器软件。在Dockerfile中完成上述定义后,使用Buildah工具构建容器镜像,使用Skopeo在多个Registry之间管理镜像,使用Podman运行容器。

上述操作完成后,容器的启动和停止仍是手工操作,远达不到生产环境要求。我们开发了一套Ansible Playbook(如图3),将容器所依赖的用户、存储、防火墙、环境变量、systemd配置等自动化,对依赖明确的容器镜像,只需简单修改即可完成上线。

图3 使用Ansible完成容器所需的配置


新业务部署容器化

对于即将上线或处于规划期的新项目,如何实现容器化主要取决于应用架构。

如果新业务的架构没有考虑容器环境,则可以先梳理其依赖关系,按照已有业务容器化的方法,将应用打包成容器镜像,在统一构建的标准操作系统环境中运行。后续再逐步迁移到Kubernetes集群。

如果是云原生理念指导下设计的应用,通常都是以容器形式部署的微服务。看似我们无需再迁移这些应用了,然而现实是,许多厂商为了避免“麻烦”,会在数据中心环境中CentOS 7的基础镜像上,部署一套独立的Kubernetes,再将应用运行其上。

这种模式部署的Kubernetes大多没有达到生产环境标准,没有配置足够强的身份验证机制,攻击者可以利用这个配置不完善的集群,大量启动“挖矿”容器。加上部分应用容器内外均以root身份执行,攻击者很容易突破容器的限制,进而滥用操作系统环境“挖矿”或加密勒索。

另一方面,业务应用厂商依旧对IPv6不重视,过于依赖双栈反向代理来服务IPv6用户,而应用本身无法在IPv6单栈环境中正常运行,这种问题必须早发现早解决。

新业务部署时,为避免厂商私自架设Kubernetes引入的问题,我们必须建设自己的纯IPv6环境Kubernetes集群,并主动邀请应用厂商深入合作调试,确保新业务可在纯IPv6环境中安全且稳定地运行。

操作系统环境优化

容器化初期,传统的完整操作系统既要为尚未容器化的应用提供交付环境,也要为容器应用提供稳定可靠的支撑。借鉴云原生理念,利用容器中的“基础设施即代码”方法,以更高效的手段维持完整操作系统运行,将是我们在这个阶段进行系统管理的主要方式。

前面提到完整操作系统在虚拟化环境中更新不及时,环境不一致,一定程度上可以利用统一构建的操作系统模版和一套Ansible Playbook来缓解。

高校环境中主流的CentOS 7及其上游已走到它的最后一个子版本7.9,意味着除安全漏洞和bug修复,不会再有新功能。包括CentOS7的基于EL[3]7的发行版,内核缺乏对现代容器能力的支持,OpenSSL也不支持TLS 1.3,已不能满足容器时代的需要。因此我们将选择一个基于EL 8的Linux发行版作为主要操作系统。

为打造环境一致、更新及时、默认安全的操作系统环境,我们规划了以下步骤:

  1. 利用reposync工具配合cron计划任务,同步发行版仓库。镜像的内容还包括适用于EL 8环境的开源数据库,以及部分商业数据库的接口驱动程序。

  2. 使用Web服务器向数据中心环境提供上述RPM仓库镜像,提高内部更新访问速度。

  3. 根据现有环境中软件包、文件系统和网络配置等需求,开发一套基本的Kickstart脚本。

  4. 配置网络启动服务器,将Kickstart[4]脚本包含在内核命令中。利用PowerShell脚本,创建用于制作模板的虚拟机,接入PXE环境网络,并在虚拟机安装完成关机后,将其转换为虚拟机模板。此操作可以每周自动执行,持续提供最新的标准环境。

  5. 以“等保2.0”中对操作系统环境安全的要求为基准,结合现有的OpenSCAP[5]安全策略,参考《SCAP安全策略自定义指南》,生成安全加固文件,在Kickstart文件中使用,安装完成的系统即包含“等保2.0”中大部分加固要求。

  6. 为最终用户和管理员撰写手册,帮助他们适应安全加固后的环境。同时广泛收集用户反馈,对软件包等安装时的配置进行合理调整。

  7. 用Ansible Playbook,根据业务需求,管理操作系统和容器环境相关配置。“基础设施即代码”这种配置模式,使得变更有据可循,并可实现大规模应用变更。

需指出,上述大部分步骤,对于容器镜像构建、容器专用操作系统加固也适用,这与我们的容器化改造的策略一致。

不断提升容器化水平

为了避免项目因长时间运行而出现效率降低、质量下降等问题,我们需要不断完善相应的基础设施,扩大知识的共享,识别并消除迁移中的种种障碍。为此我们提出以下四点,并将之贯穿容器化改造的过程中:

1.不断了解、学习、试验容器生态的新技术、新产品、新应用模式。

2.记录、分享容器化改造中遇到的问题和创新解决方法,将知识固化为代码、流程和文档。

3.利用持续集成环境(Jenkins等),跟进上游更新,构建一致的加固过的容器基础镜像。

4.完善应用的全生命周期管理,包括上线、下线、备份、监控、排障、扩容、缩容等。

构建成熟的容器环境,积极发展云原生应用,淘汰落后业务和运行环境,减少完整操作系统的使用,有助于我们逐渐摆脱长久以来基础设施的泥潭,进而提高服务质量,将有限的精力投入到更广阔的学校教学、科研、管理的数字化转型中,持续为高等教育数字化转型发出青大声音、贡献青大智慧、提供青大方案。

容器本身不是目标,我们的目标一方面是通过容器化改造,实现应用交付环境统一,让共享平台优化成为可能;另一方面则是依靠容器编排平台,增强信息化技术人员与业务应用的关联,从“对系统负责”转变为“对应用负责”“对业务负责”。围绕应用交付进行基础设施改革,可以帮助信息化部门找准自身在学校数字化转型中的定位,打破刻板印象。

已经到来的CentOS社区变化,为我们敲响了操作系统供应链的警钟,对于高校信息化部门也是难得的机遇。与其在旧的应用交付模式下纠结彷徨,不如提前布局,探索以云原生、容器化为代表的新模式。在外部环境变化时,我们既不能无视风险、消极不作为,也不能盲目、跟风、乱作为,而应积极出击,尽早制定合理的应对方案。

参考阅读

[1]CentOS社区将全力投入CentOS Stream开发,2021年12月31日后,稳定版CentOS 8不再跟进上游更新。

[2]Podman是用以替代Docker的三个容器工具之一,参见:https://www.redhat.com/en/blog/say-hello-buildah-podman-and-skopeo

[3]EL是Enterprise Linux的缩写,泛指基于RHEL开源代码构建的衍生发行版,这些发行版之间兼容性好,长期维护成本低,也是多数Linux技术人员熟悉的环境。

[4]Kickstart是EL环境下安装管理器Anaconda的脚本,安装器可以在安装时执行用户Kickstart文件中指定的各项操作,完成软件包安装、网络配置等操作。

[5]OpenSCAP是一套“合规性即代码工具”,可以帮助各类操作系统以统一的形式进行安全加固。

作者:李绪亮(青岛大学智慧校园与信息化建设中心)

责编:陈荣

投稿、转载或合作,请联系:eduinfo@cernet.com

往期推荐

● 全光网技术演进及行业发展

● 如何建设校园直播平台?

看完了,点个赞呗~

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存