目录
零、Jenkins介绍
1.Jenkins功能
2.Jenkins概念
3.Jenkins目的
4.Jenkins特性
5.产品发布流程
一、Jenkins CI/CD 流程
二、GitLab安装
1.SSH下安装
安装依赖
配置镜像
开始安装
2.Docker下安装
添加容器
启动容器
查看已存在的容器
进入容器
3.SSH连接
4.Gitlab提交代码
三、Jenkins 部署
1.SSH下安装
报错
Caused: java.io.IOException: Failed to bind to 0.0.0.0/0.0.0.0:8080
2.Docker下安装
docker-compose
运行
进入容器
四、安装Maven插件
五、新建任务Item
六、持续交付
七、Pre-Steps
零、Jenkins介绍
Jenkins的前身是Hudson,采用JAVA编写的持续集成开源工具。Hudson由Sun公司在2004年启动,第一个版本于2005年在java.net发布。2007年开始Hudson逐渐取代CruiseControl和其他的开源构建工具的江湖地位。在2008年的JavaOne大会上在开发者解决方案中获得杜克选择大奖(Duke's Choice Award)。
在2010年11月期间,因为Oracle对Sun的收购带来了Hudson的所有权问题。主要的项目贡献者和Oracle之间,尽管达成了很多协议,但有个关键问题就是商标名称“Hudson”。甲骨文在2010年12月声明拥有该名称并申请商标的权利。 因此,2011年1月11日,有人要求投票将项目名称从“Hudson”改为“Jenkins”。2011年1月29日,该建议得到社区投票的批准,创建了Jenkins项目。
2011年2月1日,甲骨文表示,他们打算继续开发Hudson,并认为Jenkins只是一个分支,而不是重命名。因此,Jenkins和Hudson继续作为两个独立的项目,每个都认为对方是自己的分支。到2013年12月,GitHub上的Jenkins拥有567个项目成员和约1,100个公共仓库,与此相对的Hudson有32个项目成员和17个公共仓库。到现在两者的差异更多,应该说Jenkins已经全面超越了Hudson。此外,大家可能是出于讨厌Oracle的情绪,作为Java开发者天然地应该支持和使用Jenkins。后面Hudson被Oracle捐给了Eclipse基金会,所以右边这老头有个Eclipse的光环加持。
为什么Jenkins更受大家欢迎?
由开发者主导、面向开发者
1.Jenkins功能
持续的软件版本发布/测试项目。监控外部调用执行的工作。
2.Jenkins概念
Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台。这是一个免费的开源项目,可以处理任何类型的构建或持续集成。集成Jenkins可以用于一些测试和部署技术。Jenkins是一种软件允许持续集成。
3.Jenkins目的
持续、自动地构建/测试软件项目。监控软件开放流程,快速问题定位及处理,提提高开发效率。
4.Jenkins特性
- 开源的java语言开发持续集成工具,支持CI,CD
- 易于安装部署配置:可通过yum安装,或下载war包以及通过docker容器等快速实现安装部署,可方便web界面配置管理
- 消息通知及测试报告:集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知,生成JUnit/TestNG测试报告
- 分布式构建:支持Jenkins能够让多台计算机一起构建/测试
- 文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等
- 丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker等
5.产品发布流程
产品设计成型 -> 开发人员开发代码 -> 测试人员测试功能 -> 运维人员发布上线
持续集成(Continuous integration,简称CI)
持续交付(Continuous delivery)
持续部署(continuous deployment)
一、Jenkins CI/CD 流程
这张图稍微更形象一点,上线之前先把代码git到版本仓库,然后通过Jenkins将Java项目通过maven去构建,这是在非容器之前,典型的自动化的一个版本上线流程。那它有哪些问题呢?
如:它的测试环境,预生产环境,测试环境。会存在一定的兼容性问题 (环境之间会有一定的差异)
这里有一个docker harbor 的镜像仓库,通常会把你的环境打包为一个镜像,通过镜像的方式来部署。
二、GitLab安装
1.SSH下安装
安装依赖
sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
配置镜像
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
开始安装
sudo EXTERNAL_URL="http://192.168.44.103" yum install -y gitlab-jh
除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 `/etc/gitlab/initial_root_password` 文件中(出于安全原因,24 小时后,此文件会被第一次 `gitlab-ctl reconfigure` 自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 `root` 登录。
2.Docker下安装
Docker默认你有
添加容器
docker run \
-itd \
-p 8090:80 \
-p 8022:22 \
-v /gitlab/etc:/etc/gitlab \
-v /gitlab/log:/var/log/gitlab \
-v /gitlab/opt:/var/opt/gitlab \
--restart always \
--privileged=true \
--name gitlab \
gitlab/gitlab-ce
启动容器
docker start gitlab
查看已存在的容器
docker ps -a
进入容器
docker exec -it gitlab /bin/bash
当首次运行出现502错误的时候排查两个原因
- 虚拟机内存至少需要4g
- 稍微再等等刷新一下可能就好了
3.SSH连接
回到你的主机:
ssh-keygen -t rsa -C '你的邮箱'
查看密码:
cat /root/.ssh/id_rsa.pub
把他复制到Gitlab里面:
点击添加密钥。
4.Gitlab提交代码
配置一下自己的用户名和邮箱:
git config --global user.name 'van'
git config --global user.email 'xxx@xxx.com'
稍微配置一下,如下:
然后咱们打开Idea:
默认你懂。
三、Jenkins 部署
1.SSH下安装
先安装Java环境:
yum install -y java-11-openjdk
Jenkins官网:Jenkins
点击进行下载,有梯子的话可以用一下:
下载完丢到linux里面就行:
开始初始化:
java -jar jenkins.war
报错
Caused: java.io.IOException: Failed to bind to 0.0.0.0/0.0.0.0:8080
检查8080端口是否被占用,若被占用直接关掉。
lsof -i:8080
初始化完成后去浏览器上访问一下(下图中那堆8720...就是密码):
把上面提到的密码复制进去:
这里选择推荐:
到这里等他自己安装就好:
这里如果大面积报错报红,则表示你的Jenkins版本较低,需要去官网下载新版。
创建一个管理员用户:
继续:
完成:
配置阿里源镜像,打开你的Maven目录(根据自己的位置来):
/usr/share/maven/conf
然后编辑 settings.xml 文件,把以下内容 覆盖 进去(配置阿里源):
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
| This is the configuration file for Maven. It can be specified at two levels:
|
| 1. User Level. This settings.xml file provides configuration for a single user,
| and is normally provided in ${user.home}/.m2/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -s /path/to/user/settings.xml
|
| 2. Global Level. This settings.xml file provides configuration for all Maven
| users on a machine (assuming they're all using the same Maven
| installation). It's normally provided in
| ${maven.conf}/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -gs /path/to/global/settings.xml
|
| The sections in this sample file are intended to give you a running start at
| getting the most out of your Maven installation. Where appropriate, the default
| values (values used when the setting is not specified) are provided.
|
|-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>${user.home}/.m2/repository</localRepository>
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If set to false,
| maven will use a sensible default value, perhaps based on some other setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
<!-- offline
| Determines whether maven should attempt to connect to the network when executing a build.
| This will have an effect on artifact downloads, artifact deployment, and others.
|
| Default: false
<offline>false</offline>
-->
<!-- pluginGroups
| This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
| when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
| "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
|-->
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
<!-- proxies
| This is a list of proxies which can be used on this machine to connect to the network.
| Unless otherwise specified (by system property or command-line switch), the first proxy
| specification in this list marked as active will be used.
|-->
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
<!-- servers
| This is a list of authentication profiles, keyed by the server-id used within the system.
| Authentication profiles can be used whenever maven must make a connection to a remote server.
|-->
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
<server>
<id>releases</id>
<username>ali</username>
<password>ali</password>
</server>
<server>
<id>Snapshots</id>
<username>ali</username>
<password>ali</password>
</server>
</servers>
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving certain artifacts.
| However, this repository may have problems with heavy traffic at times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a mirror reference for that
| repository, to be used as an alternate download site. The mirror site will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<!--This is used to direct the public snapshots repo in the
profile below over to a different nexus group -->
<id>nexus-public-snapshots</id>
<mirrorOf>public-snapshots</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
</mirror>
<mirror>
<!--This is used to direct the public snapshots repo in the
profile below over to a different nexus group -->
<id>nexus-public-snapshots1</id>
<mirrorOf>public-snapshots1</mirrorOf>
<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
</mirror>
</mirrors>
<!-- profiles
| This is a list of profiles which can be activated in a variety of ways, and which can modify
| the build process. Profiles provided in the settings.xml are intended to provide local machine-
| specific paths and repository locations which allow the build to work in the local environment.
|
| For example, if you have an integration testing plugin - like cactus - that needs to know where
| your Tomcat instance is installed, you can provide a variable here such that the variable is
| dereferenced during the build process to configure the cactus plugin.
|
| As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
| section of this document (settings.xml) - will be discussed later. Another way essentially
| relies on the detection of a system property, either matching a particular value for the property,
| or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
| value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
| Finally, the list of active profiles can be specified directly from the command line.
|
| NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
| repositories, plugin repositories, and free-form properties to be used as configuration
| variables for plugins in the POM.
|
|-->
<profiles>
<profile>
<id>development</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
<snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
<snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<!--this profile will allow snapshots to be searched when activated-->
<id>public-snapshots</id>
<repositories>
<repository>
<id>public-snapshots</id>
<url>http://public-snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public-snapshots</id>
<url>http://public-snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>development</activeProfile>
<activeProfile>public-snapshots</activeProfile>
</activeProfiles>
<!-- activeProfiles
| List of profiles that are active for all builds.
|
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
</settings>
yum install -y java-devel
2.Docker下安装
Docker默认你有。
docker-compose
编写docker-compose.yml文件(文件名就叫:docker-compose.yml):
# docker-compose.yml
version: '3'
services:
docker_jenkins:
user: root
restart: always
image: jenkins/jenkins:lts
container_name: jenkins
ports:
- 8888:8080
- 50000:50000
volumes:
- /docking/jenkins_home/:/var/jenkins_home
- /docking/docker.sock:/var/run/docker.sock
- /docking/docker:/usr/bin/docker
- /docking/docker-compose:/usr/local/bin/docker-compose
运行
docker-compose up -d
进入容器
这里加上 -u 0 是为了防止在 apt-get install vim 时报错:
docker exec -it -u 0 jenkins bash
在web上需要输入命令时直接去Linux看就行,已经挂了数据卷:
cat /docking/jenkins_home/secrets/initialAdminPassword
四、安装Maven插件
稍微等一下即可:
五、新建任务Item
输入一个任务名称,然后选中Maven,点击确定:
中选源码管理,点击 Git :
上图中的URL要去Gitlab中复制:
效果如下(这里若Jenkins会使用git命令去测试连通,若报错则需要去Jenkins服务器上安装一下,直接yum就行):
yum install -y git
若还有报错可以前往Gitlab仓库查看是否私有,如下图(点击仓库门右边的小扳手):
点击编辑:
在此处进行修改:
下面需要配置一下Maven的环境变量,让Jenkins可以找到Maven(点击 the tool configuration ):
点击新增Maven:
将自动安装取消掉,然后将你的路径写进去,然后保存:
然后回去构建一次:
我这里因为没有提前配置阿里源和jdk所以报错了,阿里源配置的xml在上面。这里的下图中代码存放的位置记一下:
回到服务器上弄一下jdk:
yum install -y java-devel
配置完阿里源后去重新构建一次:
cd /root/.jenkins/workspace/first
/usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true
构建成功
六、持续交付
这里随便搞了一台设备来测试,已经装好了java环境:
测试的话Jre就够了,没必要再上Jdk。然后回到Jenkins的web,安装一个插件:
装好后去对他进行一下配置:
把测试机器的IP、用户、密码填进去:
下面可以测试连接,完成后点击保存即可。
用处是在构建完成后通过ssh发布给另一台设备。退回到项目页面,点击项目名称对其进行配置:
把目录位置写进去,可以使用通配符:
下面可以配置目的目录和在把东西扔过去之后,执行什么命令:
保存,然后试一下:
效果:
成功拿到,能跑:
七、Pre-Steps
在交付前希望提前删掉之前交付过的文件,并将之前运行的jar杀死,这里要用到Pre-Steps。这里脚本第二行的 van 要改成自己的目录名(接收端存放jar包的目录名):
#!/bin/bash
rm -rf van
appname=$1
echo "arg:$1"
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
echo $pid
if [ -z $pid ];
then
echo "$appname not started"
else
kill -9 $pid
echo "$appname stoping...."
check=`ps -ef | grep -w $pid | grep java`
if [ -z $check ];
then
echo "$appname pid:$pid is stop"
else
echo "$appname stop failed"
fi
fi
运行脚本后面要加一个关键字参数,我这里jar包里有 docker 所以就这样写了: