jenkins pipeline实现自动构建并部署至k8s

摘要:
使用jenkins和SCM可以实现代码的整个自动构建和部署过程。为了部署jenkins,我们使用Docker方法来部署jenkins。在终端上运行docker命令,并使用jenkins ci/blue ocean图像运行容器。解锁詹金斯。使用dockerlogs命令从日志信息中复制自动生成的密码。默认密码在解锁Jenkins页面上。粘贴密码并继续。解锁jenkins后,在界面中选择“安装推荐的插件”。最后,jenkins要求创建一个管理员用户。执行jenkenpipeline时,tpl文件中包含在{}中的自定义参数将被sed命令替换为实际内容。HARBOR_CREDS是harper图像仓库的用户密码,数据保存为jenkins的“用户名和密码”

在日常开发中,经常会有发布的需求,而且经常会碰到各种环境,比如:开发环境、测试环境、生产环境。虽然可以使用手动构建、上传服务器部署的方式,但在微服务架构下一个项目经常包含多个微服务的部署,如果用手动方式就会非常繁琐而且容易出错。使用jenkins结合SCM可以实现代码的整个自动化构建部署过程。

本文中自动构建部署过程大致完成了以下步骤:

  1. 提交spring boot项目代码并打上git tag,上传代码及tag至gitlab

  2. gitlab通过webhook自动触发jenkins执行任务

  3. jenkins获取代码,执行代码编译、构建docker镜像、上传docker镜像至harbor镜像仓库、执行kubectl命令部署至k8s。

本文中采用jenkins pipeline执行整个jenkins的构建过程,在pipeline中使用docker执行maven构建。文中构建的docker镜像的tag直接采用git中的tag。
下面的示例中,jenkins版本为2.121.3,gitlab版本为10.0.2-ce,如果使用的版本不一致可能会有部分设置差异。

部署jenkins

这里采用docker的方式部署jenkins。

  1. 在终端中运行docker命令,使用jenkinsci/blueocean镜像运行容器。

docker run 
  -d 
  -u root 
  -p 8080:8080 
  -v jenkins_home:/var/jenkins_home 
  -v /var/run/docker.sock:/var/run/docker.sock 
  jenkinsci/blueocean
  1. 访问 http://localhost:8080 地址,等待出现下面解锁界面。

    https://img4.sycdn.imooc.com/5d2d2a9000010be506180387.jpg

    解锁jenkins

  2. 使用docker logs 命令从日志信息中 复制自动生成的密码(在两组星号之间)。

    https://img3.sycdn.imooc.com/5d2d2a9300011ac606300178.jpg

    默认密码

  3. 在 解锁Jenkins 页面, 粘贴密码并继续。

  4. 解锁jenkins后,在界面中选择“安装建议的插件”。

  5. 最后,jenkins要求创建管理员用户。创建新用户或使用admin用户,按照步骤完成后即可登录使用jenkis了。

注:由于后面jenkins pipeline任务会上传docker镜像至harbor仓库,如果harbor使用http需要在/etc/docker/daemon.json中将地址配置到insecure-registries;如果harbor使用自签名https证书,需要将ca证书放入/etc/docker/certs.d/目录下。设置完需要重启docker服务。

准备java示例工程

下面新建spring boot示例工程,示例工程的代码地址为:https://gitee.com/tinylk/pipeline-demo

创建spring boot示例工程

  1. 通过 https://start.spring.io/ 生成spring boot基础工程,添加一个示例Controller类。

package com.example.demo.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HomeController {    @GetMapping("")    public String hello() {        return "Hello!";
    }
}
  1. 修改application配置文件,设置端口。

spring.application.name=pipeline-demo
server.port=40080
  1. 编译运行,访问 http://localhost:40080 地址可以看到示例运行结果。

添加Dockerfile

在工程根目录创建Dockerfile,用来构建docker镜像。其中${JAR_FILE}参数在pipeline执行docker build时,通过build-arg参数传入。

FROM openjdk:8-jdk-alpine#构建参数ARG JAR_FILE
ARG WORK_PATH="/opt/demo"# 环境变量ENV JAVA_OPTS="" 
    JAR_FILE=${JAR_FILE}#设置时区RUN apk update && apk add ca-certificates && 
    apk add tzdata && 
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&     echo "Asia/Shanghai" > /etc/timezone

COPY target/$JAR_FILE $WORK_PATH/

WORKDIR $WORK_PATHENTRYPOINT exec java $JAVA_OPTS -jar $JAR_FILE

添加k8s的Deployment配置

