📖 引言:为什么我们需要DevOps?
在云原生和敏捷开发成为主流的当下,DevOps 不再是 "概念",而是企业落地快速交付、保障系统稳定性的核心能力。本次实验以 "企业级业务代码发布系统" 为目标,搭建了从代码提交→版本管理→自动化构建→镜像仓库→一键部署 的全流程 CI/CD 闭环,覆盖 DevOps 核心工具链(GitLab/Jenkins/Harbor/Docker),既还原了生产环境的核心场景,也验证了 DevOps"自动化、标准化、可追溯" 的核心思想。
想象一下这样的场景:开发小哥写完代码,通过U盘拷贝给运维小哥,运维人员再手动上传到服务器。如果出错了,开发说"我本地是好的",运维说"你环境没配对"。这就是典型的"部门墙"。
DevOps(开发运维一体化) 的出现,就是为了解决这个问题。简单来说,它就是一套**"代码提交后,自动构建、自动测试、自动上线"**的流水线。
今天,我将带你用 Red Hat Enterprise Linux 9.3 (RHEL 9.3) 作为基石,搭建一套包含 GitLab(代码仓库)→ Jenkins(自动化引擎)→ Harbor(镜像仓库)→ WebServer(生产环境) 的完整企业级发布系统。
一、实验架构与核心目标
1.1 整体架构设计
本次实验采用 5 节点分布式架构,还原企业级部署的核心拓扑,各节点职责清晰、联动闭环:

1.2 节点角色与资源规划
| 节点角色 | IP 地址 | 核心职责 | 资源配置 | 关键技术要求 |
|---|---|---|---|---|
| 开发机 | 192.168.170.20 | 代码编写、Git 提交 | 2G 内存 | Git 版本管理、Dockerfile 编写 |
| GitLab | 192.168.170.21 | 代码仓库、版本控制 | 4G 内存 | GitLab 部署、SSH 密钥配置 |
| Harbor | 192.168.170.22 | Docker 镜像仓库、权限管理 | 2G 内存 | Harbor 部署、镜像仓库权限控制 |
| Jenkins | 192.168.170.23 | CI/CD 流水线、自动化构建 | 4G 内存 | Jenkins 流水线编写、SSH 免密部署 |
| WebServer | 192.168.170.24 | 应用部署、容器运行 | 2G 内存 | Docker 容器运维、镜像拉取 |
1.3 核心目标
- 实现 "代码提交→自动构建→镜像推送→一键部署" 的无人工干预闭环;
- 解决环境不一致、部署效率低、故障排查慢等传统发布的痛点;
- 验证 DevOps 核心工具链的联动能力,掌握生产级别的权限 / 凭证管理规范;
- 为后续 AIOps(智能运维)拓展打下基础(如日志分析、故障自动自愈)。
二、关键步骤与核心技术突破
2.1 基础环境标准化:所有节点的前置配置
环境一致性是 DevOps 的基础,本次实验首先完成全节点的标准化配置,避免后续部署踩坑:
(1)安全策略配置(生产级规范)
在每台服务器上执行:
# 关闭防火墙(生产环境建议"最小端口开放",实验简化)
systemctl stop firewalld && systemctl disable firewalld
# 关闭SELinux(避免权限拦截Docker/SSH操作)
setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
(2)本地 YUM 源配置
挂载 RHEL 9.3 光盘作为本地源,解决外网依赖问题,保证部署速度:
# 挂载光盘
mount /dev/sr0 /mnt
# 创建本地yum源
cat > /etc/yum.repos.d/local.repo << 'EOF'
[base01]
name=base
baseurl=/mnt/BaseOS
enable=1
gpgcheck=0
[base02]
name=app
baseurl=/mnt/AppStream
enable=1
gpgcheck=0
EOF
# 清理缓存
yum clean all && yum makecache
2.2 Docker安装部署(所有需要Docker的服务器)
服务器:Harbor(192.168.170.22)、Jenkins(192.168.170.23)、Web Server(192.168.170.24)
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker(指定版本)
# 查看可用版本:yum list docker-ce --showduplicates | sort -r
yum install -y docker-ce-29.3.0 docker-ce-cli-29.3.0 containerd.io docker-compose-plugin
# 启动Docker
systemctl enable docker
systemctl start docker
配置Docker阿里云镜像加速器(重要!)
# 创建docker配置目录
mkdir -p /etc/docker
# 配置镜像加速器
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.cn",
"https://registry.docker-cn.com",
"https://mirror.ccs.tencentyun.com"
],
"insecure-registries": ["192.168.170.22"]
}
EOF
# 重启Docker
systemctl daemon-reload
systemctl restart docker
# 验证加速器是否生效
docker info | grep -A 10 "Registry Mirrors"
国内常用Docker镜像加速器:
| 加速器地址 | 提供商 |
|---|---|
| https://docker.1ms.run | 民间加速器 |
| https://docker.xuanyuan.cn | 玄学加速器 |
| https://registry.docker-cn.com | Docker官方中国镜像 |
| https://mirror.ccs.tencentyun.com | 腾讯云镜像 |
| https://mirror.azure.cn | Azure中国镜像 |
2.3 GitLab:代码仓库的企业级部署(192.168.170.21)
(1)核心配置要点
-
采用清华源加速安装,避免官方源下载慢;
-
配置
external_url为节点 IP,保证跨节点访问; -
解决 GitLab 初始化 502 问题:等待 3-5 分钟完成初始化,重启 Nginx+Puma 组件;
编写yum源
cat > /etc/yum.repos.d/gitlab.repo <<end
[gitlab]
name=gitlab-ce
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el9/
enabled=1
gpgcheck=0
end#安装
yum install -y gitlab-ce#配置
vim /etc/gitlab/gitlab.rb
external_url 'http://192.168.170.21'
#http://192.168.170.21必须是 GitLab 所在服务器的实际网卡 IP#使配置生效
重新启动gitlab-ce(更改过设置,重新启动,首次配置约需3-5分钟)gitlab-ctl reconfigure
gitlab-ctl restart

