全链路 DevOps 实战:基于 Jenkins、GitLab、Prometheus 与 SonarQube 的持续集成、部署、监控与优化

1.在 Linux 系统上安装 Jenkins 2.528.2,并完成基本的初始化配置,包括管理员密码的设置、插件的安装和用户权限的配置。

想要安装Jenkins就必须先安装Java

apt update && apt -y install openjdk-21-jdk

查看java -version

然后去拉取安装包

wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/jenkins_2.528.2_all.deb

然后安装

安装完成后查看状态

systemctl status jenkins.service

浏览器访问一下本机地址

去它给的文件中获取密码

登录

前者会安装大量的插件,对于我们学习测试来说,先选择后者

点击后者后,依旧会有一些推荐插件,先不安装。

点击上方的"无",然后点击最下面的"安装"

由于会有一个默认admin用户,所以先使用默认

不用填写,点击下方"使用admin账户继续"

下一步,保存并完成

然后开始使用

由于没有安装任何插件,所以界面简洁

我们进行更改密码的操作

点击右上角的人头,再点击倒数第三行的security

下滑,就看到密码(为了加密,所以不管多长的密码都是一大串,删除,然后写自己的密码,点击"save"即可)

修改后,会直接让你重新登陆,写自己的密码

已经重新回来了

接下进行安装插件的操作

点击右上角的齿轮

然后点击plugins

然后点击左边的"avaliable plugins"

搜索我们需要的插件,并点击安装

以中文插件为例子

下载完成

然后点击下方的重启,就会生效

可以看出来,比之前多了一点中文

修改权限

修改 Jenkins 的启动用户为 root

#基于 Ubuntu安装修改下面文件

root@jenkins \~#vim /lib/systemd/system/jenkins.service

#User=jenkins

#Group=jenkins

User=root

Group=root

root@jenkins \~#systemctl daemon-reload

root@jenkins \~#systemctl restart jenkins.service

2.创建一个自由风格任务,使用 Ansible 实现对远程服务器的参数化构建,要求能够通过 Jenkins 参数动态指定目标服务器的 IP 地址和构建任务。

在服务器主机上安装ansible:apt install ansible -y

查看版本

确保 Jenkins 服务器可以通过 SSH 无密码访问目标服务器:

生成公钥

传递到目标服务器

创建 Ansible Inventory 文件

创建一个基础的主机清单文件:

在 Jenkins 中安装必要插件

Ansible​ 插件

Parameterized Trigger​ 插件

SSH Agent​ 插件

创建参数化构建项目

新建任务

返回 Jenkins 首页

点击 "新建任务"

输入任务名称,例如:ansible-test

选择 "自由风格项目"

点击 "确定"

配置项目参数

在项目配置页面,勾选 "参数化构建过程"

添加第一个参数:

点击 "添加参数"

选择 "字符串参数"

配置如下:

添加第二个参数:

点击 "添加参数"

选择 "选项参数"

配置如下:

添加第三个参数(条件参数):

点击 "添加参数"

选择 "字符串参数"

配置如下

名称: SERVICE_NAME

默认值: nginx

描述: 请输入要重启的服务名称

添加第四个参数:

点击 "添加参数"

选择 "字符串参数"

配置如下:

名称: CUSTOM_CMD

默认值: date

描述: 请输入要执行的自定义命令

创建 Ansible Playbook 文件

在 Jenkins 工作空间中创建 Playbook

在项目配置页面的 "构建"​ 部分,先添加一个 "执行shell"​ 步骤

复制代码
#!/bin/bash
# 创建临时 Ansible Playbook
mkdir -p $WORKSPACE/ansible-playbooks

# 根据选择的任务类型生成不同的 playbook
cat > $WORKSPACE/ansible-playbooks/execute_task.yml << EOF
---
- name: 执行远程服务器任务
  hosts: "{{ target_host }}"
  gather_facts: no
  vars:
    service_name: "{{ service_name | default('nginx') }}"
    custom_cmd: "{{ custom_cmd | default('date') }}"
  
  tasks:
EOF

# 根据任务类型添加相应的任务
case $TASK_TO_RUN in
  "system_info")
    cat >> $WORKSPACE/ansible-playbooks/execute_task.yml << 'EOF'
    - name: 收集系统信息
      setup:
      register: system_info
    
    - name: 显示系统信息
      debug:
        msg: "主机名: {{ ansible_hostname }}, IP: {{ ansible_default_ipv4.address }}, 系统: {{ ansible_distribution }} {{ ansible_distribution_version }}"
EOF
    ;;
    
  "update_system")
    cat >> $WORKSPACE/ansible-playbooks/execute_task.yml << 'EOF'
    - name: 更新系统软件包
      package:
        name: "*"
        state: latest
      when: ansible_pkg_mgr == 'yum'
    
    - name: 更新系统软件包(apt)
      apt:
        upgrade: dist
        update_cache: yes
      when: ansible_pkg_mgr == 'apt'
EOF
    ;;
    
  "restart_service")
    cat >> $WORKSPACE/ansible-playbooks/execute_task.yml << 'EOF'
    - name: 重启服务
      systemd:
        name: "{{ service_name }}"
        state: restarted
        enabled: yes
      register: result
    
    - name: 显示重启结果
      debug:
        msg: "服务 {{ service_name }} 重启{{ '成功' if result.changed else '失败' }}"
