【DevOps】搭建实战

DevOps介绍

软件开发最开始是由两个团队组成:

  • 开发计划由开发团队从头开始设计和整体系统的构建。需要系统不停的迭代更新。
  • 运维团队将开发团队的Code进行测试后部署上线。希望系统稳定安全运行。

这看似两个目标不同的团队需要协同完成一个软件的开发。

在开发团队指定好计划并完成coding后,需要提供到运维团队。

运维团队向开发团队反馈需要修复的BUG以及一些需要返工的任务。

这时开发团队需要经常等待运维团队的反馈。这无疑延长了事件并推迟了整个软件开发的周期。

会有一种方式,在开发团队等待的时候,让开发团队转移到下一个项目中。等待运维团队为之前的代码提供反馈。

可是这样就意味着一个完整的项目需要一个更长的周期才可以开发出最终代码。


基于现在的互联网现状,更推崇敏捷式开发,这样就导致项目的迭代速度更快,但是由于开发团队与运维团队的沟通问题,会导致新版本上线的时间成本很高。这又违背的敏捷式开发的最初的目的。

那么如果让开发团队和运维团队整合到成一个团队,协同应对一套软件呢?这就被称为DevOps。

DevOps,字面意思是Development &Operations的缩写,也就是开发&运维。

虽然字面意思只涉及到了开发团队和运维团队,其实QA测试团队也是参与其中的。

网上可以查看到DevOps的符号类似于一个无穷大的符号

【DevOps】搭建实战_第1张图片
这表明DevOps是一个不断提高效率并且持续不断工作的过程

DevOps的方式可以让公司能够更快地应对更新和市场发展变化,开发可以快速交付,部署也更加稳定。

核心就在于简化Dev和Ops团队之间的流程,使整体软件开发过程更快速。

整体的软件开发流程包括:

  • PLAN:开发团队根据客户的目标制定开发计划
  • CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。
  • BUILD:编码完成后,需要将代码构建并且运行。
  • TEST:成功构建项目后,需要测试代码是否存在BUG或错误。
  • DEPLOY:代码经过手动测试和自动化测试后,认定代码已经准备好部署并且交给运维团队。
  • OPERATE:运维团队将代码部署到生产环境中。
  • MONITOR:项目部署上线后,需要持续的监控产品。
  • INTEGRATE:然后将监控阶段收到的反馈发送回PLAN阶段,整体反复的流程就是DevOps的核心,即持续集成、持续部署。

为了保证整体流程可以高效的完成,各个阶段都有比较常见的工具,如下图:

【DevOps】搭建实战_第2张图片
最终可以给DevOps下一个定义:DevOps 强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。

自动化的工具协作和沟通来完成软件的生命周期管理



直入主题

基础环境信息:

  • centos:7.9.2009 (Core)
  • docker:24.0.2
  • docker-compose: v2.18.0

GitLab

在code阶段,我们需要将不同版本的代码存储到一个仓库中,常见的版本控制工具就是SVN或者Git,这里我们采用Git作为版本控制工具,GitLab作为远程仓库。
单独准备服务器,采用Docker安装

  • 查看GitLab镜像

    docker search gitlab
    
  • 拉取GitLab镜像

    docker pull gitlab/gitlab-ce
    
  • 准备docker-compose.yml文件

    version: '3.1'
    services:
      gitlab:
        image: 'gitlab/gitlab-ce:latest'
        container_name: gitlab
        restart: always
        environment:
          GITLAB_OMNIBUS_CONFIG: |
            external_url 'http://192.168.1.190:8929'
            gitlab_rails['gitlab_shell_ssh_port'] = 2224
        ports:
          - '8929:8929'
          - '2224:2224'
        volumes:
          - './config:/etc/gitlab'
          - './logs:/var/log/gitlab'
          - './data:/var/opt/gitlab'
    
  • 启动容器

    docker-compose up -d
    
  • 访问GitLab首页

    【DevOps】搭建实战_第3张图片

  • 查看root用户初始密码

    docker exec -it gitlab cat /etc/gitlab/initial_root_password
    

    在这里插入图片描述

  • 登录root用户

    【DevOps】搭建实战_第4张图片