#查看初始密码,用于登录
[root@GitLab ~]# awk '/^Password/ {print $NF}' /etc/gitlab/initial_root_password
clcUfpsxdsUw2cJ6+4yO8ypYLl5G7osm5P9FglH0pOY=

(2)终极修复步骤(按顺序执行)
# 1. 等待 GitLab 完全初始化(关键!)
sleep 300 # 等待 5 分钟
# 2. 本地测试 Nginx 访问(用 curl 分别测试 80/8080 端口,定位 502 发生在 Nginx 还是 Puma)
curl -I http://127.0.0.1
# 3. 若仍 502,重启 Nginx + Puma
gitlab-ctl restart nginx puma
# 4. 关闭防火墙/SELinux 测试
systemctl stop firewalld
setenforce 0
(3)初始化GitLab(详细图文步骤)
第一步:访问GitLab
-
打开浏览器,输入:
http://192.168.170.21 -
等待服务启动(约2-3分钟)
第二步:设置root密码
-
首次访问会看到设置密码页面
-
输入新密码:
redhat123(需要输入两次) -
点击"Change your password"

第三步:登录
-
用户名:
root -
密码:
redhat123 -
点击"Sign in"
GitLab页面配置 - 创建项目
第一步:创建新项目
-
登录后,点击左上角"Menu" → 选择"Projects"
-
点击页面上的"New project"按钮(蓝色)

第二步:填写项目信息
-
Project name(项目名称):
hello-web -
Project URL(项目URL):自动填充为
/root/hello-web -
Description(描述,可选):填写项目描述
-
Visibility Level(可见级别):选择"Public"
-
勾选"Initialize repository with a README":不勾选(我们手动推送代码)
-
点击"Create project"

