DevOps(二)

本文详细介绍了使用Jenkins实现持续集成和持续交付的过程,从平台选择、技术选型到阶段性目标设定,包括自动化构建、静态代码扫描、自动发布等环节,并提供了手动和自动化的示例,涉及到的工具如SonarQube、Docker、Harbor和GitLab等。最后,文章讨论了Pipeline流水线的改造,以提升自动化程度。
摘要由CSDN通过智能技术生成

在这里插入图片描述

1. 平台选择

目前支持CI/CD的平台有:

  • gitlab-ci:git官方的持续集成工具,在Git工程管理页面上,也有专门的CI配置和展示页;
  • Travis CI:只支持 Github,并且绑定了Github上的项目,不支持其他代码托管服务;
  • TeamCity:由JetBrains创建的基于Java的CI / CD工具;
  • Jenkins:开源的、提供友好操作界面的持续集成(CI)工具,主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。可在Tomcat等流行的servlet容器 中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。

虽然Jenkins只是支持持续集成的众多工具之一,Jenkins ≠ 持续集成,但目前只要一提到Jenkins,人们就会联想到持续集成、CI&CD,可见其使用范围之广,用户之多。同时资料也最为丰富、社区最活跃,所以选择Jenkins也没有什么好犹豫的。

2. 技术选型

工具说明
Jenkins基础平台
Sonar&Sonarqube静态代码扫描
Python3+Allure+Pytest+Requests(接口)+Selenium(web)+UiAutomator2(APP)自动化测试环境
docker容器引擎
Harbor/dockerhub官方的docker镜像注册服务器(可以在本地搭建Harbor代替)
Kubernetes容器编排管理工具,用于部署应用程序
Gitlab/Github源代码仓库(可以在本地搭建gitlab代替)
NodeJS前端构建环境
Java+Maven后端构建环境

3. 阶段性目标

CI 阶段目标

  • 阶段目标一:自动化构建
    先解决“人工拉取代码-执行编译-通知团队”这个原本手动执行效率低下的问题,最终效果:研发提交代码–>触发webhook–>Jenkins自动拉取代码–>编译打包–>通过插件实时企微群通知,后续的发布替换还是由手动完成,一定程度上达到了节约时间,降本增效的目的。

    工具:jenkins、gitlab、gerrit

  • 阶段目标二:静态代码扫描
    在CI阶段,自动化拉取代码、自动编译只是过程,不是目的,重要的是要能够实现快速检验、快速反馈。这其中很重要的一个手段就是单元测试。但就目前团队现状而言,单元测试不现实。

    工具:sonar/sonarqube

    我们采取的是接入自动化静态代码扫描来替代单元测试,最终效果:研发提交代码–>触发webhook–>Jenkins自动拉取代码–>静态代码扫描–>编译打包,实现最基本的静态代码扫描,代码覆盖率检测,避免出现低级语法规范和一些安全隐患。

  • 阶段目标三:自动发布
    解决手动替换发包的问题:自动编译打包后,通过shell脚本自动将发布包发布到开发、测试等各个环境。

    工具:docker、shell、python、harbor

CD 阶段目标

  • 阶段目标四:自动化冒烟测试
    应当说持续交付这个阶段最考验的就是交付产物交付到各个环境以后的自动化测试能力,需要具备完善的自动化测试手段,以此来保障快速反馈,否则很难体现CD的效果。除了前面提到的单元测试、静态代码扫描,还包括如:组件集成测试、接口测试、UI测试、性能测试、安全测试等等。

    工具:Allure、Pytest

    在阶段目标四中,我们主要实现两个类型的自动化测试:

      接口测试:校验各个接口是否连通,接口业务场景是否能够正常串联执行;
      UI测试:校验系统是否能够正常登录,一些基本的冒烟测试用例是否正常执行;
    
  • 阶段目标五:Pipeline流水线改造
    将以上流程全部通过自动化手段实现以后,再利用Pipeline流水线语法进行改造,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。

    工具:jenkins-pipeline

4. 搭建示例

本节搭建的目标是:

  • 在本地提交python代码,jenkins自动触发拉取,编译(由于是python代码,所以只是执行供演示)
  • 自动触发sonarqube检测代码
  • 自动触发docker制作镜像推送到harbor
  • 在指定节点运行服务
    在这里插入图片描述

服务器规划

服务器IP用途
node-252192.168.71.252jenkins agent,sonarqube,docker
node-253192.168.71.253jenkins master,harbor
node-249192.168.70.249jenkins agent,gitlab

4.1 环境准备(节点机)

1. java版本升级

由于笔者jenkins安装的版本较高(Jenkins 2.401.2),所以要求java版本至少是11或以上的,笔者这里重新装java

