从安装到GithubAction与Jenkins搭建CICD流水线
早在学习初期查看学习路线的时候, 就看到过CI/CD , 不过开始没有什么开发的经验 , 并不能体会到CI/CD的含义以及作用。
前段时间曾总结过一篇GithubAction与阿里云镜像仓库自动化实现Docker镜像构建与推送的文章 , 通过Github Action以及阿里云的Docker镜像仓库来进行Docker镜像的构建以及推送 , 接着在部署的时候只需要从镜像仓库中拉取镜像然后运行容器即可。
这样做一方面可以降低风险(只需要推送代码到指定分支就可以自动的去构建项目) , 也使得项目部署更加方便 (直接在服务器运行shell即可, 省去了临时去构建doker镜像的讨厌的操作) , 但是还有一点问题就是仍然需要人手动的去构建容器 , 完整的CI/CD流程远非如此
今天在项目开发合并分支的时候, 项目构建的时候突然出现错误(后来发现是server顶不住了) , 不过通过项目组的大佬提前配置好的CI/CD流水线非常方便地来进行项目构建以及发布, 省去了大量的不必要的体力劳动。
计划顺着这个机会,从头来学习CI/CD的知识 , 并且通过GithubAction构建一个完整的CI/CD流水线
之前的GithubAction 配置在 adorabled4/hxBI , 可以先从这个看起, 一步步来理解
What is CI/CD?
CI/CD 是 Continuous Intergration/Continuous Deploy 的简称,翻译过来就是持续集成/持续部署。
其中CD 也会被解释为持续交付(Continuous Delivery)。
简单来说 CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。
仔细看下面这张图
一项技术或者是一种产品的提出(or 发展) , 必然会对应着相应的场景以及一定的需求 , 那么CI/CD也有对应的他需要解决的问题
Was vernünftig ist, das ist wirklich; und was wirklich ist, das ist vernünftig.
----Hegel, Grundlinien der Philosophie des Rechts, Frankfurt am Main 1972, S. 11
CI
大师 Martin Fowler 对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。
CD
CD(Continuous Delivery, 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。
比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。
如果代码没有问题,可以继续手动部署到生产环境。
Jenkins
Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。
Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。
通过GithubAction搭建CI/CD流水线
这里的主要目标是通过GithubAction + Jenkins + Docker 来进行
理想的步骤大概是:
- 编写代码
- 单元测试
- 提交代码(dev)
- 合并分支(比如dev -> test)
安装Docker&&Jenkins
安装Docker
Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。
Docker CE 分为 stable
test
和 nightly
三个更新频道。
官方网站上有各种环境下的 安装指南,这里主要介绍 Docker CE 在 CentOS上的安装。
通过命令启动docker:
1 | systemctl start docker # 启动docker服务 |
然后输入命令,可以查看docker版本:
1 | docker -v |
如图:
1 | [root@localhost ~]# docker -v |
docker官方镜像仓库网速较差,我们需要设置国内镜像服务:
参考阿里云的镜像加速文档:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
编辑完文件之后可以通过cat 命令查看是否编辑成功
1 | [root@localhost ~]# cat /etc/docker/daemon.json |
Docker安装Jenkins
这里为了方便使用Docker来进行安装
更多容器部署命令参考 docker常用容器部署命令总结
拉取镜像 docker pull jenkins/jenkins
1 | [root@localhost ~]# docker pull jenkins/jenkins |
创建挂载文件
1 | mkdir -p /mydata/jenkins/jenkins_home |
给予权限 chmod 755 mydata/jenkins/jenkins_home
创建jenkins容器
1 | docker run \ |
关于命令参数
参数 | 含义 |
---|---|
-d | 后台运行容器,并返回容器ID |
-uroot | 使用 root 身份进入容器,推荐加上,避免容器内执行某些命令时报权限错误 |
-p 11000:8080 | 将容器内8080端口映射至宿主机11000端口,这个是访问jenkins的端口 |
-p 50000:50000 | 将容器内50000端口映射至宿主机50000端口 |
–name jenkins | 设置容器名称为jenkins |
-v /home/jenkins_home:/var/jenkins_home :/var/jenkins_home | 目录为容器jenkins工作目录,我们将硬盘上的一个目录挂载到这个位置,方便后续更新镜像后继续使用原来的工作目录 |
-v /etc/localtime:/etc/localtime | 让容器使用和服务器同样的时间设置 |
jenkins/jenkins | 镜像的名称,这里也可以写镜像ID |
接着我们docker logs jenkins
查看运行日志
保存好password
接着访问Jenkinshttp://${server_ip}:{port}
选择 安装推荐的插件
因为网络原因,需要将插件源设置为国内,
这样才可以安装插件。
进入宿主机目录 /mydata/jenkins/jenkins_home/
,编辑文件 hudson.model.UpdateCenter.xml
修改 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
接着docker restart jenkins
重启容器
安装推荐插件即可
创建账户
到这里我们完成了基本的Jenkins安装操作
编写Demo项目
这里重点不在于代码编写, 因此编写的代码结构非常简单 !
接口代码
service
1 |
|
controller
1 |
|
单元测试
这里的代码非常简单 , 测试的目的在于强调单元测试的重要性。
不写单测一时爽, 项目上线火葬场
- 简单断言
1 | package com.dhx.demo.service; |
编写Dockerfile
如果你不熟悉Dockerfile的部署操作 , 建议先阅读 Docker部署Springboot+React项目
1 | FROM openjdk:8-jdk-alpine |
这里主要需要修改pom.xml
, 设置生成的jar包的名称是项目的名称。
在准备好基本的项目代码之后 , 我们把代码托管到github , 这里我的是https://github.com/adorabled4/demo
Jenkins搭建
接下来就开始准备Jenkins的相关配置。
环境配置
首先是进行环境相关的配置 , 这里由于我们使用docker来搭建jenkins , 部分的环境以及配置好了
1 | root@54eec85aa964:~/.ssh# java -version |
创建item
接着在Jenkins中配置相关的信息
General
- Github 项目url
丢弃旧的构建: 服务器资源是有限的,有时候保存了太多的历史构建,会导致Jenkins速度变慢,并且服务器硬盘资源也会被占满。当然下方的"保持构建天数" 和 保持构建的最大个数是可以自定义的,需要根据实际情况确定一个合理的值。
这里我们需要使用Git来进行版本控制 , 下面的 配置秘钥 请仔细配置
配置秘钥
关于秘钥的工作流程
比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:
- Bob将他的公开密钥传送给Alice。
- Alice用Bob的公开密钥加密她的消息,然后传送给Bob。
- Bob用他的私人密钥解密Alice的消息。
一个公钥对应一个私钥。
密钥对中,让大家都知道的是公钥,不告诉大家,只有自己知道的,是私钥。
如果用其中一个密钥加密数据,则只有对应的那个密钥才可以解密。
如果用其中一个密钥可以进行解密数据,则该数据必然是对应的那个密钥进行的加密。
使用Docker部署jenkins如果直接拉取的话是没有权限的, 因此我们需要进行相关的权限配置。
-
删除/data/jenkins/workspace/project-name后重新构建
-
通过git取消代理设置
1
2git config --global --unset http.proxy
git config --global --unset https.proxy
上面的两种方法偶尔还是会存在问题 , 最终的解决办法是通过配置公钥与私钥
首先我们进入容器docker exec -it jenkins /bin/bash
接着ssh-keygen
生成公钥与私钥
注意把邮箱替换为你的Github中使用的邮箱 ssh-keygen -t rsa -b 4096 -C dhx2648466390@163.com
秘钥的地址为/root/.ssh
1 | root@54eec85aa964:~/.ssh# pwd |
接下来我们在Github中配置公钥 , 在Jenkins中配置私钥
使用cat命令,查看公钥
1 | cat /root/.ssh/id_rsa.pub |
GitHub配置生成好的公钥。 下面的链接是配置公钥的路径!
1 | https://github.com/settings/ssh/new |
cat /root/.ssh/id_rsa
查看私钥
这里出现了ssh: connect to host github.com port 22: Network is unreachable
报错
这里是访问不了github.com的22端口 , 那么我们尝试更换端口
尝试在~/.ssh/config
文件 中添加如下的内容
1 | Host github.com |
这里容器中没有vim vi命令 , 需要我们手动进行安装
1 | #先更新apt,如果root用户 sudo 就不需要加 |
接着我们
1 | cd ~/.ssh |
然后粘贴
1 | Host github.com |
到文件中即可。
源码管理
-
Git -> 配置
-
指定代码分支
Github hook
构建触发器选择Github hook。
Payload的格式为http://jenkins_username:jenkins_password@ip/github-webhook/
。
参考
- https://segmentfault.com/a/1190000039829057
- https://zhuanlan.zhihu.com/p/362063566
- 使用Jenkins+Docker+Github快速部署SpringBoot应用 - 知乎 (zhihu.com)
- https://blog.csdn.net/BThinker/article/details/124178670
- https://zhuanlan.zhihu.com/p/422815048
- https://zhuanlan.zhihu.com/p/250534172
- https://www.cnblogs.com/Sweettesting/p/14735920.html
- https://articles.zsxq.com/id_0bp5zqagnpvo.html
- Linux安装Jenkins : https://blog.csdn.net/nanhavezhi/article/details/103071774