2.4 Harbor:企业级镜像仓库的落地
(1)安装Harbor
# 获取docker-compose文件
# wget https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64
# 查看文件
ls
docker-compose-linux-x86_64
# 移动位置
mv docker-compose-linux-x86_64 /usr/bin/docker-compose
# 添加执行权限
chmod +x /usr/bin/docker-compose
# 查看版本
docker-compose version
Docker Compose version v2.2.3
# 下载Harbor(选择需要的版本)
# wget https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz
# 解压
tar -zxf harbor-offline-installer-v2.14.0.tgz
cd harbor
# 复制配置文件
cp harbor.yml.tmpl harbor.yml
# 修改配置
vim harbor.yml
(2)配置优化
-
注释 HTTPS 配置(实验环境简化,生产环境必须开启);
-
修改
hostname为节点 IP,保证跨节点镜像推送 / 拉取;harbor.yml核心修改
第5行:hostname改为服务器IP
hostname: 192.168.170.22
http:
port: 80https相关配置注释(生产环境需配置证书)
启动Harbor
# 运行安装脚本
./install.sh
[root@Harbor] # ./prepare
# 启动Harbor(后台运行)
docker-compose up -d
# 查看状态
docker-compose ps
Harbor容器列表:
| 容器名 | 镜像 | 说明 |
|---|---|---|
| harbor-core | harbor-core:v2.10.2 | 核心服务 |
| harbor-db | harbor-db:v2.10.2 | 数据库 |
| harbor-jobservice | harbor-jobservice:v2.10.2 | 任务服务 |
| harbor-log | harbor-log:v2.10.2 | 日志服务 |
| harbor-portal | harbor-portal:v2.10.2 | Web界面 |
| nginx | nginx:1.25 | 反向代理 |
| redis | redis:7.2 | 缓存 |
| registry | registry:2.8 | 镜像仓库 |
(3)仓库管理规范
-
创建
library公共项目,用于存储实验镜像; -
配置 Jenkins/WebServer 免密登录 Harbor,避免凭证硬编码:
登录Harbor并保存凭证
docker login 192.168.170.22 -u admin -p Harbor12345
第一步:访问Harbor
-
打开浏览器,输入:
http://192.168.170.22 -
用户名:
admin -
密码:
Harbor12345 -
点击"Log in"
第二步:创建项目
-
登录后,点击"Projects"(项目)
-
点击"New Project"(新建项目)
-
填写:
-
Project Name(项目名):
library -
Access Level(访问级别):选择"Public"(公开)
-
-
点击"OK"

2.5 Jenkins:CI/CD 流水线的核心搭建
(1)安装Jenkins
版本:Jenkins 2.541.2 (LTS)
bash
wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/rpm-stable/jenkins.repo
# 为 Jenkins 包添加所需的依赖项
yum install fontconfig java-21-openjdk
yum install jenkins
systemctl daemon-reload
# 启动Jenkins
systemctl enable jenkins
systemctl start jenkins
#流水线能够正常拉取代码的基础依赖
[root@Jenkins updates]# yum install git -y
更换插件地址
[root@jenkisn-server ~]# cd /var/lib/jenkins/updates
[root@jenkisn-server updates]# sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
然后在Manage Plugin 中点击Advanced,把Update Site改为国内插件下载地址
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
(2)Jenkins页面配置(详细步骤)
第一步:解锁Jenkins
-
打开浏览器,输入:
http://192.168.170.23:8080 -
会看到"Unlock Jenkins"页面
-
获取初始管理员密码:
cat /var/lib/jenkins/secrets/initialAdminPassword -
将密码粘贴到页面输入框
-
点击"Continue"
第二步:安装插件
-
选择"Install suggested plugins"(安装推荐的插件)
-
等待插件安装完成(约5-10分钟)
-
如果部分插件安装失败,可以跳过(因为无法访问外网)

第三步:创建管理员用户
-
安装完成后,输入:
-
Username:
admin -
Password:
redhat123 -
Confirm password:
redhat123 -
Full name:
Admin -
Email:
admin@example.com
-
-
点击"Save and Continue"
第四步:配置Jenkins URL
-
Jenkins URL:
http://192.168.170.23:8080 -
点击"Save and Finish"

第四步:配置Jenkins URL
-
Jenkins URL:
http://192.168.223.23:8080 -
点击"Save and Finish"
第五步:环境适配与插件管理
- 安装 Java 21,适配 Jenkins LTS 版本要求;
- 更换清华源 / 华为云源,解决插件下载慢 / 失败问题;
- 安装核心插件:Git、GitLab、Docker、Publish Over SSH、Generic Webhook Trigger(覆盖 CI/CD 全流程)。
- 安装常用插件✅
- 然后在Manage Plugin 中点击Advanced,把Update Site改为国内插件下载地址
- 另外安装插件
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
https://repo.huaweicloud.com/jenkins/updates/update-center.json
(1)git parameter
用于基于git版本提交进行参数构建项目

(2)gitlab
用于jenkins-server拉取项目

(3)Generic Webhook Trigger
用于项目自动化构建

(4)ssh
用于jenkins-server对web-server实施项目部署

(5) Publish over SSH
通过SSH发送文件或者执行命令

