写点什么

极客时间运维进阶训练营第四周作业

作者:Starry
  • 2022-11-22
    北京
  • 本文字数:16721 字

    阅读完需:约 55 分钟

1.部署 jenkins master 及多 slave 环境

jenkins master 分布式环境中包括一个 master 节点,1 到多个 slave 节点。

jenkins master 节点负责 job 的创建、管理与触发。job 在执行时分配给特定的 jenkins slave 节点执行。

master 节点的部署之前已经完成。本次新增两台 slave 节点。

环境信息:

gitlab 10.0.0.132

jenkins-master 10.0.0.135

jenkins-node1 10.0.0.136

jenkins-node2 10.0.0.137


master 节点的 jenkins 工作目录为/var/lib/jenkins。slave 节点无需安装 jenkins,但是需要创建与 master 相同的数据目录,方便后期目录切换与制品同步。

另外 slave 节点需要配置 java 环境,以启动 jar 包。并且安装与 master 相同的基础环境,如 docker、git 等。

# 在两台slave节点操作,安装docker和java环境,并创建jenkins工作目录。# 1. 安装docker-ce# apt-get update# curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -# add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"# apt-get -y update# apt-get -y install docker-ce
# 2. 安装openjdk-11-jdk# apt install openjdk-11-jdk -y
# 3. 创建/var/lib/jenkins目录# mkdir -p /var/lib/jenkins
# git客户端在安装操作系统时已经包含了,无需再单独安装。
复制代码


在 jenkins 页面新建 slave 节点。

【系统管理】-【节点管理】-【新建节点】




添加 jenkins-node2 slave 节点时,可以通过复制 jenkins-node1 节点信息,修改其中的名称、ip、标签信息信息保存即可。

添加完成后,master 和 slave 节点间会检测连通性。节点状态如下:


slave 节点启动了 java 进程。

root@jenkins-node1:~# ps -ef |grep java |grep -v greproot       13452   13322  1 04:03 ?        00:00:04 java -jar remoting.jar -workDir /var/lib/jenkins -jar-cache /var/lib/jenkins/remoting/jarCache
复制代码


新建一个流水线任务,分别在 jenkins-slave1,jenkins-slave2 上运行,验证是否能正常执行。

pipeline {    agent none
stages { stage('Hello node1') { agent { label 'jenkins-node1' } steps { echo 'jenkins-node1, Hello World' } } stage('Hello node2') { agent { label 'jenkins-node2' } steps { echo 'jenkins-node2, Hello World' } } }}
复制代码

执行 job 后,输出如下:


2.基于 jenkins 视图对 jenkins job 进行分类

jenkins 默认只有所有视图。所有创建的 job 都现在在该视图下。

我们可以新增视图,按照项目进行归类,将一类任务放到一个视图上,方便管理。

新增视图步骤为:


进入新建的视图编辑页面,继续编辑视图信息

保存后,在新建的视图中就可以看到管理的任务。


3. jenkins pipeline 基本语法

3.1 声明式流水线结构概览

pipeline 声明式流水线结构图如下:


在这个结构中,那些虚线环绕的方格是可选的,那些实线方格是必须的。请注意,有些指令可以同时放在流水线级别和阶段级别,他们可能在一个区域中是必需的,而在另一个区域中是可选的。

  • pipeline

流水线过程定义在 pipeline{} 块中,在 pipeline 块定义了整个流水线中完成的所有的动作。

  • Stage

阶段,一个 pipeline 可以划分为若干个 stage,每个 stage 都是一个操作阶段,比如代码 clone、代码编译、代码测试和代码部署。阶段是一个逻辑分组,在 pipeline 中可以实现跨多个 node 执行不同的 stage。

  • Step

步骤,step 是 jenkins pipline 最基本的操作单元,一个 stage 中可以有多个 step,例如在代码 clone 的 stage 中需要定义代码 clone 的 step、在代码编译 stage 需要定义代码编译的 step。

  • Node

jenkins 工作节点,可以是 jenkins master 也可以是 jenkins slave,node 是执行 step 的具体服务器。


3.2 常用的指令

agent

这个 agent 指令用来指定整个流水线或者一个特定的阶段在哪里运行。这与脚本式流水线中的 node 指令用法相似。在靠近 pipeline 代码块的顶部,必须要有一个 agent 指令用来指定“默认的”执行节点。然而,在单个阶段的开始可以可选地使用一个 agent 指令,用来指定该阶段中的代码应该在哪里运行。可能的选项总结如下。

  • agent any

