逃脱只会部署集群系列 —— jenkins流水线构建容器自动部署

目录

一、 jenkins单分支流水线构建

1、把现在的库克隆到本地

2、添加单分支流水线

3、添加gitlab的webhook 

4、配置流水线的构建任务模式

5、Jenkinsfile配置SCM

6、后台进行push操作

7、代码提交后,jenkins自动开始构建任务​

二、Jenkins多分支流水线构建

1、需要部署harbor

2、钉钉告警token明文显示

3、目前只有master分支

3、创建多分支流水线任务

4、通知gitlab构建状态  

5、k8s自动获取最新的镜像地址

6、Jenkinsfile文件配置详解 

三、开始把流程走通

1、修改代码,提交至gitlab

2、提交完成gitlab会更新

​3、gitlab更新,jenkins自动扫描,自动开始构建 

​4、docker构建镜像完成,slave可以看到最新的images

​5、docker推送镜像完成,harbor新增刚才推送的镜像

​6、k8s部署文件镜像地址更新,开始apply

​7、流水线构建完成,钉钉通知


        Jenkins Pipeline 提供了一套可扩展的工具,用于将“简单到复杂”的交付流程实现为“持续交付即代码”。Jenkins Pipeline 的定义通常被写入到一个文本文件(称为 Jenkinsfile )中,该文件可以被放入项目的源代码控制库中。

        本文通过单分支流水线入门,然后进行多分支流水线任务实战,最终实现流程:git代码提交----gitlab更新代码库----jenkins自动扫描到有更新----jenkins自动构建任务----docker构建镜像库----推送至harbor----k8s获取新的image----apply容器

一、 jenkins单分支流水线构建

1、把现在的库克隆到本地

[root@k8s-node2 ~]# git clone http://gitlab.rui.com/root/myblog.git
正克隆到 'myblog'...
Username for 'http://gitlab.rui.com': root
Password for 'http://root@gitlab.rui.com': 
remote: Enumerating objects: 175, done.
remote: Counting objects: 100% (175/175), done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 175 (delta 45), reused 175 (delta 45), pack-reused 0
接收对象中: 100% (175/175), 549.86 KiB | 0 bytes/s, done.
处理 delta 中: 100% (45/45), done.

2、添加单分支流水线

3、添加gitlab的webhook 

4、配置流水线的构建任务模式

5、Jenkinsfile配置SCM

        jenkins有两个方式定义 Pipeline

        1、直接写在 web ui 项目配置

        2、提交到 SCM,在项目配置中指定其位置

       scm可以自动获取gitlab的分支信息,这样我们可以把Jenkinsfile文件直接放在git分支里面,更新时不会覆盖现有的配置,实现版本控制

[root@k8s-node2 myblog]# pwd
/root/myblog
[root@k8s-node2 myblog]# cat Jenkinsfile 
pipeline {
   agent { label '23'}

   stages {
      stage('printenv') {
         steps {
            echo 'Hello World'
            sh 'printenv'
         }
      }
      stage('check') {
          steps {
              checkout scm
          }
      }
      #stage('check') {
       #  steps {
        #    checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-user', url: 'http://gitlab.luffy.com/root/myblog.git']]])
        # }
     # }
      stage('build-image') {
         steps {
            retry(2) { sh 'docker build . -t myblog:latest'}
         }
      }
      stage('send-msg') {
         steps {
            sh """
            curl 'https://oapi.dingtalk.com/robot/send?access_token=d7d8a3e17742d2153de5223ec6b9ba7ea24fe6616495c9318e11f82751cb0d09' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", 
        "text": {
             "content": "jenkins流水线测试:myblog镜像构建完成"
        }
      }'
      """
         }
      }
   }
}

6、后台进行push操作

1、添加默认的用户和邮箱
[root@k8s-node2 myblog]# vim .git/config 

。。。
[user]
        email=rui@qq.com
        name=rui

2、查看本地哪些文件有更新需要提交
[root@k8s-node2 myblog]# git status
# 位于分支 master
# 未跟踪的文件:
#   (使用 "git add <file>..." 以包含要提交的内容)
#
#	Jenkinsfile
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

3、添加文件到本地git缓存区
[root@k8s-node2 myblog]# git add Jenkinsfile

4、推送修改到本地git库中
[root@k8s-node2 myblog]# git commit -m "添加jenkinsfile文件用于测试自动构建"
[master 3c5766c] 添加jenkinsfile文件用于测试自动构建
 1 file changed, 40 insertions(+)
 create mode 100644 Jenkinsfile

5、提交代码到远程gitlab仓库
[root@k8s-node2 myblog]# git push -u origin master
Username for 'http://gitlab.rui.com': root
Password for 'http://root@gitlab.rui.com': 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 899 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://gitlab.rui.com/root/myblog.git
   f40692e..3c5766c  master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

7、代码提交后,jenkins自动开始构建任务

 

二、Jenkins多分支流水线构建

        实际生产不可能直接提交代码至master分支,需要同时为开发和产品环境交付不同的结果。项目的交付会根据Jenkins构建不同的Git分支而有所区别。也就是说,所构建的分支决定你的流水线会执行哪一个交付阶段。

        另外,当前流水线任务还存在几个痛点,我先提出每个痛点以及对应的解决方式,最终给出一份完整的Jenkinsfile文件并注解。

1、需要部署harbor

        部署个harbor用于镜像的push和k8s部署

