这两年DevOps越来越火,持续集成和持续部署已经成为了互联网公司的标配,GitLab CI/CD作为GitLab自带的CI/CD工具,因为简单易用、和GitLab无缝集成,受到了很多团队的欢迎。我也是从去年开始学习和使用GitLab CI/CD的,从一开始的一无所知,到后来能独立搭建和配置CI/CD流水线,踩了不少坑,也积累了一些经验。今天就来分享一下我的GitLab CI/CD学习路线,聊聊我是怎么入门的。
一、为什么要学CI/CD
在学CI/CD之前,我所在的团队还是传统的部署方式,开发写完代码,提交到Git,然后测试环境要手动拉代码、编译、部署,生产环境更是要运维手动操作,每次部署都要半天,而且容易出错,经常出现"我本地是好的啊"这种问题。那时候就觉得,这种方式太原始了,效率太低,而且容易出问题,应该有更好的方式。
后来了解到了CI/CD,也就是持续集成和持续部署,简单来说,就是代码提交之后,自动进行构建、测试、部署,整个过程自动化,不需要人工干预。这样做的好处很多:第一,效率高,提交代码之后自动部署,不用等运维手动操作;第二,不容易出错,自动化的流程比人工操作可靠得多;第三,能尽早发现问题,每次提交都自动运行测试,有问题马上就能发现;第四,能让团队把精力放在开发上,不用花太多时间在部署上。
了解了CI/CD的好处之后,我就决定要学习一下,当时我们团队用的是GitLab做代码管理,而GitLab从8.0版本开始就自带了CI/CD功能,不需要额外安装Jenkins之类的工具,配置也比较简单,所以我就选择了从GitLab CI/CD入手。
二、第一步:了解基本概念
学习任何新技术,第一步都是了解基本概念,CI/CD也不例外。我首先花了一两天时间,了解了CI/CD的基本概念和术语。
首先是CI(Continuous Integration,持续集成),就是开发人员频繁地把代码提交到主干,每次提交都自动进行构建和测试,确保代码不会出问题。持续集成的核心是频繁提交、自动构建、自动测试,尽早发现集成问题。
然后是CD(Continuous Delivery / Deployment,持续交付/持续部署),持续交付是指代码经过CI之后,自动部署到测试环境或者预发布环境,经过人工确认之后再部署到生产环境;持续部署则更进一步,不需要人工确认,代码经过测试之后自动部署到生产环境。
然后是GitLab CI/CD的几个核心概念:
- Pipeline(流水线):一次CI/CD的完整过程,从代码提交到构建、测试、部署的整个流程。
- Stage(阶段):Pipeline分成多个阶段,比如build、test、deploy,每个阶段可以有多个Job,同一个阶段的Job并行执行,不同阶段的Job顺序执行。
- Job(任务):具体的执行任务,比如编译代码、运行测试、部署到服务器,每个Job定义了要执行的脚本和运行环境。
- Runner(运行器):执行Job的机器,可以是物理机、虚拟机或者Docker容器,GitLab CI/CD的Job都是在Runner上执行的。
- .gitlab-ci.yml:CI/CD的配置文件,放在项目根目录,用YAML格式定义Pipeline、Stage、Job等。
了解了这些基本概念之后,就对GitLab CI/CD有了一个整体的认识,接下来就可以动手实践了。
三、第二步:搭建Runner,跑通第一个Pipeline
了解了基本概念之后,第二步就是动手实践,搭建一个Runner,跑通第一个最简单的Pipeline。
首先是安装GitLab Runner,我是在一台Linux服务器上安装的,官方提供了很详细的安装文档,按照文档一步步来,很简单。安装完之后,需要注册Runner,注册的时候需要GitLab的URL和token,这些在GitLab项目的Settings -> CI/CD -> Runners里面能找到。注册的时候可以选择Runner的类型,有shared runner(所有项目都能用)和specific runner(只有指定项目能用),我一开始用的是specific runner,只给我的测试项目用。
Runner注册好之后,就可以在项目里创建.gitlab-ci.yml文件了。我写了一个最简单的配置,就一个Job,执行echo "Hello World",看看能不能跑通。
stages:
- test
hello_world:
stage: test
script:
- echo "Hello World"提交这个文件之后,GitLab就会自动触发Pipeline,在Runner上执行这个Job。我第一次提交之后,等了一会儿,看到Pipeline状态变成了passed,Job的输出里打印了"Hello World",当时还是很有成就感的,第一个Pipeline跑通了!
当然,第一次也不是一帆风顺的,我遇到了几个问题:第一个是Runner没有注册成功,因为token写错了,重新注册了一次就好了;第二个是Job一直pending,因为Runner没有启动,启动gitlab-runner服务就好了;第三个是脚本执行失败,因为Runner上没有安装对应的命令,后来在脚本里先安装依赖就好了。这些都是小问题,查一下文档或者搜一下就能解决。
四、第三步:学习常用配置,写更复杂的Pipeline
跑通了最简单的Pipeline之后,第三步就是学习更多的配置,写更复杂的Pipeline,满足实际项目的需求。
我首先学习了Stage的配置,把Pipeline分成多个阶段,比如build、test、deploy,每个阶段做不同的事情。比如build阶段编译代码,test阶段运行测试,deploy阶段部署到服务器。这样Pipeline的结构更清晰,也能控制执行顺序。
然后学习了Job的常用配置,比如:
- only/except:控制Job在什么情况下执行,比如只有在master分支提交的时候才执行部署,或者只有打tag的时候才执行。
- variables:定义变量,可以在脚本里使用,也可以定义环境变量。
- artifacts:把构建产物保存下来,比如编译好的二进制文件、测试报告,后续的Job可以下载使用,也可以在GitLab界面下载。
- cache:缓存依赖,比如node_modules、maven仓库,下次构建的时候直接用缓存,不用重新下载,加快构建速度。
- beforescript/afterscript:在Job执行之前/之后执行的脚本,比如安装依赖、清理环境。
- tags:指定用哪个Runner执行Job,不同的Job可以用不同的Runner。
我还学习了怎么用Docker作为执行环境,GitLab CI/CD支持在Docker容器里执行Job,只需要在配置里指定image,就会自动拉取对应的Docker镜像,在容器里执行脚本。这样做的好处是环境统一,不会出现"我本地是好的"这种问题,而且不需要在Runner上安装各种依赖,用什么镜像就有什么环境。我后来的项目基本都是用Docker执行的,非常方便。
我还学习了怎么部署到服务器,最简单的方式是用ssh,在Job里通过ssh连接到服务器,执行部署脚本。需要先在Runner上配置ssh密钥,把公钥加到目标服务器的authorized_keys里,然后在脚本里用ssh连接执行命令。我一开始就是这么做的,后来又学习了用Docker部署,把应用打包成Docker镜像,推送到镜像仓库,然后在服务器上拉取镜像启动容器,这样更规范,也更容易管理。
五、第四步:在实际项目中应用,踩坑积累经验
学习了常用配置之后,第四步就是在实际项目中应用,在实践中踩坑,积累经验。
我先是在自己的个人项目里用,把我的博客项目配置了CI/CD,提交代码之后自动构建、自动部署到服务器。一开始经常出问题,比如构建失败、部署失败、缓存不生效、artifacts下载失败等等,每个问题都要查半天,但是解决了之后就学到了很多。
后来我在公司的项目里也推广了GitLab CI/CD,一开始团队里有人不理解,觉得增加了复杂度,而且有时候CI失败会影响开发效率。但是用了一段时间之后,大家都感受到了好处,部署不用找运维了,提交代码自动部署,而且有问题CI会自动跑测试,能尽早发现,团队的开发效率提升了很多。
在实际项目中,我踩了很多坑,也积累了很多经验,比如:
- 构建速度慢的优化:用cache缓存依赖,用Docker镜像预装依赖,拆分Job并行执行,只构建变化的部分。
- 环境管理:不同的环境(开发、测试、生产)用不同的配置,用variables和only/except控制,不要把生产环境的配置写死在代码里。
- 密钥管理:数据库密码、API密钥这些敏感信息不要写在.gitlab-ci.yml里,用GitLab的CI/CD Variables来管理,设置成protected,只有保护分支才能访问。
- 失败处理:CI失败了要及时处理,不要让失败的Pipeline一直挂着,也不要随便allow_failure,要保证CI的可靠性。
- 版本回滚:部署失败了要能快速回滚,保留最近几个版本的镜像或者构建产物,出问题了马上回滚到上一个版本。
六、第五步:深入学习,拓展知识面
用了一段时间GitLab CI/CD之后,基本的使用已经没问题了,第五步就是深入学习,拓展知识面,了解更多高级用法和相关技术。
我学习了GitLab CI/CD的一些高级功能,比如:
- Multi-project pipelines:多项目流水线,一个项目的Pipeline可以触发另一个项目的Pipeline,适合有依赖关系的多个项目。
- Parent-child pipelines:父子流水线,一个主Pipeline可以触发多个子Pipeline,适合monorepo的项目,不同的模块用不同的子Pipeline。
- Dynamic child pipelines:动态生成子Pipeline,在运行时根据代码变化生成对应的Pipeline配置,更灵活。
- Pipeline schedules:定时Pipeline,可以定时执行,比如每天晚上跑一次全量测试,或者定期清理旧的构建产物。
- Environments:环境管理,可以在GitLab界面查看每个环境部署了哪个版本,还支持一键部署和回滚。
我还学习了相关的DevOps工具和理念,比如Docker、Kubernetes、Helm、Prometheus、Grafana等等,CI/CD只是DevOps的一部分,要做好DevOps,还需要了解容器化、编排、监控、日志等相关技术。我后来把项目都容器化了,用Kubernetes做编排,用GitLab CI/CD自动构建镜像并部署到K8s,形成了一套完整的DevOps流程。
我还学习了CI/CD的最佳实践,比如持续集成的最佳实践、持续部署的最佳实践、测试策略等等,这些理论知识能帮助我们更好地设计和使用CI/CD流水线,避免踩坑。
七、写在最后
GitLab CI/CD学习路线:我是怎么入门的。
以上就是我的GitLab CI/CD学习路线,从了解基本概念,到搭建Runner跑通第一个Pipeline,到学习常用配置,到在实际项目中应用,再到深入学习拓展知识面,整个过程大概花了几个月的时间。其实GitLab CI/CD并不难,入门很简单,只要动手实践,很快就能上手,但是要做好、做精,还是需要在实际项目中不断踩坑、不断积累。
CI/CD是DevOps的基础,也是现代软件开发必不可少的工具,不管你是开发还是运维,都应该了解和掌握CI/CD。如果你还没有用过CI/CD,推荐你从GitLab CI/CD入手,简单易用,和GitLab无缝集成,很适合入门。
学习新技术最好的方式就是动手实践,不要只看文档,要自己动手搭一个,跑一个Pipeline,在实践中学习,在踩坑中成长。希望我的学习路线能给想学习CI/CD的朋友一些参考,祝大家都能早日掌握CI/CD,提升开发效率。
最后用一句话结尾:"自动化是解放生产力的最好方式。"把重复的、容易出错的事情交给机器去做,把时间和精力放在更有价值的事情上,这就是CI/CD的意义,也是DevOps的意义。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录