Jenkins从基础环境搭建到实战
Jenkins,原名 Hudson,2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。
官方网站
1.GitLab安装使用
官方网站:https://about.gitlab.com/
安装所需最小配置
内存至少4G
https://docs.gitlab.cn/jh/install/requirements.html
建议分配内存4-8G
1.在ssh下安装
官方安装文档:https://gitlab.cn/install/?version=ce
1 安装依赖
sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
2 配置镜像
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
3 开始安装
EXTERNAL_URL:gitLab访问地址,对应服务器域名或ip
gitlab-jh:新版本的gitlab会多一个-jh,老版本的没有
sudo EXTERNAL_URL="http://192.168.79.101" yum install -y gitlab-jh
sudo EXTERNAL_URL="http://192.168.79.101" yum install -y gitlab-jh
除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 /etc/gitlab/initial_root_password
文件中(出于安全原因,24 小时后,此文件会被第一次 gitlab-ctl reconfigure
自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root
登录。
Notes: Default admin account has been configured with following details: Username: root Password: You didn't opt-in to print initial root password to STDOUT. Password stored to /etc/gitlab/initial_root_password. This file will be cleaned up in first reconfigure run after 24 hours.
NOTE: Because these credentials might be present in your log files in plain text, it is highly recommended to reset the password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.
笔记:
已使用以下详细信息配置默认管理员帐户:
用户名:root
密码:您没有选择将初始根密码打印到STDOUT。
密码存储到/etc/gitlab/initial_root_Password。此文件将在24小时后首次重新配置运行时清除。
注意:由于这些凭据可能以纯文本形式出现在日志文件中,因此强烈建议按照以下步骤重置密码https://docs.gitlab.com/ee/security/reset_user_password.html#reset-根密码。
4 启动GitLab
关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl mask firewalld.service
systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl mask firewalld.service
启动GitLab
gitlab-ctl start
gitlab-ctl start
5 gitlab常用命令
gitlab-ctl start # 启动所有 gitlab 组件;
gitlab-ctl stop # 停止所有 gitlab 组件;
gitlab-ctl restart # 重启所有 gitlab 组件;
gitlab-ctl status # 查看服务状态;
gitlab-ctl reconfigure # 启动服务;
vi /etc/gitlab/gitlab.rb # 修改默认的配置文件;
gitlab-ctl tail # 查看日志;
gitlab-ctl start # 启动所有 gitlab 组件;
gitlab-ctl stop # 停止所有 gitlab 组件;
gitlab-ctl restart # 重启所有 gitlab 组件;
gitlab-ctl status # 查看服务状态;
gitlab-ctl reconfigure # 启动服务;
vi /etc/gitlab/gitlab.rb # 修改默认的配置文件;
gitlab-ctl tail # 查看日志;
6 访问测试
cat /etc/gitlab/initial_root_password
cat /etc/gitlab/initial_root_password
修改密码,避免24小时候失效
2.使用docker安装gitlab
https://docs.gitlab.cn/jh/install/docker.html
安装所需最小配置
- 内存至少4G
- 系统内核至少在3.10以上
uname -r
命令可查看系统内核版本
1.安装步骤
1.添加容器
docker run --detach \
--hostname 192.168.79.102 \
--publish 443:443 --publish 80:80 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
--shm-size 256m \
registry.gitlab.cn/omnibus/gitlab-jh:latest
docker run --detach \
--hostname 192.168.79.102 \
--publish 443:443 --publish 80:80 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
--shm-size 256m \
registry.gitlab.cn/omnibus/gitlab-jh:latest
2.启动容器
docker start gitlab
docker start gitlab
3.查看已存在的容器
docker ps -a
docker ps -a
4.进入容器
docker exec -it gitlab /bin/bash
docker exec -it gitlab /bin/bash
2.访问
当首次运行出现502错误的时候排查两个原因
- 虚拟机内存至少需要4g
- 稍微再等等刷新一下可能就好了
3.管理员账号登录
用户名:root
密码存在下面文件中,登录后需要改密码不然24小时之后会失效
cat /etc/gitlab/initial_root_password
cat /etc/gitlab/initial_root_password
2.Jenkins安装
官方文档介绍非常详细
安装需求
机器要求:
256 MB 内存,建议大于 512 MB
10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像)
需要安装以下软件:
Java 8 ( JRE 或者 JDK 都可以)
Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载)
机器要求:
256 MB 内存,建议大于 512 MB
10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像)
需要安装以下软件:
Java 8 ( JRE 或者 JDK 都可以)
Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载)
1.安装JDK
1.安装步骤
#创建目录用于安装jdk,通常安装的软件都放在opt目录下
1) mkdir /opt/jdk
2) 通过xftp等文件上传工具将jdk安装包上传到 /opt/jdk 下
3) cd /opt/jdk
4) 解压 tar -zxvf jdk-8u261-linux-x64.tar.gz
#这是另一个给主机额外安装软件所安装的目录
5) mkdir /usr/local/java
#将解压到opt/jdk目录下的安装包移动到/usr/local/java目录下
6) mv /opt/jdk/jdk1.8.0_261 /usr/local/java
7) 配置环境变量的配置文件 vim /etc/profile
8) export JAVA_HOME=/usr/local/java/jdk1.8.0_261
#如果不加$PATH会导致基本命令失效
9) export PATH=$JAVA_HOME/bin:$PATH
10) source /etc/profile [让新的环境变量生效]
#创建目录用于安装jdk,通常安装的软件都放在opt目录下
1) mkdir /opt/jdk
2) 通过xftp等文件上传工具将jdk安装包上传到 /opt/jdk 下
3) cd /opt/jdk
4) 解压 tar -zxvf jdk-8u261-linux-x64.tar.gz
#这是另一个给主机额外安装软件所安装的目录
5) mkdir /usr/local/java
#将解压到opt/jdk目录下的安装包移动到/usr/local/java目录下
6) mv /opt/jdk/jdk1.8.0_261 /usr/local/java
7) 配置环境变量的配置文件 vim /etc/profile
8) export JAVA_HOME=/usr/local/java/jdk1.8.0_261
#如果不加$PATH会导致基本命令失效
9) export PATH=$JAVA_HOME/bin:$PATH
10) source /etc/profile [让新的环境变量生效]
测试是否安装成功
java -version查看版本
[root@llp home]# java -version
java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)
[root@llp home]# java -version
java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)
2.注意事项
如果是新版本的jenkins建议安装jdk11以上的版本,否则是会导致构建流水线任务失败等一系列问题
这是在构建pipeline任务时遇到的一个问题,构建任务时而成功,检查jdk环境变量和超时事件均无问题,最终将jdk版本由1.8更换为11成功解决,但是由于高版本jdk收费问题,因此推荐使用低版本的jenkins兼容1.8版本的jdk
2.安装maven
1.步骤
1.上传安装文件或者查看下载的链接直接在Linux上下载,并上传到 /opt/maven目录下
2.解压压缩包
3.配置环境变量
#上传安装文件到 /opt/maven目录下
mkdir /opt/maven
#通过下载连接从linux上下载指定版本的maven压缩包
wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
#解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz
mv /opt/maven/apache-maven-3.6.3 /usr/local/maven
#修改配置文件
vim /etc/profile
#配置jdk环境变量
export JAVA_HOME=/usr/local/java/jdk1.8.0_261
export PATH=$JAVA_HOME/bin:$PATH
#配置maven环境变量
export MAVEN_HOME=/usr/local/maven
export PATH=$MAVEN_HOME/bin:$PATH
#:wq退出
#刷新配置文件
source /etc/profile
#查看jmaven版本,没有显示版本号就去检查环境变量是否正确
mvn -v
#上传安装文件到 /opt/maven目录下
mkdir /opt/maven
#通过下载连接从linux上下载指定版本的maven压缩包
wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
#解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz
mv /opt/maven/apache-maven-3.6.3 /usr/local/maven
#修改配置文件
vim /etc/profile
#配置jdk环境变量
export JAVA_HOME=/usr/local/java/jdk1.8.0_261
export PATH=$JAVA_HOME/bin:$PATH
#配置maven环境变量
export MAVEN_HOME=/usr/local/maven
export PATH=$MAVEN_HOME/bin:$PATH
#:wq退出
#刷新配置文件
source /etc/profile
#查看jmaven版本,没有显示版本号就去检查环境变量是否正确
mvn -v
3.安装jekins
mkdir /usr/local/jenkins
#第一步:上传或下载安装包
cd/usr/local/jenkins
#第二步:启动
#nohup-后台静默启动
#/usr/local/jenkins/jenkins.war war包路径
#/usr/local/jenkins/jenkins.out 日志输入路径
#nohup & 后台静默启动
nohup java -jar /usr/local/jenkins/jenkins.war >/usr/local/jenkins/jenkins.out &
#第三步:访问
http://ip:8080
mkdir /usr/local/jenkins
#第一步:上传或下载安装包
cd/usr/local/jenkins
#第二步:启动
#nohup-后台静默启动
#/usr/local/jenkins/jenkins.war war包路径
#/usr/local/jenkins/jenkins.out 日志输入路径
#nohup & 后台静默启动
nohup java -jar /usr/local/jenkins/jenkins.war >/usr/local/jenkins/jenkins.out &
#第三步:访问
http://ip:8080
首次启动war包会在/root/.jenkins
生成配置文件
待完全启动成功后 访问服务器8080端口完成配置
初始化后的密码:
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
4e67bbe261da476abdc63c5b51311646
This may also be found at: /root/.jenkins/secrets/initialAdminPassword
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
4e67bbe261da476abdc63c5b51311646
This may also be found at: /root/.jenkins/secrets/initialAdminPassword
密码文件使用后会自动删除
3.Jenkins + Git + Maven 自动化部署配置
1.jenkins全局配置
1.配置jdk
2.配置git
当然,保险起见也可以进行配置
[root@bogon jenkins]# which git
/usr/bin/git
[root@bogon jenkins]# which git
/usr/bin/git
3.安装maven
2.构建任务配置(item配置)
1.Git配置
2.Pom.xml配置
3.配置Maven阿里云镜像
[root@bogon jenkins]# whereis maven
maven: /usr/local/maven
[root@bogon jenkins]# whereis maven
maven: /usr/local/maven
修改/usr/local/maven/conf/settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>${user.home}/.m2/repository</localRepository>
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
<proxies>
</proxies>
<servers>
<server>
<id>releases</id>
<username>ali</username>
<password>ali</password>
</server>
<server>
<id>Snapshots</id>
<username>ali</username>
<password>ali</password>
</server>
</servers>
<mirrors>
<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>
<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>
</settings>
<?xml version="1.0" encoding="UTF-8"?>
<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>${user.home}/.m2/repository</localRepository>
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
<proxies>
</proxies>
<servers>
<server>
<id>releases</id>
<username>ali</username>
<password>ali</password>
</server>
<server>
<id>Snapshots</id>
<username>ali</username>
<password>ali</password>
</server>
</servers>
<mirrors>
<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>
<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>
</settings>
4.开始构建任务
构建后生成jar包还是war在maven中进行了指定
5.进入jenkins家目录查看打包文件
#jenkins家目录
/root/.jenkins
#这里first目录是创建jenkins任务生成的
#demo-1对应项目名称
#打包生成的文件存放在target目录下
cd /root/.jenkins/workspace/first/demo-1/target
#jenkins家目录
/root/.jenkins
#这里first目录是创建jenkins任务生成的
#demo-1对应项目名称
#打包生成的文件存放在target目录下
cd /root/.jenkins/workspace/first/demo-1/target
除了通过jenkins界面的方式直接进行构建打包到,我们也可以手动的对项目源文件进行打包
#跳过测试依赖进行打包
/usr/local/maven/bin/mvn clean packge -Dmaven.test.skip=true
#注意目录实在项目根目录下
[root@bogon demo-1]# /usr/local/maven/bin/mvn clean packge -Dmaven.test.skip=true
#跳过测试依赖进行打包
/usr/local/maven/bin/mvn clean packge -Dmaven.test.skip=true
#注意目录实在项目根目录下
[root@bogon demo-1]# /usr/local/maven/bin/mvn clean packge -Dmaven.test.skip=true
3.自动化发布到测试环境并自动运行
1.准备工作
首先我们需要准备一台测试服务器并配置好java环境,让jenkins将打好的jar包发布到测试环境能够正常运行
2.publish over ssh 配置
1 安装插件:publish over ssh ,在Configure System菜单里 往下来
勾选安装publish over ssh插件
2.在Configure System中找到Publish over SSH添加一台目标服务器
3.修改配置
说明:
Source files
:准备发送的文件,该文件是相对于这个项目的workspace
目录,也就是$JENKINS_HOME/workspace/xxxx/
。
**/demo.*.jar
说明:我们jenkins打包后的文件在/root/.jenkins/workspace/first/demo-1/target/demo-1-1.0-SNAPSHOT.jar中
**
匹配所有目录,而demo.*.jar则表示以demo开头的以.jar结尾的文件,即将这些匹配的到文件发送到目标服务器上
Remote directory
:目标目录,
/llp
说明:表示在root目录下创建llp目录用于存放jenkins同步过来的文件
Remove prefix
:删除文件目录前缀。
demo-1/target
说明:jenkins同步文件是从任务目录下的文件开始即将/demo-1/target/目录下的以demo开头的以.jar结尾的文件进行同步同时也会创建/demo-1/target目录,为了不让目标服务器创建这些多余的目录,我们配置demo-1/target
Exec command
:最后执行的指令。
source /etc/profile nohup java -jar /root/llp/demo*.jar &
说明:同步成功只会执行的命令,我们让程序运行起来,&表示后台静默启动
在测试的过程中远程服务器一直没有成功执行nohup java -jar /root/llp/demo*.jar &这行指令,排查是因为环境遍历没有生效,因此配合source /etc/profile 进行处理。
可以看到文件也传输过来了
4.测试一下
4.自动化发布到测试环境并自动运行遗留问题
1.遗留问题
1.多次构建服务端口被占用问题(tomcat端口): 在前面我们完成了jekins构建之后传输打包好的文件到目标服务器并完成自动运行,但是并没有在进行构建之前去kill进程这样会导致当我们再次使用jekins构建运行时,服务端口被占用而无法运行
2.超时机制: 输出命令时一定要注意不要让窗口卡主,不然Jenkins会认为认为一直没完成
2.解决办法
1.超时问题处理
在之前我们在jenkins构架能完成之后会执行nohup java -jar /root/llp/demo*.jar
指令,该指令会让窗口卡住
1.shell的日志输出
# >表示覆盖
# 2>&1表示包含标准错误输出和标准输出
# &表示后台静默启动
#将启动日志写入到/root/llp/mylog.log文件中
nohup java -jar /root/llp/demo*.jar >/root/llp/mylog.log 2>&1 &
# >表示覆盖
# 2>&1表示包含标准错误输出和标准输出
# &表示后台静默启动
#将启动日志写入到/root/llp/mylog.log文件中
nohup java -jar /root/llp/demo*.jar >/root/llp/mylog.log 2>&1 &
2.数据流重定向
数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方
标准输入(stdin):代码为0,使用<或<<; 标准输出(stdout):代码为1,使用>或>>; 标准错误输出(stderr):代码为2,使用2>或2>>
> 覆盖写 >> 追加写
除此之外,应该结合项目情况指令执行的超时时间设置的大一些
2.端口被占用问题
运行前清理:配置杀死之前运行的进程:在jekins执行构建之前执行脚本获取服务进程号将进程kill掉
1.在跟目录下执行创建killpid.sh
root 38388 37362 45 23:16 pts/1 00:00:05 java -jar /root/llp/demo-1-1.0-SNAPSHOT.jar
#!/bin/bash
#删除历史数据
rm -rf llp/
#执行脚本时传入的参数,比如demo
appname=$1
#获取传入的参数并输出
echo "arg:$1"
#获取正在运行的jar包pid
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
#获取pid并输出
echo $pid
#如果pid为空,提示一下,否则,执行kill命令
if [ -z $pid ];
#使用-z 做空值判断
then
echo "$appname not started"
else
kill -9 $pid
echo "$appname stoping...."
#检查pid是否被kill掉
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
#!/bin/bash
#删除历史数据
rm -rf llp/
#执行脚本时传入的参数,比如demo
appname=$1
#获取传入的参数并输出
echo "arg:$1"
#获取正在运行的jar包pid
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
#获取pid并输出
echo $pid
#如果pid为空,提示一下,否则,执行kill命令
if [ -z $pid ];
#使用-z 做空值判断
then
echo "$appname not started"
else
kill -9 $pid
echo "$appname stoping...."
#检查pid是否被kill掉
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
2.创建号killpid.sh之后,文件并不具备可执行权限还需要对文件权限进行修改
#赋予killpid.sh文件可执行权限
chmod u+x killpid.sh
#执行脚本文件
[root@bogon ~]# ./killpid.sh demo
arg:demo
38388
demo stoping....
demo pid:38388 is stop
[1]+ 已杀死 nohup java -jar /root/llp/demo*.jar > /root/llp/mylog.log 2>&1
[root@bogon ~]# ll
总用量 8
-rw-r--r--. 1 root root 18 3月 26 2018 go
-rwxr--r--. 1 root root 694 10月 1 23:18 killpid.sh
#赋予killpid.sh文件可执行权限
chmod u+x killpid.sh
#执行脚本文件
[root@bogon ~]# ./killpid.sh demo
arg:demo
38388
demo stoping....
demo pid:38388 is stop
[1]+ 已杀死 nohup java -jar /root/llp/demo*.jar > /root/llp/mylog.log 2>&1
[root@bogon ~]# ll
总用量 8
-rw-r--r--. 1 root root 18 3月 26 2018 go
-rwxr--r--. 1 root root 694 10月 1 23:18 killpid.sh
3.在jenkins中配置构建执行之前要执行的脚本文件
3.查看日志访问测试
5.Jenkins自动构建
1.几种构建方式
快照依赖构建/Build whenever a SNAPSHOT dependency is built
- 当依赖的快照被构建时执行本job
触发远程构建 (例如,使用脚本)
- 远程调用本job的restapi时执行本job
job依赖构建/Build after other projects are built
- 当依赖的job被构建时执行本job
定时构建/Build periodically
- 使用cron表达式定时构建本job
向GitHub提交代码时触发Jenkins自动构建/GitHub hook trigger for GITScm polling
- Github-WebHook出发时构建本job
定期检查代码变更/Poll SCM
- 使用cron表达式定时检查代码变更,变更后构建本job
2.触发远程构建/gitlab上改动自动构建
1.需求说明
在构建触发器中配置接口和token,代码改动自动可以使用gitlab的webhook回调钩子调起Jenkins的启动任务接口
2.需求实现
1.在jenkins构建任务中配置构建触发器
Use the following URL to trigger build remotely:
JENKINS_URL
/job/first/build?token=TOKEN_NAME
或者 /buildWithParameters?token=TOKEN_NAME
Optionally append&cause=Cause+Text
to provide text that will be included in the recorded build cause.配置完成之后,我们可以通过
JENKINS_URL
/job/first/build?token=TOKEN_NAME
这个地址进行请求对任务进行构建。但是这是有限制的,当我们使用其他浏览器访问时,jenkins需要再次进行登录认证,是不能进行构建的。而我们的部署项目的服务器往往和jenkins不在
不在同一台机器上,这就需要安装一个插件Build Authorization Token使jenkins支持免登录认证。
2.安装插件
3.插件的使用:使用get|post方式对 jenkinsURL/buildByToken/build?job=构建任务名称&token=访问令牌
构成的地址发起请求
比如:http://192.168.79.103:8080/buildByToken/build?job=first&token=llp
4.gitLab配置网络钩子
如果没有开启webhooks运行对本地请求添加时会出现如下提示,需要在外层菜单配置选项中开启支持
5.idea修改代码推送到gitlab进行测试,可以看到左下角jenkins已经开始构建任务了。
6.访问测试
5.注意事项
1.添加jenkins构建触发器后,当不通的浏览器或者说服务器访问jenkins时是需要登录认证的
2.gitLab网络钩子自动化构建任务的方式会频繁的构建项目,如果项目比较庞大构建时间较长是非常不友好的,因此并不推荐这种方式。
3.定时构建
1.Jenkins cron表达式
标准cron:https://crontab.guru
Jenkins cron不是标准的cron表达式
第一个 * 表示每个小时的第几分钟,取值0~59
H * * * *
H:每小时执行一次 具体是第几分钟开始时随机的,比如每个小时的15分钟开始,那么每个小时的第15分钟都会执行一次
H/10 * * * *
H/10:每隔10分钟执行一次,时间不固定,比如每个小时的15分钟开始,那么每隔小10分钟都会执行一次
第二颗 * 表示小时,取值0~23
* 15 * * * 表示每天下午3点
* 1 * * * 表示每天凌晨1点
第三颗 * 表示一个月的第几天,取值1~31
* 1 5 * * 表示每月5日凌晨1点
第四颗 * 表示第几月,取值1~12
* 15 5 1 * 表示每年几月执行
第五颗 * 表示一周中的第几天,取值0~7,其中0和7代表的都是周日
第一个 * 表示每个小时的第几分钟,取值0~59
H * * * *
H:每小时执行一次 具体是第几分钟开始时随机的,比如每个小时的15分钟开始,那么每个小时的第15分钟都会执行一次
H/10 * * * *
H/10:每隔10分钟执行一次,时间不固定,比如每个小时的15分钟开始,那么每隔小10分钟都会执行一次
第二颗 * 表示小时,取值0~23
* 15 * * * 表示每天下午3点
* 1 * * * 表示每天凌晨1点
第三颗 * 表示一个月的第几天,取值1~31
* 1 5 * * 表示每月5日凌晨1点
第四颗 * 表示第几月,取值1~12
* 15 5 1 * 表示每年几月执行
第五颗 * 表示一周中的第几天,取值0~7,其中0和7代表的都是周日
“/”
表示每隔多长时间,比如 */10 * * * * 表示 每隔10分钟
“H”
hash散列值,以job名取值,获取到以job名为入参的唯一值,相同名称值也相同,这个偏移量会和实际时间相加,获得一个真实的运行时间
意义在于:不同的项目在不同的时间运行,即使配置的值是一样的,比如 都是15 * * * *
,表示每个小时的第15分钟开始执行任务,那么会造成同一时间内在Jenkins中启动很多job,换成H/15 * * * *
,那么在首次启动任务时,会有随机值参与进来,有的会在17分钟启动 有的会在19分钟启动,随后的启动时间也是这个值。这样就能错开相同cron值的任务执行了。
H的值也可以设置范围
H * * * *
表示一小时内的任意时间
*/10 * * * *
每10分钟
H/10 * * * *
每10分钟,可能是7,17,27,起始时间hash,步长不变
45 3 * * 1-6
每个周一至周六,凌晨3点45 执行1次
45 3-5 * * 1-6
每个周一至周六,凌晨3点45 ,凌晨4点45,凌晨5点45 各执行1次
H(40-48) 3-5 * * 1-6
在40~48之间取值 其他同上
45 3-5/2 * * 1-6
每个周一至周六,凌晨3点45 ,凌晨5点45 各执行1次
45 0-6/2 * * 1-6 * * 1-6
0点开始,每间隔2小时执行一次 0:45、2:45、4:45
2.定时构建实现步骤
4.源码变更构建
使用Poll SCM 方式与Build periodically一样,会主动定期检查代码托管服务器上是否有变化,一旦发生变化执行job构建
1.创建原边变更构建触发器Poll SCM
2.等待jenkins定期检查进行构建再次测试
4.测试报告邮件通知
1.需求说明
使用163免费邮箱发送邮件时注意密码填认证码,也就是发送手机短信后给的那个,不要用登录邮箱的密码
类似下面。。
FSCLPDKJHJEZSSGI
2.实现步骤
1.Configure System中添加发件人邮箱配置
2.添加发送内容
3.配置事件触发
4.发送测试邮件测试配置是否正确
5.配置接收人
5.配置收件人
6.在具体的构建任务中设置构建成功、构建失败后发送邮件给哪些用户组
7.再次构建测试接收邮件,这里的连接会去访问jenkins,为了能让外网访问还需要配置jenkins location时指定一个外网能访问的地址
5.自动化部署到docker容器中并运行
1.需求说明
2.需求实现
1.方式一:外挂目录运行docker镜像
1.首先使用外挂目录运行docker镜像
说明:外挂目录运行docker镜像:这样呢就不需要dockerfile去构建镜像在去运行镜像了后续只需要让jenkins将jar包文件传输到/root/jarfile目录下即可
# -v后面跟要映射的jar包文件
docker run -d -p 8888:8888 --name demo -v /root/jarfile/demo-1-1.0-SNAPSHOT.jar:/app.jar java:8 java -jar app.jar
# -v后面跟要映射的jar包文件
docker run -d -p 8888:8888 --name demo -v /root/jarfile/demo-1-1.0-SNAPSHOT.jar:/app.jar java:8 java -jar app.jar
2.修改jenkins远程连接服务器的ip地址及账户密码
3.修改jenkins构建前配置
4.修改jenkins构建后配置
5.访问测试
2.方式二: dockerfile
1.在项目中创建dockerfile编写dockerfile并提交到gitlab上
#引入jdk镜像
#FROM openjdk:11
FROM java:8
#对外开放的端口
EXPOSE 8888
#指定工作目录
WORKDIR /root
#相对WORKDIR的相对路径,完整路径是/root/jarfile/demo*.jar 将jar文件重命名并添加到/root/app.jar
ADD jarfile/demo*.jar /root/app.jar
#容器启动命令
ENTRYPOINT ["java","-jar","/root/app.jar"]
#引入jdk镜像
#FROM openjdk:11
FROM java:8
#对外开放的端口
EXPOSE 8888
#指定工作目录
WORKDIR /root
#相对WORKDIR的相对路径,完整路径是/root/jarfile/demo*.jar 将jar文件重命名并添加到/root/app.jar
ADD jarfile/demo*.jar /root/app.jar
#容器启动命令
ENTRYPOINT ["java","-jar","/root/app.jar"]
2.查看dockerfile在jenkins家目录哪个位置
-rw-r--r--. 1 root root 332 10月 2 19:30 dockerfile
[root@bogon docker]# pwd
# /root/.jenkins/workspace jenkins工作空间
# first目录对应构建任务名称
# demo-1目录对应工程名称
# docker目录对应我们创建的docker目录
/root/.jenkins/workspace/first/demo-1/docker
-rw-r--r--. 1 root root 332 10月 2 19:30 dockerfile
[root@bogon docker]# pwd
# /root/.jenkins/workspace jenkins工作空间
# first目录对应构建任务名称
# demo-1目录对应工程名称
# docker目录对应我们创建的docker目录
/root/.jenkins/workspace/first/demo-1/docker
3.jenkins构建任务,构建前配置
4.jenkins构建任务,构建后配置
docker build说明
# docker build 构建镜像
# demo是镜像名称
# .表示在当前目录下面寻找 dockerfile 文件
docker build -t demo .
# docker build 构建镜像
# demo是镜像名称
# .表示在当前目录下面寻找 dockerfile 文件
docker build -t demo .
注意docker build是区分上下文的
docker run说明
# --name:指定容器名称
# -p 5000:80 代表把容器里的80端口映射给宿主机的5000端口,映射只会5000端口是对外暴露的外部就可以通过该端口访问服务了
# demo 镜像名称
docker run -d --name demo -p 8888:8888 demo
# --name:指定容器名称
# -p 5000:80 代表把容器里的80端口映射给宿主机的5000端口,映射只会5000端口是对外暴露的外部就可以通过该端口访问服务了
# demo 镜像名称
docker run -d --name demo -p 8888:8888 demo
5.访问测试,192.168.79.105是我这里的docker私服地址
6.Jenkins集群/并发构建
1.需求说明
搭建一主两次的Jenkins集群。集群化构建可以有效提升构建效率,尤其是团队项目比较多或是子项目比较多的时候,可以并发在多台机器上执行构建。jenkins集群搭建只需要启动其中一台安装好jenkins服务的机器即可,其他的服务器包含基本的java环境即可。
2.实现步骤
1.添加jenkins-server02从节点
2.添加jenkins-server03同上
3.修改构建任务配置,使其支持并发构建。
3.构建测试
7.流水线 pipeline
流水线既能作为任务的本身,也能作为Jenkinsfile
使用流水线可以让我们的任务从ui手动操作,转换为代码化,像docker的dockerfile一样,从shell命令到配置文件,更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发Jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。
1.完整语法
5个必备的组成部分
pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步,可执行命令
pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步,可执行命令
2.测试脚本
1.基础框架
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
echo '拉取代码完成'
}
}
stage('执行构建') {
steps {
echo '执行构建完成'
}
}
}
post {
always {
echo "完成"
}
failure {
echo "失败"
}
}
}
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
echo '拉取代码完成'
}
}
stage('执行构建') {
steps {
echo '执行构建完成'
}
}
}
post {
always {
echo "完成"
}
failure {
echo "失败"
}
}
}
2.阶段视图 Stage View
3.blue ocean可视化界面
全新的流水线控制ui,可重复执行某阶段代码,在jenkins插件中心搜索blue ocean安装即可
4.post
流水线完成后可执行的任务
- always 无论流水线或者阶段的完成状态。
- changed 只有当流水线或者阶段完成状态与之前不同时。
- failure 只有当流水线或者阶段状态为"failure"运行。
- success 只有当流水线或者阶段状态为"success"运行。
- unstable 只有当流水线或者阶段状态为"unstable"运行。例如:测试失败。
- aborted 只有当流水线或者阶段状态为"aborted "运行。例如:手动取消。
5.agent
可以指定执行节点
label 指定运行job的节点标签
any 不指定,由Jenkins分配
pipeline {
agent {
node {
label "jenkins-02"
}
}
stages {
stage('拉取代码') {
steps {
sh """
sleep 10
"""
echo '拉取代码完成'
}
}
stage('执行构建') {
steps {
echo '执行构建完成'
}
}
}
post {
always {
echo "完成"
}
failure {
echo "失败"
}
}
}
pipeline {
agent {
node {
label "jenkins-02"
}
}
stages {
stage('拉取代码') {
steps {
sh """
sleep 10
"""
echo '拉取代码完成'
}
}
stage('执行构建') {
steps {
echo '执行构建完成'
}
}
}
post {
always {
echo "完成"
}
failure {
echo "失败"
}
}
}
3.pipeline中执行自动化构建
示例代码
pipeline {
agent any
//指定maven,对应的是Global Tool Configuration配置的maven名称
tools {
maven "mvn"
}
stages {
stage("拉取代码") {
steps {
echo '拉取成功'
}
}
stage("执行构建") {
steps {
echo '构建完成'
}
}
stage("clean test server"){
steps{
echo '清理jar包、停止docker容器、清理docker镜像'
}
}
stage("发送jar包到测试服务器") {
steps {
echo 'jar send over!'
}
}
}
}
pipeline {
agent any
//指定maven,对应的是Global Tool Configuration配置的maven名称
tools {
maven "mvn"
}
stages {
stage("拉取代码") {
steps {
echo '拉取成功'
}
}
stage("执行构建") {
steps {
echo '构建完成'
}
}
stage("clean test server"){
steps{
echo '清理jar包、停止docker容器、清理docker镜像'
}
}
stage("发送jar包到测试服务器") {
steps {
echo 'jar send over!'
}
}
}
}
声明式流水线
好处
- 更像是在Jenkins web ui中的操作
- 可读性比较高
- 可以使用blue ocean自动生成
- 支持语法检查
坏处
- 代码逻辑能力比脚本式弱,不能完成特别复杂的任务
脚本式流水线
好处
- 更少的代码和弱规范要求
- 更灵活的自定义代码操作
- 不受约束,可以构建特别复杂的工作流和流水线
坏处
- 读写对编程要求比较高
- 比声明式流水线代码更复杂
4.需求说明
在单机jenkins环境下创建一个pipeline构建任务,让jenkins从gitlab拉取的项目代码打包,并将打好的jar包发送到目标服务器并完成docker镜像的构建及容器启动。
5.实现步骤
1.创建一个Pipeline构建任务
2.编写脚本代码
3.生成拉取gitlab代码
stage("拉取代码") {
steps {
git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.79.102/root/jekins-test.git'
echo '拉取成功'
}
}
stage("拉取代码") {
steps {
git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.79.102/root/jekins-test.git'
echo '拉取成功'
}
}
4.执行构建
stage("执行构建") {
steps {
sh """
//当前目录在llppipeline目录,我们需要进入到demo-1工程目录中执行maven打包指令
cd demo-1
mvn clean package
"""
echo '构建完成'
}
}
stage("执行构建") {
steps {
sh """
//当前目录在llppipeline目录,我们需要进入到demo-1工程目录中执行maven打包指令
cd demo-1
mvn clean package
"""
echo '构建完成'
}
}
5.clean test server,清理远程服务器jar包、停止docker容器删除docker镜像
6.发送jar包到测试服务器并运行容器
7.完整代码
pipeline {
agent any
//指定maven,对应的是Global Tool Configuration配置的maven名称
tools {
maven "mvn"
}
stages {
stage("拉取代码") {
steps {
git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.79.102/root/jekins-test.git'
echo '拉取成功'
}
}
stage("执行构建") {
steps {
//当前目录在llppipeline目录,我们需要进入到demo-1工程目录中执行maven打包指令
sh """
cd demo-1
mvn clean package
"""
echo '构建完成'
}
}
stage("clean test server"){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf /root/jarfile
docker stop demo
docker rm demo
docker rmi demo''', execTimeout: 500000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '/root')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '清理jar包、停止docker容器、清理docker镜像'
}
}
stage("发送jar包到测试服务器并运行容器") {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker build -t demo .
docker run -d --name demo -p 8888:8888 demo''', execTimeout: 500000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/jarfile', remoteDirectorySDF: false, removePrefix: 'demo-1/target', sourceFiles: '**/demo*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo 'jar send over!'
}
}
}
}
pipeline {
agent any
//指定maven,对应的是Global Tool Configuration配置的maven名称
tools {
maven "mvn"
}
stages {
stage("拉取代码") {
steps {
git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.79.102/root/jekins-test.git'
echo '拉取成功'
}
}
stage("执行构建") {
steps {
//当前目录在llppipeline目录,我们需要进入到demo-1工程目录中执行maven打包指令
sh """
cd demo-1
mvn clean package
"""
echo '构建完成'
}
}
stage("clean test server"){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf /root/jarfile
docker stop demo
docker rm demo
docker rmi demo''', execTimeout: 500000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '/root')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo '清理jar包、停止docker容器、清理docker镜像'
}
}
stage("发送jar包到测试服务器并运行容器") {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker build -t demo .
docker run -d --name demo -p 8888:8888 demo''', execTimeout: 500000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/jarfile', remoteDirectorySDF: false, removePrefix: 'demo-1/target', sourceFiles: '**/demo*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo 'jar send over!'
}
}
}
}
6.构建测试
7.Blue Ocean插件
8.Jenkinsfile创建多分支job
如果安装了Blue Ocean插件可以直接通过该插件进行创建
创建完成之后还需要指定Jenkinsfile所在目录
在main分支和其他分支上都创建Jenkinsfile
创建多分支流水线成功后在主界面可以看到·
根分支创建了构建任务,再次进一步配置就可以实现各个分支自动化部署了