jenkins 使用pipline实现K8S中springboot服务部署

jenkins 使用pipline实现K8S中springboot服务部署

  • 关键词
  • 1. springboot 项目配置
    • 1.1 配置 dockerfile-maven-plugin:
    • 1.2 配置Dockerfile文件
    • 1.3 k8sdeployment.yaml配置文件
    • 1.4 配置service.yaml文件
    • 1.5 执行mvn打包命令
  • 2. jenkins 中pipline配置
    • 2.1 新建jenkins的item工程
    • 2.2 添加项目参数
    • 2.3 配置jenkins凭据
    • 2.4 配置pipline脚本

关键词

k8s
springboot
jenkins
dockerfile-maven-plugin
pipline
maven

1. springboot 项目配置

1.1 配置 dockerfile-maven-plugin:

            <plugin>
                <groupId>com.spotifygroupId>
                <artifactId>dockerfile-maven-pluginartifactId>
                <version>1.3.6version>
                <configuration>
                    <repository>demo/spring-boot-demorepository>
                    <tag>0.0.1tag>
                    <buildArgs>
                        <ZIP_FILE>target/${project.build.finalName}.jarZIP_FILE>
                    buildArgs>
                configuration>
            plugin>

说明:
repository 指定docker镜像的repo名称

tag 指定镜像的tag

buildArgs 指定Docerfile中使用的变量

更多的参数设置可以进入到xml的说明文档中查看,例如

contextDirectory 可以指定Dockerfile的路径,默认Dockerfile文件必须与pom文件在同一路径下。

1.2 配置Dockerfile文件

服务使用了 java-jboss-openjdk8-jdk 的镜像作为基础环境,其中可以使用脚本自动计算容器的内存限制,为服务分配合理的内存。
Dockerfile 内容如下

FROM docker.io/fabric8/java-jboss-openjdk8-jdk:latest

USER root
ARG ZIP_FILE
ADD ${ZIP_FILE} /deployments/demo/
ENV JAVA_APP_DIR=/deployments/demo

#设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone && \
    chown -R jboss:root /deployments/aistation

USER jboss
WORKDIR /deployments
CMD [ "/deployments/run-java.sh" ]

说明
${ZIP_FILE} 是由dockerfile-maven-plugin的插件配置中buildArgs属性指定的

1.3 k8sdeployment.yaml配置文件

文件内容如下

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: ${project.artifactId}
  name: ${project.artifactId}
  namespace: ${_server.k8s.namespace}
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      name: ${project.artifactId}
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: ${project.artifactId}
    spec:
      nodeSelector:
        node-role.kubernetes.io/master: ""
      nodeName: node2
      containers:
        - env:
            - name: TZ
              value: Asia/Shanghai
          image:  '${_server.image}'
          imagePullPolicy: IfNotPresent
          name: ${_server.k8s.namespace}
          ports:
            - containerPort: ${_server.port}
          livenessProbe:
            tcpSocket:
              port: ${_server.port}
            timeoutSeconds: 30
          volumeMounts:
            - mountPath: /logs #日志路径,需要根据实际的路径指定
              name: logs
      volumes:
        - name: logs
          hostPath:
            path: /usr/data/eureka/logs/ #日志路径,需要根据实际的路径指定
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