三、生产级凭证管理(核心亮点)
凭证管理是企业级 DevOps 的关键,本次实验实现全链路无明文凭证:
Jenkins 凭据能避免敏感信息(私钥 / 密码)留存服务器,是 CI/CD 最佳实践;
3.1 前置说明
| 凭证类型 | 作用场景 | 配置目标 |
|---|---|---|
| Dev/GitLab SSH 密钥 | Dev 机免密推送代码到 GitLab | Dev 机 + GitLab 后台 |
| Jenkins/GitLab SSH 密钥 | Jenkins 免密拉取 GitLab 代码 | Jenkins 机 + GitLab 后台 |
| Jenkins/Harbor 凭据 | Jenkins 免密推送镜像到 Harbor | Jenkins 后台(凭据管理) |
| Jenkins/Web Server SSH 密钥 | Jenkins 免密部署到 Web Server | Jenkins 机 + Web Server + Jenkins 后台 |
| Web Server/Harbor 凭证 | Web Server 免密拉取 Harbor 镜像 | Web Server(Docker 配置) |
3.2 详细配置步骤
3.2.1 Dev/GitLab SSH 密钥配置(Dev 机免密推送代码)
步骤 1:Dev 机(192.168.170.20)生成 SSH 密钥对
# 切换到root用户(原文档统一用root操作)
su - root
# 生成无密码SSH密钥对(-f指定路径,-P''空密码,-q静默模式)
ssh-keygen -f ~/.ssh/id_rsa -P '' -q
# 查看生成的公钥(后续复制到GitLab)
cat ~/.ssh/id_rsa.pub
步骤 2:GitLab 后台添加 Dev 机公钥
-
访问 GitLab:
http://192.168.170.21,使用root/redhat123登录; -
点击右上角头像 → 设置 → SSH 密钥;
-
在「密钥」输入框粘贴 Dev 机公钥,「标题」填写
root@dev(便于识别); -
点击「添加密钥」完成配置。
步骤 3:验证免密推送
# Dev机上测试Git免密推送(替换原HTTPS地址为SSH地址)
cd /root/hello-web
git remote set-url origin git@192.168.170.21:root/hello-web.git
# 推送代码(无需输入密码)
git push origin master
3.2.2 Jenkins/GitLab SSH 密钥配置(Jenkins 免密拉取代码)
步骤 1:Jenkins 机(192.168.170.23)生成 SSH 密钥对
# 切换到jenkins用户(Jenkins服务默认运行用户,避免权限问题)
su - jenkins -s /bin/bash
# 生成无密码SSH密钥对
ssh-keygen -f ~/.ssh/id_rsa -P '' -q
# 查看公钥(复制到GitLab)
cat ~/.ssh/id_rsa.pub
# 查看私钥(后续配置到Jenkins凭据,先复制保存)
cat ~/.ssh/id_rsa
[jenkins@Jenkins ~]$ cat ~/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEA4pJnckZpCSptY+/VcRiydEk3T1Tm66vDfnkati2Unf7lLftfrHmV
emCgH6YTNjmaJt+P/HPft3OJAkuj/EigQaOBVrPzhd05XKSDwg6iovZPIQsRk2UdMtkoY8
0bq+MPqXVq5vJijR3kmy5yaJoUvoB37i/3PzBHZBCAC9lvCuvhuNbigV340VII3hlrC9x1
u+FUawLn7IIBzTu+m02KaRe0xcv8/MkWyM8p9QdHqq1paUlbKOQs0gBhrx8G2N4fMqK8ov
...
-----END OPENSSH PRIVATE KEY-----
步骤 2:GitLab 后台添加 Jenkins 公钥
-
登录 GitLab → 右上角头像 → 设置 → SSH 密钥;
-
粘贴 Jenkins 机公钥,标题填写
jenkins@jenkins-server; -
点击「添加密钥」。
步骤 3:Jenkins 后台配置 GitLab SSH 私钥凭据
-
访问 Jenkins:
http://192.168.170.23:8080,使用admin/redhat123登录; -
左侧菜单 → 凭据 → 系统 → 全局凭据 → 添加凭据;
-
配置项(关键):
- 类型:选择「SSH Username with private key」;
- ID:填写
gitlab-ssh-cred(后续流水线引用,自定义但需统一); - 描述:填写
jenkins to gitlab ssh key(便于识别); - 用户名:填写
root(GitLab 登录用户); - 私钥:选择「直接输入」,粘贴 Jenkins 机生成的私钥;
4.点击「确定」完成配置。
[jenkins@Jenkins ~]$ ssh git@192.168.170.21
Warning: Permanently added '192.168.170.21' (ED25519) to the list of known hosts.
PTY allocation request failed on channel 0
Welcome to GitLab, @root!
Connection to 192.168.170.21 closed.
3.2.3 Jenkins/Harbor 凭据配置(Jenkins 免密推送镜像)
步骤 1:Jenkins 后台添加 Harbor 账号密码凭据
-
Jenkins 后台 → 凭据 → 系统 → 全局凭据 → 添加凭据;
-
配置项(关键):
- 类型:选择「用户名和密码」;
- ID:填写
harbor-cred(后续流水线引用); - 描述:填写
jenkins to harbor login; - 用户名:填写
admin(Harbor 默认管理员); - 密码:填写
Harbor12345(Harbor 默认密码);
3.点击「确定」。
3.2.4 Jenkins/Web Server SSH 密钥配置(Jenkins 免密部署)
步骤 1:Jenkins 机生成 SSH 密钥(复用 GitLab 的密钥即可,无需重复生成)
bash
在jenkins主机上操作:
# 切换到jenkins用户,确认密钥存在
su - jenkins -s /bin/bash
cat ~/.ssh/id_rsa.pub # 复制该公钥
步骤 2:Web Server(192.168.170.24)配置 Jenkins 公钥
bash
# 切换到root用户
su - root
# 创建.ssh目录(若不存在)
mkdir -p ~/.ssh
chmod 700 ~/.ssh # 必须700权限,否则SSH免密失效
# 将Jenkins公钥添加到authorized_keys
echo "Jenkins机的公钥内容" >> ~/.ssh/authorized_keys
# 设置文件权限(必须600,否则SSH拒绝)
chmod 600 ~/.ssh/authorized_keys
步骤 3:Jenkins 后台配置 Web Server SSH 私钥凭据
-
Jenkins 后台 → 凭据 → 系统 → 全局凭据 → 添加凭据;
-
配置项(关键):
- 类型:选择「SSH Username with private key」;
- ID:填写
web-server-ssh-cred; - 描述:填写
jenkins to web-server ssh key; - 用户名:填写
root(Web Server 登录用户); - 私钥:粘贴 Jenkins 机的私钥;
3.点击「确定」。