这个语法告诉 Jenkins 该流水线或阶段可以运行在任何一个定义好的代理节点上,而不关心它具有什么标签。

  • agent none

当用在顶端时,这表明我们不打算为流水线指定一个全局代理节点。这也意味着,如有必要,需要为单个阶段指定一个代理节点。

  • agent { label "<label>"}

这表明该流水线或阶段可以运行在任何一个具有<label>标签的代理节点上。

environment

这是声明式流水线中的一个可选指令。顾名思义,这个指令允许你为环境变量指定名称和值,这些环境变量在你的流水线范围内都是可以访问的。像使用 agent 一样,你可以在主流水线定义和(或)单个阶段中拥有一个 environment 实例。

pipeline {   agent any   environment { //全局的变量,在当前pipline所有的stage中都会生效     NAME='user1'     PASSWD='123456'   }  stages {     stage('环境变量stage1') { 	  environment { //定义在stage中的变量只会在当前stage生效,其他的stage不会生效          GIT_SERVER = 'git@10.0.0.132:magedu/app1.git'       }     steps {       sh """         echo '$NAME'         echo '$PASSWD'         echo '$GIT_SERVER'         """ 	}   }  stage('环境变量stage2') {     steps {       sh """         echo '$NAME'         echo '$PASSWD'       """ 	  }     }  }}
复制代码

options

这个指令可以用来指定一些属性和值,这些预定义的选项可以应用到整个流水线。这些就是在 Jenkins Web 表单里一个项目的基本配置中可以设定的事情(除了参数,参数使用单独的部分定义)。你可以把它理解成一个用来设置 Jenkins 所定义的项目选项的地方。

buildDiscarder(logRotator(numToKeepStr: '5')) //保留5个历史构建版本options {  buildDiscarder(logRotator(numToKeepStr: '5'))}timeout(time: 5, unit: 'MINUTES') //定义任务执行超时时间,如果不加unit参数默认时间单位为分钟timestamps() //在控制台显示命令执行的时间,格式为10:58:39retry(2) //流水线构建失败后重试次数为2次
复制代码


parameters

这个指令允许我们为一个声明式流水线指定项目参数。这些参数的输入值可以来自一个用户或者一个 API 调用。你可以认为这些参数与 Web 表单中使用此构建是参数化的(This build is parameterized)选项指定的参数是相同类型的参数。

string: #字符串类型参数,可以传递账户名、密码等参数其子参数包括description、defaultValue及name。parameters {  string(defaultValue: 'Linux', description: 'What platform?', nmae: 'platform')}
text: #文本型参数,一般用于定义多行文本内容的变量。其子参数包括name、defaultValue及description。parameters { text(defaultValue: 'No message', description: 'Enter your message', nmae: 'userMsg')}
booleanParam:#布尔型参数这是基本的true/false参数。其子参数为name、defaultValue及description。parameters { booleanParm(defaultValue: false, description: 'test run?', nmae: 'testRun')}
choice:#选择型参数,一般用于给定几个可选的值,然后选择其中一个进行赋值使用其子参数为name、choices及description。这里的choices指的是你所输入的以换行符分隔的展示给用户的选项列表。列表中的第一个值会作为默认值。parameters { choice(choices: 'Windows-1\nLinux-2',description: 'Which platform?', name: 'platform')}
password: #密码型变量,一般用于定义敏感型变量,在 Jenkins 控制台会输出为*隐藏密码。可用的子参数包括name、defaultValue及description。parameters { password(defaultValue: 'userpass1', description: 'User password?', name: 'userPW')}
复制代码


3.3 参数化构建示例

一旦你在 parameters 代码块中定义了一个参数,你就可以在你的流水线中通过 params 命名空间按照 params.<parameter_name>的格式引用这个参数。下面是一个简单的示例,在声明式流水线中使用了一个 string 参数:

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"       }     }  }}
复制代码


警告:第一次执行时参数的问题

截止到目前,在第一次运行流水线脚本时,系统不会提示用户输入参数的值。从第二次开始,你才会看到系统的提示。如上面的 pipeline job,第一次执行时报错属于正常现象。报错如下图:


第一次失败后,在 jenkins job 页面会生成一个 build with parameters 的菜单。点击配置,会看到

参数化构建过程被勾选上,pipeline 中定义的 parameters 在此都有显示。



点击 build with parameters,填写或选择需要的参数,点击开始构建,会正常执行构建。

页面呈现阶段视图。可以分阶段查看状态、点击阶段可以查看该阶段日志。

鉴于此,我们在完成编写 pipeline 脚本后,必须运行一次 job,这样才能让 jenkins 解析 pipeline,把需要的参数自动生成出来,确保该 job 后续构建时能正常运行。

4.部署代码质量检测服务

环境信息:

sornarqube-server 10.0.0.140

postgresql 10.0.0.141

jenkins-master 10.0.0.135

4.1 部署 postgresql 12.x

root@postgresql:~# apt update# 查询可安装版本root@postgresql:~# apt-cache madison postgresqlpostgresql | 12+214ubuntu0.1 | http://mirrors.aliyun.com/ubuntu focal-updates/main amd64 Packagespostgresql | 12+214ubuntu0.1 | http://mirrors.aliyun.com/ubuntu focal-security/main amd64 Packagespostgresql |     12+214 | http://mirrors.aliyun.com/ubuntu focal/main amd64 Packages
# 安装指定版本root@postgresql:~# apt install postgresql=12+214 -y
# 环境初始化root@postgresql:~# pg_createcluster --start 12 myclusterCreating new PostgreSQL cluster 12/mycluster .../usr/lib/postgresql/12/bin/initdb -D /var/lib/postgresql/12/mycluster --auth-local peer --auth-host md5The files belonging to this database system will be owned by user "postgres".This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".The default database encoding has accordingly been set to "UTF8".The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/12/mycluster ... okcreating subdirectories ... okselecting dynamic shared memory implementation ... posixselecting default max_connections ... 100selecting default shared_buffers ... 128MBselecting default time zone ... Etc/UTCcreating configuration files ... okrunning bootstrap script ... okperforming post-bootstrap initialization ... oksyncing data to disk ... ok
Success. You can now start the database server using:
pg_ctlcluster 12 mycluster start
Ver Cluster Port Status Owner Data directory Log file12 mycluster 5433 online postgres /var/lib/postgresql/12/mycluster /var/log/postgresql/postgresql-12-mycluster.log
# 修改配置文件postgresql.confroot@postgresql:~# vi /etc/postgresql/12/mycluster/postgresql.conf 修改如下配置:listen_addresses = '*'max_connections = 4096
# 修改后文件内容如下:root@postgresql:~# grep -Ev '^$|^\s*#' /etc/postgresql/12/mycluster/postgresql.confdata_directory = '/var/lib/postgresql/12/mycluster' # use data in another directoryhba_file = '/etc/postgresql/12/mycluster/pg_hba.conf' # host-based authentication fileident_file = '/etc/postgresql/12/mycluster/pg_ident.conf' # ident configuration fileexternal_pid_file = '/var/run/postgresql/12-mycluster.pid' # write an extra PID filelisten_addresses = '*' # what IP address(es) to listen on;port = 5433 # (change requires restart)max_connections = 4096 # (change requires restart)unix_socket_directories = '/var/run/postgresql' # comma-separated list of directoriesssl = onssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'shared_buffers = 128MB # min 128kBdynamic_shared_memory_type = posix # the default is the first optionmax_wal_size = 1GBmin_wal_size = 80MBlog_line_prefix = '%m [%p] %q%u@%d ' # special values:log_timezone = 'Etc/UTC'cluster_name = '12/mycluster' # added to process titles if nonemptystats_temp_directory = '/var/run/postgresql/12-mycluster.pg_stat_tmp'datestyle = 'iso, mdy'timezone = 'Etc/UTC'lc_messages = 'en_US.UTF-8' # locale for system error messagelc_monetary = 'en_US.UTF-8' # locale for monetary formattinglc_numeric = 'en_US.UTF-8' # locale for number formattinglc_time = 'en_US.UTF-8' # locale for time formattingdefault_text_search_config = 'pg_catalog.english'include_dir = 'conf.d' # include files ending in '.conf' from


# 修改配置文件pg_hba.conf,授权允许远程连接root@postgresql:~# vi /etc/postgresql/12/mycluster/pg_hba.conf修改如下配置:host all all 0.0.0.0/0 md5
# 重启服务,使配置生效root@postgresql:~# systemctl restart postgresqlroot@postgresql:~# ss -tunlpNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=795,fd=12)) tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=795,fd=13)) tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=872,fd=3)) tcp LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=6766,fd=3)) tcp LISTEN 0 4096 0.0.0.0:5433 0.0.0.0:* users:(("postgres",pid=6757,fd=3)) tcp LISTEN 0 128 127.0.0.1:6010 0.0.0.0:* users:(("sshd",pid=1333,fd=10)) tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=872,fd=4)) tcp LISTEN 0 4096 [::]:5433 [::]:* users:(("postgres",pid=6757,fd=4)) tcp LISTEN 0 128 [::1]:6010 [::]:* users:(("sshd",pid=1333,fd=9))
# 这里postgresql竟然有两个端口监听,5432监听本机,5433监听所有网卡。查看进程信息,我们要使用的是5433端口。# 5432端口进程信息root@postgresql:~# ps -ef |grep 6766postgres 6766 1 0 09:09 ? 00:00:00 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main -c config_file=/etc/postgresql/12/main/postgresql.confpostgres 6775 6766 0 09:09 ? 00:00:00 postgres: 12/main: checkpointer postgres 6776 6766 0 09:09 ? 00:00:00 postgres: 12/main: background writer postgres 6777 6766 0 09:09 ? 00:00:00 postgres: 12/main: walwriter postgres 6778 6766 0 09:09 ? 00:00:00 postgres: 12/main: autovacuum launcher postgres 6779 6766 0 09:09 ? 00:00:00 postgres: 12/main: stats collector postgres 6780 6766 0 09:09 ? 00:00:00 postgres: 12/main: logical replication launcher root 6851 1424 0 09:10 pts/0 00:00:00 grep --color=auto 6766
# 5433端口进程信息root@postgresql:~# ps -ef |grep 6757postgres 6757 1 0 09:09 ? 00:00:00 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/mycluster -c config_file=/etc/postgresql/12/mycluster/postgresql.confpostgres 6768 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: checkpointer postgres 6769 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: background writer postgres 6770 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: walwriter postgres 6771 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: autovacuum launcher postgres 6772 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: stats collector postgres 6773 6757 0 09:09 ? 00:00:00 postgres: 12/mycluster: logical replication launcher root 6857 1424 0 09:11 pts/0 00:00:00 grep --color=auto 6757
复制代码


创建数据库及账户授权

#切换到postgres普通用户root@postgresql:~# su - postgres    
#进入到postgresql命令行窗口postgres@postgresql:~$ psql -U postgres -p 5433psql (12.12 (Ubuntu 12.12-0ubuntu0.20.04.1))Type "help" for help.
#创建sonar数据库postgres=# CREATE DATABASE sonar;CREATE DATABASE#创建sonar用户密码为123456postgres=# CREATE USER sonar WITH ENCRYPTED PASSWORD '123456';CREATE ROLE #授权用户访问postgres=# GRANT ALL PRIVILEGES ON DATABASE sonar TO sonar;GRANT#执行变更postgres=# ALTER DATABASE sonar OWNER TO sonar;ALTER DATABASEpostgres=# \q
复制代码


4.2 安装 sornarqube server

# 安装jdk11root@sonarqube:~# apt install -y openjdk-11-jdk
# 调整内核参数root@sonarqube:~# vi /etc/sysctl.conf 新增两个参数:vm.max_map_count = 524288fs.file-max = 131072
root@sonarqube:~# sysctl -pvm.max_map_count = 524288fs.file-max = 131072
# 系统优化,调整资源限制root@sonarqube:~# vi /etc/security/limits.confroot soft core unlimitedroot hard core unlimitedroot soft nproc 1000000root hard nproc 1000000root soft nofile 1000000root hard nofile 1000000root soft memlock 32000root hard memlock 32000root soft msgqueue 8192000root hard msgqueue 8192000
* soft core unlimited* hard core unlimited* soft nproc 1000000* hard nproc 1000000* soft nofile 1000000* hard nofile 1000000* soft memlock 32000* hard memlock 32000* soft msgqueue 8192000* hard msgqueue 8192000
# 下载安装sonarqube# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.9.10.61524.zip# apt install unzip -y# unzip sonarqube-8.9.10.61524.zip -d /apps# useradd -r -m -s /bin/bash sonarqube && chown sonarqube.sonarqube /apps/ -R # passwd sonarqube# su - sonarqube$ cd /apps/sonarqube/conf
# 修改配置$ grep -Ev '^$|^#' sonar.properties sonar.jdbc.username=sonarsonar.jdbc.password=123456sonar.jdbc.url=jdbc:postgresql://10.0.0.141:5433/sonar
# 启动服务$ cd /apps/sonarqubesonarqube@sonarqube:/apps/sonarqube$ ./bin/linux-x86-64/sonar.sh startStarting SonarQube...Started SonarQube.
# 查看日志sonarqube@sonarqube:/apps/sonarqube$ tail -f logs/*.log...==> logs/sonar.20221122.log <==warning: no-jdk distributions that do not bundle a JDK are deprecated and will be removed in a future release2022.11.22 12:22:40 INFO app[][o.s.a.SchedulerImpl] Process[es] is up2022.11.22 12:22:40 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[[key='web', ipcIndex=2, logFilenamePrefix=web]] from [/apps/sonarqube-8.9.10.61524]: /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/apps/sonarqube-8.9.10.61524/temp -XX:-OmitStackTraceInFastThrow --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Dhttp.nonProxyHosts=localhost|127.*|[::1] -cp ./lib/sonar-application-8.9.10.61524.jar:/apps/sonarqube-8.9.10.61524/lib/jdbc/postgresql/postgresql-42.3.3.jar org.sonar.server.app.WebServer /apps/sonarqube-8.9.10.61524/temp/sq-process9113535971067822588properties2022.11.22 12:22:55 WARN app[][startup] ####################################################################################################################2022.11.22 12:22:55 WARN app[][startup] Default Administrator credentials are still being used. Make sure to change the password or deactivate the account.2022.11.22 12:22:55 WARN app[][startup] ####################################################################################################################2022.11.22 12:23:20 INFO app[][o.s.a.SchedulerImpl] Process[web] is up2022.11.22 12:23:20 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[[key='ce', ipcIndex=3, logFilenamePrefix=ce]] from [/apps/sonarqube-8.9.10.61524]: /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/apps/sonarqube-8.9.10.61524/temp -XX:-OmitStackTraceInFastThrow --add-opens=java.base/java.util=ALL-UNNAMED -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Dhttp.nonProxyHosts=localhost|127.*|[::1] -cp ./lib/sonar-application-8.9.10.61524.jar:/apps/sonarqube-8.9.10.61524/lib/jdbc/postgresql/postgresql-42.3.3.jar org.sonar.ce.app.CeServer /apps/sonarqube-8.9.10.61524/temp/sq-process2952332884398219619properties2022.11.22 12:23:26 INFO app[][o.s.a.SchedulerImpl] Process[ce] is up2022.11.22 12:23:26 INFO app[][o.s.a.SchedulerImpl] SonarQube is up...

复制代码


浏览器访问 http://10.0.0.140:9000/ admin/admin

第一次登录会提示改密码。密码修改为 12345678


成功进入主页


4.3 sonarqube server 其他配置

4.3.1 安装中文插件



提示重启服务器,点击重启。


重启完会让重新登录,有中文菜单。

4.3.2 关闭权限认证

关闭针对 jenkins 的权限认证,jenkins 就可以直接到 sonarqube 的 API 了。


4.3.3 配置 sornarqube 自启动

# 停止服务sonarqube@sonarqube:/apps/sonarqube$ ./bin/linux-x86-64/sonar.sh stop
# 在root用户下新建sonarqube.service文件root@sonarqube:~# cat /etc/systemd/system/sonarqube.service [Unit]Description=SonarQube serviceAfter=syslog.target network.target
[Service]Type=simpleUser=sonarqubeGroup=sonarqubePermissionsStartOnly=trueExecStart=/bin/nohup /usr/bin/java -Xms1024m -Xmx1024m -Djava.net.preferIPv4Stack=true -jar /apps/sonarqube/lib/sonar-application-8.9.10.61524.jar StandardOutput=syslogLimitNOFILE=131072LimitNPROC=8192TimeoutStartSec=5Restart=alwaysSuccessExitStatus=143
[Install]WantedBy=multi-user.target
# 启动服务并设置开机自启动root@sonarqube:~# systemctl daemon-reloadroot@sonarqube:~# systemctl start sonarqube.service root@sonarqube:~# systemctl enable sonarqube.service Created symlink /etc/systemd/system/multi-user.target.wants/sonarqube.service → /etc/systemd/system/sonarqube.service.root@sonarqube:~# systemctl status sonarqube.service ● sonarqube.service - SonarQube Loaded: loaded (/etc/systemd/system/sonarqube.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2022-11-22 13:14:56 UTC; 13s ago Main PID: 13685 (java) Tasks: 130 (limit: 4575) Memory: 1.1G CGroup: /system.slice/sonarqube.service ├─13685 /usr/bin/java -Xms1024m -Xmx1024m -Djava.net.preferIPv4Stack=true -jar /apps/sonarqube/lib/sonar-application-8.9.10.61524.jar ├─13713 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -XX:+UseG1GC -Djava.io.tmpdir=/apps/sonarqube-8.9.10.61524/temp -XX:ErrorFile=../logs/es_hs_err_pid%p.log -Des.networkaddress.cac> └─13838 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/apps/sonarqube-8.9.10.61524/temp -XX:-OmitStackTraceInFastThrow >
Nov 22 13:14:56 sonarqube systemd[1]: Started SonarQube.Nov 22 13:14:56 sonarqube nohup[13685]: 2022.11.22 13:14:56 INFO app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /apps/sonarqube-8.9.10.61524/tempNov 22 13:14:56 sonarqube nohup[13685]: 2022.11.22 13:14:56 INFO app[][o.s.a.es.EsSettings] Elasticsearch listening on [HTTP: 127.0.0.1:9001, TCP: 127.0.0.1:36129]Nov 22 13:14:56 sonarqube nohup[13685]: 2022.11.22 13:14:56 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[[key='es', ipcIndex=1, logFilenamePrefix=es]] from [/apps/sonarqube-8.9.10.61524>Nov 22 13:14:56 sonarqube nohup[13685]: 2022.11.22 13:14:56 INFO app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and runningNov 22 13:14:56 sonarqube nohup[13685]: warning: no-jdk distributions that do not bundle a JDK are deprecated and will be removed in a future releaseNov 22 13:15:03 sonarqube nohup[13685]: 2022.11.22 13:15:03 INFO app[][o.s.a.SchedulerImpl] Process[es] is upNov 22 13:15:03 sonarqube nohup[13685]: 2022.11.22 13:15:03 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[[key='web', ipcIndex=2, logFilenamePrefix=web]] from [/apps/sonarqube-8.9.10.615>Nov 22 13:15:03 sonarqube systemd[1]: /etc/systemd/system/sonarqube.service:3: Unknown key name 'serviceAfter' in section 'Unit', ignoring.
复制代码


4.4 部署扫描器 sonar-scanner

下载安装 sonar-scannar

# 下载sonar-scanner# wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-linux.zip
# 将sonar-scanner安装到/apps下,并建立软链接# mkdir /apps# apt install unzip# unzip sonar-scanner-cli-4.7.0.2747-linux.zip -d /apps# ln -sv /apps/sonar-scanner-4.7.0.2747-linux /apps/sonar-scanner
# 修改sonar-scanner.properties# vi /apps/sonar-scanner/conf/sonar-scanner.properties #----- Default SonarQube serversonar.host.url=http://10.0.0.140:9000
#----- Default source code encodingsonar.sourceEncoding=UTF-8
复制代码


5.实现代码质量检测

上传测试代码到 sonar-scanner 节点

将 python-test 目录上传到 sonar-scanner 节点的/apps 目录下。内容如下:

root@jenkins-master:/apps/python-test# tree.├── sonar-project.properties└── src    └── test.py
1 directory, 2 filesroot@jenkins-master:/apps/python-test# cat sonar-project.properties # Required metadatasonar.projectKey=magedu-pythonsonar.projectName=magedu-python-app1sonar.projectVersion=1.0
# Comma-separated paths to directories with sources (required)sonar.sources=src
# Languagesonar.language=py
# Encoding of the source filessonar.sourceEncoding=UTF-8root@jenkins-master:/apps/python-test# cat src/test.py #!/usr/bin/env python#coding:utf-8#Author:Zhang ShiJieimport sys
for i in range(50): if i == 10: print(i) elif i == 20: print(i) elif i == 20: print(i) else: pass
复制代码


在 gitlab 上新建项目 app2,将 python-test 下所有文件上传。

root@jenkins-master:~# cd /tmproot@jenkins-master:/tmp# git clone git@10.0.0.132:magedu/app2.gitCloning into 'app2'...remote: Enumerating objects: 3, done.remote: Counting objects: 100% (3/3), done.remote: Compressing objects: 100% (2/2), done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0Receiving objects: 100% (3/3), done.
root@jenkins-master:/tmp# cd app2root@jenkins-master:/tmp/app2# lsREADME.md
root@jenkins-master:/tmp/app2# cp -rf /apps/python-test/* .root@jenkins-master:/tmp/app2# lltotal 28drwxr-xr-x 4 root root 4096 Nov 22 14:29 ./drwxrwxrwt 15 root root 4096 Nov 22 14:28 ../drwxr-xr-x 8 root root 4096 Nov 22 14:28 .git/-rw-r--r-- 1 root root 6177 Nov 22 14:28 README.md-rw-r--r-- 1 root root 284 Nov 22 14:29 sonar-project.propertiesdrwxr-xr-x 2 root root 4096 Nov 22 14:29 src/root@jenkins-master:/tmp/app2# git add .root@jenkins-master:/tmp/app2# git commit -m "add src"[main a02143a] add src 2 files changed, 27 insertions(+) create mode 100644 sonar-project.properties create mode 100644 src/test.pyroot@jenkins-master:/tmp/app2# git pushEnumerating objects: 6, done.Counting objects: 100% (6/6), done.Delta compression using up to 2 threadsCompressing objects: 100% (4/4), done.Writing objects: 100% (5/5), 660 bytes | 660.00 KiB/s, done.Total 5 (delta 0), reused 0 (delta 0)To 10.0.0.132:magedu/app2.git 286fe28..a02143a main -> main
复制代码

5.1 基于命令实现代码质量检测

在项目所在目录下,执行扫描命令。

root@jenkins-master:/apps/python-test# pwd/apps/python-testroot@jenkins-master:/apps/python-test# lssonar-project.properties  src
# 不指定参数时,由配置文件维护扫描参数root@jenkins-master:/apps/python-test# /apps/sonar-scanner/bin/sonar-scannerINFO: Scanner configuration file: /apps/sonar-scanner-4.7.0.2747-linux/conf/sonar-scanner.propertiesINFO: Project root configuration file: /apps/python-test/sonar-project.propertiesINFO: SonarScanner 4.7.0.2747INFO: Java 11.0.14.1 Eclipse Adoptium (64-bit)INFO: Linux 5.4.0-132-generic amd64INFO: User cache: /root/.sonar/cacheINFO: Scanner configuration file: /apps/sonar-scanner-4.7.0.2747-linux/conf/sonar-scanner.propertiesINFO: Project root configuration file: /apps/python-test/sonar-project.propertiesINFO: Analyzing on SonarQube server 8.9.10INFO: Default locale: "en_US", source code encoding: "UTF-8"INFO: Load global settingsINFO: Load global settings (done) | time=191msINFO: Server id: CB29FD86-AYSfSoB83jqRb9Dozd4sINFO: User cache: /root/.sonar/cacheINFO: Load/download pluginsINFO: Load plugins indexINFO: Load plugins index (done) | time=109msINFO: Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of l10n plugins since version 5.2.INFO: Load/download plugins (done) | time=1836msINFO: Process project propertiesINFO: Process project properties (done) | time=7msINFO: Execute project buildersINFO: Execute project builders (done) | time=2msINFO: Project key: magedu-pythonINFO: Base dir: /apps/python-testINFO: Working dir: /apps/python-test/.scannerworkINFO: Load project settings for component key: 'magedu-python'INFO: Load quality profilesINFO: Load quality profiles (done) | time=99msINFO: Load active rulesINFO: Load active rules (done) | time=1811msWARN: SCM provider autodetection failed. Please use "sonar.scm.provider" to define SCM of your project, or disable the SCM Sensor in the project settings.INFO: Indexing files...INFO: Project configuration:INFO: 1 file indexedINFO: Quality profile for py: Sonar wayINFO: ------------- Run sensors on module magedu-python-app1INFO: Load metrics repositoryINFO: Load metrics repository (done) | time=25msINFO: Sensor Python Sensor [python]INFO: Starting global symbols computationINFO: Load project repositoriesINFO: 1 source file to be analyzedINFO: Load project repositories (done) | time=8msINFO: 1/1 source file has been analyzedINFO: Starting rules executionINFO: 1 source file to be analyzedINFO: 1/1 source file has been analyzedINFO: Sensor Python Sensor [python] (done) | time=6435msINFO: Sensor Cobertura Sensor for Python coverage [python]INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=9msINFO: Sensor PythonXUnitSensor [python]INFO: Sensor PythonXUnitSensor [python] (done) | time=0msINFO: Sensor CSS Rules [cssfamily]INFO: No CSS, PHP, HTML or VueJS files are found in the project. CSS analysis is skipped.INFO: Sensor CSS Rules [cssfamily] (done) | time=1msINFO: Sensor JaCoCo XML Report Importer [jacoco]INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xmlINFO: No report imported, no coverage information will be imported by JaCoCo XML Report ImporterINFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=2msINFO: Sensor C# Project Type Information [csharp]INFO: Sensor C# Project Type Information [csharp] (done) | time=0msINFO: Sensor C# Properties [csharp]INFO: Sensor C# Properties [csharp] (done) | time=0msINFO: Sensor JavaXmlSensor [java]INFO: Sensor JavaXmlSensor [java] (done) | time=1msINFO: Sensor HTML [web]INFO: Sensor HTML [web] (done) | time=3msINFO: Sensor VB.NET Project Type Information [vbnet]INFO: Sensor VB.NET Project Type Information [vbnet] (done) | time=1msINFO: Sensor VB.NET Properties [vbnet]INFO: Sensor VB.NET Properties [vbnet] (done) | time=1msINFO: ------------- Run sensors on projectINFO: Sensor Zero Coverage SensorINFO: Sensor Zero Coverage Sensor (done) | time=14msINFO: SCM Publisher No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.INFO: CPD Executor Calculating CPD for 1 fileINFO: CPD Executor CPD calculation finished (done) | time=7msINFO: Analysis report generated in 43ms, dir size=95 KBINFO: Analysis report compressed in 14ms, zip size=13 KBINFO: Analysis report uploaded in 518msINFO: ANALYSIS SUCCESSFUL, you can browse http://10.0.0.140:9000/dashboard?id=magedu-pythonINFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis reportINFO: More about the report processing at http://10.0.0.140:9000/api/ce/task?id=AYSfr0ZKukyt6x0RTTLZINFO: Analysis total time: 10.382 sINFO: ------------------------------------------------------------------------INFO: EXECUTION SUCCESSINFO: ------------------------------------------------------------------------INFO: Total time: 14.487sINFO: Final Memory: 7M/27MINFO: ------------------------------------------------------------------------
复制代码


查看 sonarqube 服务端页面,显示扫描结果。


5.2 基于 shell 脚本实现代码质量检测

jenkins 中新建自由风格的 job,代码克隆和扫描都用 shell 实现。执行 shell 里的内容如下:

# 将代码克隆到/data/gitdata/magedu[ ! -d /data/gitdata/magedu ] && mkdir -p /data/gitdata/magedu# 清除本地代码路径,确保git clone成功cd /data/gitdata/magedu && rm -rf *git clone git@10.0.0.132:magedu/app2.gitcd app2/apps/sonar-scanner/bin/sonar-scanner
复制代码

执行构建,构建成功。

5.3 基于 pipeline 实现代码质量检测

在扫描时,我们可以不依赖于配置文件进行扫描,这就需要扫描命令中传递参数。这次我们用 pipeline job 来实现代码克隆和扫描。

pipeline 内容如下:

pipeline {  agent any  stages {    stage("code clone"){			steps {                deleteDir() //删除workDir当前目录                git branch: 'main', credentialsId: 'bef9de81-4a6c-4125-9a21-8b012d51532c', url: 'git@10.0.0.132:magedu/app2.git'		    }     }    stage('python源代码质量扫描') {        steps {            sh """			  cd $env.WORKSPACE			  /apps/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=magedu -Dsonar.projectName=magedu-python-app1 -Dsonar.projectVersion=1.1  -Dsonar.sources=./src -Dsonar.language=py -Dsonar.sourceEncoding=UTF-8			"""        }    }  }}
复制代码


执行构建,构建成功。


点击上图中的链接,可查看扫描的具体信息。


用户头像

Starry

关注

还未添加个人签名 2018-12-10 加入

还未添加个人简介

评论

发布
暂无评论
极客时间运维进阶训练营第四周作业_Starry_InfoQ写作社区