手把手带你玩转k8s-jenkins流水线发布springboot项目

前言

上一篇已经将流水线常用语法案例整理了。在这之前,也使用shell写过一键部署springboot项目的脚本。本文会综合前面的知识,编写一条完整的发布springboot到k8s集群的流水线。

发布流程分析

其实,发布流程都大同小异,只是看使用的是啥工具去实现发布流程,人工/shell/jenkins等

  1. 拉取代码
  2. 编译打包
  3. 构建新的镜像
  4. 推送到私有仓库
  5. 使用模板生成新的发布yaml
  6. 调用发布命令

当然,基础流程是这样,但是有部分细节还是需要另外考虑。

关于Dockerfile

Dockerfile文件不建议另外存放了,可直接和源码一起存放。

关于k8s发布模板

这个也一样,可直接和源码一起存放。

关于生产配置文件

开源项目的生产配置文件是不可能直接放在源码上的(当然,即使是不开源,生产配置也不建议放在源码上,因为这样所有开发人员都有访问权限了),所以需要另外存放。这里暂时存放在宿主机的某个目录上。然后指定运行环境时,将目录挂载到容器中。

代码片段:

agent {

docker {

image 'maven:3-alpine'

args '-v /root/.m2:/root/.m2 -v /root/项目名称-config:/root/项目名称-config'

}

}

其中/root/.m2是maven的依赖,这样保证宿主和容器共用依赖,避免了每次都要重新下载。

关于流水线定义文件

流水线有两种定义方式,一种是前面几篇文章讲到的Pipeline script,这种直接就由Jenkins管理。另一种是Pipeline script from SCM,该种即将流水线和源码放在一起,然后使用SCM检出代码的同时检出流水线。为了调试方便,这里先使用前者,后续再考虑转成后者。

开始编码

入参说明

参数名默认值说明
project_namemldong-admin项目名称
deploy_typedeploy发布类型,暂未使用
git_urlgit@gitee.com:mldong/mldong.git仓库地址
branch_namemaster分支名称
profilestest环境类型(prod/test)
registry_urlregistry-vpc.cn-zhangjiakou.aliyuncs.comdocker镜像仓库地址
registry_nsmldong/java镜像命名空间
hostnamec.mldong.com绑定的域名
k8sCredentialsIdali-k8s-configk8s集群配置id
k8sServerUrlhttps://172.26.22.121:6443k8s集群服务地址

目录结构

├── mldong			源码根目录

├── mldong-admin

└── pom.xml

├── mldong-common

└── pom.xml

├── mldong-generator

└── pom.xml

├── mldong-mapper

└── pom.xml

├── Dockerfile

├── k8s.tpl

└── Jenkinsfile

