linux-tutorial/linux/soft/jenkins-ops.html
Travis CI User e3e645a29a deploy
2021-05-13 17:44:54 +08:00

68 lines
43 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Jenkins 运维 | LINUX-TUTORIAL</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" href="/linux-tutorial/favicon.ico">
<meta name="description" content="数据库教程">
<link rel="preload" href="/linux-tutorial/assets/css/0.styles.45d9d031.css" as="style"><link rel="preload" href="/linux-tutorial/assets/js/app.79a38eea.js" as="script"><link rel="preload" href="/linux-tutorial/assets/js/4.fb6e0f89.js" as="script"><link rel="preload" href="/linux-tutorial/assets/js/58.6d6fbc82.js" as="script"><link rel="preload" href="/linux-tutorial/assets/js/5.cb43ecfb.js" as="script"><link rel="prefetch" href="/linux-tutorial/assets/js/10.7933187b.js"><link rel="prefetch" href="/linux-tutorial/assets/js/11.b9b41530.js"><link rel="prefetch" href="/linux-tutorial/assets/js/12.70a5dba8.js"><link rel="prefetch" href="/linux-tutorial/assets/js/13.857dcc43.js"><link rel="prefetch" href="/linux-tutorial/assets/js/14.5a603a55.js"><link rel="prefetch" href="/linux-tutorial/assets/js/15.d217acb7.js"><link rel="prefetch" href="/linux-tutorial/assets/js/16.ad565eae.js"><link rel="prefetch" href="/linux-tutorial/assets/js/17.d43e9f56.js"><link rel="prefetch" href="/linux-tutorial/assets/js/18.aa00ff43.js"><link rel="prefetch" href="/linux-tutorial/assets/js/19.43ce44b3.js"><link rel="prefetch" href="/linux-tutorial/assets/js/20.5618e1ff.js"><link rel="prefetch" href="/linux-tutorial/assets/js/21.1c5a41d7.js"><link rel="prefetch" href="/linux-tutorial/assets/js/22.fbe9fdf1.js"><link rel="prefetch" href="/linux-tutorial/assets/js/23.a4fb0e74.js"><link rel="prefetch" href="/linux-tutorial/assets/js/24.e3a23b69.js"><link rel="prefetch" href="/linux-tutorial/assets/js/25.9896afe9.js"><link rel="prefetch" href="/linux-tutorial/assets/js/26.96164082.js"><link rel="prefetch" href="/linux-tutorial/assets/js/27.391033bb.js"><link rel="prefetch" href="/linux-tutorial/assets/js/28.703f74c2.js"><link rel="prefetch" href="/linux-tutorial/assets/js/29.02a952cb.js"><link rel="prefetch" href="/linux-tutorial/assets/js/30.7e13628f.js"><link rel="prefetch" href="/linux-tutorial/assets/js/31.c4652f75.js"><link rel="prefetch" href="/linux-tutorial/assets/js/32.05d2cbec.js"><link rel="prefetch" href="/linux-tutorial/assets/js/33.3b265df8.js"><link rel="prefetch" href="/linux-tutorial/assets/js/34.26330a03.js"><link rel="prefetch" href="/linux-tutorial/assets/js/35.417d706d.js"><link rel="prefetch" href="/linux-tutorial/assets/js/36.0ed775e0.js"><link rel="prefetch" href="/linux-tutorial/assets/js/37.34430c74.js"><link rel="prefetch" href="/linux-tutorial/assets/js/38.87d5e0ff.js"><link rel="prefetch" href="/linux-tutorial/assets/js/39.7b648b3e.js"><link rel="prefetch" href="/linux-tutorial/assets/js/40.3b7a219e.js"><link rel="prefetch" href="/linux-tutorial/assets/js/41.e727eee9.js"><link rel="prefetch" href="/linux-tutorial/assets/js/42.0134c187.js"><link rel="prefetch" href="/linux-tutorial/assets/js/43.175e982f.js"><link rel="prefetch" href="/linux-tutorial/assets/js/44.72d90888.js"><link rel="prefetch" href="/linux-tutorial/assets/js/45.d49955bd.js"><link rel="prefetch" href="/linux-tutorial/assets/js/46.a9c290ec.js"><link rel="prefetch" href="/linux-tutorial/assets/js/47.cc639f04.js"><link rel="prefetch" href="/linux-tutorial/assets/js/48.98c78321.js"><link rel="prefetch" href="/linux-tutorial/assets/js/49.a7c3afed.js"><link rel="prefetch" href="/linux-tutorial/assets/js/50.22d8c542.js"><link rel="prefetch" href="/linux-tutorial/assets/js/51.28055fcd.js"><link rel="prefetch" href="/linux-tutorial/assets/js/52.f8103df5.js"><link rel="prefetch" href="/linux-tutorial/assets/js/53.76541550.js"><link rel="prefetch" href="/linux-tutorial/assets/js/54.e78d2776.js"><link rel="prefetch" href="/linux-tutorial/assets/js/55.3ce3079c.js"><link rel="prefetch" href="/linux-tutorial/assets/js/56.832958c9.js"><link rel="prefetch" href="/linux-tutorial/assets/js/57.961ce896.js"><link rel="prefetch" href="/linux-tutorial/assets/js/59.d5e48112.js"><link rel="prefetch" href="/linux-tutorial/assets/js/6.c8f4721c.js"><link rel="prefetch" href="/linux-tutorial/assets/js/60.7927b23b.js"><link rel="prefetch" href="/linux-tutorial/assets/js/61.ee233f24.js"><link rel="prefetch" href="/linux-tutorial/assets/js/62.6ba50cc7.js"><link rel="prefetch" href="/linux-tutorial/assets/js/63.9cbf9f2b.js"><link rel="prefetch" href="/linux-tutorial/assets/js/64.0be148a4.js"><link rel="prefetch" href="/linux-tutorial/assets/js/65.c520257e.js"><link rel="prefetch" href="/linux-tutorial/assets/js/66.f2335390.js"><link rel="prefetch" href="/linux-tutorial/assets/js/67.e5737218.js"><link rel="prefetch" href="/linux-tutorial/assets/js/68.46427a01.js"><link rel="prefetch" href="/linux-tutorial/assets/js/69.450417bb.js"><link rel="prefetch" href="/linux-tutorial/assets/js/7.046e5a1b.js"><link rel="prefetch" href="/linux-tutorial/assets/js/70.072034d2.js"><link rel="prefetch" href="/linux-tutorial/assets/js/8.77fb8967.js"><link rel="prefetch" href="/linux-tutorial/assets/js/9.ebfa537e.js"><link rel="prefetch" href="/linux-tutorial/assets/js/vendors~flowchart.20a64d45.js"><link rel="prefetch" href="/linux-tutorial/assets/js/vendors~notification.ea176280.js">
<link rel="stylesheet" href="/linux-tutorial/assets/css/0.styles.45d9d031.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/linux-tutorial/" class="home-link router-link-active"><img src="images/dunwu-logo-100.png" alt="LINUX-TUTORIAL" class="logo"> <span class="site-name can-hide">LINUX-TUTORIAL</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/linux-tutorial/linux/cli/" class="nav-link">
Linux 命令
</a></div><div class="nav-item"><a href="/linux-tutorial/linux/ops/" class="nav-link">
Linux 运维
</a></div><div class="nav-item"><a href="/linux-tutorial/linux/soft/" class="nav-link router-link-active">
Linux 软件运维
</a></div><div class="nav-item"><a href="/linux-tutorial/docker/" class="nav-link">
Docker 教程
</a></div><div class="nav-item"><a href="https://github.com/dunwu/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
🎯 博客
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <a href="https://github.com/dunwu/linux-tutorial" target="_blank" rel="noopener noreferrer" class="repo-link">
Github
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/linux-tutorial/linux/cli/" class="nav-link">
Linux 命令
</a></div><div class="nav-item"><a href="/linux-tutorial/linux/ops/" class="nav-link">
Linux 运维
</a></div><div class="nav-item"><a href="/linux-tutorial/linux/soft/" class="nav-link router-link-active">
Linux 软件运维
</a></div><div class="nav-item"><a href="/linux-tutorial/docker/" class="nav-link">
Docker 教程
</a></div><div class="nav-item"><a href="https://github.com/dunwu/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
🎯 博客
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <a href="https://github.com/dunwu/linux-tutorial" target="_blank" rel="noopener noreferrer" class="repo-link">
Github
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Jenkins 运维</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-简介" class="sidebar-link">Jenkins 简介</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-是什么" class="sidebar-link">Jenkins 是什么</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#ci-cd-是什么" class="sidebar-link">CI/CD 是什么</a></li></ul></li><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-安装" class="sidebar-link">Jenkins 安装</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#war-包部署" class="sidebar-link">War 包部署</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#rpm-包部署" class="sidebar-link">rpm 包部署</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#访问" class="sidebar-link">访问</a></li></ul></li><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-基本使用" class="sidebar-link">Jenkins 基本使用</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#general" class="sidebar-link">General</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#source-code-management" class="sidebar-link">Source Code Management</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#build-triggers" class="sidebar-link">Build Triggers</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#build-environment" class="sidebar-link">Build Environment</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#build" class="sidebar-link">Build</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#post-build-actions" class="sidebar-link">Post-build Actions</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#开始构建" class="sidebar-link">开始构建</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#构建结果" class="sidebar-link">构建结果</a></li></ul></li><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#其他相关配置" class="sidebar-link">其他相关配置</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#ssh-server-配置" class="sidebar-link">SSH Server 配置</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#配置-gitlab-webhooks" class="sidebar-link">配置 Gitlab webhooks</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-权限管理" class="sidebar-link">jenkins 权限管理</a></li></ul></li><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#jenkins-faq" class="sidebar-link">Jenkins FAQ</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#登录密码" class="sidebar-link">登录密码</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#忘记密码" class="sidebar-link">忘记密码</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#卡在-check-页面" class="sidebar-link">卡在 check 页面</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#卡在-getting-startted-页面" class="sidebar-link">卡在 getting startted 页面</a></li><li class="sidebar-sub-header"><a href="/linux-tutorial/linux/soft/jenkins-ops.html#以-root-用户运行" class="sidebar-link">以 root 用户运行</a></li></ul></li><li><a href="/linux-tutorial/linux/soft/jenkins-ops.html#参考资料" class="sidebar-link">参考资料</a><ul class="sidebar-sub-headers"></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="jenkins-运维"><a href="#jenkins-运维" class="header-anchor">#</a> Jenkins 运维</h1> <blockquote><p>环境要求</p> <ul><li>JDKJDK7+,官网推荐是 JDK 8</li> <li>Jenkins2.190.1</li></ul></blockquote> <h2 id="jenkins-简介"><a href="#jenkins-简介" class="header-anchor">#</a> Jenkins 简介</h2> <h3 id="jenkins-是什么"><a href="#jenkins-是什么" class="header-anchor">#</a> Jenkins 是什么</h3> <p>Jenkins 是一款开源 CI&amp;CD 软件,用于自动化各种任务,包括构建、测试和部署软件。</p> <p>Jenkins 支持各种运行方式可通过系统包、Docker 或者通过一个独立的 Java 程序。</p> <h3 id="ci-cd-是什么"><a href="#ci-cd-是什么" class="header-anchor">#</a> CI/CD 是什么</h3> <p>CI(Continuous integration中文意思是持续集成)是一种软件开发时间。持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。借用网络图片对 CI 加以理解。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310174528.png" alt="img"></p> <p>CD(Continuous Delivery 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的 Staging 环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。下图反应的是 CI/CD 的大概工作模式。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310174544.png" alt="img"></p> <h2 id="jenkins-安装"><a href="#jenkins-安装" class="header-anchor">#</a> Jenkins 安装</h2> <blockquote><p>更详细内容请参考:<a href="https://jenkins.io/zh/doc/book/installing/" target="_blank" rel="noopener noreferrer">Jenkins 官方安装文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></blockquote> <h3 id="war-包部署"><a href="#war-包部署" class="header-anchor">#</a> War 包部署</h3> <p>安装步骤如下:</p> <p>1下载并解压到本地</p> <p>进入<a href="https://jenkins.io/zh/download/" target="_blank" rel="noopener noreferrer">官网下载地址<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>,选择合适的版本下载。</p> <p>我选择的是最新稳定 war 版本 2.89.4http://mirrors.jenkins.io/war-stable/latest/jenkins.war</p> <p>我个人喜欢存放在:<code>/opt/software/jenkins</code></p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">mkdir</span> -p /opt/software/jenkins
<span class="token function">wget</span> -O /opt/software/jenkins/jenkins.war http://mirrors.jenkins.io/war-stable/latest/jenkins.wa
</code></pre></div><p>2启动</p> <p>如果你和我一样,选择 war 版本,那么你可以将 war 移到 Tomcat 的 webapps 目录下,通过 Tomcat 来启动。</p> <p>当然,也可以通过 <code>java -jar</code> 方式来启动。</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token builtin class-name">cd</span> /opt/software/jenkins
<span class="token function">nohup</span> java -jar jenkins.war --httpPort<span class="token operator">=</span><span class="token number">8080</span> <span class="token operator">&gt;&gt;</span> nohup.out <span class="token operator"><span class="token file-descriptor important">2</span>&gt;</span><span class="token file-descriptor important">&amp;1</span> <span class="token operator">&amp;</span>
</code></pre></div><h3 id="rpm-包部署"><a href="#rpm-包部署" class="header-anchor">#</a> rpm 包部署</h3> <p>1下载安装</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">sudo</span> <span class="token function">wget</span> -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
<span class="token function">sudo</span> <span class="token function">rpm</span> --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum <span class="token function">install</span> jenkins
</code></pre></div><p>2启动</p> <div class="language-bash extra-class"><pre class="language-bash"><code>systemctl start jenkins
</code></pre></div><h3 id="访问"><a href="#访问" class="header-anchor">#</a> 访问</h3> <ol><li>打开浏览器进入链接 <code>http://localhost:8080</code>.</li> <li>按照说明完成安装.</li></ol> <h2 id="jenkins-基本使用"><a href="#jenkins-基本使用" class="header-anchor">#</a> Jenkins 基本使用</h2> <p>Jenkins 是一个强大的 CI 工具,虽然本身使用 Java 开发,但也能用来做其他语言开发的项目 CI。下面讲解如何使用 Jenkins 创建一个构建任务。</p> <p>登录 Jenkins 点击左侧的新建,创建新的构建任务。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-22b3c49af599565d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/374/format/webp" alt="img"></p> <p>跳转到如下界面。任务名称可以自行设定,但需要全局唯一。输入名称后选择构建一个自由风格的软件项目(其他选项不作介绍)。并点击下方的确定按钮即创建了一个构建任务。之后会自动跳转到该 job 的配置页面。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-0febc0bc4ca3cadd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1044/format/webp" alt="img"></p> <p>新建自由风格的软件项目</p> <p>下图是构建任务设置界面,可以看到上方的几个选项**&quot;General&quot;, &quot;源码管理&quot; &quot;构建触发器&quot;&quot;构建环境&quot; &quot;构建&quot; &quot;构建后操作&quot;**。下面逐一介绍。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-77998a3e6a70b83f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1032/format/webp" alt="img"></p> <h3 id="general"><a href="#general" class="header-anchor">#</a> General</h3> <p>General 是构建任务的一些基本配置。名称,描述之类的。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310221814.png" alt="img"></p> <p>重要配置项:</p> <ul><li><strong>Description</strong>:对构建任务的描述。</li> <li><strong>Discard old builds</strong>:服务器资源是有限的,有时候保存了太多的历史构建,会导致 Jenkins 速度变慢,并且服务器硬盘资源也会被占满。当然下方的&quot;保持构建天数&quot; 和 保持构建的最大个数是可以自定义的,需要根据实际情况确定一个合理的值。</li></ul> <p>点击右方的问号图标可以查看帮助信息。</p> <h3 id="source-code-management"><a href="#source-code-management" class="header-anchor">#</a> Source Code Management</h3> <p><strong>Source Code Management</strong>,即源码管理,就是配置你代码的存放位置。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310222110.png" alt="img"></p> <ul><li><strong>Git:</strong> 支持主流的 Github 和 Gitlab 代码仓库。因我们的研发团队使用的是 gitlab所以下面我只会对该项进行介绍。</li> <li><strong>Repository URL</strong>:仓库地址。</li> <li><strong>Credentials</strong>:凭证。可以使用 HTTP 方式的用户名密码,也可以是 RSA 文件。 但要通过后面的&quot;ADD&quot;按钮添加凭证。</li> <li><strong>Branches to build</strong>:构建的分支。<code>*/master</code> 表示 master 分支,也可以设置为其他分支。</li> <li><strong>Repository browser</strong>:你所使用的代码仓库管理工具,如 Github、Gitlab.</li> <li><strong>Subversion</strong>:即 SVN这里不作介绍。</li></ul> <h3 id="build-triggers"><a href="#build-triggers" class="header-anchor">#</a> Build Triggers</h3> <p><strong>Build Triggers</strong>,即构建触发器,用于构建任务的触发器。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310222608.png" alt="img"></p> <p>配置说明:</p> <ul><li><strong>Trigger builds remotely (e.g., from scripts)</strong>:触发远程构建(例如,使用脚本)。该选项会提供一个接口,可以用来在代码层面触发构建。</li> <li><strong>Build after other projects are built</strong>:该选项意思是&quot;在其他项目构建后再构建&quot;</li> <li><strong>Build periodically</strong>:周期性的构建。就是每隔一段时间进行构建。日程表类似 linux crontab 书写格式。如:<code>H/30 * * * *</code>,表示每隔 30 分钟进行一次构建。</li> <li>**Build when a change is pushed to GitLab**当有 git push 到 Gitlab 仓库,即触发构建。后面会有一个触发构建的地址,一般被称为 webhooks。需要将这个地址配置到 gitlab 中webhooks 如何配置后面介绍。这个是常用的构建触发器。</li> <li>**Poll SCM**该选项是配合上面这个选项使用的。当代码仓库发生改动jenkins 并不知道。需要配置这个选项,周期性的去检查代码仓库是否发生改动。</li></ul> <h3 id="build-environment"><a href="#build-environment" class="header-anchor">#</a> Build Environment</h3> <p><strong>Build Environment</strong>,即构建环境,配置构建前的一些准备工作,如指定构建工具。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310223004.png" alt="img"></p> <h3 id="build"><a href="#build" class="header-anchor">#</a> Build</h3> <p>Build即构建。</p> <p>点击下图中的 Add build step 按钮,会弹出一个构建任务菜单,可以根据实际需要来选择。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310223241.png" alt="img"></p> <p>【说明】</p> <ul><li><strong>Copy artifacts from another project</strong>:从其他项目获取构建。一般当本任务有上游任务,需要获取上游任务的构件时使用。比如:有个 Java Web 项目,需要依赖于上一个前端构建任务输出的静态文件压缩包。</li> <li>Eexcute NodeJS script执行 Nodejs 脚本。默认支持 nodejs、npm 命令。</li> <li><strong>Eexcute shell</strong> 执行 shell 脚本。用于 Linux 环境。</li> <li><strong>Execute Windows batch command</strong>:执行 batch 脚本。用于 Windows 环境。</li> <li><strong>Invoke Ant</strong>Ant 是一款 java 项目构建工具。</li> <li><strong>Invoke Gradle script</strong>Gradle 构建项目。</li> <li><strong>Invoke top-level Maven targets</strong>Maven 构建项目。</li></ul> <h3 id="post-build-actions"><a href="#post-build-actions" class="header-anchor">#</a> Post-build Actions</h3> <p><strong>Post-build Actions</strong>,即构建后操作,用于构建完本项目的一些后续操作,比如生成相应的代码测试报告。</p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310224106.png" alt="img"></p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310224254.png" alt="img"></p> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310224331.png" alt="img"></p> <p>个人较常用的配置:</p> <ul><li><strong>Archive the artifacts</strong>:归档构件。</li> <li><strong>Build other projects</strong>:构建其他项目。</li> <li><strong>Trigger parameterized build on other projects</strong>:构建其他项目,并传输构建参数。</li> <li><strong>Publish JUnit test result report</strong>:发布 Junit 测试报告。</li> <li><strong>E-mail Notification</strong>:邮件通知,构建完成后发邮件到指定的邮箱。</li></ul> <hr> <p><strong>以上配置完成后,点击保存即可。</strong></p> <h3 id="开始构建"><a href="#开始构建" class="header-anchor">#</a> 开始构建</h3> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310224927.png" alt="img"></p> <p>如上图所示,一切配置好后,即可点击 <strong>Build Now</strong> 开始构建。</p> <h3 id="构建结果"><a href="#构建结果" class="header-anchor">#</a> 构建结果</h3> <p><img src="https://raw.githubusercontent.com/dunwu/images/dev/snap/20200310225234.png" alt="img"></p> <ul><li><strong>构建状态</strong> <ul><li><strong>Successful 蓝色</strong>:构建完成,并且被认为是稳定的。</li> <li><strong>Unstable 黄色</strong>:构建完成,但被认为是不稳定的。</li> <li><strong>Failed 红色</strong>:构建失败。</li> <li><strong>Disable 灰色</strong>:构建已禁用</li></ul></li> <li><strong>构建稳定性</strong> <ul><li>构建稳定性用天气表示:<strong>晴、晴转多云、多云、小雨、雷阵雨</strong>。天气越好表示构建越稳定,反之亦然。</li></ul></li> <li>构建历史界面
<ul><li><strong>console output</strong>:输出构建的日志信息</li></ul></li></ul> <h2 id="其他相关配置"><a href="#其他相关配置" class="header-anchor">#</a> 其他相关配置</h2> <h3 id="ssh-server-配置"><a href="#ssh-server-配置" class="header-anchor">#</a> SSH Server 配置</h3> <p>登录 jenkins -&gt; 系统管理 -&gt; 系统设置</p> <p>配置请看下图:</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-15476f9e273daa58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1108/format/webp" alt="img"></p> <p>重要配置:</p> <ul><li><p><strong>SSH Servers:</strong> 由于 jenkins 服务器公钥文件我已经配置好,所以之后新增 SSH Servers 只需要配置这一项即可。</p></li> <li><p><strong>Name</strong> 自定义,需要全局唯一。</p></li> <li><p><strong>HostName:</strong> 主机名,直接用 ip 地址即可。</p></li> <li><p><strong>Username:</strong> 新增 Server 的用户名,这里配置的是 root。</p></li> <li><p><strong>Remote Directory:</strong> 远程目录。jenkins 服务器发送文件给新增的 server 默认是在这个目录。</p></li></ul> <h3 id="配置-gitlab-webhooks"><a href="#配置-gitlab-webhooks" class="header-anchor">#</a> 配置 Gitlab webhooks</h3> <p>在 gitlab 的 project 页面 打开<strong>settings</strong>,再打开 <strong>web hooks</strong> 。点击**&quot;ADD WEB HOOK&quot;** 添加 webhook。把之前 jenkins 配置中的那个 url 添加到这里,添加完成后,点击**&quot;TEST HOOK&quot;**进行测试,如果显示 SUCCESS 则表示添加成功。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-9f8d04a1400556f9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/246/format/webp" alt="img"></p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-154a62db330c819b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/240/format/webp" alt="img"></p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-e4d1ea1e1dbde812.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1036/format/webp" alt="img"></p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-c7a687207b2c26fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1106/format/webp" alt="img"></p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-ce8ae810bc2cb0d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1154/format/webp" alt="img"></p> <p>配置 phpunit.xml</p> <p>phpunit.xml 是 phpunit 这个工具用来单元测试所需要的配置文件。这个文件的名称同样也是可以自定义的,但是要在&quot;build.xml&quot;中配置好名字就行。默认情况下,用&quot;phpunit.xml&quot;, 则不需要在&quot;build.xml&quot;中配置文件名。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-aa212d3b3eaff548.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/798/format/webp" alt="img"></p> <p>build.xml 中 phpunit 配置</p> <p>fileset dir 指定单元测试文件所在路径include 指定包含哪些文件,支持通配符匹配。当然也可以用 exclude 关键字指定不包含的文件。</p> <p><img src="https:////upload-images.jianshu.io/upload_images/6464255-dbc0084f6d50a240.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1200/format/webp" alt="img"></p> <h3 id="jenkins-权限管理"><a href="#jenkins-权限管理" class="header-anchor">#</a> jenkins 权限管理</h3> <p>由于 jenkins 默认的权限管理体系不支持用户组或角色的配置,因此需要安装第三发插件来支持角色的配置,本文将使用 Role Strategy Plugin。基于这个插件的权限管理设置请参考这篇文章:<a href="https://link.jianshu.com?t=http%3A%2F%2Fblog.csdn.net%2Fruss44%2Farticle%2Fdetails%2F52276222" target="_blank" rel="noopener noreferrer">http://blog.csdn.net/russ44/article/details/52276222<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>,这里不作详细介绍。</p> <p>至此,就可以用 jenkins 周而复始的进行 CI 了,当然 jenkins 是一个强大的工具,功能绝不仅仅是以上这些,其他方面要是以后用到,我会更新到这篇文章中。有疑问欢迎在下方留言。</p> <h2 id="jenkins-faq"><a href="#jenkins-faq" class="header-anchor">#</a> Jenkins FAQ</h2> <h3 id="登录密码"><a href="#登录密码" class="header-anchor">#</a> 登录密码</h3> <p>如果不知道初始登录密码,可以通过以下方式查看:</p> <p>执行命令 <code>cat /root/.jenkins/secrets/initialAdminPassword</code>,打印出来的即是初始登录密码。</p> <h3 id="忘记密码"><a href="#忘记密码" class="header-anchor">#</a> 忘记密码</h3> <p>1.执行 <code>vim /root/.jenkins/config.xml</code> ,删除以下内容</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>useSecurity</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>useSecurity</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>authorizationStrategy</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>hudson.security.FullControlOnceLoggedInAuthorizationStrategy<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>denyAnonymousReadAccess</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>denyAnonymousReadAccess</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>authorizationStrategy</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>securityRealm</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>hudson.security.HudsonPrivateSecurityRealm<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>disableSignup</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>disableSignup</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>enableCaptcha</span><span class="token punctuation">&gt;</span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>enableCaptcha</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>securityRealm</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>2.重启 Jenkins 服务;</p> <p>3.进入首页&gt;“系统管理”&gt;“Configure Global Security”</p> <p>4.勾选“启用安全”;</p> <p>5.点选“Jenkins 专有用户数据库”,并点击“保存”;</p> <p>6.重新点击首页&gt;“系统管理”,发现此时出现“管理用户”;</p> <p>7.点击进入展示“用户列表”;</p> <p>8.点击右侧进入修改密码页面,修改后即可重新登录。</p> <h3 id="卡在-check-页面"><a href="#卡在-check-页面" class="header-anchor">#</a> 卡在 check 页面</h3> <p><strong>现象</strong>:输入密码后,卡在 check 页面</p> <p><strong>原因</strong>jenkins 在安装插件前总是尝试连接 www.google.com来判断网络是否连通。谷歌的网站在大陆是连不上的所以会出现这个问题。</p> <p><strong>解决方案</strong>:执行<code>vim /root/.jenkins/updates/default.json</code>,将 <code>connectionCheckUrl</code> 后的 <code>www.google.com</code> 改为 <code>www.baidu.com</code> 。然后重启即可。</p> <p>或者直接执行命令:</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">sed</span> -i <span class="token string">'s/www.google.com/www.baidu.com/g'</span> /root/.jenkins/updates/default.json
</code></pre></div><h3 id="卡在-getting-startted-页面"><a href="#卡在-getting-startted-页面" class="header-anchor">#</a> 卡在 getting startted 页面</h3> <p><strong>现象</strong>:卡在 getting startted 页面</p> <p><strong>原因</strong>jenkins 默认的插件下载服务器地址在国外,如果不翻墙下载不了。</p> <p><strong>解决方案</strong>:执行<code>vim /root/.jenkins/hudson.model.UpdateCenter.xml</code>,将 <code>&lt;url&gt;</code> 改为 <code>http://mirror.xmission.com/jenkins/updates/update-center.json</code> 。然后重启即可。</p> <p>或者直接执行命令:</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">sed</span> -i <span class="token string">'/^&lt;url&gt;/s/.*/&lt;url&gt;http:\/\/mirror.xmission.com\/jenkins\/updates\/update-center.json&lt;\/url&gt;/g'</span> /root/.jenkins/hudson.model.UpdateCenter.xml
</code></pre></div><h3 id="以-root-用户运行"><a href="#以-root-用户运行" class="header-anchor">#</a> 以 root 用户运行</h3> <p>1修改 jenkins 用户</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">vim</span> /etc/sysconfig/jenkins
</code></pre></div><p>修改用户</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token variable">$JENKINS_USER</span><span class="token operator">=</span><span class="token string">&quot;root&quot;</span>
</code></pre></div><p>2修改 <code>Jenkins</code> 相关文件夹用户权限</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">chown</span> -R root:root /var/lib/jenkins
<span class="token function">chown</span> -R root:root /var/cache/jenkins
<span class="token function">chown</span> -R root:root /var/log/jenkins
</code></pre></div><p>3重启 Jenkins</p> <div class="language- extra-class"><pre class="language-text"><code>systemctl restart jenkins
</code></pre></div><h2 id="参考资料"><a href="#参考资料" class="header-anchor">#</a> 参考资料</h2> <ul><li><p><strong>官方</strong></p> <ul><li><a href="https://jenkins.io/zh/" target="_blank" rel="noopener noreferrer">Jenkins 官网<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://jenkins.io/zh/doc/tutorials/" target="_blank" rel="noopener noreferrer">Jenkins 中文文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><p><strong>引申</strong></p> <ul><li><a href="https://github.com/dunwu/OS" target="_blank" rel="noopener noreferrer">操作系统、运维部署总结系列<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li> <li><p><strong>文章</strong></p> <ul><li>https://jenkins.io/doc/pipeline/tour/getting-started/</li> <li>https://www.cnblogs.com/austinspark-jessylu/p/6894944.html</li> <li>http://blog.csdn.net/jlminghui/article/details/54952148</li> <li><a href="https://www.jianshu.com/p/5f671aca2b5a" target="_blank" rel="noopener noreferrer">Jenkins 详细教程<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li></ul></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/dunwu/linux-tutorial/edit/master/docs/linux/soft/jenkins-ops.md" target="_blank" rel="noopener noreferrer">帮助我们改善此页面!</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">19 minutes ago</span></div></footer> <!----> </main></div><div class="global-ui"><!----><!----></div></div>
<script src="/linux-tutorial/assets/js/app.79a38eea.js" defer></script><script src="/linux-tutorial/assets/js/4.fb6e0f89.js" defer></script><script src="/linux-tutorial/assets/js/58.6d6fbc82.js" defer></script><script src="/linux-tutorial/assets/js/5.cb43ecfb.js" defer></script>
</body>
</html>