说明
文件中类似 ${_server.port} 的参数需要在pom.xml文件中定义,并且指定引用资源。在pom.xml中需要如下声明

            <resource>
                <directory>./directory>
                <includes>
                    <include>**/*.yamlinclude>
                includes>
                <filtering>truefiltering>
            resource>

部分自定义参数


    <profiles>
        <profile>
            <id>K8S-TESTid>
            <activation>
                <activeByDefault>trueactiveByDefault>
            activation>
            <properties>
                <_server.port>8761_server.port>
                <_server.image>${docker.image.prefix}/${project.artifactId}:${project.version}_server.image>
                <_server.k8s.namespace>自己定义命名空间_server.k8s.namespace>
            properties>
        profile>
    profiles>

其中directory标签指定打包后文件的路径,是相对target/classes文件夹的,当指定./时,其所在路径如下
jenkins 使用pipline实现K8S中springboot服务部署_第1张图片
include标签指定yaml文件的路径,是相对当前pom.xml文件的。

1.4 配置service.yaml文件

apiVersion: v1
kind: Service
metadata:
  name: ${project.artifactId}
  namespace: ${_server.k8s.namespace}
spec:
  ports:
    - name: ${project.artifactId}
      port: ${_server.port}
      targetPort: ${_server.port}
      protocol: TCP
  selector:
    name: ${project.artifactId}

配置及注意事项与deployment.yaml相同

1.5 执行mvn打包命令

执行

mvn clean install dockerfile:build -Dmaven.test.skip=true

在执行前需要设置DOCKER_HOST的环境变量,否则会有如下错误

Caused by: com.spotify.docker.client.exceptions.DockerException: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: org.apache.http.conn.HttpHostConnectException: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect

在windows中可以在cmd命令中执行

set DOCKER_HOST=tcp://<localhost>:2375

localhost 为docker所在的ip,在此之前需要先开放docker的2375端口

在执行成功之后可以看到镜像已经生成
执行成功之后可以看到镜像已经胜场

2. jenkins 中pipline配置

2.1 新建jenkins的item工程

选择流水线(pipline)
jenkins 使用pipline实现K8S中springboot服务部署_第2张图片

2.2 添加项目参数

选择项目中使用参数
勾选项目中使用参数,如果没有此选项,需要在jenkins的插件管理中加入相关插件
jenkins 使用pipline实现K8S中springboot服务部署_第3张图片
增加相关参数如下
jenkins 使用pipline实现K8S中springboot服务部署_第4张图片

2.3 配置jenkins凭据

部署过程需要ssh远程操作并发送文件,所以需要配置ssh凭据
jenkins 使用pipline实现K8S中springboot服务部署_第5张图片
jenkins 使用pipline实现K8S中springboot服务部署_第6张图片

2.4 配置pipline脚本

jenkins 使用pipline实现K8S中springboot服务部署_第7张图片

pipeline {
    agent any
    environment {
    # 环境变量,在此处声明之后,不需要再另外设置系统的环境变量
        DOCKER_HOST = "$DOCKER_HOST" 
    }
    tools {
    # 需要再jenkins的工具管理中设置maven 工具,否则需要单独指定maven环境
        maven 'MAVEN'
    }

    stages {
        stage('GIT PULL') {
            steps {
                echo "获取git代码:$GIT 分支:env.BRANCH"
                # 需要在jenkins的凭据管理中设置git凭据,复制凭据的ID到此处使用
                git branch: "$BRANCH", credentialsId: 'e3d1aa4f-d756-4064-8e23-dc7a1f6b0e66', url: '$GIT'
            }
        }
        stage('BUILD') {
            steps {
                echo "MAVEN BUILD $DOCKER_HOST"
                sh "mvn clean install dockerfile:build"
            }
        }
        stage ('SSH CONNECT') {
            steps {
                script {
                    stage ('SSH AUTH') {
                        def remote = [:]
                        remote.name = 'K8S-MASTER'
                        remote.host = "${TARGET_HOST}"
                        remote.user = "${TARGET_USER}"
                        remote.allowAnyHosts = true
                        # 此参数指定文件在目标机器上的路径
                        def remotePath = "/mnt/demo/"+"${PROJECT_NAME}/"+"${PROFILE}"
                        withCredentials([sshUserPrivateKey(credentialsId: '192.168.100.57', keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'userName')]) {
                        # 这两个参数是与上一行中定义的参数名对应,不要随意改动
                            remote.user = userName
   		                    remote.identityFile = identity
                            stage("SSH PUT FILE") {
                                sshCommand remote: remote, command: "mkdir -p ${remotePath}"
                                sshCommand remote: remote, command: "rm -rf ${remotePath}/*"
                                sshPut remote: remote, from: 'target/classes/k8s-deployment.yaml', into: "${remotePath}/"
                                sshPut remote: remote, from: 'target/classes/k8s-service.yaml', into: "${remotePath}/"
                            }
                            stage("BUILD DEPLOYMENT"){
                                sshCommand remote: remote, command: "kubectl apply -f ${remotePath}/k8s-deployment.yaml"
                            }
                            stage("BUILD SERVICE"){
                                sshCommand remote: remote, command: "kubectl apply -f ${remotePath}/k8s-service.yaml"
                            }
                        }
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(运维,docker,kubernetes,maven,java)