注意:这里不光是安装jenkins的服务器需要较高版本的java,节点机也需要较高版本,否则无法连接节点

参考 CHAPTER 1 Jenkins部署与基础配置 1.1.2 红帽系安装

2. 编译安装git

参考 gitlab/gerrit 2.1 环境准备

3. docker安装

参考 CHAPTER 1 Docker入门 1.3.1 yum安装

4. docker-compose安装

参考 CHAPTER 12 Compose(一)12.2.2 二进制包

5. sonarqube安装

参考 CHAPTER 5 Jenkins & SonarQube
账号:admin
密码:yurq

6. harbor安装

参考 harbor(docker仓库)仓库部署

6bDg3XQ81Y3NDWJhtIVacMDyqeNzj3oO

7. gitlab私服

参考 CHAPTER 3 Jenkins SVN GItlab 3.2.1 搭建gitlab服务器(使用官方镜像搭建)

4.2 示例一(手动)

步骤简述:

  • 在gitlab创建项目
  • 编写代码、python插件(用于flask)和Dockerfile上传至gitlab
  • jenkins拉取代码及相关文件
  • 检查代码
  • 打包代码机相关文件到docker镜像,上传到harbor
  • 下载并运行镜像
  • 测试服务
1. 创建项目

在gitlab创建项目
在这里插入图片描述

2. 编码
[root@node-252 mypython]# cat mypython.py
#!/usr/bin/env python
from flask import  Flask
app=Flask(__name__)

@app.route('/')
def index():
    return 'welcome to my webpage!'

if __name__=="__main__":
    app.run(port=8080,host="0.0.0.0",debug=True)
3. Dockerfile
[root@node-252 mypython]# cat Dockerfile
FROM lmurawsk/python2.7:latest
LABEL maintainer="mrhelloworld.com"

