当前位置: 首页 > 科技观察

如何优雅地放弃CentOS7

时间:2023-03-14 08:46:37 科技观察

背景CentOS7本身的生命周期在2024年6月30日结束。2020年底,CentOS社区宣布修改现有的发布模式,将CentOS从RHEL的下游改为CentOSStream,作为RHEL的上游,导致了CentOS8生命周期短得可怜,让社区对CentOS不满。的开发人员/用户不满意,导致CentOS放弃其他发行版。大家选择使用CentOS。虽然都在讲稳定性,但我明白RedHat更重要。作为RHEL的下游,CentOS是RHEL的下游。所有软件版本均经过RedHat测试验证,RedHat也参与后期维护,不用担心维护问题。CentOS的原始模式也存在问题,用户很难参与到RHEL的开发周期中。一位用户发现某个版本的CentOS有问题,想为CentOS贡献一份力量,以便下一个版本的CentOS可以修复这个问题。这个时候就只有一个办法,就是自己贡献开源组件,但这也只是修复才有可能。能否修复取决于RedHat开发者的决定(毕竟RHEL/CentOS中有大量的开源组件是不包含它们的,但是RHEL/CentOS通过Patchin的方式包含了Patch)转速规格)。CentOSStream推出后,用户可以向CentOS社区做出贡献,以确保下一版本的CentOS包含该补丁。至于RHEL有没有包含,用户不关心,那是RedHat关心的。Fedora更关注上游社区的最新代码,其中包含最丰富的功能,作为先锋;CentOSStream作为RHEL的上游,提供稳定可靠的持续交付版本,保证更多贡献者参与;RHEL为企业用户使用,RedHat提供完善的维护服务。在现有模式下,CentOSStream已经背离了CentOS原用户的初衷。现有的CentOS7用户需要寻找新的替代品。在国产化的浪潮下,选择的方向也发生了一定的变化。社区替代RockyLinux?RockyLinux旨在像CentOS之前所做的那样充当下游构建,在将它们添加到上游供应商之后构建版本,而不是之前。AlmaLinux?AlmaLinuxOS正在取代CentOS作为RedHatEnterpriseLinux的下游重建。CentOS宣布政策改变后,社区出现了两个备选方案,分别是RockyLinux和AlmaLinux。两者的目的相同,都是作为RHEL的下游来构建和发布,发布方式和发布周期采用CentOSLegacy模式。通过AlmaLinux[1]官方提供的发行版对比,可以看出AlmaLinux和RockyLinux对于用户来说没有区别。如果一定是真的,那就是AlmaLinux大部分来自CloudLinux公司,而RockyLinux是Greg的公司。.国产替代AnolisOS(阿里巴巴)?AnolisOS8是由OpenAnolis社区发布的完全开源、中立、开放的版本。支持多计算架构,针对云端场景进行优化,兼容CentOS软件生态。AnolisOS8旨在为开发者和运维人员提供稳定、高性能、安全可靠、开源的操作系统服务。openEuler(华为)?openEuler是一个开源操作系统。目前的openEuler内核源自Linux,支持鲲鹏等多种处理器,可以充分释放计算芯片的潜能。是由全球开源贡献者打造的高效、稳定、安全的开源操作系统,适用于数据库、大数据、云计算、人工智能等应用场景。同时,openEuler是一个全球操作系统开源社区。通过社区合作,打造创新平台,构建统一、开放、支持多处理器架构的操作系统,促进软硬件应用生态的繁荣发展。银河麒麟操作系统?银河麒麟高级服务器操作系统V10面向企业级关键业务,满足虚拟化、云计算、大数据、工业互联网,按照CMMI5标准开发的新一代独立服务器操作系统,提供本质安全、云原生支持、独立平台深度优化、高性能、易管理。系统的选择需要考虑国内的替代方案。目前(个人知识)符合信创标准的操作系统只有银河麒麟,openEuler和AnolisOS还没有完全通过信创审核。这一系列备选方案中,RockyLinux、AlmaLinux和AnolisOS采用了发布模式和版本控制方式,都保持了CentOS原有的模式,即8.1、8.2、8.3发布模式。openEuler和银河麒麟OS虽然也使用RPM作为包管理器,大部分组件版本与社区中的CentOS8相同,但并不完全等同,这里需要注意。相比之下,如果要满足鑫创的要求,只能选择银河麒麟作为替代;如果从使用的角度考虑,选择RockyLinux/AlmaLinux/AnolisOS是更好的选择,有很好的社区支持,版本控制也和CentOS保持一致,精神负担更小;如果考虑国产硬件支持,openEuler是个不错的选择。上面讨论的发行版,目前使用的packages管理器都是RPM,所有的软件都已经按照RPM粒度安装。在RPM之上,会有Yum/DNF,一个基于RPM的包管理器,包括RPM依赖管理、冲突管理、降级等功能,其中CentOS7系列使用的基于RPM的包管理器是Yum,而当前维护版本中其他发行版使用的基于RPM的包管理器是DNF(DandifiedYum)。升级转换在使用CentOS7的现有环境中,需要使用替代品将CentOS7升级到目标版本版本。如果应用环境是单体应用,有时间进行离线维护,那么先备份数据,然后彻底重装操作系统是一个安全的选择。如果应用环境为集群,且大部分应用已经容器化,需要仔细测试验证,依次在单节点重装OS。不同release版本的默认系统参数可能不同,即使上层基础平台保证版本一致(比如Kubernetes、containerd、runc的版本一致),也可能会出现异常情况。如果选择不重装操作系统,就地升级转换有两种方式:自动和手动。其中RockyLinux/AlmaLinux/AnolisOS提供自动升级转换方式,openEuler和银河麒麟可以使用手动转换方式。自动过程自动升级转换依赖于Leapp[2]。Leapp是由Redhat员工开发的开源工具。Leapp本身只是一个工作流框架,包括Actor、Model、Message、Workflow等概念。具体的组件关系图如下,其中workerflow包括多个阶段,每个阶段包含3个阶段:Before、Main、After,每个阶段包含多个Actor,其中Actor之间没有严格的顺序,但是通过Message通信,Message跟随Model的定义,如果ActorA如果ActorB依赖ActorB生成的MessageB,那么ActorA会在ActorB之后执行,没有MessageB依赖的ActorC会按照加载的先后顺序执行,没有严格的顺序依赖。目前Leapp主要用于基于RedHat的版本升级,以及不同版本之间的升级切换。在整个升级过程中,使用统一定义的Workflow,在不同阶段(如升级前、升级、Firstboot等)调用同一个Workflow,但执行阶段是根据指定的不同标签和参数来确定的。预升级(preupgrade)收集和检测环境信息,并将检测结果以报告的形式提供给用户。这里进行的信息收集和检查项目数量多,包含的细节也多,除了一些基本组件的检查:除了CPU架构,openssh配置变更,PAM模块变更,Driver支持,NTP变更等,它还包括一些第三方应用程序检查:SAPHANA、Memcached、Pagoda等。Upgrade(升级),升级的主要动作,使用与预检查相同的Workflow。configuration_phaseFactsCollection勾选TargetTransactionFactsCollection生成一个临时的最小环境,包括目标版本的完整运行环境,用于使用目标版本的工具栈,比如DNF、RPM高级特性等。这个环境也会用来生成下一步需要的initramfs镜像TargetTransactionCheck,通过上面生成的最小环境,使用dnf工具,dnfrhel-upgradecheck查看当前节点是否可以升级ReportsDownload,升级需要的软件包下载步骤,dnfrhel-upgrade下载InterimPreparation,生成下一步所需的initramfs,在前面步骤的最小环境中安装dracut相关工具包,使用dracut[3]生成initramfs镜像,生成完成后调整系统启动项,并进行设置作为第一个启动项临时环境升级(InterimUpgrade),实际步骤to执行RPM升级,使用与预检查相同的工作流程。系统重启后,系统启动到前面步骤生成的initramfs,系统正常启动。在dracuthook中,增加了两个hook,分别是85sys-upgrade-redhat[4]和90sys-upgrade[5],其中85是实际执行节点软件包升级的动作(leappupgrade–resume),90配置systemd升级单元(重启相关)InitRamStart,去掉启动项设置LateTestsPreparationRPMUpgrade,dnfrhel-upgrade升级升级RPMApplicationsThirdPartyApplicationsFinalization后升级动作(Firstboot),升级后系统自动重启进入目标版本系统完成,此时会执行Firstboot阶段。执行完成后,系统升级会完成FirstBoot、Executecleanupactions、修改部分配置(NM)等完整的升级过程,共执行4次Workflow,使用临时环境执行升级动作的目的是:升级动作执行工具链是目标环境对应版本的工具链自动实现方法项目地址:https://github.com/oamg/leapphttps://github.com/oamg/leapp-repositoryhttps://github.com/AlmaLinux/leapp-data其中leapp是框架本身,leapp-repository是Leapp的应用实现,也就是Actor实现升级时执行,leapp-data用于升级基本配置信息。不同的发行版将维护自己的leapp-repository。例如AnolisOS维护了自己的Git仓库(在Gitee上),并有针对性地添加了自己的检查项。在Leapp的架构中,由于最终应用会安装在独立的机架中,Python的syspath可能会发生变化,查看代码时需要相应修改路径地址。以NTP检查为例:NTP检查的Actor实际发现:fromleapp.actorsimportActorfromleapp.libraries.actor.checkntpimportcheck_ntpfromleapp.modelsimportInstalledRedHatSignedRPM,NtpMigrationDecision,Reportfromleapp.tagsimportChecksPhaseTag,IPUWorkflowTagclassCheckNtp(Actor):"""检查是否需要迁移ntp和/或ntpdate配置。"""name='check_ntp'consumes=(InstalledRedHatSignedRPM,)produces=(Report,NtpMigrationDecision)tags=(ChecksPhaseTag,IPUWorkflowTag)defprocess(self):installed_pa??ckages=set()signed_rpms=self.consume(InstalledRedHatSignedRPM)forrpm_pkgsinsigned_rpms:forpkginrpm_pkgs.items:installed_pa??ckages.add(pkg.name)self.produce(check_ntp(installed_pa??ckages))Actor中调用的check_ntp函数现实:#Check来自用于迁移的ntp包的服务defcheck_ntp(installed_pa??ckages):service_data=[('ntpd','ntp','/etc/ntp.conf'),('ntpdate','ntpdate','/etc/ntp/step-tickers'),('ntp-wait','ntp-perl',None)]migrate_services=[]migrate_configs=[]forservice,package,main_config在service_data:ifpackageininstalled_pa??ckagesand\check_service('{}.service'.format(service))and\(notmain_configoris_file(main_config)):migrate_services.append(service)ifmain_config:migrate_configs.append(service)ifmigrate_configs:reporting.create_report([reporting.Title('{}配置将被迁移'.format('and'.join(migrate_configs))),reporting.Summary('{}服务检测到已启用和活动'.format(','.join(migrate_services))),reporting.Severity(reporting.Severity.LOW),reporting.Groups([reporting.Groups.SERVICES,reporting.Groups.TIME_MANAGEMENT]),]+related)#保存将被ren的配置文件amedintheupgradeconfig_tgz64=get_tgz64(files)else:api.current_logger().info('ntpd/ntpdateconfigurationwillnotbemigrated')migrate_services=[]config_tgz64=''returnNtpMigrationDecision(migrate_services=migrate_servicesg4z6=config)手动处理对于Linux发行版来说,整体是由无数个RPM组成的。在最终系统中看到的最小粒度是RPM。我们可以通过RPM升级来完成整体发行版的升级和变更,但是对于某些RPM,RPM之间的依赖性使得我们无法通过依次升级部分RPM来完成一次完整的升级和更换。一些关键组件,如glibc、glib2、openssl等,都是强依赖的,必须想办法完成整体升级。Yum中有一个distribution-synchronization命令,可以将当前OS中的所有RPM同步到目标Repository中的版本,但是使用Yum可能无法识别rpmlib。作为基本的包管理器,RPM将以rpmlib依赖项的形式提供一些高级功能。如果当前系统的包管理器不能识别rpmlib,同步过程中会出现无法解决的依赖冲突。示例:目标RPM为dnf-4.2.23-6.oe1.noarch.rpm,升级提示dependsonrpmlib(RichDependencies)<=4.12.0-1conflict。这是因为dnf-4.2.23RPM(可能在openEuler20.03或更高版本)在构建阶段使用的rpm环境高于当前OSRPM版本(CentOS7),因此当前rpm不能满足此依赖条件。我们可以使用DNF的distro-sync配合一些RPM修改来完成手动升级转换。过程如下:将当前的CentOS7升级到CentOS7.x系列最新版本;停止节点上运行的所有应用程序,配置CentOS7Repository,安装DNF(DNF依赖于glib2的执行版本,但在spec中没有声明,glib2需要单独升级)去掉yummanager防止冲突用DNF配置目标发布版本Repository使用dnfdistro-sync升级转换使用dnfremove去除无用RPM重启主机生效手动执行当前CentOS7包管理器为Yum,在目标版本中打包的管理器为地下城与勇士。通过Yum安装DNF后,在确保Yum(DNF)Repository配置为目标版本的前提下,使用dnfdistro-sync命令升级同步RPM。此命令将更新安装在当前操作系统上的RPM与Yum存储库中的RPM相匹配。RPM版本匹配存在于以下几种情况:如果当前RPM版本低于目标Repository包含的RPM版本,则升级;如果当前RPM版本高于目标存储库中包含的RPM版本,它将被降级;如果当前RPM包含在目标存储库中,如果RPM被替换(指定Obsolete),将安装新的RPM,并卸载(替换)原来的RPM;如果当前RPM版本与目标Repository中包含的RPM版本相同,但其他RPM元数据(如dist)不同,则会重新安装;当前RPM被其他RPM依赖引入,但其他RPM已被替换,该RPM将被卸载;当前RPM未包含在目标存储库中,将不会被处理;总结通过自动或手动的方式,我们可以将CentOS7升级In-place转换为我们想要的目标发行版。社区RockyLinux/AlmaLinux/AnolisOS可自动完成,国内非对等替代openEuler可通过控制Repository手动完成,减少发布版本变更带来的工作量。