Jenkins

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具

Jenkins应用广泛,大多数互联网公司都采用Jenkins配合GitLab、Docker、K8s作为实现DevOps的核心工具。

Jenkins最强大的就在于插件,Jenkins官方提供了大量的插件库,来自动化CI/CD过程中的各种琐碎功能。

Jenkins最主要的工作就是将GitLab上可以构建的工程代码拉取并且进行构建,再根据流程可以选择发布到测试环境或是生产环境。

一般是GitLab上的代码经过大量的测试后,确定发行版本,再发布到生产环境。

CI/CD可以理解为:

  • CI过程即是通过Jenkins将代码拉取、构建、制作镜像交给测试人员测试。
    • 持续集成:让软件代码可以持续的集成到主干上,并自动构建和测试。
  • CD过程即是通过Jenkins将打好标签的发行版本代码拉取、构建、制作镜像交给运维人员部署。
    • 持续交付:让经过持续集成的代码可以进行手动部署。
    • 持续部署:让可以持续交付的代码随时随地的自动化部署。

【DevOps】搭建实战_第5张图片

安装Jenkins
  • docker-compose.yml
    注意挂载数据卷,且data目录赋予足够的权限

    version: "3.1"
    services:
      jenkins:
        image: jenkins/jenkins:2.401.1-lts
        container_name: jenkins
        ports:
          - 8080:8080
          - 50000:50000
        volumes:
          - ./data/:/var/jenkins_home/
    
  • 启动Jenkins容器后,由于Jenkins需要下载大量内容,可以设置国内镜像站提高下载速度。

    
    
    <sites>
      <site>
        <id>defaultid>
        <url>https://updates.jenkins.io/update-center.jsonurl>
      site>
    sites>
    
    
    
    <sites>
      <site>
        <id>defaultid>
        <url>http://mirror.esuni.jp/jenkins/updates/update-center.jsonurl>
      site>
    sites>
    
    
  • 访问Jenkins
    【DevOps】搭建实战_第6张图片

    输入密码,在日志中得到体现。
    【DevOps】搭建实战_第7张图片

  • 下载插件
    【DevOps】搭建实战_第8张图片
    【DevOps】搭建实战_第9张图片
    下载失败的话也可以去官网上去下载插件,手动安装:友情链接

  • 下载完毕设置信息进入首页
    【DevOps】搭建实战_第10张图片

    设置实例
    【DevOps】搭建实战_第11张图片

    正式进入首页
    【DevOps】搭建实战_第12张图片

  • 下载需要的插件
    【DevOps】搭建实战_第13张图片
    查看插件安装情况
    在这里插入图片描述

配置(Maven&JDK)

代码拉取到Jenkins本地后,需要在Jenkins中对代码进行构建,这里需要Maven的环境,而Maven需要Java的环境,接下来需要在Jenkins中安装JDK和Maven,并且配置到Jenkins服务。

构建Java项目的工具一般有两种选择,一个是Maven,一个是Gradle。

这里我们选择Maven作为项目的编译工具。

  • Maven:3.9.2
  • JDK:11 (搭建过程中发现jenkins/jenkins:2.401.1-lts镜像集成了Java11,所以jdk目录放入存储卷后并未使用,特此说明。)

注意修改Maven的仓库地址,以免后期打包依赖下载不了。

  • 将包并放入映射卷
    在这里插入图片描述

  • 在jenkins中配置JDK和Maven
    【DevOps】搭建实战_第14张图片

【DevOps】搭建实战_第15张图片


Publish Over SSH

程序包构建好之后,就可以根据情况发布环境,配置之前下载好的插件Publish Over SSH。

