【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(下)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

一、Jenkins Pipeline 语法介绍

1.1 Jenkins Pipeline 介绍

1.2 为什么用 Jenkins Pipeline

1.3 Jenkins pipeline 入门

二、Pipeline 声明式语法实战讲解

三、Pipeline Scripted 语法

3.1 流程控制

3.2 Declarative pipeline 和 Scripted pipeline 的比较

四、基于 Jenkins+k8s+nexus+gitlab+harbor+sonarqube+springloud 构建 DevOps

4.1 安装码扫描工具 sonarqube

4.2 Jenkins 界面添加 harbor 凭据

4.2.1 添加凭据

4.2.2 编写 jenkins pipeline

4.3 安装 nexus

4.3.1 安装 nexus

4.3.2 在 pom.xml 文件中声明发布的宿主仓库和 release 版本发布的仓库

4.3.3 在 settings.xml 文件中配置由于用 Maven 分发构件到远程仓库需要认证须要在 ~/.m2/settings.xml 或者中加入验证信息

4.4 安装 gitlab

4.4.1 安装 gitlab

4.4.2 登录 gitlab

4.4.3 在 Jenkins 安装插件

4.4.4 在 Jenkins 上添加 gitlab 凭据

4.4.5 在 gitlab 上新建项目

4.4.6 配置公钥

4.4.7 提交本地代码到 gitlab

4.5 测试跑通流程


本篇文章所用到的资料文件下载地址microservic-test.zip-kubernetes文档类资源-CSDN下载

一、Jenkins Pipeline 语法介绍

1.1 Jenkins Pipeline 介绍

        Jenkins pipeline 流水线是一套运行于 jenkins 上的工作流框架将原本独立运行于单个或者多个节点的任务连接起来实现单个任务难以完成的复杂流程编排与可视化。它把持续提交流水线Continuous Delivery Pipeline的任务集成到 Jenkins 中。

pipeline 是 jenkins2.X 最核心的特性 帮助 jenkins 实现从 CI 到 CD 与 DevOps 的转变。

        持续提交流水线Continuous Delivery Pipeline会经历一个复杂的过程从版本控制、向用户和客户提交软件软件的每次变更提交代码到仓库到软件发布Release。这个过程包括以一种可靠并可重复的方式构建软件以及通过多个测试和部署阶段来开发构建好的软件称为Build。

总结

  • Jenkins Pipeline 是一组插件让 Jenkins 可以实现持续交付管道的落地和实施。

  • 持续交付管道(CD Pipeline)是将软件从版本控制阶段到交付给用户或客户的完整过程的自动化表现。

  • 软件的每一次更改提交到源代码管理系统都要经过一个复杂的过程才能被发布。

1.2 为什么用 Jenkins Pipeline

        本质上Jenkins 是一个自动化引擎它支持许多自动模式。 Pipeline 向 Jenkins 中添加了一组强大的工具支持简单的 CI 到全面的 CD pipeline。通过对一系列的相关任务进行建模用户可以利用 pipeline 的很多特性:

  1. 代码Pipeline 以代码的形式实现使团队能够编辑审查和迭代其 CD 流程。

  2. 可持续性Jenkins 重启或者中断后都不会影响 Pipeline Job。

  3. 停顿Pipeline 可以选择停止并等待人工输入或批准然后再继续 Pipeline 运行。

  4. 多功能Pipeline 支持现实复杂的 CD 要求包括循环和并行执行工作的能力。

  5. 可扩展Pipeline 插件支持其 DSL 的自定义扩展以及与其他插件集成的多个选项。

        DSL 是 Domain Specific Language 的缩写中文翻译为领域特定语言下简称 DSL而与 DSL 相对的就是 GPL这里的 GPL 并不是我们知道的开源许可证而是 General Purpose Language 的简称即通用编程语言也就是我们非常熟悉的 Objective-C、Java、Python 以及 C 语言等等。

1.3 Jenkins pipeline 入门

pipeline 脚本是由 groovy 语言实现的但无需专门学习 groovy。

pipeline 支持两种语法

  • -Declarative声明式
  • -Scripted pipeline 脚本式

声明式 pipeline 语法规则官网流水线语法

声明式语法包括以下核心流程

  1. pipeline声明其内容为一个声明式的 pipeline 脚本。
  2. agent执行节点job 运行的 slave 或者 master 节点。
  3. stages阶段集合包裹所有的阶段例如打包部署等各个阶段。
  4. stage阶段被 stages 包裹一个 stages 可以有多个 stage。
  5. steps步骤为每个阶段的最小执行单元被 stage 包裹。
  6. post执行构建后的操作根据构建结果来执行对应的操作。