EOF
    ;;
    
  "custom_command")
    cat >> $WORKSPACE/ansible-playbooks/execute_task.yml << 'EOF'
    - name: 执行自定义命令
      command: "{{ custom_cmd }}"
      register: cmd_result
    
    - name: 显示命令输出
      debug:
        var: cmd_result.stdout_lines
EOF
    ;;
esac

创建动态的 Ansible Playbook:

复制代码
#!/bin/bash
# 创建临时 inventory 文件
cat > $WORKSPACE/inventory.ini << EOF
[target_server]
${TARGET_IP}

[target_server:vars]
ansible_ssh_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa
EOF

# 显示 inventory 内容
echo "===== 生成的 Inventory 文件 ====="
cat $WORKSPACE/inventory.ini
echo "================================="

创建动态的 Inventory 文件

"构建" ​ 部分,再添加一个 **"执行shell"**​ 步骤:

复制代码
#!/bin/bash
# 设置参数
export TARGET_IP="${TARGET_IP}"
export TASK="${TASK_TO_RUN}"
export SERVICE="${SERVICE_NAME}"
export CMD="${CUSTOM_CMD}"

echo "============================================="
echo "开始执行 Ansible 任务"
echo "目标服务器: ${TARGET_IP}"
echo "执行任务: ${TASK_TO_RUN}"
echo "服务名称: ${SERVICE_NAME}"
echo "自定义命令: ${CUSTOM_CMD}"
echo "============================================="

# 执行 Ansible Playbook
ansible-playbook \
  -i $WORKSPACE/inventory.ini \
  $WORKSPACE/ansible-playbooks/execute_task.yml \
  --extra-vars "target_host=target_server service_name=${SERVICE_NAME} custom_cmd=${CUSTOM_CMD}" \
  -v

# 检查执行结果
if [ $? -eq 0 ]; then
    echo "✅ Ansible 任务执行成功!"
else
    echo "❌ Ansible 任务执行失败!"
    exit 1
fi

添加第三个 **"执行shell"**​ 步骤:

测试任务

保存配置

点击页面底部的 **"保存"**​ 按钮

执行构建

返回项目页面

点击左侧的 "立即构建"

点击构建,之后成功

3.使用 Jenkins 2.528.2 和 GitLab 插件,基于 HTTP 和 SSH 协议配置一个自由风格任务,实现从 GitLab 仓库拉取代码并进行构建。

要实现从gitlab上拉取代码,首先我们需要安装一些插件

Git Plugin

作用:是 Jenkins 拉取 Git 仓库代码的基础插件,支持通过 HTTPS/SSH 方式克隆 Git 仓库。

GitLab Plugin

作用:实现 Jenkins 与 GitLab 的深度集成,支持:

从 GitLab 仓库拉取代码;

通过 GitLab WebHook 触发 Jenkins 自动构建;

向 GitLab 反馈构建状态(成功 / 失败)。

步骤一:创建 GitLab 个人访问令牌(HTTP 推荐,比密码安全)

GitLab 网页端操作:

登录 GitLab → 右上角头像 →「Edit profile」→「Access Tokens」;

填写令牌信息:

Name:jenkins-http-token(自定义);

Expires at:可选设置过期时间;

Scopes:勾选 read_repository(仅读仓库,最小权限原则);

点击「Create personal access token」→ 复制生成的令牌

glpat-CRCpWN371fCr__CFqoB_IG86MQp1OjEH.01.0w1dh7k86

步骤 2:Jenkins 中创建自由风格任务

登录 Jenkins 后台 → 左侧「New Item」;

输入任务名称:GitLab-HTTP-Pull(自定义);

选择「Freestyle project」→ 点击「OK」。

步骤 3:配置任务的「源码管理」(核心:HTTP 拉取)

找到「Source Code Management」模块 → 勾选「Git」;

「Repository URL」:粘贴 GitLab 仓库的 HTTP 地址

「Credentials」(凭证):

点击右侧「Add」→ 选择「Jenkins」;

弹出的凭证配置框:

Kind:选择「Username with password」;

Username:填写 GitLab 登录用户名(如 root);

Password:填写步骤 1 生成的「个人访问令牌」(或 GitLab 登录密码);

ID:自定义(如 gitlab-http-cred),方便识别;

Description:可选填写「GitLab HTTP 拉取凭证」;

点击「Add」保存凭证 → 回到源码管理,在「Credentials」下拉框选择刚创建的凭证;

「Branches to build」:默认 */main(或 */master,和 GitLab 仓库主分支一致)。

步骤 4:配置「构建步骤」(验证拉取 + 简单构建)

1.找到「Build Steps」模块 → 点击「Add build step」→ 选择「Execute shell」(Linux/Mac)/「Execute Windows batch command」(Windows);

2.在命令框中输入极简构建命令(验证代码拉取成功,并模拟构建):

查看拉取的文件(验证代码是否拉取成功)

ls -l cat test.py

模拟简单构建(比如输出构建成功日志)

echo "===== HTTP 协议拉取代码并构建成功 ====="

步骤 5:保存并执行构建

点击页面底部「Save」保存任务;

回到任务主页 → 点击左侧「Build Now」(立即构建);