在工程根目录创建k8s-deployment.tpl文件,此文件用来作为k8s的yaml文件模板。在jenkens pipeline执行时,会先将tpl文件中{}括起来的自定义参数用sed命令替换为实际的内容。(由于对k8s的了解有限,不知道有没有更好的方式来实现)

apiVersion: apps/v1kind: Deploymentmetadata:  name: {APP_NAME}-deployment  labels:    app: {APP_NAME}spec:  replicas: 1  selector:    matchLabels:      app: {APP_NAME}  template:    metadata:      labels:        app: {APP_NAME}    spec:      containers:      - name: {APP_NAME}        image: {IMAGE_URL}:{IMAGE_TAG}        ports:        - containerPort: 40080        env:          - name: SPRING_PROFILES_ACTIVE            value: {SPRING_PROFILE}

添加Jenkinsfile

在工程根目录创建Jenkinsfile,用来执行jenkins pipeline任务。Jenkinsfile文件的大概内容描述如下:

  • environment中变量说明,environment的文档说明参见:https://jenkins.io/zh/doc/book/pipeline/jenkinsfile/#%E5%A4%84%E7%90%86%E5%87%AD%E8%AF%81 。

    • HARBOR_CREDS为harbor镜像仓库的用户密码,数据保存为jenkins的“username and password”类型的凭据,用credentials方法从凭据中获取。使用时通过HARBOR_CREDS_USR获取用户名,HARBOR_CREDS_PSW获取密码。

    • K8S_CONFIG为k8s中kubectl命令的yaml配置文件内容,数据保存为jenkins的“Secret Text”类型的凭据,用credentials方法从凭据中获取。这里保存的yaml配置文件内容以base64编码格式保存,在设置凭据时先要进行base64编码。(此base64编码是非必须的,如果直接保存原文,下面Jenkinsfile中需要去掉base64 -d 解码)

    • GIT_TAG变量通过执行sh命令获取当前git的tag值。由于后面构建docker镜像时使用git的tag作为镜像的标签,所以这个变量也不能为空。

  • parameters中变量说明

    • HARBOR_HOST:harbor镜像仓库地址。

    • DOCKER_IMAGE:docker镜像名,包含harbor项目名称。

    • APP_NAME:k8s中的标签名称,对应k8s的yaml模板中的{APP_NAME}。

    • K8S_NAMESPACE:k8s中的namespace名称,执行kubectl命令会部署至此命名空间。

  • stages说明:

    • Maven Build:使用docker的方式执行maven命令,args参数中将.m2目录映射出来,避免执行时重复从远端获取依赖;stash步骤中将jar文件保存下来,供后面的stage使用。

    • Docker Build:unstash获取jar文件。通过sh依次执行docker命令登录harbor、构建镜像、上传镜像、移除本地镜像。构建镜像时,会获取jar文件名传入JAR_FILE参数。

    • Deploy:使用docker的方式执行kubectl命令。在执行前先将K8S_CONFIG中的内容进行base64解密并存为~/.kube/config配置文件,然后执行sed命令将k8s-deployment.tpl文件中“{参数名}”形式参数替换为实际的参数值,最后执行kubectl命令部署至k8s。

parameters中的参数在pipeline任务执行一次后,第二次执行时可以在界面上修改参数值。
这里的stage都是一个接一个自动执行,如果需要手动执行可以使用input指令实现。参见:https://jenkins.io/zh/doc/book/pipeline/syntax/#input