SSH配置
  • 配置连接相关环境
    【DevOps】搭建实战_第16张图片
  • 按照提示填写相关信息
    在这里插入图片描述
项目准备
  • 搭建个简单的项目
    【DevOps】搭建实战_第17张图片

  • Gitlab创建相关项目并将本地项目推送
    【DevOps】搭建实战_第18张图片
CI:持续集成
拉取代码并打包
  • Jenkins创建任务
    【DevOps】搭建实战_第19张图片

  • 简单入门选择自由风格软件项目
    【DevOps】搭建实战_第20张图片

  • 配置源码管理为git并填写仓库地址
    【DevOps】搭建实战_第21张图片

  • 配置构建环境
    【DevOps】搭建实战_第22张图片

  • 选择Build Steps配置maven
    【DevOps】搭建实战_第23张图片
  • 选择配置好的maven并配置打包命令
    【DevOps】搭建实战_第24张图片
  • 尝试打包,观看相关日志
    【DevOps】搭建实战_第25张图片
    【DevOps】搭建实战_第26张图片
  • 进入Jenkins工作目录查看Jar包
    在这里插入图片描述
发布到目标服务器
  • 项目准备dockerfile等并推送gitlab

    • dockerfile
      FROM java:openjdk-8u111
      
      COPY *.jar /usr/local/test.jar
      
      WORKDIR /usr/local/
      
      ENTRYPOINT ["/bin/sh","-c","java -Dfile.encoding=utf8 -Djava.security.egd=file:/dev/./urandom -jar test.jar"]
      
    • docker-compose.yml
      version: "3"
      services:
        my_test:
          build:
            context: ./
            dockerfile: dockerfile
          image: test:v1
          container_name: my_test
          ports:
            - "9090:9090"
      
    • 目录结构【DevOps】搭建实战_第27张图片
  • 追加Jenkins构建后操作脚本命令
    【DevOps】搭建实战_第28张图片

    cd /usr/local/test/docekr
    mv ../target/*.jar ./
    docker-compose down
    docker-compose up -d --build
    
  • Jenkins尝试构建并发布

    哈哈哈失败好几次,反正就是来回调试就完事了
    【DevOps】搭建实战_第29张图片
    查看#16控制台日志
    【DevOps】搭建实战_第30张图片

  • 查看容器
    在这里插入图片描述

  • 接口验证
    在这里插入图片描述

CD:持续交付

程序代码在经过多次集成操作到达最终可以交付,持续交付整体流程和持续集成类似,不过需要选取指定的发行版本。

  • 确定Jenkins中有Git Parameter插件
  • 设置项目参数化构建
    【DevOps】搭建实战_第31张图片
  • 修改Build配置并保存
    【DevOps】搭建实战_第32张图片
  • 修改项目并推送
    【DevOps】搭建实战_第33张图片
  • Gitlab添加tag版本
    在这里插入图片描述
  • 尝试重新构建
    【DevOps】搭建实战_第34张图片
    【DevOps】搭建实战_第35张图片
  • 查看日志并测试程序
    在这里插入图片描述
    在这里插入图片描述

阶段总结

搭建的地方有两个坑,集中在配置maven和jdk两个地方,在这里列举一下,免得走弯路。

  1. jdk方面:因为探索阶段都是在论坛上东搞搞西搞搞看看借鉴下来的,大家都说要安装jdk,但是我后面Jenkins里面配置全局工具的时候,发现jenkins内置了Java11,所以我就直接使用了内置的。
    在这里插入图片描述
  2. maven方面:Jenkins搭建的时候使用了数据卷挂载,包括解压maven到数据卷中,从上图可以看到,Jenkins容器内使用的是jenkins用户,而挂载进去的maven目录的用户和用户组为root,配置的时候并不报错,代码构建的时候报出了 Cannot run program "var/jenkins_home/maven/bin/mvn" (in directory "/var/jenkins_home/workspace/mytest"): error=2, No such file or directory的错误。解决方案如下:设置之后配置正常。
    • 方案1: 在宿主机将挂载的目录用户和用户组设置为 1000(容器内jenkins所属与1000:1000)
    • 方案2:容器以root用户启动(不推荐)
      在这里插入图片描述

截至此段落位置,DevOps 简单入门版整体结构如下:
【DevOps】搭建实战_第36张图片



SonarQube 集成

Sonar Qube是一个开源的代码分析平台,支持Java、Python、PHP、JavaScript、CSS等25种以上的语言,可以检测出重复代码、代码漏洞、代码规范和安全性漏洞的问题。

Sonar Qube可以与多种软件整合进行代码扫描,比如Maven,Gradle,Git,Jenkins等,并且会将代码检测结果推送回Sonar Qube并且在系统提供的UI界面上显示出来

最新长期支持版本9.9.1
【DevOps】搭建实战_第37张图片
本文使用8.9.3-community,最新版下载太慢了。

ps:
Sonar Qube在7.9版本中已经放弃了对MySQL的支持,并且建议在商业环境中采用PostgreSQL,那么安装Sonar Qube时需要依赖PostgreSQL。

SonarQube 安装

  • 拉取镜像

    docker pull postgres
    docker pull sonarqube:8.9.3-community
    
  • 编写docker-compoe.yml

    version: "3.1"
    services:
      db:
        image: postgres
        container_name: db
        ports:
          - 5432:5432
        networks:
          - sonarnet
        environment:
          POSTGRES_USER: sonar
          POSTGRES_PASSWORD: sonar
      sonarqube:
        image: sonarqube:8.9.3-community
        container_name: sonarqube
        depends_on:
          - db
        ports:
          - "9000:9000"
        networks:
          - sonarnet
        environment:
          SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
          SONAR_JDBC_USERNAME: sonar
          SONAR_JDBC_PASSWORD: sonar
    networks:
      sonarnet:
        driver: bridge
    
  • 启动容器

    docker-compose up -d
    
  • 日志报错记录

    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] initialized
    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] starting ...
    2023.06.13 03:19:42 INFO  es[][o.e.t.TransportService] publish_address {127.0.0.1:40954}, bound_addresses {127.0.0.1:40954}
    2023.06.13 03:19:42 INFO  es[][o.e.b.BootstrapChecks] explicitly enforcing bootstrap checks
    ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
    bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    ERROR: Elasticsearch did not exit normally - check the logs at /opt/sonarqube/logs/sonarqube.log
    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] stopping ...
    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] stopped
    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] closing ...
    2023.06.13 03:19:42 INFO  es[][o.e.n.Node] closed
    2023.06.13 03:19:42 WARN  app[][o.s.a.p.AbstractManagedProcess] Process exited with exit value [es]: 78
    2023.06.13 03:19:42 INFO  app[][o.s.a.SchedulerImpl] Process[es] is stopped
    2023.06.13 03:19:42 INFO  app[][o.s.a.SchedulerImpl] SonarQube is stopped
    
  • 按照日志要求修改虚拟内存【DevOps】搭建实战_第38张图片执行命令刷新

    sysctl -p
    
  • 重启服务观察日志在这里插入图片描述

  • 访问Sonar Qube首页,初始账户密码都为admin
    【DevOps】搭建实战_第39张图片

  • 第一次登陆后要求修改密码,然后进入首页 【DevOps】搭建实战_第40张图片

  • 安装中文插件
    【DevOps】搭建实战_第41张图片

  • 成功后重启刷新喜提中文
    【DevOps】搭建实战_第42张图片


SonarQube 代码分析

可以选择 maven 集成或者使用 sonar-scanner 进行代码质量分析。

集成 Mavne 方式
  • 修改Maven的settings.xml文件配置SonarQube配置
    <profile>
    	<id>sonarid>
    	<activation>
    		<activeByDefault>trueactiveByDefault>
    	activation>
    	<properties>
    		<sonar.login>adminsonar.login>
    		<sonar.password>你的密码sonar.password>
    		<sonar.host.url>http://192.168.1.190:9000sonar.host.url>
    	properties>
    profile>
    
  • 在代码目录下执行相关命令:mvn sonar:sonar
    等待执行完毕
    在这里插入图片描述
  • SonarQube主页查看结果
    【DevOps】搭建实战_第43张图片
sonar-scanner 方式
  • 下载 Sonar-scanner,为匹配SonarQube服务版本,本文选择下载4.6.x Linux版本版本。

  • 上传到服务器并解压缩

    unzip sonar-scanner-cli-4.6.2.2472-linux.zip 
    mv sonar-scanner-4.6.2.2472-linux sonar-scanner
    
  • 配置sonarQube服务端地址,修改conf目录下的sonar-scanner.properties
    在这里插入图片描述

  • 获取SonarQube登录者令牌(Token)
    【DevOps】搭建实战_第44张图片

  • 测试使用sonar-scanner检测代码
    在项目目录下执行指令

    ~/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=test -Dsonar.login=a29d38cf824b24d9e495e4a714879deb10ced30e -Dsonar.projectKey=linux-scanner -Dsonar.java.binaries=target/
    

    【DevOps】搭建实战_第45张图片
    Dsonar.sources :扫描资源目录
    Dsonar.projectname:指定项目的名称
    Dsonar.projectKey:项目键,唯一标识符
    Dsonar.login:设置账户token
    Dsonar.java.binaries:指定编译生成的 Java 二进制文件的位置

  • 查看结果
    【DevOps】搭建实战_第46张图片


Jenkins 集成

Jenkins继承SonarQube实现代码扫描需要先下载整合插件:SonarQube Scanner

  • 将解压后的sonar-scanner目录移入Jenkins存储卷
    注意将目录的用户和用户组设置为 1000
    在这里插入图片描述

  • 插件商店进行安装
    【DevOps】搭建实战_第47张图片

  • 开启SonarQube权限验证
    【DevOps】搭建实战_第48张图片

  • 配置Jenkins的SonarQube信息
    【DevOps】搭建实战_第49张图片
    【DevOps】搭建实战_第50张图片

  • 配置Jenkins全局工具之SonarQube Scanner
    【DevOps】搭建实战_第51张图片

  • 修改任务,配置Sonar-scanner
    【DevOps】搭建实战_第52张图片
    【DevOps】搭建实战_第53张图片

  • 重新构建测试并观察控制台日志
    【DevOps】搭建实战_第54张图片

  • 查看SonarQube控制台
    【DevOps】搭建实战_第55张图片

  • 接口访问验证
    在这里插入图片描述

阶段总结

截止本段落位置,各架构关系图为

【DevOps】搭建实战_第56张图片



Harbor 集成

懂得都懂,不做介绍。

Harbor 搭建

下载相关资源:️友情链接

  • 拖拽到Linux并解压:

    tar -zxvf harbor-offline-installer-v2.3.4.tgz -C /usr/local/
    
  • 修改Harbor配置文件:

    • 首先复制一份harbor.yml配置

      cp harbor.yml.tmpl harbor.yml
      
    • 编辑harbor.yml配置文件

      【DevOps】搭建实战_第57张图片

  • 启动

    ./install.sh
    
  • 运行命令后可以发现 Harbor 也是以docker容器的形式启动的
    【DevOps】搭建实战_第58张图片

  • 访问Harbor并登录
    【DevOps】搭建实战_第59张图片

  • 创建测试项目
    在这里插入图片描述

  • 修改daemon.json,定义私库地址,重启Docker让配置生效
    在这里插入图片描述

  • 尝试推送镜像并查看仓库
    【DevOps】搭建实战_第60张图片
    【DevOps】搭建实战_第61张图片


Jenkins集成

构建镜像和发布镜像到harbor都需要使用到docker命令。设置Jenkins容器内部直接采用宿主机的Docker,节省点资源。当然,Jenkins里也可以安装docker。

Jenkins docker
  • 设置宿主机docker.sock权限:
    chown root:root /var/run/docker.sock
    chmod o+rw /var/run/docker.sock
    
  • Jenkins 添加数据卷
    version: "3.1"
    services:
      jenkins:
        image: jenkins/jenkins:2.401.1-lts
        container_name: jenkins
        ports:
          - 8080:8080
          - 50000:50000
        volumes:
          - ./data/:/var/jenkins_home/
          - /usr/bin/docker:/usr/bin/docker
          - /var/run/docker.sock:/var/run/docker.sock
          - /etc/docker/daemon.json:/etc/docker/daemon.json
    
  • 重启Jenkins并验证docker
    在这里插入图片描述
shell脚本 - 镜像 - 推送
  • 修改Jenkins任务

    • 修改配置:原构建后操作删除(不需要传输了,走Harbor仓库)
      【DevOps】搭建实战_第62张图片
    • 新增构建后操作,执行shell(制作镜像并推送)
      【DevOps】搭建实战_第63张图片
  • 测试任务

    • Gitlab新的Tag
      在这里插入图片描述
    • Jenkins任务构建并推送
      【DevOps】搭建实战_第64张图片
      • 报错了:要以非交互方式运行该命令,防止密码最历史记录或日志文件中
        【DevOps】搭建实战_第65张图片
    • shell命令再次修改(骂骂咧咧)
      • 在Jenkins容器用户目录下生成保存密码的文件
        在这里插入图片描述
      • 修改shell命令
        【DevOps】搭建实战_第66张图片
        mv target/*.jar docker/
        docker build -t 192.168.1.190:80/mytest/test:$tag docker/
        docker login --username admin --password-stdin < ~/my_password.txt 192.168.1.190:80
        docker push 192.168.1.190:80/mytest/test:$tag
        
  • 再次尝试构建任务(成功)
    【DevOps】搭建实战_第67张图片
    【DevOps】搭建实战_第68张图片

部署到目标服务器

部署项目需要通过Publish Over SSH插件,让目标服务器执行命令。

为了方便一次性实现拉取镜像和启动的命令,推荐采用脚本文件的方式。

添加脚本文件到目标服务器,再通过Publish Over SSH插件让目标服务器执行脚本即可。

  • 目标服务器脚本文件准备
    harbor_url=$1
    harbor_project_name=$2
    project_name=$3
    tag=$4
    port=$5
    
    imageName=$harbor_url/$harbor_project_name/$project_name:$tag
    
    containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
    if [ "$containerId" != "" ] ; then 
        docker stop $containerId
        docker rm $containerId
        echo "Delete Container Success"
    fi
    
    imageId=`docker images | grep ${project_name} | awk '{print $3}'`
    
    if [ "$imageId" != "" ] ; then
        docker rmi -f $imageId
        echo "Delete Image Success"
    fi
    
    docker login  --username admin --password-stdin < ~/my_password.txt $harbor_url
    
    docker pull $imageName
    
    docker run -d -p $port:$port --name $project_name $imageName
    
    echo "Start Container Success"
    echo $project_name
    
  • 添加执行权限,并移入环境变量(为了可以任意文件夹下执行)
    在这里插入图片描述
  • 配置Jenkins任务构建后操作
    【DevOps】搭建实战_第69张图片
  • 测试流程
    • 修改代码并Gitlab Tag
      【DevOps】搭建实战_第70张图片在这里插入图片描述
    • 构建并测试接口
      • Jenkins构建成功
        【DevOps】搭建实战_第71张图片
      • docker容器运行成功
        【DevOps】搭建实战_第72张图片
      • 程序接口测试成功
        在这里插入图片描述

架构图总结

【DevOps】搭建实战_第73张图片

你可能感兴趣的:(实战教程,文档整理,运维)