等待构建完成(页面下方「Build History」会显示构建编号,如 #1)。

步骤 6:验证构建结果

点击「Build History」中的构建编号(如 #1)→ 选择「Console Output」(控制台输出);

查看输出日志,能看到以下内容即成功:plaintext

4.编写一个 Jenkins Pipeline 脚本,实现以下功能:从 GitLab 拉取代码、编译代码、运行单元测试,并在测试通过后将构建结果部署到指定的服务器。

一、前置准备(必做,决定实验成败)

1.1 安装 Jenkins 必需插件

登录 Jenkins → 「Manage Jenkins」→「Plugins」→「Available plugins」,安装以下插件:

插件名称 作用
Pipeline 核心 Pipeline 支持
Pipeline: Nodes and Processes 支持 Pipeline 执行 shell/SSH 命令
GitLab Plugin 与 GitLab 集成,拉取代码
Maven Integration Plugin 支持 Maven 编译 / 测试(Java 项目必需)
Publish Over SSH 通过 SSH 部署文件到目标服务器
JUnit Plugin 解析单元测试报告,展示测试结果

安装后重启 Jenkins:sudo systemctl restart jenkins

1.2 配置 Jenkins 全局工具(JDK/Maven)

Jenkins 编译 Java 代码需要 JDK 和 Maven,需提前配置:

  1. 「Manage Jenkins」→「Global Tool Configuration」;
  2. JDK 配置
    • 点击「Add JDK」→ 取消「Install automatically」(若手动装了 JDK);
    • Name:JDK21(自定义,后续脚本要引用);
    • JAVA_HOME:填写 Jenkins 主机 JDK 路径(如 /usr/lib/jvm/java-21-openjdk-amd64);
  3. Maven 配置
    • 点击「Add Maven」→ 取消「Install automatically」;
    • Name:Maven3.8.7(自定义,后续脚本要引用);
    • MAVEN_HOME:填写 Maven 路径(如 /usr/local/maven/apache-maven-3.8.7);
  4. 点击「Save」保存。

1.3 配置 Jenkins 凭证(3 类凭证)

「Manage Jenkins」→「Credentials」→「System」→「Global credentials (unrestricted)」→「Add Credentials」,添加以下 3 类凭证:

(1)GitLab 拉取代码凭证(HTTP 方式)
  • Kind:Username with password
  • Username:GitLab 用户名(如 root);
  • Password:GitLab 个人访问令牌(需勾选 read_repository 权限);
  • ID:gitlab-http-creds(自定义,脚本要引用);
  • Description:GitLab拉取代码凭证
(2)部署服务器 SSH 凭证(推送构建产物)
  • Kind:SSH Username with private key
  • Username:部署服务器的登录用户名(如 ubuntu);
  • Private Key:粘贴 Jenkins 主机的私钥(或直接输入,推荐提前生成 Jenkins 到部署服务器的 SSH 免密);
  • ID:deploy-server-ssh(自定义,脚本要引用);
  • Description:部署服务器SSH凭证

1.4 部署服务器准备

假设部署服务器 IP:192.168.1.200,需完成:

  1. 创建部署目录,授权:

  2. 确保 Jenkins 主机能通过 SSH 连接部署服务器(配置免密更佳):

1.5 GitLab 仓库准备(上传带编译 / 测试的 Java 代码)

步骤 1:在 GitLab 网页端创建新仓库(可选,也可命令行创建)

登录 GitLab(http://10.0.0.100)→ 「New Project」→ 填写:

  1. Project name:test-project-java21
  2. Visibility Level:Public/Private(选 Private)→ 点击「Create project」。
步骤 2:在 GitLab 主机(10.0.0.100)创建 Maven 项目文件
复制代码
克隆新建的空仓库到GitLab主机本地
复制代码
创建标准Maven目录结构(一键创建)
复制代码
 创建pom.xml(适配JDK21 + Maven3.8.7,极简配置)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo</groupId>
    <artifactId>test-project-java21</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 适配JDK21 -->
    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.1</junit.version> <!-- JUnit5适配JDK21 -->
    </properties>

    <!-- JUnit5单元测试依赖(极简) -->
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- Maven编译/测试插件(适配3.8.7) -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version> <!-- 适配Maven3.8.7 + JDK21 -->
                <configuration>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.2.2</version> <!-- 生成JUnit测试报告 -->
            </plugin>
        </plugins>
    </build>
</project>

创建极简业务代码(src/main/java/com/demo/HelloDemo.java)

package com.demo;

/**
 * 极简业务代码(仅返回字符串,满足编译+测试需求)
 */
public class HelloDemo {
    // 核心方法:返回固定字符串
    public String getMessage() {
        return "JDK21 + Maven3.8.7 测试成功";
    }

    // 主方法(可选,方便本地测试)
    public static void main(String[] args) {
        HelloDemo demo = new HelloDemo();
        System.out.println(demo.getMessage());
    }
}

创建极简单元测试代码

package com.demo;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * 极简单元测试(仅验证getMessage方法返回值)
 */
public class HelloDemoTest {
    @Test
    public void testMessage() {
        HelloDemo demo = new HelloDemo();
        // 断言:返回值等于预期字符串
        assertEquals("JDK21 + Maven3.8.7 测试成功", demo.getMessage());
    }
}
步骤 3:提交并推送到 GitLab 新仓库

编写 Jenkins Pipeline 脚本

创建流水线任务

Pipeline模块中写脚本

复制代码
pipeline {
    agent any  // 任意Jenkins节点执行
    tools {
        // 关联全局配置的JDK和Maven(名称必须和全局配置一致)
        jdk 'JDK21'
        maven 'Maven3.8.7'
    }
    environment {
        // 专属变量(已适配你的环境)
        GITLAB_REPO_URL = 'http://10.0.0.100/root/test-project-java21.git'  // GitLab新仓库地址
        DEPLOY_SERVER_IP = '10.0.0.102'                                     // 部署主机IP
        DEPLOY_DIR = '/opt/jenkins-deploy/test-project-java21'              // 部署目录
        GIT_CRED_ID = 'gitlab-http-cred'                                   // GitLab凭证ID(需和你配置的一致)
        SSH_CRED_ID = 'deploy-server-ssh'                                  // 部署服务器SSH凭证ID(需和你配置的一致)
    }
    stages {
        // 阶段1:拉取GitLab代码
        stage('Checkout Code') {
            steps {
                echo "===== 开始拉取GitLab新仓库代码 ====="
                git(
                    url: env.GITLAB_REPO_URL,
                    credentialsId: env.GIT_CRED_ID,
                    branch: 'main'  // 若GitLab分支是master,改为master
                )
            }
        }

        // 阶段2:编译代码
        stage('Compile Code') {
            steps {
                echo "===== 开始编译JDK21代码 ====="
                sh 'mvn clean compile -U'
            }
            post {
                failure {
                    echo "===== 代码编译失败,终止流程 ====="
                    error('编译失败')
                }
            }
        }

        // 阶段3:运行单元测试
        stage('Run Unit Tests') {
            steps {
                echo "===== 开始运行单元测试 ====="
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'  // 展示测试报告
                }
                failure {
                    echo "===== 单元测试失败,终止流程 ====="
                    error('单元测试失败')
                }
            }
        }

        // 阶段4:部署到目标服务器
        stage('Deploy to Server') {
            when {
                success()  // 仅测试成功时部署
            }
            steps {
                echo "===== 开始部署到服务器 ${env.DEPLOY_SERVER_IP} ====="
                // 打包生成JAR包
                sh 'mvn package -DskipTests'
                
                // SSH推送JAR包到部署主机
                sshPublisher(
                    publishers: [
                        sshPublisherDesc(
                            configName: env.SSH_CRED_ID,
                            transfers: [
                                sshTransfer(
                                    sourceFiles: 'target/test-project-java21-1.0-SNAPSHOT.jar',
                                    remoteDirectory: env.DEPLOY_DIR,
                                    cleanRemote: false,
                                    flatten: true,
                                    removePrefix: 'target'
                                )
                            ],
                            // 部署后验证
                            postTransfer: [
                                sshCommand(
                                    command: "echo 'JAR包已部署到${env.DEPLOY_DIR}'",
                                    configName: env.SSH_CRED_ID,
                                    runInBackground: false
                                )
                            ]
                        )
                    ]
                )

                // 验证部署结果
                echo "===== 验证部署结果 ====="
                sh "ssh -o StrictHostKeyChecking=no ${env.DEPLOY_SERVER_IP} 'ls ${env.DEPLOY_DIR}/test-project-java21-1.0-SNAPSHOT.jar'"
            }
            post {
                success {
                    echo "===== 部署成功!JAR包路径:${env.DEPLOY_SERVER_IP}:${env.DEPLOY_DIR} ====="
                }
                failure {
                    echo "===== 部署失败 ====="
                    error('部署失败')
                }
            }
        }
    }

    // 全局后置操作
    post {
        always {
            echo "===== Pipeline流程执行完成 ====="
        }
        success {
            echo "===== 全流程成功:拉取→编译→测试→部署 ====="
        }
        failure {
            echo "===== 全流程失败,请检查日志 ====="
        }
    }
}

保存

进行构建

构建成功但是不稳定

验证代码拉取 + 编译

102也推送成功

5.配置 Jenkins 2.528.2 的分布式工作机制,使用 JNLP 协议设置一个远程 agent,实现基于 Docker 容器化构建 Java 项目。

阶段 1:前置环境准备(主节点 + Agent 节点)

1.1 主节点(10.0.0.101)环境配置

1.1.1 安装必要插件

Jenkins 主节点→「Manage Jenkins」→「Plugins」→「Available plugins」,搜索并安装以下插件(需重启 Jenkins):

  • Docker Plugin:Docker 容器管理
  • Docker Pipeline:Pipeline 中操作 Docker
  • JNLP Agent Protocol:JNLP 协议支持(Jenkins 2.528.2 默认自带,验证是否启用)
  • Maven Integration Plugin:Maven 构建支持
  • Publish Over SSH(可选,保留部署功能)
1.1.2 验证主节点 JDK/Maven 配置

「Manage Jenkins」→「Global Tool Configuration」:

  • JDK:名称JDK21,路径指向主节点 JDK21 安装目录(如/usr/lib/jvm/java-21-openjdk-amd64);
  • Maven:名称Maven 3.8.7,路径指向 Maven 安装目录(如/usr/share/maven);
  • Docker:无需配置,由 Agent 节点提供 Docker 环境。

Agent 节点(10.0.0.102)环境配置

安装 JDK21

安装 Docker + 配置权限

安装 Docker Compose

阶段 2:Jenkins 主节点配置远程 Agent(JNLP 协议)

2.1 开启 JNLP 通信端口

「Manage Jenkins」→「Configure Global Security」:

  • 找到「Agents」区域:
    • 勾选「Enable security」;
    • 「TCP port for inbound agents」:选择「Fixed」,填写端口(如50000);
    • 「Agent protocols」:确保勾选「JNLP4-connect」(核心协议,Jenkins 2.528.2 推荐);
  • 点击「Save」保存。

2.2 创建远程 Agent 节点

  1. 「Manage Jenkins」→「Manage Nodes and Clouds」→「New Node」;
  2. 节点配置:
    • Node nameagent-102-docker(自定义,标识 Agent 节点);
    • Type :选择「Permanent Agent」(永久节点);
    • 点击「OK」进入详细配置:
      • Number of executors :填写2(并发构建数,根据 Agent 节点性能调整);
      • Remote root directory/home/jenkins/agent(Agent 工作目录,需提前在 102 节点创建);
      • Labels :填写docker java21(标签,后续 Pipeline 通过标签指定该节点);
      • Usage:选择「Use this node as much as possible」;
      • Launch method:选择「Launch agent by connecting it to the master」(JNLP 方式,Agent 主动连接主节点);
      • Availability :选择「Keep this agent online as much as possible」;
  3. 点击「Save」,进入 Agent 节点详情页,记录以下信息(后续 Agent 启动用):
    • Secret:Agent 连接密钥(页面显示「Agent secret」);
    • Agent URL :主节点地址 + JNLP 端口(如http://10.0.0.101:8080);
    • Agent Jar 下载地址 :页面显示「Download agent.jar」(或主节点地址http://10.0.0.101:8080/jnlpJars/agent.jar)。

阶段 3:Agent 节点(10.0.0.102)启动 JNLP Agent

准备 Agent 工作目录

下载 agent.jar 并启动 Agent

3.3 验证 Agent 连接状态

  • 主节点→「Manage Jenkins」→「Manage Nodes and Clouds」:
    • 节点agent-102-docker状态显示「Online」(绿色),说明连接成功;
    • 若显示「Offline」,检查防火墙(主节点 50000 端口是否开放)、Secret 是否正确

3.4 配置 Agent 后台运行

阶段 4:编写 Docker 容器化构建 Pipeline 脚本

4.1 在 GitLab 仓库添加 Dockerfile(10.0.0.100)

进入test-project-java21仓库,添加Dockerfile(适配 Java21):

4.2 编写 Pipeline 脚本(指定 Agent 节点 + 容器化构建)

在 Jenkins 中创建新 Pipeline 任务(或修改原有任务),脚本如下

复制代码
pipeline {
    // 指定Agent节点(通过标签匹配102节点)
    agent {
        node {
            label 'docker java21'  // 匹配agent-102-docker的标签
        }
    }
    tools {
        jdk 'JDK21'
        maven 'Maven 3.8.7'
    }
    environment {
        GITLAB_REPO_URL = 'http://10.0.0.100/root/test-project-java21.git'
        DOCKER_IMAGE_NAME = 'test-project-java21:v1.0'
        DEPLOY_DIR = '/opt/jenkins-deploy/test-project-java21'
    }
    stages {
        // 阶段1:拉取GitLab代码(Agent节点执行)
        stage('Checkout Code') {
            steps {
                echo "===== Agent节点拉取代码 ====="
                git(
                    url: env.GITLAB_REPO_URL,
                    credentialsId: 'gitlab-http-cred',
                    branch: 'main'
                )
            }
        }

        // 阶段2:Maven编译打包(Agent节点执行)
        stage('Maven Build') {
            steps {
                echo "===== Agent节点编译代码 ====="
                sh 'mvn clean package -DskipTests'
            }
        }

        // 阶段3:Docker构建镜像(Agent节点执行,利用本地Docker环境)
        stage('Docker Build') {
            steps {
                echo "===== Agent节点构建Docker镜像 ====="
                sh "docker build -t ${DOCKER_IMAGE_NAME} ."
            }
        }

        // 阶段4:Docker运行容器(部署到Agent节点)
        stage('Docker Run') {
            steps {
                echo "===== Agent节点启动容器 ====="
                // 停止旧容器(若存在)
                sh "docker rm -f test-project-java21 || true"
                // 启动新容器(挂载部署目录,方便查看文件)
                sh "docker run -d --name test-project-java21 -v ${DEPLOY_DIR}:/app/deploy ${DOCKER_IMAGE_NAME}"
            }
        }

        // 阶段5:验证容器运行
        stage('Verify Container') {
            steps {
                echo "===== 验证容器状态 ====="
                sh "docker ps | grep test-project-java21"
                sh "docker exec test-project-java21 java -jar app.jar"  // 执行容器内JAR包
            }
        }
    }
    post {
        success {
            echo "===== 容器化构建部署成功! ====="
            echo "Docker镜像:${DOCKER_IMAGE_NAME}"
            echo "容器名称:test-project-java21"
        }
        failure {
            echo "===== 构建部署失败 ====="
            error('构建失败')
        }
    }
}

5.1 执行 Pipeline 任务

  • 点击「Build Now」,Jenkins 会将任务调度到agent-102-docker节点执行;
  • 查看 Console Output,确认各阶段:
    • 代码拉取:在 Agent 节点/home/jenkins/agent/workspace/目录;
    • Maven 构建:在 Agent 节点完成,生成 JAR 包;
    • Docker 构建:在 Agent 节点生成镜像;
    • 容器启动:在 Agent 节点运行容器。

5.2 验证结果

  1. Agent 节点(10.0.0.102)验证:

    复制代码
    # 查看Docker镜像
    docker images | grep test-project-java21
    
    # 查看运行中的容器
    docker ps | grep test-project-java21
    
    # 查看容器日志
    docker logs test-project-java21
  2. 验证容器内 JAR 包功能:

    复制代码
    docker exec test-project-java21 java -jar app.jar
    # 输出:JDK21 + Maven3.8.7 测试成功

6.在 Linux 系统上安装 GitLab 18.5.2,完成备份操作后,模拟数据丢失场景,进行数据恢复,并验证恢复后的数据完整性。

首先我们要有一个项目

在ctl执行备份命令

查看是否有备份文件生成

模拟数据丢失场景,直接删除

执行数据恢复操作

停止 GitLab 核心服务

执行恢复命令

重新启动后查看

登录网页查看:恢复成功

7.配置 GitLab 的 HTTPS 安全设置,为 GitLab 服务器生成并安装 SSL 证书。同时,实现对 GitLab 用户的权限管理,包括创建用户组、分配角色和设置访问权限。

创建 GitLab 证书目录并赋予权限

生成私钥

生成证书签名请求并填写信息

复制代码
执行后会提示填写信息,核心填:
# Common Name (e.g. server FQDN or YOUR name) → 输入GitLab服务器的IP(如192.168.1.100)
# 其他信息(国家、组织等)可随意填写

生成证书

修正权限

配置 GitLab 启用 HTTPS

编辑 GitLab 核心配置文件

修改相关配置

应用配置并重启

在浏览器验证测试,因为是私人证书,不安全但是能访问

二、GitLab 用户权限管理(用户组、角色、访问权限)

GitLab 管理员账号(初始 root 账号) 操作,核心是 "创建用户组→创建用户→将用户加入组→给组分配仓库权限"。

(一)步骤 1:创建用户组

用户组用于统一管理多个用户的权限(避免单独分配)。

  1. 登录 GitLab 后,点击顶部导航栏的GroupsNew group
  2. 填写组信息:
    • Group name:输入组名(如dev-team,标识开发团队);
    • Group URL:自动生成(或自定义,如dev-team,作为组的访问路径);
    • Visibility Level:选择Private(仅组内成员可见,实验环境推荐);
  3. 点击Create group完成创建。

(二)步骤 2:创建新用户

  1. 点击顶部导航栏的Admin(扳手图标)→ UsersNew user
  2. 填写用户信息(实验环境可填虚拟数据):
    • Username:用户名(如user1);
    • Email:邮箱(如user1@example.com,无需真实邮箱);
    • Password:设置密码(需符合复杂度:至少 8 位,含字母 / 数字 / 符号);
    • Name:用户全名(如User One);
  3. 点击Create user完成创建。

(三)步骤 3:将用户添加到用户组

  1. 进入刚创建的用户组(如dev-team);

  2. 点击左侧导航栏的MembersAdd members

  3. Select members or groups输入框中搜索目标用户(如user1);

  4. 选择Access level(用户组角色,核心权限说明):

    角色 核心权限
    Owner 组所有者:可管理组、添加 / 删除成员、修改组权限
    Maintainer 可管理组内项目、推送代码、创建分支 / 标签
    Developer 可推送代码、创建分支,但不能删除项目 / 修改组配置
    Reporter 只能查看项目、提交 Issue,不能推送代码
    Guest 只能查看公开项目内容,无提交 / 推送权限
  5. 实验环境推荐选Developer,点击Add to group完成添加

(四)步骤 4:为用户组分配仓库访问权限

将用户组关联到目标仓库(如之前的test-project),实现批量权限分配:

  1. 进入目标仓库(test-project);
  2. 点击左侧导航栏的SettingsMembers
  3. 点击Add group
  4. Select a group输入框中搜索用户组(如dev-team);
  5. 选择Access level(仓库角色,同用户组角色权限);
  6. 点击Invite group完成权限分配。

(五)步骤 5:验证权限生效

  1. 退出管理员账号,用新用户(如user1)登录 GitLab;
  2. 权限验证操作:
    • 若角色是Developer:尝试克隆test-project并推送新代码,能成功即权限生效;
    • 若角色是Reporter:尝试推送代码会提示 "权限不足",仅能查看仓库内容;
  3. 切换不同角色(如将user1改为Guest),重复验证对应权限范围。

8.在 Linux 系统上安装 Prometheus 3.5.0 和 Node Exporter 1.10.2,配置 Prometheus 以监控本地服务器的 CPU、内存和磁盘使用情况,并将监控数据存储到 Prometheus 数据库。

前期准备

确保安装依赖工具

检查端口占用

创建专用用户

下载 Prometheus 3.5.0 安装包

查看系统架构 arch # 输出x86_64则执行以下下载命令 wget https://github.com/prometheus/prometheus/releases/download/v3.5.0/prometheus-3.5.0.linux-amd64.tar.gz -P /tmp/

解压并部署

解压

创建核心目录并移动

设置目录权限

安装并下载Node Exporter 1.10.2

解压并部署

sudo vim /etc/prometheus/prometheus.yml

验证配置的语法

配置系统服务vim

复制代码
/etc/systemd/system/node_exporter.service

创建 Prometheus 系统服务文件(注意将注释换行)

复制代码
 vim /etc/systemd/system/prometheus.service

重载系统并设置开机自启动

查看状态

验证 Prometheus 监控数据与存储

访问10.0.0.102:9090

验证抓取目标(Node Exporter)

  1. 点击 Web UI 顶部的StatusTargets
  2. 查看node_exporter任务的State列,显示UP(绿色),说明 Prometheus 已成功连接 Node Exporter;
  3. 若显示DOWN,检查 Node Exporter 是否运行、9100 端口是否放行、prometheus.yml配置是否正确。

查询核心监控指标(CPU / 内存 / 磁盘)

在 Web UI 的Expression输入框中输入以下指标,点击Execute查询数据:

监控指标 指标含义 查询表达式
CPU 使用率 单核心 CPU 平均使用率 100 - (avg by (cpu) (irate(node_cpu_seconds_total{mode="idle"}[1m])) * 100)
内存使用率 总内存使用率 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100)
根目录磁盘使用率 / 目录的磁盘使用率 100 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100)
磁盘 IO(读) 每秒磁盘读字节数 irate(node_disk_read_bytes_total[1m])
  • 预期结果:查询后下方会显示 "图表" 和 "表格" 数据,有数值且随时间变化,说明指标采集与存储正常。

9.安装 Grafana 12.2.2,并将其与 Prometheus 集成。创建一个 Grafana 仪表板,展示 Node Exporter 收集的系统指标,包括 CPU 使用率、内存使用率、磁盘 I/O 等。

准备环境

安装

复制代码
apt install grafana=12.2.2 -y

配置 Grafana 服务

二、访问 Grafana Web UI 并初始化

步骤 1:登录 Grafana

在浏览器中输入:http://你的服务器IP:3000,进入 Grafana 登录页:

  • 初始账号:admin
  • 初始密码:admin

首次登录会提示 "修改初始密码",按提示设置新密码(记好新密码)。

三、集成 Prometheus 数据源

Grafana 需关联 Prometheus(数据源)才能读取监控指标,步骤如下:

步骤 1:进入数据源配置页面

  1. 登录 Grafana 后,点击左侧导航栏的**(Connections)** → 选择Data Sources
  2. 点击右上角Add data source

步骤 2:选择 Prometheus 数据源

在 "Search by name" 输入框中搜索 "Prometheus",点击Prometheus图标进入配置页。

步骤 3:配置 Prometheus 连接信息

在配置页填写以下核心参数(同主机部署,参数简化):

  • HTTP > URL :输入http://localhost:9090(Prometheus 默认地址);
  • 其他参数保持默认,滚动到页面底部点击Save & test

若提示 "Data source is working",说明 Prometheus 与 Grafana 集成成功。

四、创建系统指标仪表板(导入 Node Exporter 模板)

手动创建 CPU、内存、磁盘 I/O 面板效率低,推荐使用 Grafana 官方的Node Exporter Full模板(ID:1860),该模板已包含所有 Node Exporter 采集的系统指标。

步骤 1:导入仪表板模板

  1. 点击右上方导航栏的加号图标(+) → 选择Import
  2. 在 "Import via grafana.com" 输入框中填写模板 ID:1860,点击Load

步骤 2:关联 Prometheus 数据源

模板加载后,在 "Options" 区域:

  • 点击Import完成导入。

五、验证仪表板数据(核心指标展示)

导入完成后,会自动进入 "Node Exporter Full" 仪表板,可看到以下系统指标面板(数据实时更新):

1. CPU 指标面板

  • 显示CPU 核心使用率(每个 CPU 核心的负载);
  • 显示CPU 平均负载(1 分钟 / 5 分钟 / 15 分钟负载);
  • 显示CPU 状态占比(idle/used/system 等状态的时间占比)。

2. 内存指标面板

  • 显示内存总容量 / 已用 / 可用(以 GB 为单位);
  • 显示内存使用率趋势图
  • 显示Swap 内存使用情况(若开启 Swap)。

3. 磁盘指标面板

  • 显示磁盘总容量 / 已用 / 可用 (按挂载点分类,如/根目录);
  • 显示磁盘 I/O 速率(读 / 写字节数 / 秒);
  • 显示磁盘 IOPS (每秒读写操作数)。

10.安装 SonarQube 9.9.8.100196 和 sonar-scanner 7.3.0.5189。配置 Jenkins 2.528.2 与 SonarQube 集成,实现对 Java 项目的代码扫描,分析代码质量并生成报告,展示代码中的漏洞、代码异味和测试覆盖率等指标

前期准备

安装适配的JDK17

创建专属用户

调整系统内核参数

安装并配置 SonarQube 9.9.8.100196

创建专属目录

下载

解压

重命名目录并赋予权限

配置系统服务vim /etc/systemd/system/sonarqube.service

启动 SonarQube 并设置开机自启

登陆网站查看

2.6 验证 SonarQube Web UI 访问

在浏览器中输入:http://服务器IP:9000,等待页面加载完成:

  • 初始账号:admin
  • 初始密码:admin首次登录会提示修改初始密码,按提示设置新密码(记好新密码)。

SonarQube 初始化(生成访问令牌)

Jenkins 集成 SonarQube 需要通过令牌认证,步骤如下:

  1. 登录 SonarQube Web UI(http://服务器IP:9000);
  2. 点击右上角头像 → My AccountSecurity
  3. 在 "Tokens" 区域,填写:
    • Token Name:jenkins-token(自定义名称);
    • Expires In :留空(永久有效,实验环境);
  4. 点击Generate生成令牌;
  5. 复制生成的令牌(如sqp_xxxxxxxxxxxxxxxxxxxx),保存到本地(仅显示一次,丢失需重新生成)。

Jenkins 集成 SonarQube 配置

安装 SonarQube Scanner 插件

  1. 登录 Jenkins Web UI(http://服务器IP:8080);
  2. 点击左侧Manage JenkinsPluginsAvailable plugins
  3. 在搜索框中输入 "SonarQube Scanner",勾选插件;
  4. 点击Install without restart(安装完成后建议重启 Jenkins);
  5. 验证插件:安装完成后,进入Manage JenkinsPluginsInstalled plugins ,搜索 "SonarQube Scanner",确认状态为 "Installed"。

配置 Jenkins 关联 SonarQube 服务器

  1. 进入 Jenkins → Manage JenkinsSystem
  2. 滚动到 "SonarQube servers" 区域,点击Add SonarQube
  3. 配置参数:
    • Name:SonarQube-9.9.8;
    • Server URLhttp://服务器IP:9000(SonarQube 地址);
    • Server Authentication Token :点击Add → 选择 "Jenkins" 凭证类型:
      • Kind:Secret text;
      • Secret:粘贴步骤四生成的 SonarQube 令牌;
      • ID:sonarqube-token(自定义 ID);
      • Description:SonarQube Jenkins Token;
    • 点击Add保存凭证,然后在下拉框中选择该凭证;
  4. 点击ApplySave 保存配置。

准备 Java 测试项目

拉取Maven示例项目到Jenkins工作目录 sudo git clone https://github.com/SonarSource/sonar-scanning-examples.git /var/lib/jenkins/workspace/sonar-java-maven

赋予Jenkins用户权限 sudo chown -R jenkins:jenkins /var/lib/jenkins/workspace/sonar-java-maven

创建 Jenkins 任务
  1. 登录 Jenkins → 左侧「New Item」→ 输入项目名(如 sonar-java-scan-no-scanner)→ 选择「Freestyle project」→「OK」;
  2. 配置源码(可选,若已手动拉取可跳过):
    • 「Source Code Management」→ 选择 Git → Repository URL:https://github.com/SonarSource/sonar-scanning-examples.git
    • 「Branches to build」:*/master

配置构建步骤(核心:调用 Jenkins 插件的扫描能力):

  • 滚动到「Build」→ 点击「Add build step」→ 选择「Invoke top-level Maven targets」;
  • 配置 Maven 参数(直接调用 SonarQube 扫描):
    • 「Goals」:填写 clean verify sonar:sonar

    • 「Properties」:填写(替换为你的 SonarQube 地址和令牌):

      sonar.host.url=http://10.0.0.101:9000
      sonar.login=sqa_93c70096615a2950aa3f50815a67ae2b55aea919
      sonar.projectKey=jenkins-java-demo-no-scanner
      sonar.projectName=Jenkins-Java-Demo-No-Scanner
      sonar.java.source=11
      sonar.java.target=11

执行 Jenkins 构建,完成扫描
  1. 点击任务左侧「Build Now」→ 等待构建完成(状态为 SUCCESS);
  2. 查看构建日志:点击构建记录(如 #1)→「Console Output」,确认日志中有 "SonarQube analysis finished: SUCCESS"。
验证实验效果(SonarQube 查看报告)
  1. 登录 SonarQube Web UI(http://10.0.0.101:9000);
  2. 首页会显示新项目「Jenkins-Java-Demo-No-Scanner」,点击进入:
    • 查看「Vulnerabilities」(漏洞):如 SQL 注入、空指针等;
    • 查看「Code Smells」(代码异味):如冗余代码、格式不规范;
    • 查看「Coverage」(测试覆盖率):示例项目自带测试代码,会显示覆盖率数值;
    • 查看「Duplications」(代码重复率)、「Metrics」(代码复杂度)等指标。
相关推荐
IT WorryFree14 小时前
基于Fortinet MIB实现设备资产管理完整方案
运维·服务器·网络
鼎讯信通14 小时前
宽频高敏・全域监测|鼎讯 DXMP 系列,打造风电射频侦测新范式
运维·能源·信息与通信
网络系统管理14 小时前
第八届江苏技能状元大赛选拔赛信息通信网络运行管理项目模块D网络服务与系统运维-Linux样题
linux·运维
Sunny_202283714 小时前
CAD在执行移动命令的时候按正交F8,老是卡住
运维·pccad插件、cad·pccad个人免费版·免费cad插件
零陵上将军_xdr14 小时前
Shell流程控制:if/case/for/while让脚本活起来
linux·运维·服务器
志栋智能14 小时前
从云端到边缘:无处不在的超自动化巡检需求
运维·自动化
BJ_Bonree15 小时前
聊点技术 | 从“统一接入“到“统一调度“:重塑可观测平台的数据底座
运维·人工智能·可观测性
AOwhisky15 小时前
学习自测与解析:Redis系列第一期与第二期核心知识点详解
运维·数据库·redis·学习·云计算
流浪00115 小时前
Linux系统篇(五):Linux 进程控制全解:fork、exec、wait 核心原理与实战
linux·运维·服务器
从入门到放弃-咖啡豆15 小时前
记录一次docker部署过程和一些常用的docker指令
运维·docker·容器