云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud

目录

  • 一、简介
  • 二、代码
  • 三、monitor监控服务流水线(先推送一个服务把整个流程走完)
    • 3.1 创建流水线
    • 3.2 拉取代码
    • 3.3 项目编译
    • 3.4 构建镜像
    • 3.5 推送镜像仓库
    • 3.6 monitor部署k8s
    • 3.7 邮件通知
  • 四、monitor监控服务部署成功
  • 五、部署所有微服务
    • 构建镜像
    • 推送镜像
    • 部署k8s
  • 六、前端项目流水线
    • 代码修改
    • deploy
    • Dockerfile
  • 附录
    • 前端项目Jenkinsfile
    • monitor服务Jenkinsfile文件
    • 所有微服务Jenkinsfiel文件
    • deploy.yml k8s部署文件

一、简介

在前面的学习中,我们已经通过手动的打包、制作镜像、推送镜像仓库、部署k8s的形式完成了对RuoYICloud项目的部署:https://blog.csdn.net/DreamsArchitects/article/details/121121109

但是这种方式过于复杂繁琐。现在我们来学习一下通过流水线来自动化部署RuoYICloud项目。
前提需要部署好MySQL、Nacos、Redis 服务。
Nacos 上云部署

完整流程:

  1. 拉取代码
  2. 项目编译
  3. 制作镜像
  4. 推送镜像仓库
  5. k8s部署
  6. 邮件通知
    云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第1张图片

二、代码

三、monitor监控服务流水线(先推送一个服务把整个流程走完)

先推送一个服务把整个流程走完

3.1 创建流水线

3.2 拉取代码

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第2张图片

3.3 项目编译

3.4 构建镜像

3.5 推送镜像仓库

需要创建镜像仓库凭证

3.6 monitor部署k8s

需要指定Kubeconfig
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第3张图片

3.7 邮件通知

以QQ邮箱为例:
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第4张图片
点击 如何设置:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=369

为 KubeSphere 流水线设置电子邮件服务器:
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第5张图片

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第6张图片
编辑配置文件:

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第7张图片
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第8张图片
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第9张图片

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第10张图片
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第11张图片

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第12张图片

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第13张图片
收到的邮件没有动态取值$BUILD_NUMBER
我们需要修改body:
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第14张图片
将单引号修改为双引号:
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第15张图片
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第16张图片

四、monitor监控服务部署成功

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第17张图片

查看容器运行日志:

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第18张图片

五、部署所有微服务

需要在构建镜像、推送镜像、部署k8s时候 添加并行阶段

构建镜像

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第19张图片

推送镜像

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第20张图片

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第21张图片

部署k8s

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第22张图片

六、前端项目流水线

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第23张图片
流程与后端微服务部署是一样的:

  1. 拉取代码
  2. 项目编译
  3. 构建镜像
  4. 推送镜像
  5. 部署k8s
  6. 邮件通知

注意 在前端项目执行流水线时我们需要指定nodejs容器,不是maven容器。
云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第24张图片

KubeSphere 的 内置四种容器模板

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第25张图片

代码修改

云原生Java架构师——KubeSphere DevOps流水线部署RuoyiCloud_第26张图片

deploy

ruoyi-ui 目录下创建deploy目录,创建deploy.yml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ruoyi-ui
  name: ruoyi-ui
  namespace: ruoyi   #一定要写名称空间
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: ruoyi-ui
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ruoyi-ui
    spec:
      imagePullSecrets:
        - name: aliyun-docker-hub  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$ALIYUNHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER
          #         readinessProbe:
          #           httpGet:
          #             path: /actuator/health
          #             port: 8080
          #           timeoutSeconds: 10
          #           failureThreshold: 30
          #           periodSeconds: 5
          imagePullPolicy: Always
          name: app
          # 前端的端口为80  不是8080
          ports:
            - containerPort: 80
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ruoyi-ui
  name: ruoyi-ui
  namespace: ruoyi
spec:
  ports:
    - name: http
      # Service 暴露 80 端口
      port: 80
      protocol: TCP
      targetPort: 80
      nodePort: 32248
  selector:
    app: ruoyi-ui
  sessionAffinity: None
  type: NodePort

Dockerfile

ruoyi-ui目录下创建Dockerfile文件。
Dockerfile文件的内容是基于nginx镜像 复制编译后的dist文件夹下的文件到容器内的/usr/share/nginx/html/目录,最后暴露80端口。

FROM nginx

#将dist目录内容复制到nginx容器html内部
COPY dist /usr/share/nginx/html/

EXPOSE 80

附录

前端项目Jenkinsfile

