Jenkins是什么?

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。

CI/CD是什么?

CI(Continuous integration,中文意思是持续集成)是一种软件开发时间。持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。借用网络图片对CI加以理解。
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a6ec3fdcc.png" />
CD(Continuous Delivery, 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。下图反应的是CI/CD 的大概工作模式。
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a6f001677.png" />

Jenkins安装及配置

  1. JDK配置
    配置构建项目需要JDK,在Linux系统下安装好JDK后,在Jenkins的配置相关的安装路径:
    ![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a779d2ea5.png" />
  2. Maven配置
    ![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a787caeb7.png" />
  3. Ant配置
    ![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a78ecb195.png" />
  1. Ant 项目构建
    ![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7c5cc0f6.png" />

填写描述
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7e526664.png" />
源码管理输和SVN地址,账号和密码:
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7ea14e34.png" />

构建环境选择“Invoke Ant”
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7eedaa9d.png" />
设置ant构建文件
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7f32e43f.png" />
构建后选择“Send build artifacts over FTP”
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a7ff8f204.png" />
文件复制参数设置如下:
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a804a75a7.png" />
项目保存后,点“立即构建”开始项目的构建:
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a80b4393c.png" />

项目构建完成,可以在目标的FTP目录找到构建后的文件:
![img](http://showdoc.gzlplink.com/Public/Uploads/2020-08-12/5f33a8105dfb5.png" />

jenkins通过ssh启动服务失败

查看tomcat启动日志发现报错:war包拒绝访问

因jenkins配置的ssh对应的windows账号不是administrator会出现没权限问题

方案1.更改jenkins的ssh用户为administrator

方案2.给需要权限的文件夹或文件授权

1
2
3
4
5
6
windows命令给用户授权
cacls E:\tomcat /t /e /c /r nmk 拒绝
Cacls E:\tomcat /t /e /c /g nmk:F 允许

多用户情况下可以给everyone
Cacls E:\SFTP\sftp\nmk.war /t /e /c /g everyone:F

自动部署脚本

windows自动部署war包脚本
1
2
3
4
5
6
7
for /f "tokens=5" %%e in ('netstat -aon ^| findstr ":9021"') do (set f=%%e)
taskkill /t /f /pid %f%

rd /s /q "E:\tomcat-9021\webapps\cmpay"
del "E:\tomcat-9021\webapps\cmpay.war"
move cmpay.war "E:\tomcat-9021\webapps\"
net start tomcat9021

因windows启动tomcat会被jenkins杀掉,所以要把tomcat做成服务

windows自动部署jar包脚本
1
2
3
4
5
6
for /f "tokens=5" %%i in ('netstat -aon ^| findstr ":8081"') do (set j=%%i)
taskkill /t /f /pid %j%

del E:\gzlp_red_package\lepeng-red-package-coupon.jar
move lepeng-red-package-coupon-1.0-SNAPSHOT.jar "E:\gzlp_red_package\lepeng-red-package-coupon.jar"
javaw -Xms256m -Xmx512m -jar "E:\gzlp_red_package\lepeng-red-package-coupon.jar" --spring.profiles.active=dev
linux自动部署war包脚本

jenkins配置

1
sh /home/tomcat/upload/omall.sh

omall.sh脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#Java Env
export JAVA_HOME=/usr/java
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

port=19181
#根据端口号查询对应的pid
pid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{ print $1 }');

#杀掉对应的进程,如果pid不存在,则不执行
if [ -n "$pid" ]; then
kill -9 $pid;
fi

rm -rf /home/tomcat/omall/webapps/omall.war
rm -rf /home/tomcat/omall/webapps/omall
mv /home/tomcat/upload/omall.war /home/tomcat/omall/webapps
cd /home/tomcat/omall/bin
./startup.sh
linux自动部署jar包脚本

jenkins配置

1
2
cd /home/tomcat/app/admin-core
nohup sh /home/tomcat/upload/admin-core.sh >> catalina.out 2>&1

admin-core.sh脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#Java Env
export JAVA_HOME=/usr/java
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

port=48094
#根据端口号查询对应的pid
pid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{ print $1 }');

#杀掉对应的进程,如果pid不存在,则不执行
if [ -n "$pid" ]; then
kill -9 $pid;
fi

rm -r /home/tomcat/app/admin-core/admin-core-0.0.1-SNAPSHOT.jar
mv /home/tomcat/upload/admin-core-0.0.1-SNAPSHOT.jar /home/tomcat/app/admin-core
cd /home/tomcat/app/admin-core
java -Xms256m -Xmx512m -jar /home/tomcat/app/admin-core/admin-core-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev &
k8s自动部署后端脚本

执行shell

1
2
3
cd admin-core
chmod +x ./build.sh
./build.sh prod $BUILD_NUMBER

gitlab配置

build.sh

1
2
3
4
5
6
7
#!/bin/bash
#构建有版本号的镜像,以防需要回滚,而且是从镜像创建服务
docker build -t registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/admin-core-$1:$2 . -f Dockerfile_$1
docker push registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/admin-core-$1:$2
#构建latest版本,用于自动部署
docker build -t registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/admin-core-$1:latest . -f Dockerfile_$1
docker push registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/admin-core-$1:latest

start.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

JARFILE=/home/App.jar
LOGPATH=/home/logs
LOG=/home/logs/App.log

#日志挂载
ip=`ip addr |grep inet |grep eth0|awk '{print $2}' |awk -F "/" '{print $1}'`
mkdir -p /home/log/gzlp_equity/$ip
cd /var/log
ln -s /home/log/gzlp_equity/$ip java

if [ ! -d $LOGPATH ];then
mkdir -p $LOGPATH
fi

java -jar -Xms512m -Xmx1024m -Dskywalking.agent.namespace=prod -Dskywalking.agent.service_name=prod-admin-core -javaagent:/home/skywalking-agent-plugins/agent-prod-bj/skywalking-agent.jar $JARFILE -Djava.security.egd=file:/dev/./urandom --spring.profiles.active=$ACTIVE >> $LOG &

tail -100f $LOG

Dockerfile_prod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM   registry-vpc.cn-beijing.aliyuncs.com/lepeng/centos:latest
MAINTAINER nmk

COPY target/admin-core-0.0.1-SNAPSHOT.jar /home/App.jar
COPY start.sh /home/start.sh
RUN mkdir /home/tomcat/
RUN chmod +x /home/start.sh
ENV JAVA_HOME=/usr/local/java
ENV PATH $JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV LC_ALL="en_US.UTF-8"
ENV LANG="en_US.UTF-8"
ENV ACTIVE=prod

EXPOSE 48094
CMD ["/home/start.sh"]
k8s自动部署前端脚本

执行shell

1
2
3
4
5
6
cd ..
tar zcvf mps-admin-ui.tar mps-admin-ui_tdev
mv mps-admin-ui.tar mps-admin-ui_tdev/docker/
cd mps-admin-ui_tdev/docker/
chmod +x ./build.sh
./build.sh test $BUILD_NUMBER

gitlab配置

Dockerfile_test

1
2
3
4
5
6
7
8
9
10
11
12
FROM   registry-vpc.cn-beijing.aliyuncs.com/lepeng/nginx:latest
MAINTAINER nmk

COPY mps-admin-ui.tar /home/mps-admin-ui.tar
RUN mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.default
RUN tar zxvf /home/mps-admin-ui.tar -C /home/
RUN mv /home/mps-admin-ui_tdev/docker/nginx.conf /usr/local/nginx/conf/nginx.conf
COPY start.sh /home/start.sh
RUN chmod +x /home/start.sh

EXPOSE 80
CMD ["/home/start.sh"]

build.sh

1
2
3
4
5
6
7
#!/bin/bash
#构建有版本号的镜像,以防需要回滚,而且是从镜像创建服务
docker build -t registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/mps-admin-ui-$1:$2 . -f Dockerfile_$1
docker push registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/mps-admin-ui-$1:$2
#构建latest版本,用于自动部署
docker build -t registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/mps-admin-ui-$1:latest . -f Dockerfile_$1
docker push registry-vpc.cn-beijing.aliyuncs.com/lepeng-$1/mps-admin-ui-$1:latest

start.sh

1
2
3
4
5
6
7
#!/bin/bash
mv /home/mps-admin-ui_tdev /home/mps-admin-ui
cd /usr/local/nginx
./sbin/nginx
./sbin/nginx -t
echo "nginx Start successfully" >> nginx.log
tail -10f nginx.log

nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
user nginx nginx;
worker_processes 8;
error_log logs/error_log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events {
use epoll;
worker_connections 51200;
}

http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 512;
client_header_buffer_size 512k;
large_client_header_buffers 4 256k;
client_max_body_size 100m;
client_body_buffer_size 10m;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
server_tokens off;
sendfile on;
#tcp_nopush on;
keepalive_timeout 120;
tcp_nodelay on;
proxy_buffering on;
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间。一般设置1和2
gzip_comp_level 2;
gzip_buffers 4 8k;
gzip_http_version 1.1;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
#设置缓存路径并且使用一块最大100M的共享内存,用于硬盘上的文件索引,包括文件名和请求次数,每个文件在1天内若不活跃(无请求)则从硬盘上淘汰,硬盘缓存最大10G,满了则根据LRU算法自动清除缓存。
proxy_connect_timeout 10;
proxy_read_timeout 180;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 96k;
proxy_temp_file_write_size 96k;
proxy_temp_path /tmp/temp_dir;
#proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;
log_format main '[$remote_addr] - [$remote_user] [$time_local] [$request] [$status] [$body_bytes_sent] [$http_referer] [$http_user_agent] [$http_x_forwarded_for] [$request_time] [$upstream_response_time] [$upstream_addr] [$upstream_status]';
server {
listen 80;
server_name tdev.gzlplink.com;
add_header backendIP $upstream_addr; #把后端具体的 upstream 返回给前端 header
add_header backendCode $upstream_status;
include proxy.conf;
access_log /data1/logs/nginx/tdev.gzlplink.com-access_log main;
error_log /data1/logs/nginx/tdev.gzlplink.com-error_log;

location /mps-admin-ui {
root /home/;
index index.html index.htm;
if ( -d $request_filename ){
rewrite ^/(.*)([^/])$ $scheme://$host/$1$2/ permanent;
}
log_not_found off;
# 关闭日志
access_log off;
# 缓存时间7天
expires 7d;
# 指定上面设置的缓存区域
#proxy_cache imgcache;
# 缓存过期管理
proxy_cache_valid 200 302 1d;
proxy_cache_valid 404 10m;
proxy_cache_valid any 1h;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
}
}
}
通过jenkins更新生产的nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@iZ2ze18q1ojbig8zevjrbuZ nginx]# cat nginx_reload 
#/bin/bash
check_status="`/usr/local/nginx/sbin/nginx -t 2>&1`"

if [ $? -eq 0 ]; then
#echo "nginx configure file ok"
echo $check_status
/usr/local/nginx/sbin/nginx -s reload
else
#echo "nginx configure file failed"
echo $check_stutus
exit
fi