3.2.5 Web Server/Harbor 凭证配置(Web Server 免密拉取镜像)
步骤:Web Server 登录 Harbor 并保存凭证
bash
# Web Server(192.168.170.24)执行
docker login 192.168.170.22 -u admin -p Harbor12345
# 验证凭证是否自动保存(加密存储在config.json)
cat /root/.docker/config.json
输出示例(密码已加密,无明文):
bash
[root@web-server ~]# cat /root/.docker/config.json
{
"auths": {
"192.168.170.22": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
}
}
说明 :后续 Web Server 执行docker pull 192.168.170.22/library/hello-web:latest时,Docker 会自动读取该文件的凭证,无需重复输入账号密码。

3.2.6 Jenkins创建流水线任务(详细步骤)
核心流水线实现 "拉取代码→构建镜像→推送 Harbor→部署到 WebServer" 闭环:
第一步:新建任务
-
点击Jenkins主页左侧的"新建Item"(New Item)
-
输入任务名称:
hello-web-build -
选择"流水线"(Pipeline)
-
点击"确定"
第二步:配置流水线
-
在"流水线"区域,选择"Pipeline script"
-
在脚本框中粘贴以下内容:
bash
pipeline {
agent any
environment {
// 基础配置(仅保留IP,无http/ssh前缀)
GITLAB_URL = "192.168.170.21"
HARBOR_URL = "192.168.170.22"
WEB_SERVER = "192.168.170.24"
// 从Jenkins凭证库加载凭证(对应你的凭证ID)
GITLAB_SSH_CREDS = credentials('gitlab-ssh-cred') // GitLab SSH密钥凭证
HARBOR_CREDS = credentials('harbor-cred') // Harbor账号密码凭证
WEB_SERVER_SSH_CREDS = credentials('web-server-ssh-cred') // Web服务器SSH密钥凭证
}
stages {
stage('Clone Code (SSH)') {
steps {
echo 'Cloning code from GitLab via SSH...'
sh '''
# 清理旧代码目录(不存在则忽略错误)
rm -rf hello-web || true
# SSH方式克隆代码(核心:使用GitLab SSH地址,无需密码)
# 格式:git clone git@GitLabIP:项目路径.git
git clone git@${GITLAB_URL}:root/hello-web.git
# 验证克隆结果
if [ ! -d "hello-web" ]; then
echo "❌ Git SSH克隆失败!"
exit 1
fi
# 列出目录内容,确认代码拉取成功
ls -la hello-web/
'''
}
}
stage('Build Docker Image') {
steps {
echo 'Building Docker image...'
sh '''
cd hello-web
# 构建镜像并打Harbor标签
docker build -t ${HARBOR_URL}/library/hello-web:latest .
# 验证镜像构建成功
docker images | grep hello-web
'''
}
}
stage('Push to Harbor') {
steps {
echo 'Pushing image to Harbor...'
sh '''
# 使用Harbor凭证登录(自动拆分用户名/密码)
docker login ${HARBOR_URL} -u ${HARBOR_CREDS_USR} -p ${HARBOR_CREDS_PSW}
# 推送镜像到Harbor
docker push ${HARBOR_URL}/library/hello-web:latest
'''
}
}
stage('Deploy to Web Server (SSH)') {
steps {
echo 'Deploying to Web Server via SSH...'
// 使用SSH密钥免密登录Web服务器(无需sshpass)
sshagent(['web-server-ssh-cred']) {
sh '''
# 关键修正:here-document的EOF必须顶格,且前后无空格
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@${WEB_SERVER} << EOF
# 停止并删除旧容器(不存在则忽略错误)
docker rm -f hello-web || true
# 拉取最新镜像(失败则退出)
if ! docker pull ${HARBOR_URL}/library/hello-web:latest; then
echo "拉取镜像失败"
exit 1
fi
# 启动新容器
docker run -d --name hello-web -p 80:80 ${HARBOR_URL}/library/hello-web:latest
EOF
'''
}
}
}
}
post {
success {
echo '✅ Deployment successful (SSH mode)!'
}
failure {
echo '❌ Deployment failed (SSH mode)!'
}
}
}
3.点击"保存"
四、开发机配置dev(192.168.170.20)
4.1 准备项目代码
创建项目目录和文件:
bash
# 创建项目目录
mkdir -p /root/hello-web
cd /root/hello-web
创建index.html
bash
<!DOCTYPE html>
<html>
<head>
<title>Hello DevOps</title>
</head>
<body style="font-family:Arial;text-align:center;padding:50px;">
<h1 style="color:green;">Hello DevOps!</h1>
<p>Build Success!</p>
</body>
</html>
创建 Dockerfile:
bash
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
4.2.初始化Git并推送
bash
# 进入项目目录
cd /root/hello-web
# 初始化Git仓库
[root@dev hello-web]# yum install git -y
git init
# 配置用户信息
git config --global user.name "developer"
git config --global user.email "developer@example.com"
# 添加远程仓库
git remote add origin http://root:redhat123@192.168.223.21/root/hello-web.git
# 添加所有文件
git add .
# 提交代码
git commit -m "Initial commit - Hello DevOps HTML page"
# 推送到GitLab
git push -u origin master
可以看到GitLab的hello-web项目里面已经存在这两个文件了:

