Jenkins的安装及构建
更新时间:2018-06-13 | 阅读量(2,347)
> 微服务架构已经是现在无处不在讨论的一种架构风格了,无论是大公司还是小公司,大团队还是小团队。在这里我们不讨论是否真的所有应用都有必要采用微服务架构,但是只要你才用了微服务架构后就有一个你不得不面对的问题,那就是部署的成本会直线上升,那么此时持续集成就显得十分重要了。
本篇文章我会先介绍一个持续集成利器 Jenkins 的安装,以及最简单的一个服务构建案例,更多应用请持续关注 [叩丁狼官网](http://www.wolfcode.cn) 的技术文章更新或 [叩丁狼的简书号](https://www.jianshu.com/u/231b43e2c05f)
### 持续集成
百度百科的介绍是,持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误
其实总结一句话就是,将软件整体整合起来进行自动化编译、构建、测试,并可以持续进行多次集成。说到这里可能就有点奇怪了,我们一般谈及 Jenkins 就是理解为一个可以帮我们完成自动化部署的工具,但貌似持续集成的概念里面也没有自动化部署啊
其实 Jenkins 的核心功能就是帮我们完成持续集成,而我们所提到的自动化部署其实应该是叫做“持续交付”,这个概念我就不再详述了哈,有兴趣的自行百度。总之我们需要在 Jenkins 在为我们测试、构建完成后,进行项目的自动化部署,这个其实也是使用的 Jenkins 为我们提供的特性来完成的,在后面的课程中我会陆续把这些功能加上来
### Jenkins 持续集成的流程
下图简单描述了利用 Jenkins 完成持续集成的整个流程,当然还有很多细节点没有体现出来,比如如何进行远程部署(本地的 Jenkins 帮助远程的服务器完成部署),如何进行批量部署等等。这些操作都将在后续的实战文章中体现出来

如上图所示,流程大概如下:
1. 开发者编码完成后,将源码推送到代码仓库(git/svn)
2. 在 Jenkins 的构建任务中,添加 git hook 或者配置定时检测源码仓库是否有更新
3. Jenkins 检测到有源码更新(根据第二部触发),则向源码仓库拉去源码到 workspace
4. 使用工具对源码进行编译、测试、打包等等操作(这里我们使用 Maven,你也可以使用 Ant 或者 Gradle)
5. 构建完成后,使用预先编写好的脚本对编译后的项目进行部署,比如说将原有 tomcat 关闭,并将原来的项目进行备份,然后将新的项目更新到 tomcat webapps,并启动 tomcat
6. 项目部署完成,即可访问网站了
### Jenkins & Docker

直接部署 Jenkins 很简单,你只需要去官网下载对应版本的 war 包,然后将其丢到一个 tomcat 中即可运行,下面我介绍的是 Jenkins & Docker 结合起来使用,你需要提前有一些 Docker 的使用经验
**Jenkins + Docker 的结合主要体现在以下两点:**
- 使用 Docker 管理 Jenkins 资源
- 使用 Jenkins 构建 Docker 镜像

这里解释一个误区,Docker 和 Jenkins 是分别独立的两个非常优秀的开源程序,Jenkins 的出现让应用的持续集成成为可能。而 Docker 是一个基于 Linux 容器化技术实现的类似轻量虚拟机的程序,我们能够将软件运行到 Docker 容器中,从而使我们的软件可以拥有独立的运行环境,并且可以获得远远小于虚拟机的性能消耗。
也正是因为这样的特性,我们的软件在开发周期中可能因为不同的版本更新不同的特性需要多套运行环境进行持续集成,此时我们可以完美的将 Jenkins 和 Docker 整合起来,完成应用容器化的持续集成
### 环境准备
好了,那么废话不多说,我们直接开始准备安装一下 Jenkins 吧,首先需要先确定你的系统已经有如下环境
- **Docker:**前面已经说过了,不用 Docker 的安装实在太简单了所以就不多介绍了,我在这边采用了 1.18 版本的 Docker,主要是将其用于构建镜像以及将镜像推送到 Docker 仓库
- **docker-compose:**他的作用是帮我们管理 Docker 容器,我们将原本使用 `docker run` 命令的所有参数以服务配置的形式,通过一个 docker-compose.yml 文件来统一管理起来,避免重复输入一些冗长但每次都相同的命令
- **JDK:**Jenkins 是一个 Java 程序,所以是需要有 JRE 才能将其运行起来。不过因为我们是使用 Docker 容器来部署 Jenkins 服务,所以也可以不需要。版本的话根据你需要进行部署的项目来看,我这边使用的 Oracle JDK1.8
- **Maven:**例子中的构建工具主要还是以 Maven 为主,当然你可以改成 Ant 或者 Gradle,配置的区别不算太大,只是安装不同的插件而已。我使用的 3.5.3 版本
- **CentOS7:**系统我使用的 CentOS7,如果你是用的是 7 以下的 CentOS 版本,那么要装新版本的 Docker 你需要升级内核,否则就只能装低版本的 Docker(你也可以使用一个已经安装好 Docker 的 Winodws 系统,只需要将我的例子所涉及到的地址修改为 Windows 下的地址即可)
大致拥有以上环境就可以开始了,其实主要还是在 Docker 上,Docker 没问题了在什么系统没有太大的区别,那么接下来我们便可以开始进行安装 Jenkins 了
#### 安装 Jenkins
下面是一段 docker-compose 的配置文件,里面我只配置了一个 Jenkins 服务。当然你可以把他换成 `docker run` 命令来启动,但这样的话命令可能会显得比较长,所以推荐还是使用 docker-compose 来进行管理比较好
```docker-compose
version: '2' # docker-compose 版本号
services: # 服务配置列表
jks_8300: # 服务名(不是容器名)
image: jenkins # 基础镜像
ports: # 将端口映射到宿主机(数组配置,宿主机端口:容器端口)
- 8300:8080
- 50000:50000
volumes: # 宿主机与容器文件共享 宿主机目录:容器目录
- /var/jenkins_home:/var/jenkins_home # jenkins_home 放在宿主机管理
- /var/run/docker.sock:/var/run/docker.sock # 与主机共享 docker
- /usr/bin/docker:/usr/bin/docker # 与主机共享 docker
- /etc/docker:/etc/docker # 与主机共享 docker
- /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 # 共享运行 docker 所需要的系统包
- /usr/local/jdk1.8.0_171:/usr/local/jdk1.8 # 共享 JDK,当然也可以使用 Jenkins 自身的 JDK,看情况
- /usr/local/apache-maven-3.5.3:/usr/local/apache-maven-3.5.3 # 与主机共享 Maven
- ~/.m2:/root/.m2 # 共享 Maven 本地仓库与配置(看需要了,也可以全部放容器中)
- /data/sh:/data/sh # 远程部署或者本地脚本执行,将所有脚本放在 Jenkins 服务主机,统一管理
user: root # 运行容器的用户
restart: always # 容器重启策略,总是重启
```
以上就是运行 Jenkins 的所有配置了,我将一些宿主机的目录映射到容器中与 Jenkins 共享,这样在配置起来会更方便,接下来你便可以使用 docker-compose 的命令将你的容器运行起来了
在 docker-compose.yml 文件所在位置使用 `docker-compose up` 命令运行容器,不过此时没有加 -d 参数(`docker-compose up -d` 该命令可以后台启动容器)表示我是以前台运行的方式来启动容器,因为这样我便可以看到容器内的日志输出,在 Jenkins 第一次启动的时候他会初始化一个密码,如下图

保留 39b935......b2ce 这段字符,当然你的肯定不一样。这是 Jenkins 在第一次启动时初始化的密码,当然你也可以直接启动完容器后,进入容器内部查看 /var/jenkins_home/secrets/initialAdminPassword 该文件同样可以得到初始化密码
```
docker exec -it root_jks_8300_1 /bin/bash # 进入容器
cat /var/jenkins_home/secrets/initialAdminPassword # 查看初始密码
```
保存完初始化密码后,使用 ctrl + c 退出容器,再使用 `docker-compose start` 将容器启动起来,启动成功后你可以使用 `docker-compose ps`(实际上底层还是 docker ps 命令) 来查看容器的运行状态

#### Jenkins 初始化配置
看到上图的输入内容,State 下面显示的 Up 状态,便可以去访问你的 Jenkins 后台了。输入你自己的地址(http://your_ip:8300),进入 Jenkins 管理后台

输入密码后,点击右下角 Continue 按钮,进入插件安装选择界面

该页面有两个按钮,第一个是安装推荐插件,第二个则是进入插件管理界面,自己选择需要的插件进行安装,这里我们选择第二种,点击后进入如下界面

此页面默认为选中推荐(你可以将那些你确定不会用到的插件去掉,比如 Ant...),我们需要再而外选中几个其他的。
比如获取源码用的 **Git Parameter** 和 **GitHub/GitLab**,构建完成后的邮件通知以及远程部署所需要的 **SSH**,当然还有后面我们要使用的 **Maven** 插件。不过这个页面没法安装 **Maven**,只有 Ant 和 Gradle,**我们待会再去安装 Maven**


OK,那么目前为止暂时所需要的插件就选好了,接下来点击右下角的 **install**,泡杯茶等待插件安装完成即可进入下一步
忘记截图插件安装完成的样子自动跳转了,大家脑补一下选中的插件一堆勾勾即可,当然要是出现**部分插件安装失败影响也不大,可以进入后台插件管理重新安装**

插件安装完成后会自动跳转到该界面,填写你的用户名密码等信息就可以啦(我当然不会告诉你我的密码是6个1),然后点击 **Save And Finish** 保存即可
到了这个界面,恭喜你安装基本完成了,点击 **Start using Jenkins** 开始使用吧

OK~ 到这一步你的 Jenkins 服务就已经安装完成了,介于篇幅原因我们下一篇文章[《Jenkins 持续集成:插件管理 & 持续集成案例》](http://www.wolfcode.cn)再来继续讨论 Jenkins 的插件管理以及基础配置,当然还有一个持续集成的案例哦