pipeline {
  agent {
    node {
      label 'nodejs'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('nodejs') {
          git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh', branch: 'master', changelog: true, poll: false)
          sh 'ls -al ruoyi-ui/'
        }

      }
    }

    stage('项目编译') {
      agent none
      steps {
        container('nodejs') {
          sh 'npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/'
          sh 'npm install --registry=https://registry.npm.taobao.org'
          sh 'cd ruoyi-ui/'
          sh 'npm run build '
          sh 'ls -al'
        }

      }
    }

    stage('构建镜像') {
      agent none
      steps {
        container('nodejs') {
          sh 'ls'
          sh 'docker build -t ruoyi-ui:latest -f ruoyi-ui/Dockerfile  ./ruoyi-ui'
        }

      }
    }

    stage('推送镜像') {
      agent none
      steps {
        container('nodejs') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-docker-registry' ,usernameVariable : 'DOCKER_USER_VAR' ,passwordVariable : 'DOCKER_PWD_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag ruoyi-ui:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('部署到dev环境') {
      agent none
      steps {
        kubernetesDeploy(configs: 'ruoyi-ui/deploy/**', enableConfigSubstitution: true, kubeconfigId: 'demo-kubeconfig')
      }
    }

    stage('邮件确认') {
      agent none
      steps {
        mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: 'RuoyiCloud UI DevOps流水线 第 "$BUILD_NUMBER" 次 执行成功! ', cc: '[email protected]')
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
    ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'devops-java-sample'
  }
}

monitor服务Jenkinsfile文件

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh-monitor', branch: 'master', changelog: true, poll: false)
          sh 'ls -al'
        }

      }
    }

    stage('项目编译') {
      agent none
      steps {
        container('maven') {
          sh 'mvn clean package  -Dmaven.test.skip=true'
          sh 'ls -al'
        }

      }
    }

    stage('构建monitor镜像') {
      agent none
      steps {
        container('maven') {
          sh 'ls -l ruoyi-visual/ruoyi-monitor/target/'
          sh 'docker build -t ruoyi-monitor:latest -f ruoyi-visual/ruoyi-monitor/Dockerfile ./ruoyi-visual/ruoyi-monitor/'
        }

      }
    }

    stage('推送monitor镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-repository' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag   ruoyi-monitor:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('monitor部署k8s') {
      agent none
      steps {
        kubernetesDeploy(enableConfigSubstitution: true, deleteResource: false, kubeconfigId: 'demo-kubeconfig', configs: 'ruoyi-visual/ruoyi-monitor/deploy/**')
      }
    }

    stage('邮件确认') {
      agent none
      steps {
        mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: "RuoyiCloud Monitor服务 DevOps流水线 第 $BUILD_NUMBER 次 执行成功!", cc: '[email protected]')
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
    ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'devops-java-sample'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

所有微服务Jenkinsfiel文件

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          git(url: 'https://gitee.com/L1692312138/RuoYi-Cloud.git', credentialsId: 'gitee-lsh-monitor', branch: 'master', changelog: true, poll: false)
          sh 'ls -al'
        }

      }
    }

    stage('项目编译') {
      agent none
      steps {
        container('maven') {
          sh 'mvn clean package  -Dmaven.test.skip=true'
          sh 'ls -al'
        }

      }
    }

    stage('构建monitor镜像') {
      agent none
      steps {
        container('maven') {
          sh 'ls -l ruoyi-visual/ruoyi-monitor/target/'
          sh 'docker build -t ruoyi-monitor:latest -f ruoyi-visual/ruoyi-monitor/Dockerfile ./ruoyi-visual/ruoyi-monitor/'
        }

      }
    }

    stage('推送monitor镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-repository' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag   ruoyi-monitor:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('monitor部署k8s') {
      agent none
      steps {
        kubernetesDeploy(enableConfigSubstitution: true, deleteResource: false, kubeconfigId: 'demo-kubeconfig', configs: 'ruoyi-visual/ruoyi-monitor/deploy/**')
      }
    }

    stage('邮件确认') {
      agent none
      steps {
        mail(to: '[email protected]', subject: 'RuoyiCloud流水线执行结果', body: "RuoyiCloud Monitor服务 DevOps流水线 第 $BUILD_NUMBER 次 执行成功!", cc: '[email protected]')
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'registry.cn-shanghai.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'lsh_k8s_repository'
    ALIYUNHUB_NAMESPACE = 'lsh_k8s_repository'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'devops-java-sample'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

deploy.yml k8s部署文件

注意创建名称空间,及修改app、name及拉取的镜像名称。
还需要注意拉取镜像时候使用的镜像仓库的凭证imagePullSecrets

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ruoyi-monitor
  name: ruoyi-monitor
  namespace: ruoyi   #一定要写名称空间
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: ruoyi-monitor
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ruoyi-monitor
    spec:
      imagePullSecrets:
        - name: aliyun-docker-hub  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$ALIYUNHUB_NAMESPACE/ruoyi-monitor:SNAPSHOT-$BUILD_NUMBER
 #         readinessProbe:
 #           httpGet:
 #             path: /actuator/health
 #             port: 8080
 #           timeoutSeconds: 10
 #           failureThreshold: 30
 #           periodSeconds: 5
          imagePullPolicy: Always
          name: app
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ruoyi-monitor
  name: ruoyi-monitor
  namespace: ruoyi
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
#      使用NodePort方式暴露端口  固定端口
#      nodePort: 30887
  selector:
    app: ruoyi-monitor
  sessionAffinity: None
  type: ClusterIP
#  type: NodePort

你可能感兴趣的:(云原生,java,云原生,kubernetes)