根据上面流程创建一个简单的 pipeline

pipeline{
    agent any
    stages{
        stage("This is first stage"){
            steps("This is first step"){
                echo "I am xianchao"
            }
        }
    }
    post{
        always{
            echo "The process is ending"
        }
    }
}

语法解释

  • Pipeline作用域应用于全局最外层表明该脚本为声明式 pipeline。是否必须必须

  • agent作用域可用在全局与 stage 内。agent 表明此 pipeline 在哪个节点上执行是否必须是

参数any、none、label、node、docker、dockerfile

agent any                运行在任意的可用节点上

agent none              全局不指定运行节点由各自 stage 来决定

agent { label 'master' }        运行在指定标签的机器上具体标签名称由 agent 配置决定

agent { 
     node {
         label  'my-defined-label'
         customWorkspace 'xxxxxxx'
    } 
}
# node{ label 'master'} 和 agent { label 'master' } 一样但是 node 可以扩展节点信息允许额外的选项 (比如 customWorkspace )。

agent { docker 'python'  }         使用指定的容器运行流水线

agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}

# 定义此参数时执行 Pipeline 或 stage 时会动态的在具有 label 'my-defined-label' 标签的 node 提供 docker 节点去执行 Pipelines。docker 还可以接受一个 args直接传递给 docker run 调用。
agent {
    // Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
    dockerfile {
        filename 'Dockerfile.build'
        dir 'build'
        label 'my-defined-label'
        additionalBuildArgs  '--build-arg version=1.0.2'
    }
}

二、Pipeline 声明式语法实战讲解

创建一个任务 -> 输入上面代码 -> 立即构建 -> Build with Parameters -> 开始构建

控制台输出观察构建结果

三、Pipeline Scripted 语法

        Groovy 脚本不一定适合所有使用者因此 jenkins 创建了 Declarative pipeline为编写Jenkins 管道提供了一种更简单、更有主见的语法。但是由于脚本化的 pipeline 是基于 groovy 的一种 DSL 语言所以与 Declarative pipeline 相比为 jenkins 用户提供了更巨大的灵活性和可扩展性。

3.1 流程控制

        pipeline 脚本同其它脚本语言一样从上至下顺序执行它的流程控制取决于 Groovy 表达式如 if/else 条件语句举例如下

node {
    stage('Example') {
        if (env.BRANCH_NAME == 'master') {
            echo 'I only execute on the master branch'
        } else {
            echo 'I execute elsewhere'
        }
    }
}

3.2 Declarative pipeline 和 Scripted pipeline 的比较

  • 共同点

  两者都是 pipeline 代码的持久实现都能够使用 pipeline 内置的插件或者插件提供的 stage两者都可以利用共享库扩展。

  • 区别

  两者不同之处在于语法和灵活性。Declarative pipeline 对用户来说语法更严格有固定的组织结构更容易生成代码段使其成为用户更理想的选择。但是 Scripted pipeline 更加灵活因为Groovy 本身只能对结构和语法进行限制对于更复杂的 pipeline 来说用户可以根据自己的业务进行灵活的实现和扩展。

四、基于 Jenkins+k8s+nexus+gitlab+harbor+sonarqube+springloud 构建 DevOps

4.1 安装码扫描工具 sonarqube

# 在 node2 上操作下面命令
[root@k8s-node2 ~]# docker run -d --restart=always --name postgres10 -p 5432:5432 -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=123456 postgres

# 设置虚拟内存
[root@k8s-node2 ~]# sysctl -w vm.max_map_count=262144
[root@k8s-node2 ~]# sysctl -a|grep vm.max_map_count
[root@k8s-node2 ~]# vi /etc/sysctl.conf
vm.max_map_count=262144

[root@k8s-node2 ~]# docker run -d --restart=always --name sonarqube7.9 -p 9000:9000 --link postgres10 -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres10:5432/sonar -e  SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=123456 -v sonarqube_conf:/opt/sonarqube/conf -v sonarqube_extensions:/opt/sonarqube/extensions -v sonarqube_logs:/opt/sonarqube/logs -v sonarqube_data:/opt/sonarqube/data sonarqube

容器日志报错信息

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

解决办法设置虚拟内存