WORKDIR /usr/local
RUN mkdir -p /plugins
COPY package/*.whl /plugins/

RUN pip install /plugins/click-3.0-py2.py3-none-any.whl
RUN pip install /plugins/itsdangerous-1.1.0-py2.py3-none-any.whl
RUN pip install /plugins/MarkupSafe-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl
RUN pip install /plugins/Werkzeug-0.16.0-py2.py3-none-any.whl
RUN pip install /plugins/Jinja2-2.11.0-py2.py3-none-any.whl
RUN pip install /plugins/Flask-0.12.5-py2.py3-none-any.whl

COPY ./mypython.py /usr/local/

EXPOSE 8080


CMD python /usr/local/mypython.py
4. 拷贝python插件文件

由于我们要使用python flask的web功能,但是镜像中没有相关插件,所以需要把插件打包到镜像中

[root@node-252 mypython]# cp ../mypython_bak/*.whl .
[root@node-252 mypython]# ll
total 648
-rw-r--r-- 1 root root     11 Jul 10 05:43 blog.txt
-rw-r--r-- 1 root root  57939 Jul 10 20:34 click-3.0-py2.py3-none-any.whl
-rw-r--r-- 1 root root   1104 Jul 10 20:32 Dockerfile
-rw-r--r-- 1 root root  81748 Jul 10 20:34 Flask-0.12.5-py2.py3-none-any.whl
-rw-r--r-- 1 root root  16743 Jul 10 20:34 itsdangerous-1.1.0-py2.py3-none-any.whl
-rw-r--r-- 1 root root 126742 Jul 10 20:34 Jinja2-2.11.0-py2.py3-none-any.whl
-rw-r--r-- 1 root root  24542 Jul 10 20:34 MarkupSafe-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl
-rw-r--r-- 1 root root    208 Jul 10 05:43 mypython.py
-rw-r--r-- 1 root root   6161 Jul 10 05:43 README.md
-rw-r--r-- 1 root root 327277 Jul 10 20:34 Werkzeug-0.16.0-py2.py3-none-any.whl

后续可以制作python2.7+flask相关插件的镜像

5. 上传gitlab

上传代码

[root@node-252 mypython]# cat ~/.gitconfig
[user]
name = yurq
email = yurq@qq.com
[credential]
        helper = store
[http]
sslVerify = false
[root@node-252 MyPython]# git commit mypython.py
[detached HEAD 6182db3] flask
 1 file changed, 8 insertions(+), 2 deletions(-)
[root@node-252 mypython]# git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 396 bytes | 396.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To http://192.168.70.249:9980/devs/mypython.git
   f3047fb..0249dc8  main -> main

上传dockerfile

[root@node-252 mypython]# git add Dockerfile
[root@node-252 mypython]# git commit Dockerfile
[main 059968e] add dockerfile
 1 file changed, 25 insertions(+)
 create mode 100644 Dockerfile
[root@node-252 mypython]# git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 657 bytes | 657.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To http://192.168.70.249:9980/devs/mypython.git
   0249dc8..059968e  main -> main
6. jenkins拉取代码

创建jenkins项目,配置节点和下载相关插件
在这里插入图片描述
配置sonar
在这里插入图片描述
由于网络原因,docker-build-step插件一直下载不了,所以手动写了构建/推送命令
在这里插入图片描述

7. 查看代码检查结果

在这里插入图片描述

8. 查看harbor镜像

在这里插入图片描述

9. 模拟发布

由于网络原因,有些插件下载不了,所以笔者又创建了一个jenkins项目并在其他节点运行,以模拟生产场景
在这里插入图片描述
在这里插入图片描述

10. 示例演示

在这里插入图片描述
该示例中有很多步骤都是手动运行的,其原因是很多jenkins插件由于网络原因无法下载,在下例中将逐步改进

4.3 示例二(自动)

说明:在该示例中,我们将在示例一的基础上实现更多功能,包括:

  • 代码提交后,自动触发jenkins任务
  • jenkins任务整合,通过multi job顺序执行
  • docker镜像通过插件打tag,上传到harbor及在指定节点执行(而非通过命令行)
  • 更新base镜像,把python插件打包进镜像中,不在执行任务期间安装插件

本节中,我们需要安装的jenkins的插件有:

  • docker-build-step
  • CloudBees Docker Build and Publish
  • multi job
  • gitlab
1. 创建multi job
  • 记录下gitlab钩子的URL
  • 编排任务序列,让任务顺序执行
    在这里插入图片描述
    在这里插入图片描述
2. 配置gitlab webhook
  • 配置webhook,选择事件类型,当有事件发生时才能自动触发jenkins执行任务
    在这里插入图片描述
    注意:

    如果添加webhook提示Url is blocked: Requests to the local network are not allowed的问题,在gitlab->menu->admin area->Setting->network->Outbound requests
    勾选:Allow requests to the local network from web hooks and services即可解决

3. 更新base镜像
  • 我们把python插件打包进基础镜像中,后续使用新的镜像进行打包
  • 在harbor建好仓库python2.7
[root@node-252 mypython]# cat dockerfile2
FROM lmurawsk/python2.7:latest
LABEL maintainer="mrhelloworld.com"

WORKDIR /usr/local
RUN mkdir -p /plugins
COPY package/*.whl /plugins/

RUN pip install /plugins/click-3.0-py2.py3-none-any.whl
RUN pip install /plugins/itsdangerous-1.1.0-py2.py3-none-any.whl
RUN pip install /plugins/MarkupSafe-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl
RUN pip install /plugins/Werkzeug-0.16.0-py2.py3-none-any.whl
RUN pip install /plugins/Jinja2-2.11.0-py2.py3-none-any.whl
RUN pip install /plugins/Flask-0.12.5-py2.py3-none-any.whl

[root@node-252 mypython]# docker build -f dockerfile2 -t yurq/python2.7:latest .
[root@node-252 mypython]# docker tag yurq/python2.7:latest 192.168.71.253:80/python2.7/yurq_python2.7:latest
[root@node-252 mypython]# docker push 192.168.71.253:80/python2.7/yurq_python2.7:latest

4. jenkins任务修改
  • 子任务MyPython 修改
    插件excute docker command不太好用,直接用命令行替代
    Docker build and publish可以使用
    在这里插入图片描述
    在这里插入图片描述
  • 子任务 Mypython2 修改
    添加了判断,如果容器已经启动,则停止/删除,启动新的容器

在这里插入图片描述

5. 示例演示
  • 修改代码
[root@node-252 mypython]# cat mypython.py
#!/usr/bin/env python
from flask import  Flask
app=Flask(__name__)

@app.route('/')
def index():
    return 'welcome to my webpage! power by python!'

if __name__=="__main__":
    app.run(port=8080,host="0.0.0.0",debug=True)

[root@node-252 mypython]# git commit -m "add power by" mypython.py
[main 9f4af70] add power by
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@node-252 mypython]# git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 293 bytes | 293.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To http://192.168.70.249:9980/devs/mypython.git
   de86dd3..9f4af70  main -> main
  • 可以看到本次由gitlab启动
    在这里插入图片描述
  • 访问网址
    在这里插入图片描述

5. 小结

  • 本次初步搭建的CD简易流程,还缺少测试环节,笔者这边安装allure出现了状况,后续改善之后再进行完善
  • devops更多的用在微服务的发布流程中,后续笔者会推出java开发的程序+k8s部署服务的更完整的流程
  • 后续可能还会在除jenkins之外的平台进行尝试
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值