Linux搭建自己的Docker镜像仓库-阿里云开发者社区介绍如何在自己的服务器搭建docker镜像仓库https://developer.aliyun.com/article/719971

2、钉钉告警token明文显示

        目前流水线任务配置中,最终结果钉钉通知的token还是明文,jenkins类似k8s的secret也有两种加密认证的方式,token认证和用户密码加密认证,jenkins界面设置全局凭证后,jenkinsfile可以直接调用变量。

# JenkinsFile文件添加全局变量
   environment {
        DINGTALK_CREDS = credentials('dingTalk')
    }
# 调用
这实际设置了下面的三个环境变量:
- `DINGTALK_CREDS_CREDS` - 包含一个以冒号分隔的用户名和密码,格式为 `username:password`。
- `DINGTALK_CREDS_CREDS_USR` - 附加的一个仅包含用户名部分的变量。
- `DINGTALK_CREDS_PSW` - 附加的一个仅包含密码部分的变量。

应用举例:
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}'

3、目前只有master分支

        为了测试多分支构建,创建一个develop新分支

$ git checkout develop
分支 develop 设置为跟踪来自 origin 的远程分支 develop。
切换到一个新分支 'develop'

$ git status
# 位于分支 develop
无文件要提交,干净的工作区

3、创建多分支流水线任务

        多分支流水线配置扫描的gitlab地址、频率以及发现分支的规则,无需手动指定git的分支信息,jenkins会自动每分钟扫描一次,或者符合规则的分支的变动。

4、通知gitlab构建状态  

        Jenkins端做了构建,可以通过gitlab通过的api将构建状态通知过去,作为开发人员发起Merge Request或者合并Merge Request的依据之一。

        注意一定要指定gitLabConnection('gitlab'),不然没法认证到Gitlab

jenkinsfile文件配置:

gitLabConnection('gitlab')

updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')

 我们可以访问gitlab,然后找到commit记录,查看同步状态

提交merge request,也可以查看到相关的任务状态,可以作为项目owner合并代码的依据之一

5、k8s自动获取最新的镜像地址

# 把容器部署的yaml放在项目同级deploy目录
[root@k8s-node2 myblog]# tree deploy/
deploy/
├── configmap.yaml
├── deploy-myblog.yaml
├── ingress.yaml
├── secret.yaml
└── svc-myblog.yaml

# 修改deploy-myblog.yaml镜像地址为变量
image: {{IMAGE_URL}}

# Jenkinsfile文件每次构建后修改镜像地址
stage('K8s集群部署容器:') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' deploy/*"
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR
                }
            }
        }

6、Jenkinsfile文件配置详解 

        综合以上提出的问题,最终给出一份实际可行的jenkinsfile文件

pipeline {
    agent { label '23'}		# 选择任务构建的slave节点标签
    
    options {
		buildDiscarder(logRotator(numToKeepStr: '10'))		# 清理策略,保存最近10次构建
		disableConcurrentBuilds()		# jenkins禁止并行构建
		timeout(time: 20, unit: 'MINUTES')		# 超时时间
		gitLabConnection('gitlab')	# 构建结果通知gitlab
	}

    environment {
        IMAGE_REPO = "192.168.0.121:5000/myblog/myblog"	# 镜像仓库环境变量
        DINGTALK_CREDS = credentials('dingTalk')	# 钉钉全局凭证用于token加密调用
        TAB_STR = "\n                    \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
    }	# 没啥意思,用于展示美观

    stages {
        stage('配置环境变量:') {
            steps {
                script{
                    sh "git log --oneline -n 1 > gitlog.file"	# 自定义环境变量用于钉钉告警展示
                    env.GIT_LOG = readFile("gitlog.file").trim()
                }
                sh 'printenv'
            }
        }
        stage('检测GIT分支:') {
            steps {
                checkout scm	# scm自动获取gitlab的分支信息
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')	# 通知构建完成状态给gitlab
                script{
                    env.BUILD_TASKS = env.STAGE_NAME + "OK!" + env.TAB_STR
                }
            }
        }
        stage('Docker构建镜像:') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}	# 失败再次执行,两次失败才报错停止,防止网络等原因影响
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR	# env.BUILD_TASKS获取每次的stage('Docker构建镜像:')的值
                }
            }
        }
        stage('Docker推送镜像:') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR
                }
            }
        }
        stage('K8s集群部署容器:') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' deploy/*"	# GIT_COMMIT数值当作镜像tag,并且替换至dep.yaml中
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f deploy/"
                }
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR
                }
            }
        }
    }
    post {	# 构建结果返回几个状态值,根据不同的状态值配置输出
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \ # 此处钉钉token已加密,用变量代替
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "^v^ 构建成功 ^v^ \n**项目名称**:rui  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}   \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """ 
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "-_-# 构建失败 -_-# \n**项目名称**:rui  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}  \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

三、开始把流程走通

1、修改代码,提交至gitlab

[root@k8s-node2 myblog]# git status
[root@k8s-node2 myblog]# git add Jenkinsfile
[root@k8s-node2 myblog]# git commit -m 'jenkins多分支自动构建镜像自动部署通关测试'
[root@k8s-node2 myblog]# git push origin develop 

2、提交完成gitlab会更新

3、gitlab更新,jenkins自动扫描,自动开始构建 

4、docker构建镜像完成,slave可以看到最新的images

5、docker推送镜像完成,harbor新增刚才推送的镜像

6、k8s部署文件镜像地址更新,开始apply

7、流水线构建完成,钉钉通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

情绪零碎碎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值