// 需要在jenkins的Credentials设置中配置jenkins-harbor-creds、jenkins-k8s-config参数
pipeline {     agent any     environment {         HARBOR_CREDS = credentials('jenkins-harbor-creds')         K8S_CONFIG = credentials('jenkins-k8s-config')         GIT_TAG = sh(returnStdout: true,script: 'git describe --tags').trim()     }     parameters {         string(name: 'HARBOR_HOST', defaultValue: '172.23.101.66', description: 'harbor仓库地址')         string(name: 'DOCKER_IMAGE', defaultValue: 'tssp/pipeline-demo', description: 'docker镜像名')         string(name: 'APP_NAME', defaultValue: 'pipeline-demo', description: 'k8s中标签名')         string(name: 'K8S_NAMESPACE', defaultValue: 'demo', description: 'k8s的namespace名称')     }     stages {         stage('Maven Build') {             when { expression { env.GIT_TAG != null } }             agent {                 docker {                     image 'maven:3-jdk-8-alpine'                     args '-v $HOME/.m2:/root/.m2'                 }             }             steps {                 sh 'mvn clean package -Dfile.encoding=UTF-8 -DskipTests=true'                 stash includes: 'target/*.jar', name: 'app'             }         }         stage('Docker Build') {             when {                  allOf {                     expression { env.GIT_TAG != null }                 }             }             agent any             steps {                 unstash 'app'                 sh "docker login -u ${HARBOR_CREDS_USR} -p ${HARBOR_CREDS_PSW} ${params.HARBOR_HOST}"                 sh "docker build --build-arg JAR_FILE=`ls target/*.jar |cut -d '/' -f2` -t ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG} ."                 sh "docker push ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"                 sh "docker rmi ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"             }                      }         stage('Deploy') {             when {                  allOf {                     expression { env.GIT_TAG != null }                 }             }             agent {                 docker {                     image 'lwolf/helm-kubectl-docker'                 }             }             steps {                 sh "mkdir -p ~/.kube"                 sh "echo ${K8S_CONFIG} | base64 -d > ~/.kube/config"                 sh "sed -e 's#{IMAGE_URL}#${params.HARBOR_HOST}/${params.DOCKER_IMAGE}#g;s#{IMAGE_TAG}#${GIT_TAG}#g;s#{APP_NAME}#${params.APP_NAME}#g;s#{SPRING_PROFILE}#k8s-test#g' k8s-deployment.tpl > k8s-deployment.yml"                 sh "kubectl apply -f k8s-deployment.yml --namespace=${params.K8S_NAMESPACE}"             }                      }              } }
配置jenkins pipeline任务

创建jenkins pipeline任务,并设置需要的参数。

新建pipeline任务

点击“新建任务”,输入名称并选择“流水线”(pipeline),然后点击确定。

https://img2.sycdn.imooc.com/5d2d2a9d0001360607270360.jpg

新建pipeline

配置 pipeline任务

进入任务的配置界面,在流水线(pipeline)设置部分,选择“Pipeline script from SCM”。SCM选项选为“Git”,配置好工程的git地址以及获取代码的凭证信息。然后在“Additional Behaviours”中添加“Clean before checkout”。

https://img3.sycdn.imooc.com/5d2d2ab90001536f07240448.jpg

配置pipeline

配置harbor账号与密码

选择“凭据”,然后在下图所示位置点击“添加凭据”。在新凭据设置界面,类型选择为“Username with password”,ID设置为“jenkins-harbor-creds”(此处的ID必须与Jenkinsfile中的保持一致)。Username与Password分别设置为harbor镜像私库的用户名和密码。

https://img4.sycdn.imooc.com/5d2d2abd0001c6ba07120311.jpg

添加凭证

https://img1.sycdn.imooc.com/5d2d2ac200016f1607300220.jpg

设置harbor账号密码

配置k8s的kube.config配置信息

k8s中使用kubectl命令时需要yaml格式的服务器及授权信息配置文件。这里将kubectl的yaml配置文件的内容以base64编码后保存在jenkins的凭据中。pipeline任务执行时,先从jenkins凭据中获取内容,进行base64解码后将配置保存为~/.kube/config文件。kubectl的配置文件的内容如下:

apiVersion: v1kind: Configclusters:- name: "test"  cluster:    server: "https://xxxxx"    api-version: v1    certificate-authority-data: "xxxxxx"users:- name: "user1"  user:    token: "xxxx"contexts:- name: "test"  context:    user: "user1"    cluster: "test"current-context: "test"

可以在linux中采用下面命令将kubectl的yaml配置文件进行base64编码。

base64 kube-config.yml > kube-config.txt

然后类似上一步,在jenkins凭据中增加配置文件内容。在凭据设置界面,类型选择为“Secret text”,ID设置为“jenkins-k8s-config”(此处的ID必须与Jenkinsfile中的保持一致),Secret设置为上面经过base64编码后的配置文件内容。

https://img2.sycdn.imooc.com/5d2d2add0001f33607000245.jpg

配置kube配置

测试pipeline任务

在创建的pipeline任务中,点击“立即构建”即可立即执行pipeline任务。

https://img3.sycdn.imooc.com/5d2d2ae100019e4f07350312.jpg

立即构建

在jenkins中存在一个名为Blue Ocean的新界面,在新界面中也可以执行pipeline任务,而且新的界面中查看任务的执行结果更加清晰,所以执行结果日志建议在新界面中查看。点击“Open Blue Ocean”菜单进入新界面。

https://img4.sycdn.imooc.com/5d2d2ae40001bff407140365.jpg

打开Blue Ocean新界面

在Blue Ocean新界面中,可以点击“运行”执行pipeline任务。

https://img2.sycdn.imooc.com/5d2d2afd0001decb07260241.jpg

