1.jenkins执行shell命令或脚本实现以非交互方式clone gitlab代码
# 生成密钥对 jenkins 172.18.10.182
root@ubuntu-virtual-machine:/data/scripts# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:xtykluv6C9L6LU+LILzSzt3JFzLV0lvAKiuUfAcG094 root@ubuntu-virtual-machine
The key's randomart image is:
+---[RSA 3072]----+
| oo . |
| .+ o |
| . + o +.. |
| + +oE=o . |
| . . =S..o |
| . ..+o... |
| .o o.ooo. |
|...+ *.B.. |
| o+ o.B*B. |
+----[SHA256]-----+
# 私钥在jenkins服务器上,公钥放到gitlab上
root@ubuntu-virtual-machine:/data/scripts# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRFsoyBLRSaAr7U2yIxghrvd8cKpKluyGxmRSfjT/+mw5JekttprV3JCSzovYvs2nCIYCyz/kUdkPDTTKJvYjjwkJgH7l2IRX3EaD++IihmxmlsCJyMPJR6XLKPMChQl21JgkMofYXBiiJ4ooe6ttC0LQ8kQANCfdynOWkweo5kP5VkCtTP5vJLeddeYZ2FTw0HwHu/XaQhaeGZIahfKMwIfq9B52CV9AazmLR3ULvfCwtWA0rBMaao4jVFxkghFtIzwACSxLDhlEnKGGJEFH+hSfR7R1XHnCRRFZWhDcOfyNQ6qYzm99PeFAlcrNrsil0wd2n8bdZoZDxgjw974ZSM9RInTpPXEbhMlMQ8QMLmzr7Jnt9OGLgJ8eZglTASt9DHzuDu7BYtxAbYK1SBBQK82Vz6XwQSYimuwULYU2Plmn3D+3Wd1sB2m2QjH+G4meLv7beH69CdkvXu1Lh0B5ynTjaTtrKg5wt0pRI4Nq/rIWhQoeblkJq59DLbkKcITc= root@ubuntu-virtual-machine
# 配置gitlab ssh key
偏好设置-ssh秘钥-新建添加秘钥
# 克隆项目
# 克隆代码脚本
root@ubuntu-virtual-machine:/data/scripts# cat test.sh
#!/bin/bash
rm -rf /data/scripts/gitlab/order
cd /data/scripts/gitlab/
git clone git@172.18.10.181:magedu/order.git
# kenkins中配置自动拉取gitlab代码
添加jebkins服务器用户私钥
配置shell
执行构建
2.实现代码手动clone并制作镜像实 现nginx容器环境的frontend前端代码更新
# clone代码,jenkins 172.18.10.182上操作
root@ubuntu-virtual-machine:/data/scripts/gitlab# rm -rf order
root@ubuntu-virtual-machine:/data/scripts/gitlab# git clone git@172.18.10.181:magedu/order.git
root@ubuntu-virtual-machine:/data/scripts/gitlab# cd order/
# 代码打包,排除gitlat相关配置文件
root@ubuntu-virtual-machine:/data/scripts/gitlab/order# tar -zcvf frontend.tar.gz --exclude=.git --exclude=.gitignore --exclude=README.md ./
# 免秘钥登录
root@ubuntu-virtual-machine:/data/scripts/gitlab/order# ssh-copy-id 172.18.10.130
# 打包好的文件拷贝到docker主机上 172.18.10.130
root@ubuntu-virtual-machine:/data/scripts/gitlab/order# scp frontend.tar.gz root@172.18.10.130:/opt/ubuntu-dockerfile/
# 制作镜像并上传到镜像仓库
[root@k8s-harbor ubuntu-dockerfile]# ll
总用量 1108
-rw-rw-rw- 1 root root 293 12月 17 21:35 build-command.sh
-rw-rw-rw- 1 root root 884 12月 17 21:35 Dockerfile
-rw-r--r-- 1 root root 38717 12月 20 05:41 frontend.tar.gz
-rw-rw-rw- 1 root root 1073322 12月 17 21:36 nginx-1.22.0.tar.gz
-rw-rw-rw- 1 root root 2812 12月 17 21:35 nginx.conf
-rw-rw-rw- 1 root root 1139 12月 17 21:35 sources.list
[root@k8s-harbor ubuntu-dockerfile]# cat Dockerfile
FROM ubuntu:22.04
MAINTAINER "xingwei@qq.com"
ADD sources.list /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make
ADD nginx-1.22.0.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.22.0 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin
RUN groupadd -g 2088 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2088 nginx && chown -R nginx.nginx /apps/nginx
ADD nginx.conf /apps/nginx/conf/
ADD frontend.tar.gz /apps/nginx/html/
EXPOSE 80 443
#ENTRYPOINT ["nginx"]
CMD ["nginx","-g","daemon off;"]
[root@k8s-harbor ubuntu-dockerfile]# cat build-command.sh
#!/bin/bash
docker build -t harbor.linuxarchitect.io/myserver/nginx:v1 .
docker push harbor.linuxarchitect.io/myserver/nginx:v1
[root@k8s-harbor ubuntu-dockerfile]# sh build-command.sh
# 启动容器
[root@k8s-harbor ubuntu-dockerfile]# docker run -it --rm -p 8888:80 harbor.linuxarchitect.io/myserver/nginx:v1
# 页面访问测试 http://172.18.10.130:8888/
3.掌握jenkins的参数传递配置及使用
添加字符参数
输出参数
传参执行构建
选项参数使用:添加选项参数
执行脚本时传入参数
构建job时选择参数
4.实现代码自动clone并制作镜像实现nginx容器环境的frontend前端代码更新;
# 自动更新脚本
root@ubuntu-virtual-machine:/data/scripts# cat magedu-app1-deploy.sh
#!/bin/bash
#Version: v1
#记录脚本开始执行时间
starttime=`date +'%Y-%m-%d %H:%M:%S'`
#变量
SHELL_DIR="/data/scripts"
SHELL_NAME="$0"
IMAGE_BUILD_NODE="172.18.10.130"
DOCKER_NODE="172.18.10.130"
DATE=`date +%Y-%m-%d_%H_%M_%S`
METHOD=$1
BRANCH=$2
if test -z $BRANCH;then
BRANCH=develop
fi
function Code_Clone(){
Git_URL="git@172.18.10.181:magedu/order.git"
DIR_NAME=`echo ${Git_URL} |awk -F "/" '{print $2}' | awk -F "." '{print $1}'`
DATA_DIR="/data/gitdata/magedu"
Git_Dir="${DATA_DIR}/${DIR_NAME}"
cd ${DATA_DIR} && echo "即将清空上一版本代码并获取当前分支最新代码" && sleep 1 && rm -rf ${DIR_NAME}
echo "即将开始从分支${BRANCH} 获取代码" && sleep 1
git clone -b ${BRANCH} ${Git_URL}
echo "分支${BRANCH} 克隆完成,即将进行代码编译!" && sleep 1
#cd ${Git_Dir} && mvn clean package
#echo "代码编译完成,即将开始将IP地址等信息替换为测试环境"
#####################################################
sleep 1
cd ${Git_Dir}
GIT_TAG=`git reflog | head -n 1 | awk '{print $1}'`
tar czvf frontend.tar.gz --exclude=.git --exclude=.gitignore --exclude=README.md ./
}
#将打包好的压缩文件拷贝到k8s 控制端服务器
function Copy_File(){
echo "压缩文件打包完成,即将拷贝到k8s 控制端服务器${IMAGE_BUILD_NODE}" && sleep 1
scp ${Git_Dir}/frontend.tar.gz root@${IMAGE_BUILD_NODE}:/opt/ubuntu-dockerfile/
echo "压缩文件拷贝完成,服务器${IMAGE_BUILD_NODE}即将开始制作Docker 镜像!" && sleep 1
}
#到控制端执行脚本制作并上传镜像
function Make_Image(){
echo "开始制作Docker镜像并上传到Harbor服务器" && sleep 1
ssh root@${IMAGE_BUILD_NODE} "cd /opt/ubuntu-dockerfile && bash build-command.sh ${DATE}-${GIT_TAG}"
IMAGE_NAME="harbor.magedu.net/myserver/nginx:${DATE}-${GIT_TAG}"
echo "Docker镜像制作完成并已经上传到harbor服务器" && sleep 1
}
#到控制端更新docker-compose yaml文件中的镜像版本号,从而保持yaml文件中的镜像版本号和镜像仓库中的镜像版本号保持一致
function Update_docker-compose_yaml(){
echo "即将更新docker-compose yaml文件中镜像版本" && sleep 1
ssh root@${DOCKER_NODE} "cd /data/magedu-app1 && sed -i 's/image: harbor.magedu.net\/myserver\/nginx:.*/image\: harbor\.magedu\.net\/myserver\/nginx\:${DATE}\-${GIT_TAG}/g' docker-compose.yml"
echo "docker-compose yaml文件镜像版本更新完成,即将开始更新容器中镜像版本" && sleep 1
}
#到控制端更新docker-compose中容器的版本号
function Update_docker_container(){
ssh root@${DOCKER_NODE} "cd /data/magedu-app1 && docker-compose pull && docker-compose up -d"
echo "容器镜像更新完成" && sleep 1
echo "当前业务镜像版本: harbor.magedu.net/myserver/nginx:${DATE}-${GIT_TAG}"
#计算脚本累计执行时间,如果不需要的话可以去掉下面四行
endtime=`date +'%Y-%m-%d %H:%M:%S'`
start_seconds=$(date --date="$starttime" +%s);
end_seconds=$(date --date="$endtime" +%s);
echo "本次业务镜像更新总计耗时:"$((end_seconds-start_seconds))"s"
}
#回滚到上一个版本
function rollback_last_version(){
Git_URL="git@172.31.5.101:magedu/app1.git"
DIR_NAME=`echo ${Git_URL} |awk -F "/" '{print $2}' | awk -F "." '{print $1}'`
DATA_DIR="/data/gitdata/magedu"
Git_Dir="${DATA_DIR}/${DIR_NAME}"
echo "即将回滚到上一个版本"
cd ${Git_Dir}
git reset --hard HEAD^
GIT_TAG=`git reflog | head -n 1 | awk '{print $1}'`
tar czvf frontend.tar.gz --exclude=.git --exclude=.gitignore --exclude=README.md ./
}
#使用帮助
usage(){
echo "部署使用方法为 ${SHELL_DIR}/${SHELL_NAME} deploy "
echo "回滚到上一版本使用方法为 ${SHELL_DIR}/${SHELL_NAME} rollback_last_version"
}
#主函数
main(){
case ${METHOD} in
deploy)
Code_Clone;
Copy_File;
Make_Image;
Update_docker-compose_yaml;
Update_docker_container;
;;
rollback_last_version)
rollback_last_version;
Copy_File;
Make_Image;
Update_docker-compose_yaml;
Update_docker_container;
;;
*)
usage;
esac;
}
main $1 $2
[root@k8s-harbor magedu-app1]# cat docker-compose.yml
version: '3.8'
services:
nginx-server:
#image: nginx:1.22.0-alpine
image: harbor.linuxarchitect.io/myserver/nginx:v1
container_name: nginx-web1
# network_mode: bridge #网络1,使用docker安装后的默认网桥
expose:
- 80
- 443
ports:
- "8088:80"
- "8443:443"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有两块网卡
- front
- backend
links:
- tomcat-server
tomcat-server:
#image: tomcat:7.0.93-alpine
image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/tomcat-myapp:v1
container_name: tomcat-app1
##network_mode: bridge #网络1,使用docker安装后的默认网桥
#expose:
# - 8080
#ports:
# - "8080:8080"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有一块网卡
- backend
links:
- mysql-server
mysql-server:
image: mysql:5.6.48
container_name: mysql-container
# network_mode: bridge #网络1,使用docker安装后的默认网桥
volumes:
- /data/mysql:/var/lib/mysql
#- /etc/mysql/conf/my.cnf:/etc/my.cnf:ro
environment:
- "MYSQL_ROOT_PASSWORD=12345678"
- "TZ=Asia/Shanghai"
expose:
- 3306
ports:
- "3306:3306"
networks: #网络2,使用自定义的网络,如果网络不存在则会自动创建该网络并分配子网,并且容器会有一块网卡
- backend
networks:
front: #自定义前端服务网络,需要docker-compose创建
driver: bridge
backend: #自定义后端服务的网络,要docker-compose创建
driver: bridge
default: #使用已经存在的docker0默认172.17.0.1/16的网络
external:
name: bridge
创建job:
执行job任务:
访问测试:
5.配置Prometheus监控jenkins指标
安装插件:Prometheus metrics 、CloudBees Disk Usage Simple
系统管理–>系统设置–>Prometheus
# 修改prometheus配置
root@redis-1:~# vim /apps/prometheus/prometheus/prometheus.yml
- job_name: "jenkins-metrics"
metrics_path: /prometheus
static_configs:
- targets: ['172.18.10.182:8080']
root@redis-1:~# systemctl restart prometheus
验证grafana图形,导入模版9964
6.掌握jenkins分布式的使用并基于pipeline指定slave节点执行job
# jenkins slave节点创建工作目录与基本环境配置,如果jenkins slave节点需要clone代码和执行java 代码编译,则jenkins slave节点也需要配置java环境并且安装git、svn、maven等与master相同的基础运行环境,另外也要创建与master相同的数据目录,方便后期目录切换与制品同步,此路径通常与master和各node节点保持一致。
# 安装jenkins slave
root@ubuntu-virtual-machine:~# mkdir -p /var/lib/jenkins
root@ubuntu-virtual-machine:~# apt install openjdk-17-jdk
root@ubuntu-virtual-machine:~# cd /apps/
root@ubuntu-virtual-machine:/apps# ls
jenkins_2.414.3_all.deb
root@ubuntu-virtual-machine:/apps# dpkg -i jenkins_2.414.3_all.deb
root@ubuntu-virtual-machine:/apps# systemctl stop jenkins
root@ubuntu-virtual-machine:/apps# vim /etc/default/jenkins
JENKINS_USER=root
JENKINS_GROUP=root
root@ubuntu-virtual-machine:/apps# vim /lib/systemd/system/jenkins.service
User=root
Group=root
JAVA_ARGS="-Djava.awt.headless=true -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true" #关闭跨站请求伪造保护(CSRF)保护
root@ubuntu-virtual-machine:/apps# systemctl daemon-reload && systemctl restart jenkins.service
# http://172.18.10.183:8080/login?from=%2F
添加slave节点:Jenkins—系统管理—节点管理—新建节点
创建流水线任务在slave节点上运行,创建测试脚本式pipline运行测试
7.掌握pipline的基本使用
流水线的优势:
1.可持续性:jenkins的重启或者中断后不影响已经执行的Pipline Job
2.支持暂停:pipline可以选择停止并等待人工输入或批准后再继续执行。
3.可扩展性:通过groovy的编程更容易的扩展插件。
4.并行执行:通过groovy脚本可以实现stage(阶段)、step(步骤)之间的并行执行,提高构建效率缩短部署时间。
流水线的分类及对比:
pipline流水线分为脚本式流水线与声明式流水线
1.语法差异,声明式的在pipline {}块中定义,而脚本式则直接以node开始
2.脚本式的在一台节点执行所有操作,而声明式可以将不同的节点定义到不同的节点执行。
3.声明式比脚本式的写法更复杂,但功能更强大
4.目前主要使用声明式较多
// 1、定义执行的jenkins节点
pipeline {
agent any // agent定义jenkins节点,any可以再任何可用节点执行,none标识没有定义默认的jenkins节点,需要在后续的没一个stage中单独定义
//agent { label 'jenkins-node1' } //基于label指定具体执行的步骤节点,非必须
}
// 2、node和label指定节点的区别:node:和 label 的功能类似都是用于指定节点,区别是node可以额外设置一些参数配置,比如设置customWorkspace(设置当前stage的自定义工作目录),比如在节点和云管理-master-设置中 给master指定label为jenkins-master
pipeline {
agent none
stages {
stage('代码clone'){
agent {
node {
label 'master'
customWorkspace "/data/gitdata/magedu"
}
}
steps {
sh "echo 代码clone"
}
}
stage('代码部署'){
agent {
node {
label 'jenkins-node1'
customWorkspace "/data/gitdata/magedu"
}
}
steps {
sh "echo 代码部署"
}
}
}
}
//3、Input 指令可以在流水线中实现必要的交互式操作,比如选择要部署的环境、是否向后继续执行任务等。
/* input配置简介:
message:必选,在input界面的提示信息,比如:“是否继续?”等,内容可自定义。
id:可选,input 的标识符,默认为 stage 的名称。
ok:可选,确认按钮的显示信息,比如可以是“确定”、“允许”等 自定义内容,默认继续为Proceed 、取消为 Abort。
submitter:可选,指定允许提交 input 操作的用户或组的名称,如果为空(任何登录用户均具有提交 input的权限)
parameters:提供一个参数列表供 input 使用。
*/
pipeline {
agent { label 'jenkins-node1' }
stages {
stage('交互测试') {
input {
message "是否继续部署?"
ok "继续部署"
submitter "jenkinsadmin"
}
steps {
echo "Hello jenkins!"
}
}
}
}
// Jenkins通知机制,明式Pipeline中使用post。post一般用于pipline流水线执行后的进一步处理,比如错误通知等,post可以针对流水线不同的执行结果做出不同的处理,比如执行成功做什么处理、执行失败做什么处理等。
/*
always:无论Pipeline或stage的最后是执行成功还是失败,都执行post中定义的指令。
changed:只有当前Pipeline或stage的完成状态与它之前的运行不同时,比如从成功转换为失败、或从失败转换为成功,才执行post中定义的指令。
fixed:当本次Pipeline或stage成功,且上一次构建是失败或不稳定时,就执行post中定义的指令,从失败转换为成功。
regression:当本次Pipeline或stage的状态为失败、不稳定或终止,且上一次构建的状态为成功时,就执行post中定义的指令,从成功转换为失败。
failure:只有当前Pipeline或stage的完成状态为失败(failure),才允许在post部分运行该步骤,而且通常这时在Web界面中显示为红色。
success:当前执行状态为成功(success),执行post步骤,通常在Web界面中显示为蓝色或绿色。
unstable:当前状态为不稳定(unstable),执行post步骤,通常原因是由于测试失败或代码违规等造成,而且会在Web界面中显示为黄色。
aborted:当前状态为终止(aborted),执行该post步骤,通常由于流水线被手动终止触发,这时在在Web界面中显示为灰色。
unsuccessful:当前状态只要不是success时,执行该post步骤;
cleanup:无论pipeline或stage的完成状态如何,都允许运行该post中定义的指令,和always的区别在于cleanup会在post其它条件执行之后执行(最后执
行cleanup)。
*/
// post发送邮件通知示例:
pipeline {
agent any
stages {
stage('post测试-代码clone阶段') {
steps {
sh 'echo git clone'
sh 'cd /data/xxx' //此步骤会执行失败,用于验证构建失败的邮件通知
}
post {
cleanup {
echo "post cleanup-->测试是否执行"
}
always {
echo "post always"
}
aborted {
echo "post aborted"
}
success {
script {
mail to: '2521277651@qq.com',
subject: "Pipeline Name: ${currentBuild.fullDisplayName}",
body: " ${env.JOB_NAME} -Build Number-${env.BUILD_NUMBER} - 构建成功!\n 点击链接 ${env.BUILD_URL} 查看详情"
}
}
failure {
script {
mail to: '2521277651@qq.com',
subject: "Pipeline Name: ${currentBuild.fullDisplayName}",
body: " ${env.JOB_NAME} -Build Number-${env.BUILD_NUMBER} - 构建失败!\n 点击链接 ${env.BUILD_URL} 查看详情"
}
}
}
}
}
}
//声明式Pipline快速入门
//pipline环境变量,基于environment传递环境变量
pipeline {
agent any
environment { //全局的变量,在当前pipline所有的stage中都会生效
NAME='user1'
PASSWD='123456'
}
stages {
stage('环境变量stage1') {
environment { //定义在stage中的变量只会在当前stage生效,其他的stage不会生效
GIT_SERVER = 'git@172.31.5.101:magedu/app1.git'
}
steps {
sh """
echo '$NAME'
echo '$PASSWD'
echo '$GIT_SERVER'
"""
}
}
stage('环境变量stage2') {
steps {
sh """
echo '$NAME'
echo '$PASSWD'
"""
}
}
}
}
// pipline参数
/*
parameters简介:
string: #字符串类型参数,可以传递账户名、密码等参数
text: #文本型参数,一般用于定义多行文本内容的变量。
booleanParam:#布尔型参数
choice:#选择型参数,一般用于给定几个可选的值,然后选择其中一个进行赋值使用
password: #密码型变量,一般用于定义敏感型变量,在 Jenkins 控制台会输出为*隐藏密码
*/
//pipline参数示例
pipeline {
agent any
parameters {
string(name: 'BRANCH', defaultValue: 'develop', description: '分支选择') //字符串参数,会配置在jenkins的参数化构建过程中
choice(name: 'DEPLOY_ENV', choices: ['develop', 'production'
], description: '部署环境选择') //选项参数,会配置在jenkins的参数化构建过程中
}
stages {
stage('测试参数1') {
steps {
sh "echo $BRANCH"
}
}
stage('测试参数2') {
steps {
sh "echo $DEPLOY_ENV"
}
}
}
}
//pipline if指令
pipeline {
agent any
environment {
//代码仓库变量
def BRANCH_NAME = 'main'
}
stages {
stage('if指令测试') {
steps {
script {
if (env.BRANCH_NAME == 'main') {
echo '我是master'
} else if (env.BRANCH_NAME == 'develop'){
echo '我是develop'
} else {
echo '我是默认的'
}
}
}
}
}
}
//options选项配置参数简介
/*
buildDiscarder(logRotator(numToKeepStr: '5')) //保留5个历史构建版本
timeout(time: 5, unit: 'MINUTES') //定义任务执行超时时间1小时,如果不加unit参数默认时间单位为分钟,支持NANOSECONDS,
MICROSECONDS,MILLISECONDS,SECONDS,MINUTES,HOURS,DAYS
timestamps() //在控制台显示命令执行的时间,格式为10:58:39
retry(2) //流水线构建失败后重试次数为2次
*/
pipeline {
agent any
environment { //全局的变量,在当前pipline所有的stage中都会生效
NAME='user1'
PASSWD='123456'
}
options { //定义pipline参数
buildDiscarder(logRotator(numToKeepStr: '5')) //保留5个历史构建版本
timeout(time: 5, unit: 'MINUTES') //定义任务执行超时时间1小时,如果不加unit参数默认时间单位为分钟,支持NANOSECONDS,MICROSECONDS,MILLISECONDS,SECONDS,MINUTES,HOURS,DAYS
timestamps() //在控制台日志命令前显示命令的执行时间,格式为10:58:39
retry(2) //流水线构建失败后重试次数为2次
}
stages {
stage('代码clone') {
environment { //定义在stage中的变量只会在当前stage生效,其他的stage不会生效
GIT_SERVER = 'git@172.18.10.181:magedu/order.git'
}
steps {
sh """
echo '代码clone'
"""
}
}
}
}
8.部署postgresql及sonarqube
# postgresql部署
root@ubuntu-virtual-machine:~# apt update
root@ubuntu-virtual-machine:~# apt-cache madison postgresql
root@ubuntu-virtual-machine:~# apt install postgresql
# PostgreSQL环境初始化
root@ubuntu-virtual-machine:~# pg_createcluster --start 14 mycluster
root@ubuntu-virtual-machine:~# vim /etc/postgresql/14/mycluster/pg_hba.conf
96 # IPv4 local connections:
97 host all all 0.0.0.0/0 scram-sha-256
root@ubuntu-virtual-machine:~# vim /etc/postgresql/14/mycluster/postgresql.conf
60 listen_addresses = '*' # what IP address(es) to listen on;
# 创建数据库及账户授权:
root@ubuntu-virtual-machine:~# su - postgres
postgres@ubuntu-virtual-machine:~$ psql -U postgres #进入到postgresql命令行
postgres=# CREATE DATABASE sonar #创建sonar数据库
postgres-# ;
CREATE DATABASE
postgres=# CREATE USER sonar WITH ENCRYPTED PASSWORD '123456'; #创建sonar用户密码为123456
CREATE ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE sonar TO sonar; #授权用户访问
GRANT
postgres=# ALTER DATABASE sonar OWNER TO sonar; #执行变更
ALTER DATABASE
postgres=# \q
# 部署SonarQube Server 9.9.x:
# 安装jdk 11:
root@ubuntu-virtual-machine:~# apt install -y openjdk-11-jdk
# 修改内核参数
root@ubuntu-virtual-machine:~# vim /etc/sysctl.conf
vm.max_map_count=262144
fs.file-max=1000000
root@ubuntu-virtual-machine:~# mkdir /apps && cd /apps/
root@ubuntu-virtual-machine:/apps# unzip sonarqube-9.9.3.79811.zip
root@ubuntu-virtual-machine:/apps# ln -sv /apps/sonarqube-9.9.3.79811 /apps/sonarqube
root@ubuntu-virtual-machine:/apps# useradd -r -m -s /bin/bash sonarqube && chown sonarqube.sonarqube /apps/ -R && su - sonarqube
# 使用普通用户操作,不能使用root用户启动SonarQube
sonarqube@ubuntu-virtual-machine:~$ vim /apps/sonarqube/conf/sonar.properties
26 sonar.jdbc.username=sonar
27 sonar.jdbc.password=123456
44 sonar.jdbc.url=jdbc:postgresql://172.18.10.184/sonar
# 启动
sonarqube@ubuntu-virtual-machine:~$ cd /apps/sonarqube/bin/linux-x86-64
sonarqube@ubuntu-virtual-machine:/apps/sonarqube/bin/linux-x86-64$ sh sonar.sh start
# 访问http://172.18.10.184:9000
修改中文 Administration–> Marketplace–> I understand the risk(首次需要点击我理解风险)–>all
Administration–> System–> Restart Server #新插件安装成功后需要重启SonarQube server
关闭身份认证:
配置启动脚本
root@ubuntu-virtual-machine:~# vim /etc/systemd/system/sonarqube.service
[Unit]
Description=SonarQube service
After=syslog.target network.target
[Service]
Type=simple
User=sonarqube
Group=sonarqube
PermissionsStartOnly=true
ExecStart=/bin/nohup /usr/bin/java -Xms1024m -Xmx1024m -Djava.net.preferIPv4Stack=true -jar /apps/sonarqube/lib/sonar-application-9.9.3.79811.jar
StandardOutput=syslog
LimitNOFILE=131072
LimitNPROC=8192
TimeoutStartSec=5
Restart=always
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
9.jenkins结合shell脚本实现代码扫描
# jenkins部署代码扫描器
root@ubuntu-virtual-machine:/apps# cd /apps/
root@ubuntu-virtual-machine:/apps# unzip sonar-scanner-cli-5.0.1.3006.zip
root@ubuntu-virtual-machine:/apps# ln -sv /apps/sonar-scanner-5.0.1.3006 /apps/sonar-scanner
# 配置服务器地址和用户密码
root@ubuntu-virtual-machine:/apps# vim /apps/sonar-scanner/conf/sonar-scanner.properties
#----- Default SonarQube server
sonar.host.url=http://172.18.10.184:9000
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
#sonarqube账户
sonar.login=admin
#sonarqube密码
sonar.password=123456
# 检测代码质量,上传测试代码
root@ubuntu-virtual-machine:/data/gitdata/magedu/python-test# ll
total 16
drwxr-xr-x 3 root root 4096 12月 23 17:42 ./
drwxr-xr-x 4 root root 4096 12月 23 17:42 ../
-rw-r--r-- 1 root root 284 12月 17 21:35 sonar-project.properties
drwxr-xr-x 2 root root 4096 12月 17 21:35 src/
root@ubuntu-virtual-machine:/data/gitdata/magedu/python-test# cat sonar-project.properties
# Required metadata
sonar.projectKey=magedu-python #项目key,项目唯一标识、通常使用项目名称
sonar.projectName=magedu-python-app1 #项目名称,当前的服务名称
sonar.projectVersion=1.0 #当前的代码版本
# Comma-separated paths to directories with sources (required)
sonar.sources=src #源代码路径、sonar-scanner会扫描./src 下的代码
# Language
sonar.language=py #编程语言类型
# Encoding of the source files
sonar.sourceEncoding=UTF-8 #字符集
# 基于配置文件执行扫描
root@ubuntu-virtual-machine:/data/gitdata/magedu/python-test# /apps/sonar-scanner/bin/sonar-scanner
# 第二种:基于传递扫描参数:/apps/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=magedu -Dsonar.projectName=magedu-python-app1 -Dsonar.projectVersion=1.0 -Dsonar.sources=./src -Dsonar.language=py -Dsonar.sourceEncoding=UTF-8 -Dsonar.login=admin -Dsonar.password=12345678
jenkins结合shell脚本实现代码扫描
# 准备工作,上传代码,新建项目py-test
root@ubuntu-virtual-machine:/data/gitdata/magedu# git clone git@172.18.10.181:magedu/py-test.git
root@ubuntu-virtual-machine:/data/gitdata/magedu# cd py-test/
root@ubuntu-virtual-machine:/data/gitdata/magedu/py-test# ls
sonar-project.properties src
root@ubuntu-virtual-machine:/data/gitdata/magedu/py-test# git add .
root@ubuntu-virtual-machine:/data/gitdata/magedu/py-test# git commit -m 'v1'
root@ubuntu-virtual-machine:/data/gitdata/magedu/py-test# git push
root@ubuntu-virtual-machine:/data/scripts# cat sonar-jenkins.sh
#!/bin/bash
# 变量 分支
BRANCH=$1
if test -z $BRANCH;then
BRANCH=develop
fi
# 克隆代码
function Code_Clone(){
Git_URL="git@172.18.10.181:magedu/py-test.git"
DIR_NAME=`echo ${Git_URL} |awk -F "/" '{print $2}' | awk -F "." '{print $1}'`
DATA_DIR="/data/gitdata/magedu"
Git_Dir="${DATA_DIR}/${DIR_NAME}"
cd ${DATA_DIR} && echo "即将清空上一版本代码并获取当前分支最新代码" && sleep 1 && rm -rf ${DIR_NAME}
echo "即将开始从分支${BRANCH} 获取代码" && sleep 1
git clone -b ${BRANCH} ${Git_URL}
echo "分支${BRANCH} 克隆完成,即将进行代码扫描!" && sleep 1
sleep 1
cd ${Git_Dir}
}
# 代码扫描
function Code_Scan(){
cd ${Git_Dir}
echo "开始执行代码扫描"
/apps/sonar-scanner/bin/sonar-scanner
echo "代码扫描完成并奖结果上传到服务器上"
}
Code_Clone
Code_Scan
jenkins创建job完成代码扫描
查看扫描结果: