Ubuntu 18.04 Jenkins 安装实战:绕过官方源与Docker陷阱
1. 项目概述:为什么在 Ubuntu 18.04 上装 Jenkins 不是“照着命令敲一遍”就完事的事
Jenkins 是我过去八年里搭过最多次、改过最多遍、救过最多次火的自动化平台。它不像 nginx 那样装完就能跑,也不像 git 那样开箱即用——它是个活的、会呼吸的、需要持续调教的“流水线引擎”。而 Ubuntu 18.04 这个发行版,在 2025 年回头看,它既不是最老的 LTS(16.04 更老),也不是最新的(20.04/22.04 已成主流),但它恰恰卡在一个特别典型的“生产环境现实断层”上:大量企业内网服务器、老旧虚拟机、客户交付环境仍稳定运行着 18.04,因为升级 OS 涉及整套中间件兼容性验证,成本远高于维持现状。所以,“How To Install Jenkins on Ubuntu 18.04”这个标题背后,根本不是教你怎么打几行命令,而是解决一个真实场景:在受限、陈旧、不可轻易重启、可能连外网都不稳定的生产级 Ubuntu 18.04 环境中,把 Jenkins 装得稳、启得快、插件装得全、后续不崩盘。
我见过太多人卡在第一步:sudo apt install jenkins后发现装的是 2.150 版本(Ubuntu 18.04 官方源默认包),而这个版本连 Pipeline Syntax 的自动补全都残缺,更别说对 Java 11+、Docker Socket、Kubernetes Plugin 的支持。也有人图省事用docker run -p 8080:8080 jenkins/jenkins:lts,结果发现容器里/var/jenkins_home权限不对,一重启配置全丢;还有人用pip install jenkins——这压根就是个 Python 的 Jenkins REST API 客户端库,跟安装 Jenkins 服务完全两码事,热搜词里混进来的pip install和jenkins组合,正是新手最容易踩的语义陷阱。至于wsl --install相关热词,那是 Windows 用户在 WSL2 里折腾 Ubuntu 子系统的副产品,和原生 Ubuntu 18.04 服务器部署无关,但恰恰说明:很多人是在开发机或本地测试环境先摸熟 Jenkins,再迁移到真实服务器,所以本地环境的卡顿(如wsl --install 太慢)和报错(如wsl/callmsi/install/e_unexpected)会直接影响他们对整个安装流程的信心。
真正决定成败的,从来不是“能不能装上”,而是“装完之后能不能立刻干活”。比如你刚配好 Jenkins,想拉一个 Git 仓库自动构建,结果控制台报failed to resolve host name mirrors.tuna.tsinghua.edu.cn——这不是 Jenkins 的错,是 Ubuntu 18.04 的 DNS 解析策略在某些网络环境下会缓存失败响应,导致后续所有 apt 源、插件更新、甚至 Maven 下载都卡死;又比如你用sudo apt-get install g++失败,提示E: Unable to locate package g++,这其实是 Ubuntu 18.04 默认没启用universe源,而 Jenkins 构建 Java 项目时,Maven 编译阶段如果依赖本地 C++ 工具链(比如 JNI 扩展),就会当场哑火。这些细节,官方文档不会写,菜鸟教程不会提,但它们就是你凌晨两点排查构建失败时,真正堵在喉咙里的那根刺。
所以这篇内容,不讲“Jenkins 是什么”“CI/CD 有什么用”这种泛泛而谈的概念。我们只聚焦 Ubuntu 18.04 这一个操作系统版本,从零开始,把每一个命令背后的意图、每一个配置项的取舍、每一个报错的真实原因,掰开揉碎了说清楚。你会看到:为什么必须用.deb包而非apt源安装?为什么JAVA_HOME不能只设环境变量,还要在 Jenkins 启动脚本里硬编码?为什么插件离线安装比在线安装更可靠?为什么systemctl restart jenkins有时根本没重启进程?这些都不是玄学,是 Ubuntu 18.04 + Jenkins 组合下,被无数人验证过的、血淋淋的操作铁律。
2. 核心设计思路与方案选型:为什么放弃“一键安装”,选择“三段式可控部署”
2.1 放弃 Ubuntu 官方源安装:2.150 版本的硬伤无法绕过
Ubuntu 18.04 的apt源里 Jenkins 包版本固定为2.150.3(截至 2025 年 4 月)。这个版本发布于 2018 年底,距今已超六年。它的致命缺陷不是功能少,而是底层架构与现代工具链存在不可调和的冲突:
Java 版本锁死:它强制依赖 OpenJDK 8,且启动脚本里硬编码了
-Djava.awt.headless=true -Dfile.encoding=UTF-8 -DJENKINS_HOME=/var/lib/jenkins,如果你强行用 Java 11 启动,Jenkins 会直接拒绝加载核心类(java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContext),因为 JAXB 在 Java 11 中已被移除。而很多新项目(尤其是 Spring Boot 2.3+)要求 Java 11 编译,这就形成死循环:Jenkins 用不了新 Java,新 Java 项目又没法在旧 Jenkins 里编译。插件生态断层:
2.150.3的插件管理器(Plugin Manager)API 与当前 Jenkins 插件市场严重不兼容。当你尝试安装Docker Pipeline插件时,它会报Failed to download plugin docker-workflow:1.26,因为插件索引服务器返回的是 JSON v2 格式,而2.150.3只认旧版 XML 格式。手动下载.hpi文件安装?你会发现依赖的workflow-cps-global-lib插件版本号对不上,强制安装后 Jenkins 启动失败,日志里全是PluginDependencyMonitor报错。安全漏洞堆积:CVE-2020-2176、CVE-2021-21670、CVE-2022-25059 等高危漏洞均存在于
2.150.x系列,且 Ubuntu 官方不再为该包提供安全更新(EOL Policy)。这意味着,一旦你的 Jenkins 暴露在内网可访问范围,它就是一个现成的跳板机入口。
提示:你可以用
apt policy jenkins查看当前源的版本信息,用apt list --installed | grep jenkins确认是否已误装。如果已装,务必先执行sudo apt remove --purge jenkins彻底卸载,包括/var/lib/jenkins目录,否则残留配置会污染后续安装。
2.2 为什么选择 Jenkins 官方.deb包而非 Docker?
Docker 安装看似时髦,但在 Ubuntu 18.04 生产环境中,它引入了三重不可控风险:
文件系统权限地狱:Docker 容器默认以
jenkins用户(UID 1000)运行,而宿主机/var/jenkins_home目录若由 root 创建,容器内 Jenkins 进程无权写入,导致首次启动卡在 “Please wait while Jenkins is getting ready to work…” 无限循环。修复方法是chown -R 1000:1000 /var/jenkins_home,但这又带来新问题:如果 Jenkins 需要调用宿主机的docker命令(常见于构建 Docker 镜像场景),就必须挂载/var/run/docker.sock,此时容器内 UID 1000 会尝试操作宿主机的 docker daemon,而 daemon 默认只信任 root 或 docker 组用户,权限再次错乱。系统服务集成缺失:Ubuntu 18.04 的
systemd服务管理是基石。Docker 容器无法被systemctl原生管理(systemctl status jenkins查不到),日志分散在docker logs和容器内/var/log/jenkins/jenkins.log两处,故障排查效率骤降。更关键的是,systemd的Restart=on-failure、StartLimitIntervalSec=600等自愈策略,对 Docker 容器完全失效。资源隔离反效果:Jenkins 是内存大户,尤其在并行构建多项目时。Docker 默认不限制内存,容易吃光宿主机资源;若手动加
--memory=4g,又可能因 JVM 堆内存(-Xmx)与容器内存限制冲突,触发 OOM Killer 杀死 Jenkins 进程,而systemd日志里只显示Killed process 1234 (java) total-vm:...,根本看不出是 Docker 的锅。
因此,我们采用Jenkins 官方维护的.deb包 + systemd 原生服务 + 独立 JDK 环境的三段式方案。.deb包由 Jenkins 团队直接构建,版本明确(如2.440.4),内置完整依赖声明,dpkg安装过程会自动处理init.d脚本和systemd单元文件;systemd提供进程守护、日志聚合、启动顺序控制;独立 JDK 则彻底解耦 Java 运行时与系统默认 JDK,避免apt upgrade时意外升级 Java 导致 Jenkins 崩溃。
2.3 JDK 选型:为什么锁定 OpenJDK 11,且必须手动安装?
Ubuntu 18.04 默认apt install openjdk-11-jdk安装的是11.0.19+7-post-Ubuntu-0ubuntu1~18.04.1,这个版本存在两个隐蔽坑点:
java.security策略文件缺陷:该版本的java.security文件中,jdk.tls.disabledAlgorithms列表默认禁用了TLSv1.1,而部分老旧内网 Nexus 私服或 Artifactory 仓库仍使用 TLSv1.1 提供服务。Jenkins 在配置 Maven 全局设置时,若指定私服 URL,会因 SSL 握手失败而卡住,日志里只有javax.net.ssl.SSLHandshakeException: No appropriate protocol,毫无指向性。jpackage工具缺失:jpackage是 Java 14+ 引入的打包工具,用于将 Java 应用打包成原生安装包。虽然 Jenkins 本身不用它,但如果你后续要在 Jenkins 里构建 JavaFX 应用或生成 Windows MSI 安装包,这个工具就必不可少。而 Ubuntu 18.04 源里的 OpenJDK 11 不含jpackage。
解决方案是绕过apt,直接下载 Adoptium(现为 Eclipse Temurin)提供的 OpenJDK 11 LTS 二进制包。Temurin 的11.0.23+12版本经过严格测试,包含完整工具链,且其java.security策略文件更宽松。安装路径固定为/opt/java/jdk-11.0.23+12,这样JAVA_HOME就不会随系统更新漂移。
2.4 网络与源配置:为什么必须预置清华镜像源并禁用 IPv6 DNS 查询
Ubuntu 18.04 的systemd-resolved服务在某些网络环境下(尤其是企业内网通过代理上网时)会优先尝试 IPv6 DNS 查询,而内网 DNS 服务器往往不响应 IPv6 请求,导致apt update、插件下载、Git 克隆等所有网络操作超时。错误日志里常出现Could not resolve 'mirrors.tuna.tsinghua.edu.cn',但ping mirrors.tuna.tsinghua.edu.cn却能通——这就是典型的 IPv6 DNS 解析阻塞。
同时,mirrors.tuna.tsinghua.edu.cn是国内最稳定的 Jenkins 插件镜像源,但它的 HTTPS 证书由GlobalSign Root CA - R3签发,而 Ubuntu 18.04 的ca-certificates包版本较老(20180409),可能缺少该根证书,导致curl https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json返回SSL certificate problem: unable to get local issuer certificate。
因此,我们必须在安装 Jenkins 前,完成两项底层加固:
- 强制
systemd-resolved使用 IPv4 DNS:修改/etc/systemd/resolved.conf,设置DNS=114.114.114.114 8.8.8.8并注释掉#FallbackDNS=行; - 更新
ca-certificates并信任清华镜像源证书:sudo apt update && sudo apt install -y ca-certificates && sudo update-ca-certificates。
这两步看似与 Jenkins 无关,但它们决定了 Jenkins 后续能否顺利下载插件、连接 Git 仓库、推送 Docker 镜像——这是整个自动化链条的“氧气供应”。
3. 核心细节解析与实操要点:从系统准备到首屏解锁的每一步深意
3.1 系统初始化:清理残留、锁定内核、校准时钟
在敲任何 Jenkins 相关命令前,请先执行以下四步系统级检查。这不是仪式感,而是避免后续所有操作在“地基不稳”的状态下进行:
清理历史 Jenkins 残留:
sudo systemctl stop jenkins sudo apt remove --purge jenkins sudo rm -rf /var/lib/jenkins /var/cache/jenkins /var/log/jenkins sudo find /etc -name "*jenkins*" -delete 2>/dev/null注意:
find /etc -name "*jenkins*"是关键。Ubuntu 18.04 的apt remove不会删除/etc/default/jenkins这类配置文件,而该文件里硬编码了JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64,如果后续你换用 Temurin JDK,这个路径就失效,导致systemctl start jenkins启动失败,日志里只显示Job for jenkins.service failed because the control process exited with error code.,根本看不出是 JAVA_HOME 错了。锁定内核版本,防止意外升级:
Ubuntu 18.04 默认内核是4.15.0-204-generic,但apt upgrade可能升级到4.15.0-213。某些老旧硬件驱动(如特定型号的 RAID 卡)在新内核下会丢失磁盘识别能力。执行:sudo apt-mark hold linux-image-4.15.0-204-generic linux-headers-4.15.0-204-generic这样
apt upgrade就不会再碰这两个包,保证系统稳定性。校准系统时钟,避免证书失效:
Jenkins 的 HTTPS 管理界面、Git over HTTPS 认证、Docker Hub 登录,全部依赖准确的时间戳。Ubuntu 18.04 的systemd-timesyncd服务默认启用,但内网环境可能无法访问time1.google.com。改为使用国内 NTP 服务器:sudo timedatectl set-ntp false sudo systemctl stop systemd-timesyncd sudo apt install -y ntp echo "server ntp.aliyun.com iburst" | sudo tee -a /etc/ntp.conf sudo systemctl enable ntp && sudo systemctl start ntp sudo ntpq -p # 查看同步状态,输出应有 * 号标记的活动服务器如果
ntpq -p显示No association ID's returned,说明 NTP 服务未正常启动,需检查防火墙是否放行 UDP 123 端口。创建专用 Jenkins 用户与组:
sudo groupadd jenkins sudo useradd -m -s /bin/bash -c "Jenkins Automation User" -g jenkins jenkins sudo usermod -aG docker jenkins # 如果需调用宿主机 Docker sudo mkdir -p /var/lib/jenkins sudo chown -R jenkins:jenkins /var/lib/jenkins sudo chmod 755 /var/lib/jenkins关键点:
useradd -m创建家目录/home/jenkins,这是 Jenkins 插件安装时的临时工作区;-g jenkins指定主组,确保chown权限精准;-aG docker是为后续 Docker 构建授权,但必须确认宿主机已安装 Docker 且docker组存在(getent group docker可查)。
3.2 JDK 安装:Temurin 11 的静默部署与环境固化
Adoptium 已迁移至 Eclipse Temurin,其 OpenJDK 11 LTS 下载页为https://adoptium.net/temurin/releases/?version=11。截至 2025 年,推荐版本是11.0.23+12(LTS)。下载链接格式为:https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.23%2B12/OpenJDK11U-jdk_x64_linux_hotspot_11.0.23_12.tar.gz
执行安装:
cd /tmp wget https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.23%2B12/OpenJDK11U-jdk_x64_linux_hotspot_11.0.23_12.tar.gz sudo tar -xzf OpenJDK11U-jdk_x64_linux_hotspot_11.0.23_12.tar.gz -C /opt/java/ sudo ln -sf /opt/java/jdk-11.0.23+12 /opt/java/jdk11环境变量固化是成败关键。不能只改~/.bashrc,因为systemd服务启动时读取的是/etc/default/jenkins。所以分两步:
全局环境变量(影响所有用户):
echo 'export JAVA_HOME="/opt/java/jdk11"' | sudo tee -a /etc/environment echo 'export PATH="$JAVA_HOME/bin:$PATH"' | sudo tee -a /etc/environment source /etc/environmentJenkins 服务专属环境(覆盖全局,确保万无一失):
echo 'JAVA_HOME="/opt/java/jdk11"' | sudo tee /etc/default/jenkins echo 'JENKINS_HOME="/var/lib/jenkins"' | sudo tee -a /etc/default/jenkins echo 'JENKINS_USER="jenkins"' | sudo tee -a /etc/default/jenkins
验证:
sudo -u jenkins $JAVA_HOME/bin/java -version # 输出应为:openjdk version "11.0.23" 2024-04-16如果报Command 'java' not found,说明PATH未生效,检查/etc/environment是否有语法错误(如多出空格)。
3.3 Jenkins 主体安装:.deb包的下载、校验与强制安装
Jenkins 官方.deb包地址为https://www.jenkins.io/download/,选择Long Term Support (LTS)版本。截至 2025 年 4 月,最新 LTS 是2.440.4,对应包名为jenkins_2.440.4_all.deb。
下载与校验:
cd /tmp wget https://get.jenkins.io/debian-stable/jenkins_2.440.4_all.deb # 校验 SHA256(官方页面提供) echo "a1b2c3d4e5f6... jenkins_2.440.4_all.deb" | sha256sum -c # 若校验失败,立即停止!可能是下载中断或镜像源被篡改关键来了:不要用sudo dpkg -i jenkins_*.deb直接安装。因为该.deb包声明依赖openjdk-11-jre-headless | java11-runtime-headless,而我们已手动安装 Temurin JDK,dpkg无法识别这个非标准路径的 JDK,会报dependency problems - leaving unconfigured。
正确做法是强制忽略依赖,安装后再手动修复:
sudo dpkg -i --force-depends jenkins_2.440.4_all.deb sudo apt-get install -f -y # 自动修复其他依赖(如 adduser, procps)此时dpkg -l | grep jenkins应显示ii jenkins 2.440.4,状态为installed。但sudo systemctl status jenkins很可能显示inactive (dead),因为JAVA_HOME还没生效。
修复启动脚本:
sudo sed -i 's|^JAVA_HOME=.*|JAVA_HOME="/opt/java/jdk11"|' /etc/default/jenkins sudo systemctl daemon-reload sudo systemctl start jenkins sudo systemctl enable jenkins验证启动:
sudo systemctl status jenkins | grep "active (running)" # 应输出:Active: active (running) since ... sudo journalctl -u jenkins -n 50 --no-pager | grep "Jenkins is fully up and running" # 应看到:INFO: Jenkins is fully up and running如果journalctl里出现java.lang.UnsupportedClassVersionError: Jenkins has been compiled by a more recent version of the Java Runtime,说明JAVA_HOME仍指向旧 JDK,请检查/etc/default/jenkins和/etc/environment是否有冲突。
3.4 首次访问与管理员密码提取:绕过浏览器沙盒限制
Jenkins 首次启动后,会在/var/lib/jenkins/secrets/initialAdminPassword生成初始密码。但直接cat该文件可能失败,因为jenkins用户对/var/lib/jenkins有严格权限控制。
安全提取方式:
sudo -u jenkins cat /var/lib/jenkins/secrets/initialAdminPassword将输出的 32 位随机字符串复制到剪贴板。打开浏览器访问http://<your-server-ip>:8080。注意:
- 不要用 Chrome 或 Edge 的隐身模式:Jenkins 首页会加载大量第三方 JS(如 jQuery UI),隐身模式可能因广告拦截扩展阻止加载,导致页面空白。
- 如果页面卡在 “Please wait while Jenkins is getting ready to work…”:检查
sudo journalctl -u jenkins -f实时日志,常见原因是插件索引下载超时。此时需手动配置清华镜像源。
配置清华镜像源(在 Jenkins Web 界面):
- 进入
Manage Jenkins→Plugins→Advanced标签页; - 在
Update Site输入框中,将https://updates.jenkins.io/update-center.json替换为https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json; - 点击
Check now,等待进度条完成; - 返回
Available标签页,搜索Locale插件并安装(解决中文界面乱码); - 搜索
Docker Pipeline、Git、Pipeline Utility Steps等核心插件,勾选并点击Install without restart。
注意:
Install without restart不是万能的。如果插件有 native library 依赖(如subversion插件),仍需重启 Jenkins。此时执行sudo systemctl restart jenkins,并等待journalctl -u jenkins -n 20显示Jenkins is fully up and running。
4. 实操过程与核心环节实现:从插件安装到首个 Pipeline 任务的完整闭环
4.1 插件离线安装:应对无外网或防火墙严格的生产环境
很多企业内网服务器完全无法访问外网,Check now按钮永远是灰色的。这时必须用离线方式安装插件。步骤如下:
在有网机器上下载插件及其所有依赖:
访问清华镜像源插件列表页:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/。例如,要下载git插件(最新版4.17.0),其下载地址为:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/git/4.17.0/git.hpi
但git.hpi依赖apache-httpcomponents-client-4-api、credentials、scm-api等插件。手动找依赖太麻烦,用 Jenkins CLI 工具批量下载:# 在有网机器上 wget https://get.jenkins.io/war/2.440.4/jenkins.war java -jar jenkins.war --httpPort=-1 --ajp13Port=-1 # 启动一个临时 Jenkins # 浏览器访问 http://localhost:8080,用初始密码登录 # 进入 Manage Jenkins → Plugins → Available,搜索 git,勾选,点击 Download now and install after restart # 此时插件及依赖会下载到 /tmp/jenkins/plugins/ 目录(临时 Jenkins 的 home) # 打包上传:tar -czf jenkins-plugins-offline.tgz /tmp/jenkins/plugins/在目标服务器上离线安装:
# 上传 jenkins-plugins-offline.tgz 到目标服务器 sudo systemctl stop jenkins sudo tar -xzf jenkins-plugins-offline.tgz -C /var/lib/jenkins/ # 修复权限 sudo chown -R jenkins:jenkins /var/lib/jenkins/plugins sudo systemctl start jenkins验证插件加载:
sudo journalctl -u jenkins -n 100 | grep "Plugin loaded",应看到类似:INFO: Plugin git startedINFO: Plugin credentials started
如果某插件报Failed to load plugin,说明其依赖插件未安装,需回退到第 1 步补全。
4.2 配置 Java 与 Maven:让 Jenkins 知道“怎么编译你的代码”
Jenkins 本身不编译代码,它只是调度器。真正的编译由java和mvn命令完成。因此,必须在 Jenkins 系统层面配置 JDK 和 Maven 的路径。
进入Manage Jenkins→Global Tool Configuration:
- JDK 配置:点击
Add JDK,Name 填Temurin-11,JAVA_HOME填/opt/java/jdk11(与系统JAVA_HOME一致); - Maven 配置:点击
Add Maven,Name 填Maven-3.9.6,MAVEN_HOME填/opt/maven/apache-maven-3.9.6(需提前下载安装 Maven)。
Maven 安装(在目标服务器):
cd /tmp wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz sudo tar -xzf apache-maven-3.9.6-bin.tar.gz -C /opt/maven/ sudo ln -sf /opt/maven/apache-maven-3.9.6 /opt/maven/latest echo 'export MAVEN_HOME="/opt/maven/latest"' | sudo tee -a /etc/environment echo 'export PATH="$MAVEN_HOME/bin:$PATH"' | sudo tee -a /etc/environment source /etc/environment关键点:
Global Tool Configuration里的路径必须与系统实际路径完全一致,包括软链接。Jenkins 会用which mvn验证,如果which mvn返回空,说明PATH未生效。
4.3 创建首个 Pipeline 任务:用声明式语法部署一个静态 HTML 页面
我们以最简单的场景为例:将 GitHub 上一个index.html仓库,自动拉取、并拷贝到/var/www/html目录,实现“前端静态页自动发布”。
在 GitHub 创建仓库:新建仓库
jenkins-demo-html,放入一个index.html文件,内容随意。在 Jenkins 创建 Pipeline 任务:
- 点击
New Item→ 输入名称demo-html-deploy→ 选择Pipeline→OK; - 在
Pipeline部分,Definition选择Pipeline script from SCM; SCM选择Git,Repository URL填https://github.com/yourname/jenkins-demo-html.git;Script Path填Jenkinsfile(稍后创建);- 点击
Save。
- 点击
在代码仓库中创建
Jenkinsfile:pipeline { agent any environment { TARGET_DIR = '/var/www/html' } stages { stage('Checkout') { steps { checkout scm } } stage('Deploy') { steps { sh "sudo cp -r ${WORKSPACE}/* ${env.TARGET_DIR}/" sh "sudo chown -R www-data:www-data ${env.TARGET_DIR}" } } } post { success { echo 'Deployment succeeded!' } failure { echo 'Deployment failed!' } } }注意:
sh "sudo cp ..."会失败,因为 Jenkins 默认以jenkins用户运行,没有sudo权限。需配置sudoers:echo "jenkins ALL=(ALL) NOPASSWD: /bin/cp, /bin/chown" | sudo tee /etc/sudoers.d/jenkins sudo chmod 440 /etc/sudoers.d/jenkins触发构建:回到 Jenkins 任务页,点击
Build Now。查看Console Output,应看到:Cloning the remote Git repositorycp: preserving permissions for ‘/var/www/html/index.html’: Operation not permitted—— 这是因为cp -r尝试保留 SELinux 上下文,而 Ubuntu 18.04 默认无 SELinux,忽略即可。
最终输出Deployment succeeded!,访问http://<your-server-ip>/index.html即可看到页面。
4.4 配置两个服务器凭证:用 SSH Key 实现跨服务器部署
Jenkins 任务常需部署到另一台服务器(如应用服务器、数据库服务器)。jenkins 配置两个服务器凭证这个热搜词,直指核心需求:安全、免密、可审计的跨服务器操作。
在 Jenkins 服务器生成 SSH Key 对:
sudo -u jenkins ssh-keygen -t rsa -b 4096 -f /var/lib/jenkins/.ssh/id_rsa -N "" # 公钥内容:sudo -u jenkins cat /var/lib/jenkins/.ssh/id_rsa.pub将公钥追加到目标服务器的
authorized_keys:# 在目标服务器(如 192.168.1.100)上 sudo mkdir -p /home/ubuntu/.ssh echo "ssh-rsa AAAAB3NzaC1yc2E... jenkins@ubuntu" | sudo tee -a /home/ubuntu/.ssh/authorized_keys sudo chown -R ubuntu:ubuntu /home/ubuntu/.ssh sudo chmod 700 /home/ubuntu/.ssh sudo chmod 600 /home/ubuntu/.ssh/authorized_keys在 Jenkins 中添加凭证:
- 进入
Manage Jenkins→Manage Credentials→System→Global credentials (unrestricted)→Add Credentials; Kind选择SSH Username with private key;Scope选Global;Username填ubuntu(目标服务器用户名);Private Key选择Enter directly,粘贴sudo -u jenkins cat /var/lib/jenkins/.ssh/id_rsa的内容;Passphrase留空(因为我们生成时用了-N "");ID填ssh-to-app-server,Description填Deploy to Application Server。
- 进入
在 Pipeline 中使用凭证:
修改Jenkinsfile,用withCredentials步骤包裹 SSH 命令:stage('Deploy to App Server') { steps { withCredentials([sshUserPrivateKey( credentialsId: 'ssh-to-app-server', keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER' )]) { sh """ scp -o StrictHostKeyChecking=no -i \$SSH_KEY \${WORKSPACE}/index.html \${SSH_USER}@192.168.1.100:/var/www/html/ ssh -o StrictHostKeyChecking=no -i \$SSH_KEY \${SSH_USER}@192.168.1.100 "sudo chown www-data:www-data /var/www/html/index.html" """ } } }StrictHostKeyChecking=no是为了跳过首次连接的Are you sure you want to continue connecting (yes/no)?交互提示,否则 Pipeline 会卡住。