3.进入项目构建历史
从项目主页进入hello-web-build流水线,查看所有构建记录。这一步的目的是快速定位失败的构建任务,避免每次都重新跑完整流水线,节省调试时间。

2.打开构建的「控制台输出」
点击失败构建右侧的下拉菜单,选择「Console Output」。这是 Jenkins 里唯一能看到流水线每一步执行细节、错误日志、命令输出的地方,所有构建失败的根本原因都会在这里暴露。

3.分析日志并验证修复
截图中可以看到,我修复后的构建 #4 最终显示Finished: SUCCESS,并且日志里明确输出了Deployment successful (SSH mode)!。这一步验证了我之前对问题的判断(SSH Agent 插件 / 网络配置问题)是正确的,也证明了修复方案的有效性。

然后就可以通过web-server查看到html的内容了!

五、Web Server配置
5.1 修改veb上的html代码
bash
[root@dev hello-web]# vim index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello DevOps</title>
</head>
<body style="font-family:Arial;text-align:center;padding:50px;">
<h1 style="color:blue;">Hello DevOps!</h1>
<p>Build Success again!</p>
</body>
</html>
5.2 提交代码
bash
[root@dev hello-web]# git add . #重新上传代码
[root@dev hello-web]# git commit -m "Update: 描述修改内容"
[master 94f1f02] Update: 描述修改内容
1 file changed, 2 insertions(+), 2 deletions(-)
[root@dev hello-web]# git push origin master
枚举对象中: 5, 完成.
对象计数中: 100% (5/5), 完成.
使用 2 个线程进行压缩
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 365 字节 | 365.00 KiB/s, 完成.
总共 3(差异 1),复用 0(差异 0),包复用 0(来自 0 个包)
To http://192.168.170.21/root/hello-web.git
f79fb92..94f1f02 master -> master
5.3 然后刷新GitLab
可以明显的看到html多了一个标签

