最近我们把一个运行了好几年的旧系统,从传统的虚拟机部署,迁移到了容器化部署,整个过程涉及到安全、兼容性、数据迁移、灰度发布等多个方面,踩了不少坑,也积累了一些经验。
这个旧系统,是公司的一个核心业务系统,已经在线上运行了快五年了,一直是部署在虚拟机上,用传统的方式运维。随着业务的发展,虚拟机部署的问题越来越多,比如环境不一致、部署慢、扩容难、资源利用率低、运维成本高等。公司这两年一直在推容器化,其他系统都陆续迁到了容器平台上,就剩这个核心系统,因为比较重要,也比较复杂,一直没敢动。
这次终于下定决心,把这个系统也迁移到容器平台上,整个过程从准备到完成,花了大概一个多月的时间,中间踩了不少坑,也遇到了一些安全方面的问题,好在最终顺利完成了迁移,系统运行稳定,也达到了预期的效果。
今天来分享一下这次容器安全迁移的实战经验,从迁移前的准备、迁移方案的设计、安全方面的考虑、迁移过程中的注意事项,到迁移后的验证和优化,详细记录整个过程,希望能给正在做容器化迁移的朋友一些参考。
一、为什么要做容器化迁移
在说迁移过程之前,先说说为什么要做容器化迁移,以及旧的虚拟机部署有什么问题。
这个旧系统,是一个Java Web应用,架构是典型的单体应用,前端、后端、数据库都有,还有一些定时任务和消息消费。之前是部署在三台虚拟机上,一台跑应用,一台跑数据库,一台跑定时任务和其他辅助服务,用Nginx做反向代理和负载均衡。
虚拟机部署用了好几年,刚开始的时候还好,但随着业务发展,问题越来越多:
1. 环境不一致
开发、测试、生产环境的配置不一样,经常出现"在我机器上是好的"的问题。开发环境能跑,测试环境出问题,测试环境没问题,生产环境又出问题,排查起来很麻烦,浪费了很多时间。
2. 部署慢,扩容难
每次发布新版本,都要手动部署,停服务,包,部署,启动,验证,整个过程快则半小时,慢则一两个小时,而且很容易出错。扩容的时候,也要手动申请虚拟机,安装环境,部署应用,配置负载均衡,快则一两天,慢则更久,遇到流量突增的时候,根本来不及扩容。
3. 资源利用率低
虚拟机的资源是固定分配的,不管应用实际用多少,CPU、内存都占着,很多时候资源利用率很低,浪费严重。而且不同应用之间不能共享资源,有的虚拟机资源不够用,有的又闲置着,调度不灵活。
4. 运维成本高
虚拟机的运维很麻烦,要管理操作系统、补丁、依赖、配置,每台虚拟机都要单独维护,机器多了之后,运维成本很高。而且环境配置没有版本管理,改了什么配置,谁改的,什么时候改的,都不知道,出了问题很难回溯。
5. 安全风险
虚拟机的安全管理也比较麻烦,每台虚拟机都要单独做安全加固、补丁更新、病毒防护,很容易遗漏。而且应用和操作系统耦合在一起,应用的安全漏洞和操作系统的安全漏洞混在一起,不好管理和修复。
这些问题,随着系统的运行时间越长,越明显,也越影响开发和运维的效率。公司这两年推容器化,其他系统迁移之后,这些问题都得到了很好的解决,所以这次我们也下定决心,把这个核心系统也迁移到容器平台上。
二、迁移前的准备
容器化迁移,不是简单地把应用打包成镜像,放到容器里跑就行了,尤其是核心业务系统,迁移前的准备非常重要,准备得越充分,迁移过程就越顺利,出问题的概率就越小。
我们在正式迁移之前,做了大概两周的准备工作,主要包括这几个方面:
1. 系统梳理和评估
首先,我们对旧系统做了全面的梳理和评估,搞清楚系统的架构、依赖、配置、数据、流量等各个方面的情况。
具体梳理的内容包括:
- 系统的整体架构,有哪些组件,组件之间的调用关系
- 应用的技术栈,用了什么框架、什么版本、什么依赖
- 系统的配置项,有哪些配置,哪些是环境相关的,哪些是固定的
- 依赖的外部服务,比如数据库、缓存、消息队列、第三方接口等
- 数据的情况,有哪些数据,数据量多大,哪些是需要迁移的
- 系统的流量情况,QPS、响应时间、高峰时段等
- 系统的定时任务、批处理任务、消息消费等后台任务
- 系统的安全要求,有哪些安全合规的要求,数据敏感度如何
通过全面的梳理,我们对系统有了清晰的认识,也识别出了迁移的难点和风险点,为后续的迁移方案设计提供了依据。
2. 容器平台的调研和准备
我们公司已经有统一的容器平台了,基于Kubernetes搭建的,其他系统都跑在上面,所以这次不需要自己搭建容器平台,只需要把应用迁移到现有的平台上就行。
但即使是用现有的平台,我们也做了一些准备工作:
- 了解容器平台的使用规范,比如镜像构建规范、部署规范、配置管理规范、日志规范、监控规范等
- 申请容器平台的资源,包括命名空间、CPU、内存、存储等,根据系统的资源需求,申请足够的资源
- 配置网络和域名,确保容器平台里的应用能访问到依赖的外部服务,也能被外部访问到
- 配置日志和监控,确保应用的日志能正常收集,监控指标能正常上报
- 了解容器平台的安全机制,比如镜像安全、运行时安全、网络策略、权限管理等,确保迁移后的系统满足安全要求
3. 迁移方案的设计
这是准备阶段最重要的工作,我们设计了详细的迁移方案,包括:
- 镜像构建方案:怎么把应用打包成Docker镜像,基础镜像选什么,怎么优化镜像大小,怎么保证镜像的安全
- 部署方案:应用在容器平台上怎么部署,用什么控制器(Deployment、StatefulSet等),副本数多少,怎么配置资源限制
- 配置管理方案:应用的配置怎么管理,哪些用环境变量,哪些用配置文件,哪些用ConfigMap,哪些用Secret
- 数据迁移方案:数据库怎么迁移,是用容器平台里的数据库,还是继续用外部的数据库,数据怎么同步,怎么保证数据一致性
- 网络方案:应用的网络怎么配置,服务怎么暴露,怎么做负载均衡,怎么做灰度发布
- 灰度发布方案:怎么从旧系统平滑迁移到新系统,怎么灰度,怎么回滚,怎么保证业务不中断
- 安全方案:迁移过程中怎么保证安全,镜像安全、运行时安全、数据安全、网络安全等
- 应急预案:迁移过程中出了问题怎么办,怎么回滚,怎么快速恢复
方案设计好了之后,我们还组织了评审,邀请了运维、安全、DBA、业务等相关的同事一起评审,找问题,补漏洞,确保方案的可行性和安全性。
4. 测试环境的验证
在正式迁移到生产环境之前,我们先在测试环境做了完整的验证,把应用打包成镜像,部署到测试环境的容器平台上,跑了一遍完整的测试,包括功能测试、性能测试、安全测试等,确保应用在容器环境下能正常运行,性能和安全都满足要求。
测试环境的验证,帮我们发现了不少问题,比如配置不对、依赖缺失、性能不达标、安全漏洞等,这些问题在测试环境解决了,就不会带到生产环境,大大降低了生产迁移的风险。
三、镜像构建和安全考虑
镜像构建是容器化迁移的基础,镜像的质量和安全,直接影响到应用的运行和安全。在镜像构建这块,我们踩了不少坑,也总结了一些经验。
1. 基础镜像的选择
基础镜像的选择很重要,不同的基础镜像,大小、安全性、兼容性都不一样。我们最开始用的是官方的openjdk镜像,功能没问题,但镜像比较大,有几百MB,而且里面有很多不需要的工具和依赖,增加了安全攻击面。
后来我们换成了alpine基础镜像,alpine是一个轻量级的Linux发行版,体积很小,只有几MB,基于alpine构建的应用镜像,也小很多,只有几十MB,下载和部署都快很多,而且攻击面也小,更安全。
不过,alpine也有一些坑,比如它用的是musl libc,而不是glibc,有些依赖glibc的应用,在alpine上可能会出问题,需要额外处理。我们的应用是Java的,对libc的依赖不大,用alpine没问题,但如果是C/C++的应用,就要注意了。
另外,基础镜像一定要用官方的,或者是可信的镜像,不要随便用来源不明的镜像,避免镜像里有后门或者恶意代码。而且,要尽量用固定版本的标签,不要用latest,避免基础镜像自动更新带来的不确定性和安全风险。
2. 多阶段构建优化镜像
我们用了Docker的多阶段构建,来优化镜像的大小。第一阶段用完整的构建镜像,安装所有的依赖,编译打包应用;第二阶段用精简的运行时镜像,只把编译好的应用和必要的运行时依赖拷贝进去,这样最终的镜像里,就不会有编译工具、源代码、中间产物这些不需要的东西,镜像大小大大减小。
比如我们的Java应用,第一阶段用maven镜像,拉取依赖,编译打包,生成jar包;第二阶段用openjdk:jre-alpine镜像,只把jar包拷贝进去,设置启动命令。这样最终的镜像,只有jar包和JRE,没有maven、源代码、依赖缓存这些,大小从原来的几百MB,降到了几十MB,优化效果很明显。
镜像小了之后,好处很多:下载快,部署快,占用存储空间少,攻击面小,更安全。所以,构建镜像的时候,一定要尽量优化镜像大小,只包含运行时必要的东西。
3. 不要用root用户运行
这是一个很重要的安全最佳实践。很多人构建镜像的时候,默认用root用户运行应用,这样很危险,一旦应用被攻破,攻击者就有容器里的root权限,可能会进一步攻击宿主机或者其他容器。
我们在构建镜像的时候,专门创建了一个普通用户,用这个普通用户来运行应用,而不是用root。这样即使应用被攻破,攻击者也只有普通用户的权限,能做的事情有限,大大降低了安全风险。
具体的做法,就是在Dockerfile里,用useradd创建一个用户,然后用USER指令切换到这个用户,后续的命令和应用启动,都用这个用户运行。同时,要注意文件权限,确保应用需要读写的文件和目录,这个用户有权限访问。
4. 镜像安全扫描
构建好镜像之后,我们做了镜像安全扫描,用容器平台自带的安全扫描工具,扫描镜像里有没有已知的安全漏洞,有没有高危的配置,有没有敏感信息泄露等。
扫描的结果,发现了几个问题:
- 基础镜像里有几个已知的安全漏洞,虽然是中低危的,但我们还是升级了基础镜像的版本,把漏洞修复了
- 镜像里有一个测试用的配置文件,里面有测试环境的密码,属于敏感信息泄露,我们把这个文件从镜像里删掉了,密码也改成了通过环境变量注入
- 有一个依赖的jar包,有已知的安全漏洞,我们升级了这个依赖的版本
把这些问题都修复之后,重新构建镜像,再扫描,就没有高危的安全问题了。镜像安全扫描,是容器安全的重要一环,一定要做,而且要在CI/CD流程里集成,每次构建镜像都自动扫描,有高危漏洞就不让部署,从源头保证镜像的安全。
5. 不要把敏感信息打到镜像里
这也是一个常见的安全问题。很多人构建镜像的时候,把数据库密码、API密钥、证书这些敏感信息,直接写到配置文件里,打到镜像里,这样很不安全。镜像一旦被别人拿到,敏感信息就泄露了。
正确的做法是,敏感信息不要打到镜像里,而是在运行的时候,通过环境变量、Secret、配置中心等方式注入。镜像里只放非敏感的、固定的配置,环境相关的、敏感的配置,都在运行时注入。
我们这次迁移,就把所有的敏感信息,比如数据库密码、Redis密码、第三方API密钥等,都从配置文件里抽出来了,用容器平台的Secret来管理,运行的时候注入到容器里,镜像里没有任何敏感信息,大大提高了安全性。
四、配置管理和数据迁移
1. 配置管理
旧系统的配置,是写在配置文件里的,不同环境用不同的配置文件,部署的时候替换对应的配置文件。这种方式,管理起来比较麻烦,配置文件没有版本管理,改了什么不知道,而且容易出错。
迁移到容器平台之后,我们用了更规范的配置管理方式:
- 非敏感的、固定的配置,打到镜像里,或者用ConfigMap管理
- 环境相关的配置,用ConfigMap管理,不同环境用不同的ConfigMap
- 敏感的配置,比如密码、密钥,用Secret管理,加密存储
- 应用通过环境变量或者挂载配置文件的方式,读取配置
这样,配置和镜像解耦了,同一个镜像,可以在不同环境运行,只需要挂载不同的配置就行,不用为不同环境构建不同的镜像。而且配置有版本管理,改了什么,谁改的,什么时候改的,都清清楚楚,出了问题也能回溯。
在配置管理这块,我们也踩了一个坑。旧系统里有一个配置,是写死在代码里的,指向旧的数据库地址,迁移的时候,我们找了半天,才发现这个写死的配置,改了代码重新构建镜像才解决。所以,迁移的时候,一定要全面梳理配置,不要漏掉写死在代码里的配置,最好把所有配置都抽出来,统一管理,不要写死在代码里。
2. 数据迁移
数据迁移是这次迁移的重点和难点。这个系统的数据库,已经跑了好几年了,数据量有几十GB,还有一些文件存储,数据量也不小。数据迁移,要保证数据的完整性和一致性,还要尽量减少停机时间,不能影响业务。
我们最开始考虑,把数据库也迁移到容器平台里,用容器平台的数据库服务。但评估之后,发现这个系统的数据库比较特殊,有一些自定义的配置和存储过程,而且数据量不小,迁移到容器平台的数据库,风险比较大,性能也不一定能满足要求。所以我们最终决定,数据库继续用原来的外部数据库,不迁移,只把应用迁移到容器里,应用通过网络访问外部的数据库。
这样,数据迁移的工作量就小了很多,因为数据库不用动,只需要把一些静态文件,迁移到容器平台的存储里就行。静态文件的迁移比较简单,用rsync同步过去就行,而且静态文件变化不大,同步一次就可以了。
虽然数据库不用迁移,但我们还是做了一些准备工作:
- 确保容器平台里的应用,能正常访问到外部的数据库,网络是通的,权限是对的
- 数据库的连接信息,用Secret管理,不写到镜像里
- 做了数据库的备份,万一迁移出问题,可以快速恢复
- 评估了数据库的性能,确保应用迁移到容器之后,数据库的性能能满足要求,不会成为瓶颈
如果是需要迁移数据库的情况,建议用主从同步的方式,先在新环境建一个从库,同步旧库的数据,同步完成之后,再切换到新库,这样停机时间很短,风险也小。切换之前,一定要做好备份,万一出问题,可以回滚。
五、灰度发布和平滑迁移
应用迁移,最怕的就是一次性切换,出了问题影响大,回滚难。所以,我们采用了灰度发布的方式,逐步把流量从旧系统切到新系统,平滑迁移,降低风险。
我们的灰度方案,是基于Nginx的流量切分来做的:
第一步:新系统部署,不接流量
先把新的容器化应用部署好,配置好,验证功能正常,但不接线上流量,只做内部测试。这一步,确保新系统本身是没问题的,能正常运行。
第二步:小流量灰度
在Nginx上配置,把一小部分流量,比如5%,切到新系统,剩下的95%还是走旧系统。这样,即使新系统出问题,也只有5%的用户受影响,影响面小。
小流量灰度之后,我们观察了一段时间,看新系统的日志、监控、错误率、响应时间等,确认没有问题,用户也没有反馈异常。
第三步:逐步加大流量
确认小流量没问题之后,我们逐步加大新系统的流量比例,从5%到10%,到20%,到50%,每一步都观察一段时间,确认没问题再继续加大。
这个过程,我们花了大概一周的时间,比较稳妥,每一步都留足了观察时间,有问题能及时发现,及时回滚。
第四步:全量切换
当新系统的流量加到100%,所有用户都走新系统,观察了几天,确认没有问题之后,我们就把旧系统下线了,迁移完成。
在整个灰度过程中,我们做了充分的监控和告警,新系统的任何异常,都能第一时间收到告警。同时,也做好了回滚预案,一旦新系统出问题,随时可以把流量切回旧系统,快速恢复。
幸运的是,整个灰度过程都比较顺利,没有出什么大问题,新系统运行稳定,性能也比旧系统好一些,最终顺利完成了迁移。
在灰度发布这块,我们也有一个经验:灰度的时候,一定要注意数据兼容性。因为新旧系统同时运行,都在读写同一个数据库,如果新系统改了数据结构,或者写的数据格式和旧系统不一样,就可能出问题。所以,迁移的时候,要确保新旧系统的数据是兼容的,新系统不要做不兼容的数据变更,等迁移完成,旧系统下线之后,再做数据结构的升级。
六、迁移过程中的安全考虑
这次迁移,我们特别重视安全,因为是核心业务系统,数据也比较敏感,安全出了问题,后果很严重。在迁移过程中,我们主要从这几个方面考虑安全:
1. 镜像安全
前面已经说了,镜像安全这块,我们做了基础镜像选择、多阶段构建、非root用户运行、镜像安全扫描、不把敏感信息打到镜像里等工作,从源头保证镜像的安全。
2. 运行时安全
应用在容器里运行的时候,也要保证安全。我们主要做了这些:
- 用普通用户运行应用,不用root
- 配置了资源限制,CPU和内存都设置了上限,防止应用异常占用过多资源,影响其他应用
- 配置了安全上下文,比如只读根文件系统、禁止特权模式、禁止权限提升等,减小攻击面
- 配置了网络策略,只允许应用访问必要的外部服务,不允许不必要的网络访问,防止横向移动
- 配置了日志审计,应用的操作日志和访问日志都收集起来,便于安全审计和问题排查
3. 数据安全
数据安全是重点,我们做了这些:
- 数据库继续用外部的安全数据库,不迁移到容器里,保证数据库的安全
- 数据库的连接信息用Secret管理,加密存储,不泄露
- 应用和数据库之间的通信,用SSL加密,防止数据在传输过程中被窃取
- 静态文件存储,配置了访问权限,只有应用能读写,外部不能直接访问
- 做了数据备份,迁移前备份了全量数据,迁移过程中也有增量备份,万一出问题,可以快速恢复
4. 访问安全
应用的访问安全,我们做了这些:
- 应用通过Nginx反向代理暴露,Nginx做了安全加固,比如限制请求大小、防止SQL注入、防止XSS等
- 配置了HTTPS,所有外部访问都用HTTPS加密,防止数据被窃取和篡改
- 管理后台和内部接口,做了IP白名单和身份认证,只有内部人员能访问
- 配置了WAF(Web应用防火墙),拦截常见的Web攻击,比如SQL注入、XSS、CSRF等
5. 安全测试
迁移完成之后,我们还做了一次完整的安全测试,包括漏洞扫描、渗透测试、配置检查等,确保迁移后的系统没有安全漏洞,满足安全要求。测试发现了几个小问题,比如某个配置项不安全、某个依赖有低危漏洞,我们都及时修复了,确保系统上线的时候是安全的。
七、迁移后的验证和优化
迁移完成之后,我们没有掉以轻心,继续做了验证和优化,确保系统稳定运行,也充分发挥容器化的优势。
1. 功能和性能验证
迁移完成之后,我们做了完整的功能验证,确保所有功能都正常,没有因为迁移而出问题。同时,也做了性能测试,对比迁移前后的性能,看看容器化之后,性能是提升了还是下降了。
测试结果,功能都正常,性能方面,响应时间和迁移前差不多,甚至略好一些,因为容器平台的资源调度更灵活,应用的资源更有保障。吞吐量也能满足业务需求,高峰时段也没有性能瓶颈。
2. 监控和告警完善
迁移之后,我们完善了监控和告警,除了应用本身的监控,还加了容器层面的监控,比如容器的CPU、内存、网络、磁盘等,还有容器平台的监控,比如Pod状态、节点状态、调度情况等。告警也做了完善,任何异常都能第一时间收到告警,及时处理。
有了完善的监控和告警,系统的运行状态一目了然,出了问题也能快速发现和定位,运维效率提高了不少。
3. 弹性伸缩配置
容器化的一大优势,就是弹性伸缩,能根据流量自动扩缩容。迁移稳定之后,我们配置了弹性伸缩,根据应用的CPU使用率和QPS,自动调整副本数,流量大的时候自动扩容,流量小的时候自动缩容,既保证了性能,又节省了资源。
配置了弹性伸缩之后,遇到流量突增的情况,系统能自动扩容,不用人工干预,很方便。而且资源利用率也提高了,不用一直保持高峰时段的副本数,节省了成本。
4. CI/CD流程优化
迁移到容器之后,我们也优化了CI/CD流程,实现了自动化的构建、测试、部署。代码提交之后,自动构建镜像,自动跑测试,自动扫描镜像安全,测试通过之后,自动部署到测试环境,验证通过之后,手动确认部署到生产环境。整个流程自动化,大大提高了发布效率,也减少了人为出错的概率。
以前发布一次,要手动操作大半天,现在自动化之后,十几分钟就能完成,而且更可靠,出错的概率小了很多。
5. 持续优化
迁移不是终点,而是新的起点。迁移完成之后,我们还在持续优化,比如优化镜像大小、优化应用性能、优化资源配置、完善安全策略等,让系统运行得更稳定、更高效、更安全。
容器化带来的好处,也在逐步显现:部署更快了,扩容更容易了,资源利用率更高了,运维成本更低了,环境一致性更好了,开发和运维的效率都提高了。这次迁移,虽然过程有点折腾,但结果是好的,达到了预期的目标。
八、踩过的坑和经验总结
这次迁移,我们踩了不少坑,也总结了一些经验,分享给大家。
踩过的坑:
- 配置写死在代码里:旧系统有一些配置写死在代码里,迁移的时候找了半天才发现,改了代码重新构建镜像才解决。迁移的时候一定要全面梳理配置,不要漏掉写死在代码里的配置。
- 时区问题:容器默认的时区是UTC,和我们的时区不一样,导致应用里的时间都差了8个小时。后来在镜像里设置了时区,或者通过环境变量设置时区,才解决。构建镜像的时候,一定要注意时区问题。
- 文件权限问题:用普通用户运行应用之后,应用需要读写的一些文件和目录,权限不对,导致应用启动失败。后来调整了文件和目录的权限,给运行用户授权,才解决。用非root用户运行的时候,一定要注意文件权限。
- JVM内存设置问题:Java应用在容器里运行,JVM的内存设置很重要,设置不好,要么内存不够用,要么浪费资源,甚至被容器OOM杀掉。我们最开始设置的JVM内存不对,应用经常被OOM杀掉,后来调整了JVM参数,设置了合理的堆内存和元空间内存,才解决。Java应用容器化,一定要注意JVM内存的设置。
- 日志输出问题:旧系统的日志是写到文件里的,迁移到容器之后,日志文件在容器里,容器重启之后日志就没了,而且也不方便收集。后来我们把日志改成输出到控制台,容器平台自动收集控制台的日志,这样日志就不会丢了,也方便查询和分析。容器化的应用,日志最好输出到控制台,不要写到文件里。
- 健康检查配置问题:容器平台的健康检查,配置不对的话,会认为应用不健康,频繁重启容器。我们最开始配置的健康检查接口不对,超时时间也太短,导致应用还没启动完成,就被认为不健康,重启了。后来调整了健康检查的接口、超时时间、初始延迟时间,才解决。配置健康检查的时候,要根据应用的启动时间和响应时间,合理设置参数。
经验总结:
- 迁移前充分准备:迁移前的准备非常重要,系统梳理、方案设计、测试验证,每一步都要做扎实,准备得越充分,迁移越顺利。不要没准备好就仓促上线,风险很大。
- 灰度发布,平滑迁移:不要一次性切换,要用灰度发布的方式,逐步切流量,观察验证,没问题再加大流量,出了问题能快速回滚,把影响降到最低。
- 安全要贯穿始终:安全不是迁移完成之后才考虑的,而是要贯穿迁移的整个过程,从镜像构建、运行时、数据、访问,各个方面都要考虑安全,确保迁移后的系统是安全的。
- 做好备份和回滚预案:迁移之前,一定要做好数据备份,也要做好回滚预案,万一迁移出问题,能快速回滚,恢复业务,把损失降到最低。
- 充分利用容器化的优势:迁移不是把应用放到容器里就完了,还要充分利用容器化的优势,比如弹性伸缩、CI/CD自动化、资源调度、环境一致性等,这样才能真正发挥容器化的价值。
- 持续优化,不断改进:迁移完成不是终点,而是新的起点,要持续优化,不断改进,让系统运行得更稳定、更高效、更安全。
九、写在最后
这次容器安全迁移,从准备到完成,花了一个多月的时间,中间踩了不少坑,也遇到了一些挑战,但最终顺利完成了迁移,系统运行稳定,也达到了预期的效果。
容器化是现在的趋势,越来越多的系统在做容器化迁移,但容器化迁移不是一件简单的事情,尤其是核心业务系统,涉及到安全、兼容性、数据、灰度等多个方面,需要认真对待,充分准备,才能顺利完成。
希望这篇文章,能给正在做容器化迁移,或者打算做容器化迁移的朋友一些参考,少踩一些坑,顺利完成迁移。也欢迎大家在评论区分享自己的容器化迁移经验,一起交流学习。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录