阚野坪 發表於 2023-5-21 00:00:00

Jenkins & Docker 持续集成实践

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>前言</li><li>常见持续集成工具<ul class="second_class_ul"><li>Jenkins</li><ul class="third_class_ul"><li>Jenkins 特点</li><li>Jenkins 几个概念</li><li>Jenkins 部署</li><li>Jenkins 有没有 API?</li></ul></ul></li></ul></div><p class="maodian"></p><h2>前言</h2>
<p>持续集成(CI/CD)是一种软件开发实践。用于帮助团队成员频繁、快速的集成,测试他们的工作成果,以尽快发现集成错误。 更频繁、更早的集成意味着更早的发现问题。通过持续集成,及时发现和解决代码故障,提高代码质量,减少故障处理成本等等。</p>
<p class="maodian"></p><h2>常见持续集成工具</h2>
<p>目前持续集成的生态越来越完善,工具也有很多,开源的或商业的。如:</p>
<ul class="list-paddingleft-2">
<li>最最流行的,也是使用最多的 Jenkins</li>
<li>有着持续集成DNA的ThoughtWorks GO。理念:”Deployment as pipeline” (华为容器平台应该是基于GO做的二次开发实现)</li>
<li>Atlassian工具链之一的Bamboo (数人云应该是基于Banboo实现的CI/CD)</li>
<li>与Gitlab紧密集成的Gitlab CI</li>
<li>专为开源打造的Travis CI,与Github紧密集成</li>
<li>使用 python 语言实现的Buildbot,相信 pythoner 看到会喜欢</li>
</ul>
<p>我们的选型是 Jenkins,所以我们来看下 Jenkins</p>
<p class="maodian"></p><h3>Jenkins</h3>
<p class="maodian"></p><h4>Jenkins 特点</h4>
<ul class="list-paddingleft-2">
<li>Jenkins是开源的应用最广泛的持续集成工具,支持CI, CD;</li>
<li>Jenkins有很多插件,而且用户也可以自定义插件,可扩展性非常强;</li>
<li>Jenkins对Docker支持非常好,有一套完善的Docker插件;</li>
<li>Jenkins2.0开始支持Pipeline,一个非常强大的插件,使用基于Groovy的DSL,支持CI/CD流水线;</li>
<li>Jenkins 基于 Java 语言开发;</li>
</ul>
<p class="maodian"></p><h4>Jenkins 几个概念</h4>
<ul class="list-paddingleft-2">
<li>master 是jenkins安装和运行的地方,它负责解析job脚本,处理任务,调度计算资源;</li>
<li>agent 负责处理从master分发的任务;</li>
<li>executor 就是执行任务的计算资源,它可以在master或者agent上运行。多个executor也可以合作执行一些任务;</li>
<li>job 任务,用来定义具体的构建过程;</li>
<li>Groovy 是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy 可以使用其他 Java 语言编写的库。Jenkins 用Groovy作为DSL;</li>
<li>pipeline 流水线即代码(Pipeline as Code),通过编码而非配置持续集成/持续交付(CI/CD)运行工具的方式定义部署。流水线使得部署是可重现、可重复的;
<p><strong>流水线包括节点(Node)、阶段(Stage)和步骤(Step)。</strong><br>
流水线执行在节点上。节点是Jenkins安装的一部分。流水线通常包含多个阶段。一个阶段包含多个步骤。流水线上手指南可以查看到更多的内容。</p>
<p><strong>node</strong> 在Pipeline中的context中,node是 job 运行的地方。node会给job创建一个工作空间。工作空间就是一个文件目录,这是为了避免跟资源相关的处理互相产生影响。工作空间是node创建的,在node里的所有step都执行完毕后会自动删除。</p>
<p><strong>stage</strong> 阶段,stage是一个任务执行过程的独立的并且唯一的逻辑块,pipeline定义在语法上就是由一系列的stage组成的。每一个stage逻辑都包含一个或多个step。</p>
<p><strong>step</strong> 步骤,一个step是整个流程中的一系列事情中的一个独立的任务,step是用来告诉Jenkins如何做。</p>
</li>
<li>Jenkinfile Jenkins支持创建流水线。它使用一种基于Groovy的流水线领域特定语言(Pipeline DSL)的简单脚。而这些脚本,通常名字叫Jenkinsfile。它定义了一些根据指定参数执行简单或复杂的任务的步骤。流水线创建好后,可以用来构建代码,或者编排从代码提交到交付过程中所需的工作。Jenkins中的Jenkinsfile有点类似Docker中的Dockfile的感觉</li>
</ul>
<p class="maodian"></p><h4>Jenkins 部署</h4>
<p>Jenkins组件其实非常少,安装部署也非常简单。Jenkins按角色就两类: master节点和slave节点。master安装完成后,在控制台中添加节点即可。</p>
<p>下面以Dcoker的部署方式为例说一下Jenkins的部署:</p>
<ul class="list-paddingleft-2">
<li>
<h5>master 节点</h5>
</li>
</ul>
<p><strong>查看 docker hub 中 jenkins 的 image</strong></p><pre class="brush:bash;toolbar:false"># docker search jenkinsNAME                              
DESCRIPTION                                     STARS     OFFICIAL   AUTOMATEDjenkins Official Jenkins Docker image                   2600             stephenreed/jenkins-java8-maven-git   Automated build that provides a continuous...   53</pre><p>可以看到第一个是官方提供的,所以我们选择这个即可。</p>
<p><strong>拉取 jenkins image</strong></p><pre class="brush:bash;toolbar:false">docker pull jenkins</pre><p><strong>启动 jenkins 容器</strong></p>
<p>jenkins没有数据库,所有数据都是存放在文件中的,首先在本地创建jenkins数据目录,用于保存jenkins的数据 这个目录需要定期的备份,用于容灾(当前jenkins容器所在节点由于不可抗因素无法使用时,可以在新机器上使用备份的数据启动新的jenkins master节点)。</p><pre class="brush:bash;toolbar:false">sudo mkdir /var/jenkins
sudo chown 1000:1000 /var/jenkins
sudo docker run -p 8080:8080 -p 50000:50000 -v /var/jenkins:/var/jenkins_home --name my_jenkins -d jenkins</pre><p>这样jenkins就成功跑起来了。可以直接通过机器的8080端口访问jenkins. 本地的/var/jenkins就相当于容器里jenkins用户的用户主目录,所以要保证该目录的权限为uid为j1000的用户目录。</p>
<p><strong>配置 jenkins</strong></p>
<p>启动完 jenkins master 后,在浏览器中数据输入 http://jenkins_master_ip:8080 登录 Jenkins 控制台进行接下来的安装和配置。 具体图就不贴出来了~~</p>
<p><strong>查看jenkins的版本</strong></p><pre class="brush:bash;toolbar:false">java -jar /usr/share/jenkins/jenkins.war --version</pre><p></p>
<ul class="list-paddingleft-2">
<li>
<h5>slave 节点</h5>
</li>
</ul>
<p><strong>安装 java jdk</strong></p><pre class="brush:bash;toolbar:false">yun install java-1.8.0-openjdk</pre><p><strong>创建 jenkins 用户</strong></p><pre class="brush:bash;toolbar:false">$ useradd -m jenkins -d /home/jenkins$ passwd jenkins</pre><p><strong>创建工作目录</strong></p><pre class="brush:bash;toolbar:false">mkdir /data/jenkinschown jenkins.jenkins /data/jenkins</pre><p><strong>添加 jenkins 用户到 docker 用户组</strong></p><pre class="brush:bash;toolbar:false">sudo usermod -a -G docker jenkins</pre><p><strong>配置 ssh 互信,master免密码登陆slave</strong></p>
<p>master 有多种管理 slave 的方式,我们选择SSH方式 在master节点中,切换到jenkins用户 ssh-keygen -t rsa 创建秘钥对 把公钥拷贝到slave节点</p><pre class="brush:bash;toolbar:false">scp ~/.ssh/id_rsa.pub jenkins@slave_ip:~/.ssh/authorized_keys</pre><p>确保在scp前,slave节点根目录下.ssh目录已存在</p><pre class="brush:bash;toolbar:false">chmod 700 authorized_keys</pre><p>使用 jenkins 来构建 docker 是需要安装插件的。那我们需要安装哪些插件呢?</p>
<h5>Jenkins 有哪些 Docker 的 Plugins</h5>
<p><img src="https://zhuji.jb51.net/uploads/img/20230517/9ffce76d7763dae00bf64dfbbaeb55af.jpg" width="1024" height="444"></p>
<p>是非常丰富的,但并不是我们都能用的上,所以需要根据你使用的环境和平台来选择适合自己的 plugin 安装就可以了。 每个 plugin 都需要适配 Jenkins 的版本,且每个 plugin 也需要依赖一些其它 plugin,上面都已经做了标注,需要配套来用。</p>
<p>这里介绍几个常用的 Docker 插件</p>
<p><strong>Docker Commons Plugin</strong></p>
<p>其基本功能:</p>
<ul class="list-paddingleft-2">
<li>API for managing Docker image and container fingerprints</li>
<li>Credentials and location of Docker Registry</li>
<li>Credentials and location of Docker Daemon (aka Docker Remote API)</li>
<li>ToolInstallation for Docker CLI clients</li>
<li>DockerImageExtractor extension point to get Docker image relations from jobs</li>
<li>Simple UI referring related image fingerprints in Docker builds</li>
</ul>
<p><strong>Docker Plugins</strong></p>
<p>该插件是将 docker 作为 jenkins 的 slave 来使用,来在 docker 容器种完成项目的build,build 完成后该容器 slave 容器就会被销毁。所有的工作都是在 slave 容器内完成。</p>
<blockquote><p>docker-build-step</p></blockquote>
<p>该插件在 build 过程种增加了对 Docker 命令的支持。</p>
<p><strong>Docker Pipeline Plugin</strong></p>
<p>基于 Docker Commons Plugin 实现的一些上层的基于 Docker 的 Pipeline 编排</p>
<p><strong>Docker Hub Notification Trigger Plugin</strong></p>
<p>该插件提供了当registry中的image发生变化时触发build新镜像的功能。</p>
<p><strong>CloudBees Docker Build and Publish</strong></p>
<p>该插件提供了通过 Dockerfile 来构建项目并将生成的镜像上传到镜像仓库的功能。</p>
<p><strong>CloudBees Docker Custom Build Environment</strong></p>
<p>This plugin allows the definition of a build environment for a job using a Docker container.</p>
<p>该插件适用于 “自由风格的软件项目”,如图:</p>
<p><img src="https://zhuji.jb51.net/uploads/img/20230517/503973703702317f2f97dfb843a0865a.jpg" width="1024" height="537"></p>
<p><strong>CloudBees Docker Traceability</strong></p>
<p>用于追踪通过jenkins启停的容器的事件</p>
<p><strong>Kubernetes</strong></p>
<blockquote><p>This plugin allows Jenkins agents to be dynamically provisioned on a Kubernetes cluster. The aim of the Kubernetes plugin is to be able to use a Kubernetes cluster to dynamically provision a Jenkins agent (using Kubernetes scheduling mechanisms to optimize the loads), run a single build, then tear-down that slave.</p></blockquote>
<p>与 Kubernetes 结合,通过 kubernetes 提供 jenkins 的 slave 节点。利用 kubernetes 的调度功能提供快速的启停 slave 节点执行 build 等任务。目前是0.11版本,稳定性有待验证。</p>
<p class="maodian"></p><h4>Jenkins 有没有 API?</h4>
<p>因为,我们不是直接在 Jenkins 的 Dashbord 来操作, 而是集成到现有平台,所以我们需要使用它的API。</p>
<p>Jenkins的Remote API以REST的形式进行提供。例如,我们搭建的Jenkins站点为http://myjenkins.com:8080。那么,访问http://myjenkins.com:8080/api 即可查看到该站点所有可用的API;</p>
<p><strong>查询操作</strong></p>
<p><img src="https://zhuji.jb51.net/uploads/img/20230517/6a79f563d87070cfa85c5a5d042a30e1.jpg" width="1024" height="337"></p>
<p><strong>执行一些动作</strong></p>
<p><img src="https://zhuji.jb51.net/uploads/img/20230517/83654115e60493e7a462509eaf816898.jpg" width="1024" height="383"></p>
<p>例如,我要创建一个 job,名字为 my_job<br>
my_job的配置文件</p>
<p><img src="https://zhuji.jb51.net/uploads/img/20230517/33bffd2114ee121b6ff710edcbdd0504.jpg" width="1024" height="578"></p>
<p>调用 api 创建 my_job</p><pre class="brush:bash;toolbar:false">curl -X POST http://www.xxx.xxx/jenkins/createItem?name=my_job  --user uname:pass --data-binary "my_job_config.xml" -H "Content-Type: application/xml"</pre><p>然后,你就可以在 Jenkins dashboard 上看到这个 job 了。它的管理页面为http://myjenkins.com:8080/job/my_job。那么我们访问 /my_job/api/ 即可查看到该job可用的API。</p>
<p>更多的 api 介绍可以参考Jenkins的官方wiki,这里只是个引子,在此就不过多进行介绍。</p>
頁: [1]
查看完整版本: Jenkins & Docker 持续集成实践