核心文件说明

  • mldong/Dockerfile

    服务镜像定义文件,与之前一键部署的springboot项目的一致

    /java_projects/mldong-admin

    [root@mldong mldong-admin]# cat Dockerfile

    # 指定基础镜像

    FROM openjdk:8u212-jdk-alpine

    # 维护者信息

    MAINTAINER mldong <524719755@qq.com>

    # 创建应用目录

    RUN mkdir -p /app && mkdir -p /app/config

    # 进入工作目录

    WORKDIR /app

    # 复制jar

    COPY app.jar .

    # 配置配置文件

    COPY config/* .

    # EXPOSE 映射端口

    EXPOSE 8080

    # CMD 运行以下命令(如果yaml文件定义了command会被覆盖)

    CMD ["/bin/sh","-c","set -e && java -jar app.jar --spring.profiles.active=dev --server.port=8080"]

  • mldong/k8s.tpl

    k8s发布模板,与之前一键部署的springboot项目的一致

    apiVersion: v1

    kind: Namespace

    metadata:

    name: {{NAMESPACE}}

    ---

    apiVersion: v1

    kind: Service

    metadata:

    name: {{APP_NAME}}-nodeport

    namespace: {{NAMESPACE}}

    spec:

    type: NodePort

    ports:

    - port: 8080

    targetPort: 8080

    selector:

    app: {{APP_NAME}}

    ---

    apiVersion: v1

    kind: Service

    metadata:

    name: {{APP_NAME}}

    namespace: {{NAMESPACE}}

    spec:

    type: ClusterIP

    ports:

    - port: 8080

    protocol: TCP

    targetPort: 8080

    selector:

    app: {{APP_NAME}}

    ---

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: {{APP_NAME}}

    namespace: {{NAMESPACE}}

    spec:

    selector:

    matchLabels:

    app: {{APP_NAME}}

    replicas: 1

    template:

    metadata:

    labels:

    app: {{APP_NAME}}

    spec:

    containers:

    - name: {{APP_NAME}}

    env:

    - name: TZ

    value: Asia/Shanghai

    image: {{IMAGE_URL}}:{{IMAGE_TAG}}

    imagePullPolicy: IfNotPresent

    ports:

    - containerPort: 8080

    name: port

    protocol: TCP

    command: ["/bin/sh"]

    args: ["-c", "set -e && java -jar app.jar --spring.profiles.active={{PROFILES}} --server.port=8080"]

    ---

    apiVersion: extensions/v1beta1

    kind: Ingress

    metadata:

    annotations:

    name: {{APP_NAME}}-ingress

    namespace: {{NAMESPACE}}

    spec:

    rules:

    - host: {{HOST}}

    http:

    paths:

    - backend:

    serviceName: {{APP_NAME}}

    servicePort: 8080

    path: /

  • mldong/Jenkinsfile

    流水线定义文件

    pipeline {

    agent any

    // 环境变量

    environment {

    // docker私有仓库凭证

    dockerhub_credentials = credentials('ali-dockerhub')

    // 镜像版本

    image_tag = sh(returnStdout:true,script:'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()

    }

    // 入参定义

    parameters {

    string(name:'project_name', defaultValue:'mldong-admin', description:'项目名称')

    string(name:'deploy_type', defaultValue:'deploy', description:'发布类型')

    string(name:'git_url', defaultValue:'git@gitee.com:mldong/mldong.git', description:'仓库地址')

    string(name:'branch_name', defaultValue:'master', description:'git分支')

    string(name:'profiles', defaultValue:'test', description:'环境')

    string(name:'registry_url', defaultValue:'registry-vpc.cn-zhangjiakou.aliyuncs.com', description:'镜像仓库地址')

    string(name:'registry_ns', defaultValue:'mldong/java', description:'镜像命名空间')

    string(name:'hostname', defaultValue:'c.mldong.com', description:'绑定的域名')

    string(name:'k8sCredentialsId', defaultValue:'ali-k8s-config', description:'k8s集群配置id')

    string(name:'k8sServerUrl', defaultValue:'https://172.26.22.121:6443', description:'k8s集群服务地址')

    }

    stages{

    stage('检出代码') {

    steps{

    // 检出代码

    checkout([$class:'GitSCM', branches: [[name:"*/${params.branch_name}"]],

    doGenerateSubmoduleConfigurations:false,

    extensions: [],

    submoduleCfg: [],

    userRemoteConfigs: [[

    credentialsId:'mldong-gitbash',

    url:"${params.git_url}"]]])

    }

    }

    stage("编译打包"){

    agent {

    docker {

    image 'maven:3-alpine'

    args "-v /root/.m2:/root/.m2 -v /root/${params.project_name}-config:/root/${params.project_name}-config"

    }

    }

    steps{

    // 编译打包

    sh "mvn -B -DskipTests clean package"

    // 删除当前目录下的config

    sh "rm -rf config"

    // 复制配置文件到当前工作空间

    sh "cp -rf /root/${params.project_name}-config config"

    sh "pwd"

    }

    }

    stage('构建镜像及推送到docker仓库') {

    steps {

    sh "pwd"

    // 将前一步的配置文件复制到当前目录下

    sh "cp -rf ${env.WORKSPACE}@2/config config"

    // 将前一步生成的jar包复制到当前工作空间下

    sh "cp -rf ${env.WORKSPACE}@2/${params.project_name}/target/${params.project_name}.jar app.jar"

    // 登录镜像仓库

    sh "docker login -u ${dockerhub_credentials_USR} -p ${dockerhub_credentials_PSW} ${params.registry_url}"

    // 构建镜像

    sh "docker build -t ${params.registry_url}/${params.registry_ns}/${params.project_name}:${image_tag} ."

    // 推送镜像到私服

    sh "docker push ${params.registry_url}/${params.registry_ns}/${params.project_name}:${image_tag}"

    // 删除当前目录下的config

    sh "rm -rf config"

    // 删除当前目录下的app.jar

    sh "rm -rf app.jar"

    }

    }

    stage('生成k8s发布模板') {

    steps {

    // 生成k8s发布模板

    sh "sed -e 's#{{APP_NAME}}#${params.project_name}#g;s#{{NAMESPACE}}#${params.project_name}-${params.profiles}#g;s#{{PROFILES}}#${params.profiles}#g;s#{{IMAGE_URL}}#${params.registry_url}/${params.registry_ns}/${params.project_name}#g;s#{{IMAGE_TAG}}#${image_tag}#g;s#{{HOST}}#${params.hostname}#g' k8s.tpl > k8s.yaml"

    // 暂存文件

    stash name:"k8s.yaml", includes:"k8s.yaml"

    // 查看文件

    sh "cat k8s.yaml"

    }

    }

    stage("kubectl apply") {

    agent {

    docker {

    image 'lwolf/helm-kubectl-docker'

    }

    }

    steps {

    withKubeConfig([credentialsId:"${params.k8sCredentialsId}",serverUrl:"${params.k8sServerUrl}"]) {

    // 取出文件

    unstash("k8s.yaml")

    // 发布到k8s集群

    sh 'kubectl apply -f k8s.yaml'

    }

    }

    }

    }

    }

    使用说明

    配置私有仓库用户名密码

配置k8s凭证

宿主机上添加springboot配置文件,目录和编译打包挂载的目录一致。

新增任务(略)

构建项目

结果

可查查看pods详情,镜像一致

kubectl describe pods -n mldong-admin-test

小结

本文以springboot项目为例,编写一个较为完整的发布流水线。看过前面一键部署springboot项目的同学,可能对这个会更有感触些。在我看来,自己使用shell写的一键发布脚本和jenkins流水线写的发布脚本,其实现的思路都大同小异。只不过jenkins的流水线会有更多的配套。而我之所以两个版本都分享了(其实加上快速开发框架的那个一键部署脚本,也有三个版本了),一是为了循序渐进地学习,二是为了让想学习这块内容的同学更多的思路,同时可以根据自己公司的情况,选择不一样的发布方式。咱们做这些,都是为了效率。

相关文章

手把手带你玩转k8s-集群创建和Hello World

手把手带你玩转k8s-ConfigMap与持久化存储

手把手带你玩转k8s-完整的发布一个可对外访问的服务

手把手带你玩转k8s-docker进阶Dockerfile与docker-compose

手把手带你玩转k8s-一键部署springboot项目

手把手带你玩转k8s-一键部署vue项目

手把手带你玩转k8s-常用对象详解

手把手带你玩转k8s-jenkins安装与流水线

手把手带你玩转k8s-jenkins流水线语法

以上是 手把手带你玩转k8s-jenkins流水线发布springboot项目 的全部内容, 来源链接: utcz.com/a/34009.html

回到顶部