在 jenkins 中安装 sonarqube 插件

        系统管理 -> 插件管理 -> 可选插件搜索 sonar找到 Sonarqube Scanner -> 选择Sonarqube Scanner 直接安装 -> 安装之后重启 jenkins 即可

        登录 sonarqube web 界面node2 ip:9000默认账号密码都为 admin在 sonarqube 的 web 界面创建一个 token

把 copy 后面的一串 token 记录下来0e7e0d837275659b83c25015b0a69f2a00285568 

回到 k8s 的控制节点

# 上传代码项目压缩包并解压
[root@k8s-master1 ~]# unzip -o microservic-test.zip 
[root@k8s-master1 ~]# cd microservic-test/

# 把代码上传到 sonarqube
mvn sonar:sonar -Dsonar.host.url=http://192.168.78.145:9000 -Dsonar.login=0e7e0d837275659b83c25015b0a69f2a00285568

可以查看我的这篇文章安装 mavenLinux 下安装 JDK 和 Maven 环境_Stars.Sky的博客-CSDN博客

注意此次实验只做演示作用生成环境中根据实际情况操作。此次代码目前不支持这个版本的sonarqube所以这个上传到 sonarqube 是有问题的会报错版本不支持结果大家可以不用看了解过程就可以。

4.2 Jenkins 界面添加 harbor 凭据

需要有一台 harbor 服务我的 harbor 安装在了192.168.78.138 的机器上。

可以查看我这篇文章安装 harbor【云原生 | Docker 高级篇】11、Docker 私有镜像仓库 Harbor 安装及使用教程_Stars.Sky的博客-CSDN博客

4.2.1 添加凭据

首页 ------> 系统管理 ------> 管理凭据 ------> 点击 Stores scoped to Jenkins 下的第一行 jenkins显示如下

点击这个全局凭据出现如下 

点击添加凭据出现如下 

  • usernameadmin

  • passwordHarbor12345

  • IDharbor

  • 描述随意

4.2.2 编写 jenkins pipeline

        因为镜像要上传到 harbor 私有镜像仓库所以需要在 harbor 上创建一个项目项目名称是 jenkins-demo如下所示

上面项目创建成功之后执行如下步骤在 jenkins 新建一个任务 ------> 输入一个任务名称处输入 jenkins-harbor ------> 流水线 ------> 确定 ------> 在 Pipeline script 处输入如下内容

        修改为自己的 harbor ip 和 GitHub 地址同时也需要在 GitHub 项目上修改 k8s-dev-harbor.yaml、k8s-qa-harbor.yaml 和 k8s-prod-harbor.yaml 的镜像名称 ip

node('test') {
    stage('Clone') {
        echo "1.Clone Stage"
        git url: "https://github.com/loveyou2333/jenkins-sample.git"
        script {
            build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
        }
    }
    stage('Test') {
      echo "2.Test Stage"

    }
    stage('Build') {
        echo "3.Build Docker Image Stage"
        sh "docker build -t 192.168.78.138/jenkins-demo/jenkins-demo:${build_tag} ."
    }
    stage('Push') {
        echo "4.Push Docker Image Stage"
        withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
            sh "docker login 192.168.78.138 -u ${dockerHubUser} -p ${dockerHubPassword}"
            sh "docker push 192.168.78.138/jenkins-demo/jenkins-demo:${build_tag}"
        }
    }
    stage('Deploy to dev') {
        echo "5. Deploy DEV"
		sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev-harbor.yaml"
        sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev-harbor.yaml"
//        sh "bash running-devlopment.sh"
        sh "kubectl apply -f k8s-dev-harbor.yaml  --validate=false"
	}	
	stage('Promote to qa') {	
		def userInput = input(
            id: 'userInput',

            message: 'Promote to qa?',
            parameters: [
                [
                    $class: 'ChoiceParameterDefinition',
                    choices: "YES\nNO",
                    name: 'Env'
                ]
            ]
        )
        echo "This is a deploy step to ${userInput}"
        if (userInput == "YES") {
            sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-qa-harbor.yaml"
            sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-qa-harbor.yaml"
//            sh "bash running-qa.sh"
            sh "kubectl apply -f k8s-qa-harbor.yaml --validate=false"
            sh "sleep 6"
            sh "kubectl get pods -n qatest"
        } else {
            //exit
        }
    }
	stage('Promote to pro') {	
		def userInput = input(

            id: 'userInput',
            message: 'Promote to pro?',
            parameters: [
                [
                    $class: 'ChoiceParameterDefinition',
                    choices: "YES\nNO",
                    name: 'Env'
                ]
            ]
        )
        echo "This is a deploy step to ${userInput}"
        if (userInput == "YES") {
            sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod-harbor.yaml"
            sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod-harbor.yaml"
//            sh "bash running-production.sh"
            sh "cat k8s-prod-harbor.yaml"
            sh "kubectl apply -f k8s-prod-harbor.yaml --record --validate=false"
        }
    }
}