5.4 Jenkins重新触发构建
-
点击任务:
hello-web-build -
点击左侧:"立即构建"
5.5 查看结果
访问网站:http://192.168.170.24

5.6 全流程验证
- 开发机编写
index.html和Dockerfile,提交到 GitLab; - Jenkins 自动触发流水线,完成镜像构建→推送→部署;
- 访问 WebServer IP(192.168.170.24),验证页面正常访问;
- 查看 Harbor 仓库,确认镜像已推送;查看 WebServer 容器状态,确认部署成功。
六、实验中的难点与解决方案
6.1 GitLab 初始化 502 错误
- 原因:GitLab 初始化需要加载 PostgreSQL/Redis 等组件,耗时 3-5 分钟,提前访问会出现 502;
- 解决方案:等待初始化完成,重启 Nginx+Puma 组件,关闭防火墙 / SELinux 避免拦截。
6.2 Jenkins 推送 Harbor 镜像失败
- 原因:Harbor 未配置为 "不安全仓库",Docker 拒绝推送;
- 解决方案 :在 Docker daemon.json 中添加
insecure-registries: ["192.168.170.22"],重启 Docker。
6.3 Jenkins 免密部署到 WebServer 失败
- 原因:SSH 密钥权限错误(.ssh 目录需 700,authorized_keys 需 600);
- 解决方案:严格配置 SSH 文件权限,验证 Jenkins 用户能免密登录 WebServer。
6.4 插件下载失败
- 原因:Jenkins 默认源访问慢 / 被墙;
- 解决方案:更换清华源 / 华为云源,手动下载插件包上传安装。
七、实验价值与亮点
7.1 技术层面
- 掌握 DevOps 核心工具链的企业级部署与联动,理解 "流程即代码" 的思想;
- 熟悉生产级别的凭证 / 权限管理规范,避免安全漏洞(如凭证硬编码);
- 具备流水线问题排查能力,能定位镜像构建、网络访问、权限配置等核心问题。
7.2 亮点分析
- "本次实验搭建了覆盖代码提交到部署的完整 CI/CD 闭环,核心解决了传统发布中'环境不一致、人工操作多、故障排查慢'的问题,还原了企业级 DevOps 的核心流程;"
- "在凭证管理上,采用 Jenkins 凭据中心统一管理 SSH 密钥和账号密码,避免明文存储,符合生产环境的安全规范;"
- "流水线设计考虑了可维护性(环境变量解耦)和资源清理(post 阶段删除镜像),兼顾功能与性能;"
- "后续可拓展 AIOps 能力,比如采集 Jenkins 构建日志,用 Python + 机器学习识别构建失败原因,实现故障自动预警。"
7.3 岗位适配性
- DevOps 工程师:体现流水线设计、工具配置、权限管理能力;
- 运维工程师:体现环境搭建、容器运维、故障排查能力;
- SRE 工程师:体现高可用设计、自动化部署、稳定性保障思路。
八、总结与拓展
本次实验是 DevOps 落地的 "最小闭环",覆盖了工具部署、流程设计、权限管理、问题排查等核心环节,既验证了 DevOps"自动化、标准化" 的核心思想,也为后续拓展打下基础:
- 横向拓展:接入 K8s 实现容器编排,替代单节点 Docker 部署;
- 纵向拓展:接入 AIOps 实现日志分析、故障自动自愈;
- 安全拓展:接入 SonarQube 实现代码质量检测,接入 Vault 实现凭证动态管理。
DevOps 的核心不是 "工具堆砌",而是 "流程优化"------ 本次实验的价值在于,从 "解决实际问题" 出发,把抽象的 DevOps 理念落地为可执行、可验证的流程,这也是企业招聘中最看重的 "实战能力"。