关于linux:采用-jenkins-pipeline-实现自动构建并部署至-k8s

47次阅读

共计 9549 个字符,预计需要花费 24 分钟才能阅读完成。

前言

在日常开发中,常常会有公布的需要,而且常常会碰到各种环境,比方:开发环境、测试环境、生产环境。尽管能够应用手动构建、上传服务器部署的形式,但在微服务架构下一个我的项目常常蕴含多个微服务的部署,如果用手动形式就会十分繁琐而且容易出错。应用 jenkins 联合 SCM 能够实现代码的整个自动化构建部署过程。

本文中主动构建部署过程大抵实现了以下步骤:

  • 提交 spring boot 我的项目代码并打上 git tag,上传代码及 tag 至 gitlab
  • gitlab 通过 webhook 主动触发 jenkins 执行工作
  • 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 地址,期待呈现上面解锁界面。

  1. 应用 docker logs 命令从日志信息中 复制主动生成的明码(在两组星号之间)。

  1. 在 解锁 Jenkins 页面, 粘贴明码并持续。
  2. 解锁 jenkins 后,在界面中抉择“装置倡议的插件”。
  3. 最初,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/pipe…

创立 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;
@RestController
public class HomeController {@GetMapping("")
    public String hello() {return "Hello!";}
}

2. 批改 application 配置文件,设置端口。

spring.application.name=pipeline-demo
server.port=40080

3. 编译运行,拜访 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_PATH
ENTRYPOINT exec java $JAVA_OPTS -jar $JAR_FILE

增加 k8s 的 Deployment 配置

在工程根目录创立 k8s-deployment.tpl 文件,此文件用来作为 k8s 的 yaml 文件模板。在 jenkens pipeline 执行时,会先将 tpl 文件中 {} 括起来的自定义参数用 sed 命令替换为理论的内容。(因为对 k8s 的理解无限,不晓得有没有更好的形式来实现)

apiVersion: apps/v1
kind: Deployment
metadata:
  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/boo…。
  • 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/boo…

// 须要在 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 --always').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),而后点击确定。

配置 pipeline 工作

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

配置 harbor 账号与明码

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

增加凭证


设置 habor 账号密码

配置 k8s 的 kube.config 配置信息

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

apiVersion: v1
kind: Config
clusters:
- 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 编码后的配置文件内容。

测试 pipeline 工作

在创立的 pipeline 工作中,点击“立刻构建”即可立刻执行 pipeline 工作。

在 jenkins 中存在一个名为 Blue Ocean 的新界面,在新界面中也能够执行 pipeline 工作,而且新的界面中查看工作的执行后果更加清晰,所以执行后果日志倡议在新界面中查看。点击“Open Blue Ocean”菜单进入新界面。

在 Blue Ocean 新界面中,能够点击“运行”执行 pipeline 工作。

在执行 pipeline 工作,执行“git describe –tags”命令出错,这是因为下面示例的 Jenkinsfile 中要求必须有 git 的 tag。在 git 中减少 tag,并提交上传至 gitlab 后即可解决。

在 git 中减少 tag,并提交上传至 gitlab 后从新执行 pipeline 工作,所有步骤都执行胜利。

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

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

设置 gitlab 主动触发 jenkins

后面的步骤中曾经实现了手动执行 jenkins 执行 pipeline 工作实现构建部署工作,上面阐明如何在代码提交后让 gitlab 主动触发 jenkins 执行 pipeline 工作。

jenkins 中装置 gitlab 插件

要实现 gitlab 主动触发 jenkins 工作,须要在 jenkins 中装置 gitlab 插件。从 jenkins 的“系统管理”-“治理插件”中找到 gitlab 插件并下载安装,重启 jenkins 后失效。

在 gitlab 中创立拜访 token

装置的 gitlab 插件在配置时,须要 gitlab 的拜访 token,先要在 gitlab 中创立拜访的 token。点击“用户设置”-“Access Tokens”菜单,进入拜访 token 设置界面。而后输出“Name”,并在“Scopes”中勾选“api”,点击“Create …”按钮即可创立拜访 token。创立胜利后,肯定要将生成的 token 保留下来,前面将无奈再查看生成的 token,如果未保留前面只能从新生成。

jenkins 中配置 gitlab 插件

在 jenkins 中,进入“系统管理”-“零碎设置”-“Gitlab”配置。

输出“Connection name”、“Gitlab host URL”,在“Credentials”中点击“Add”增加 gitlab 的受权 token。

点击增加后,会进入增加凭据界面。在增加界面,抉择类型为“GitLab API token”,API token 设置为后面在 gitlab 中创立的 token 值。而后点击“增加”按钮创立凭据。

增加完 gitlab api token,在 Gitlab 设置界面“Credentials”中抉择后面增加的 token,而后点击“Test Connection”测试是否胜利。测试胜利后保留。

配置 pipeline 工作,启用触发器

进入 jenkins 的工作设置界面,在“构建触发器”中,勾上“Build when a change pushed to Gitlab.Gitlab webhook URL …”(这里的 webhook URL 在前面配置 gitlab 时须要),依据本人的须要设置其它的选项。点击“高级”按钮,而后点击“Generate”按钮生成 Secret token(这里的 token 前面配置 gitlab 时须要)。

gitlab 配置 webhook


在 gitlab 的我的项目设置中抉择“Integrations”,而后在 URL 和 Secret token 中填入上一步 jenkins 设置中的到的内容。因为本文中是在 git 上打了 tag 后才触发 jenkins 执行工作,所以这里勾选“Tag push events”,而后去掉“Enable SSL verification”的勾选项,并点击“Add webhook”按钮增加。如果须要每次提交代码都触发则应该选“Push events”(留神:这里抉择 Push events 后,Jenkinsfile 中也须要做相应的批改,去掉 git 的 tag 相干内容,否则执行时会出错)。

webhook 测试

增加实现后,在上面能够看到方才增加的 webhook,点击“Test”按钮在弹出的菜单中选择“Tag push events”发送测试申请,发送胜利后会显示“Hook executed successfully”信息。

Tag push Test


push 胜利

webhook 发送胜利后,到 jenkins 中能够看到正在执行触发的工作。配置胜利后,前面只有有 git 的 tag 提交到 gitlab 即可间接触发 jenkins 执行 pipline 工作。

webhook 触发执行

作者:tinylk
原文:www.jianshu.com/p/2d89fd1b4403

正文完
 0