在新界面中运行

在执行pipeline任务,执行“git describe --tags”命令出错,这是由于上面示例的Jenkinsfile中要求必须有git的tag。在git中增加tag,并提交上传至gitlab后即可解决。

https://img4.sycdn.imooc.com/5d2d2b010001152e07370196.jpg

git无tag时执行错误

在git中增加tag,并提交上传至gitlab后重新执行pipeline任务,所有步骤都执行成功。

https://img2.sycdn.imooc.com/5d2d2b050001c7c007320350.jpg

打上tag执行成功

执行成功后,查看harbor镜像仓库,docker镜像成功上传至harbor。

https://img3.sycdn.imooc.com/5d2d2b2100019ebe07260226.jpg

harbor中镜像

执行成功后,查看k8s中pod运行日志,服务启动成功。

https://img1.sycdn.imooc.com/5d2d2b240001fb4a07100285.jpg

k8s中执行成功

设置gitlab自动触发jenkins

前面的步骤中已经完成了手动执行jenkins执行pipeline任务完成构建部署任务,下面说明如何在代码提交后让gitlab自动触发jenkins执行pipeline任务。

jenkins中安装gitlab插件

要实现gitlab自动触发jenkins任务,需要在jenkins中安装gitlab插件。从jenkins的“系统管理”-“管理插件”中找到gitlab插件并下载安装,重启jenkins后生效。

https://img4.sycdn.imooc.com/5d2d2b290001fff107230361.jpg

选择gitlab插件

https://img4.sycdn.imooc.com/5d2d2b4900013e6607400228.jpg

安装gitlab插件

在gitlab中创建访问token

安装的gitlab插件在配置时,需要gitlab的访问token,先要在gitlab中创建访问的token。点击“用户设置”-“Access Tokens”菜单,进入访问token设置界面。然后输入“Name”,并在“Scopes”中勾选“api”,点击“Create ...”按钮即可创建访问token。创建成功后,一定要将生成的token保存下来,后面将无法再查看生成的token,如果未保存后面只能重新生成。

https://img1.sycdn.imooc.com/5d2d2b4c00012bf507230316.jpg

创建token

https://img2.sycdn.imooc.com/5d2d2b510001c79e07260268.jpg


作者:幕布斯6054654
链接:https://www.imooc.com/article/278426
来源:慕课网

免责声明:文章转载自《jenkins pipeline实现自动构建并部署至k8s》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Docker最全教程——从理论到实战(六)自监督学习(Self-Supervised Learning)多篇论文解读(上)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

配置Prometheus抓取k8s集群外的监测数据

K8s集群内的Prometheus抓取监测数据是通过servicemonitor这个crd来完成的。每个servicemonitor对应Prometheus中的一个target。每个servicemonitor对应一个或多个service,负责获取这些service上指定端口暴露的监测数据,并向Prometheus上报。 service是k8s集群内的资源...

Docker快速指南

Docker使用Go语言开发,基于Linux内核的cgroup、namespace以及AUFS等技术对进程进行封装隔离,是一种操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 Docker则使用宿主机内核提供的隔离机制创建沙盒环境,容器内的应用进程直接运行于宿主的内核。 因为容器内没有虚拟硬件和内核,容器在启动时间、...

阿里云天池新人赛——docker练习场比赛心得

由于在阿里的淘宝商品直播识别大赛中提交结果需要用到docker,以前也没有用过。正好阿里提供了docker的新人赛,借此机会学习一下。 既然学习docker,首先就要了解docker是什么:   Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可...

巅峰对决之Swarm、Kubernetes、Mesos

  另外一篇 https://www.sohu.com/a/157185937_287582 Docker Docker是一个主流容器管理工具,它是第一个基于Linux容器(LXC)的[2],但是现在被runC[46]所取代了(runC是是一个由Open Containers Initiative开发的CLI工具,它能够创建和运行容器[36])。Docke...

docker国内镜像地址

https://registry.docker-cn.com http://hub-mirror.c.163.com https://docker.mirrors.ustc.edu.cn 修改docker镜像地址为阿里云地址: sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <&l...

通过docker安装elasticsearch和安装ik分词器插件及安装kibana

前提: 已经安装好docker运行环境; 步骤: 1.安装elasticsearch 6.2.2版本,目前最新版是7.2.0,这里之所以选择6.2.2是因为最新的SpringBoot2.1.6默认支持的就是6.2.2的,而7.x是有很大更新的,SpringBoot正常集成的情况下无法和es最新版本兼容; 这里只需要记住Document的一个index只能创...