4.3 安装 nexus

        Nexus 服务器是一个代码包管理的服务器可以理解 Nexus 服务器是一个巨大的 Library 仓库。Nexus 可以支持管理的工具包括 Maven、npm 等对于 JAVA 开发来说只要用到 Maven 管理就可以了。

        Nexus 服务器作用因为传统的中央仓库在国外其地理位置比较远下载速度比较缓慢。因此当公司开发人员数量越来越多时如果不架设一台自己的 Nexus 服务器会产生大量的流量阻塞带宽并且在出现一些不可抗原因光缆被挖断导致无法连接到中央仓库时开发就会因为无法下载相关依赖包而进度停滞。因此在本地环境部署一台私有的 Nexus 服务器来缓存所有依赖包并且将公司内部开发的私有包也部署上去方便其他开发人员下载是非常有必要的。因为 Nexus 有权限控制因此外部人员是无法得到公司内部开发的项目包的。

下面将介绍如何将自己的 maven 构件发布到 nexus 私服上呢

4.3.1 安装 nexus

在 harbor 服务器上安装

[root@harbor harbor]# docker run -d --restart=always -p 8081:8081 -p 8082:8082 -p 8083:8083 -v /etc/localtime:/etc/localtime --name nexus3  sonatype/nexus3

        docker logs nexus3 在日志中会看到一条消息Started Sonatype Nexus OSS 3.37.3-02 这意味着 Nexus Repository Manager 可以使用了。现在转到浏览器并打开 http://192.168.78.138:8081/

4.3.2 在 pom.xml 文件中声明发布的宿主仓库和 release 版本发布的仓库

<!-- 发布构件到Nexus -->
    <distributionManagement>
        <repository>
            <id>releases</id>
            <name>nexus-releases</name>
            <url>http://192.168.78.138:8081/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <name>nexus-snapshots</name>
            <url>http://192.168.78.138:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

4.3.3 在 settings.xml 文件中配置由于用 Maven 分发构件到远程仓库需要认证须要在 ~/.m2/settings.xml 或者中加入验证信息

<servers>  
   <server>  
           <id>public</id>  
           <username>admin</username>  
           <password>123456</password>  
       </server>  
   <server>  
           <id>releases</id>  
           <username>admin</username>  
           <password>123456</password>  
       </server>  
   <server>  
           <id>snapshots</id>  
           <username>admin</username>  
           <password>123456</password>  
       </server>  
 </servers>  
注意第二、第三步的文件内容是开发来做的运维只需要第一步安装即可也可以自己了解一下。settings.xml 中 server 元素下 id 的值必须与 POM 中 repository 或snapshotRepository 下 id 的值完全一致 。

4.4 安装 gitlab

4.4.1 安装 gitlab

在 192.168.78.140 服务器上安装生产环境中可以单独一个服务器上安装独立的服务性能好

[root@client01 ~]# docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce

# 修改配置文件在最后面添加下面内容
[root@client01 ~]# vim /home/gitlab/config/gitlab.rb 
external_url 'http://192.168.78.128'
gitlab_rails['gitlab_ssh_host'] = '192.168.78.128'
gitlab_rails['gitlab_shell_ssh_port'] = 22

# 重启 gitlab 服务
[root@client01 ~]# docker restart gitlab 

4.4.2 登录 gitlab

在浏览器访问 192.168.78.128 进入gitlab在页面注册账号后不能登录

解决办法——重置密码

Gitlab 重装密码官网文档Reset a user's password | GitLab

[root@client01 ~]# docker exec -it gitlab sh
# gitlab-rails console -e production        # 启动 Ruby on Rails 控制台等待控制台加载完毕
irb(main):005:0> u=User.where(id:1).first
=> #<User id:1 @root>
irb(main):006:0> u.password='qwe123456'
=> "qwe123456"
irb(main):007:0> u.password_confirmation='qwe123456'
=> "qwe123456"
irb(main):008:0> u.save!
=> true
irb(main):009:0> exit
# exit

重新登录 gitlab

  • 用户名是 root

  • 密码是 qwe123456

4.4.3 在 Jenkins 安装插件

安装 git 插件系统管理 - 插件管理- 可选插件 - 搜索 git 安装即可

4.4.4 在 Jenkins 上添加 gitlab 凭据

4.4.5 在 gitlab 上新建项目

点击右上角的 new project -> Create blank project

4.4.6 配置公钥

[root@client01 ~]# ssh-keygen -t rsa

[root@client01 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8t5LbIE+U29JBAR5UbgZeaKe330yExlMoErPWRAzCoYtFcf2wXBpbzMLTxfsBjr/lBwoJ2BcLOQC30AWkXM3rdwzZHoWFn7r+6DnWxcEbrbNBwUJCf3X9RHBh7e4HlY3hbJEx1Y6Tl/rKnxtg0ASuiUfyiVDSVPcUwcIX8WVuUBvXQU8RHRowFWGcZYaX7RxVswrLObtTLg0CZQ0kUAn6j10wFH2nHdjljBBYjg9WlRc++bE71HSroOENnAvqX6dN7Io86HX0sV66abyNuP2CrJpuR6UZc4iZ9cPyw2E8jzAi9fpMWTwSrwr9yT1zCAFf0ysC7AM98VnX4CwIQm9P root@client01

4.4.7 提交本地代码到 gitlab

# 上传本地代码文件 microservic-test.zip
[root@client01 ~]# yum install git -y
[root@client01 ~]# unzip microservic-test.zip 
[root@client01 microservic-test]# git init    # 建仓
[root@client01 microservic-test]# git add *   # 把当前文件夹所有代码提交 
[root@client01 microservic-test]# git config --global user.email "163.com"
[root@client01 microservic-test]# git config --global user.name "sky"
[root@client01 microservic-test]# git commit -m "add microservic-test"    # 代码提交到缓冲区
[root@client01 microservic-test]# git remote add origin http://192.168.78.128/root/microservic-test.git                    # 代码提交到远程仓库
[root@client01 microservic-test]# git push -u origin master    # 输入 gitlab 账号和密码

回到 gitlab 首页可以看到已经有项目了

4.5 测试跑通流程

        上传 jenkins-jnlp-v2.tar.gz 文件到 node1、node2 并手动解压在 http://192.168.78.143:30002/configureClouds/把 Container  Template 镜像改成 jenkins-jnlp-v2.tar.gz 压缩包解压之后的镜像 xianchao/jenkins-jnlp:v2

修改 gitlab 上 portal.yaml 文件

把 image 镜像变成192.168.78.138/microservice/jenkins-demo:v1 

注意192.168.78.138 为 Harbor 服务器 ip且需要在 harbor 里提前创建这个 microservice 仓库。

打开 Jenkins新建流水线流水线名字是 mvn-gitlab-harbor-springcloud在 Pipeline Script 处输入如下内容根据实际情况修改

node('test') {
   stage('Clone') {
       echo "1.Clone Stage"
      git credentialsId: 'gitlab', url: 'http://192.168.78.128/root/microservic-test.git '
       script {
           build_tag = sh(returnStdout: true, script: 'git rev-parse --shortHEAD').trim()
       }
    }

   stage('Test') {
     echo "2.Test Stage"
    }
   stage('mvn') {
     sh "mvn clean package -D maven.test.skip=true"
    }
   stage('Build') {
       echo "3.Build Docker Image Stage"
       sh "cd /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service"
       sh "docker build --tag 192.168.78.138/microservice/jenkins-demo:v1 /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/portal-service/"
    }
   stage('Push') {
       echo "4.Push Docker Image Stage"
       withCredentials([usernamePassword(credentialsId: 'harbor',passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {
           sh "docker login 192.168.78.138 -u ${dockerHubUser} -p ${dockerHubPassword}"
           sh "docker push 192.168.78.138/microservice/jenkins-demo:v1"
       }
    }
     stage('Promoteto pro') {    
    sh "kubectl apply -f /home/jenkins/agent/workspace/mvn-gitlab-harbor-springcloud/k8s/portal.yaml"
      }
}

立即构建即可

上一篇文章【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台中_Stars.Sky的博客-CSDN博客_k8s运维管理平台

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: k8s

“【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(下)” 的相关文章