云原生KubeSphere DevOps流水线部署RuoyiCloud

一、简介

        DevOps (Development和Operations的组合词)是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI) 和持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。

我们借助KubeSphere来学习DevOpsKubeSphere DevOps 系统

在这里插入图片描述

步骤如下:

  1. 拉取代码
  2. 项目编译
  3. 构建镜像
  4. 推送镜像仓库
  5. 部署k8s

二、首先创建一个devops工程以及流水线

1、创建流水线工程

 

 2、创建流水线

 

 

 

 3、 编辑流水线

 选择上面的流水线模板:

上面的模板我们需要自定义,主要分为如下几个步骤:

  1. 拉取代码
  2. 项目编译
  3. 构建镜像
  4. 推送镜像仓库
  5. 部署k8s

 

 


三、开始定义流水线之拉取代码

1、编写第一个拉取代码的步骤

点击添加步骤:

 

可以参考kubesphere的官网,可供选择的有4个容器:

 

 

 

 点击添加嵌套步骤主要是用来拉取代码:

 

 

 

下面我们再加一个嵌套步骤,用来看拉取代码是否成功: 

 

 

 

点击确认: 

 

点击保存:

 

下面我们点击运行,看看第一步拉取代码是否成功:

 点击进去:

发现失败了,可以查看日志:

重新编辑流水线,将容器换成maven:

 

点击运行,查看日志,第一步代码已经拉取成功:

 

 


四、开始定义流水线之项目编译

1、开始编写项目编译步骤

 

2、先指定容器为maven

 

 

 

 3、添加嵌套命令ls,确定代码

 

 

4、再次添加嵌套的shell命令用来打包项目代码

 

 

 

mvn clean package -Dmaven.skip.test=true 

 

5、点击确定保存,运行流水线

 

注意:
在使用mvn clean pacgage Dmaven.test.skip=true 命令进行编译打包时,Maven会从中央仓库去下载依赖,这样速度会很慢,我们需要修改Maven的配置文件ks-devops-agent,修改为阿里云的,注意这个要使用admin账户登录,选择集群管理

 

 

 

下面我们重新运行看看速度:

 

可以发现是从阿里云下载的依赖了 


五、开始定义流水线之构建镜像

1、开始编写构建镜像命令,下面我们以ruoyi-auth服务为例,指定容器

 

 

2、添加嵌套步骤,查看编译好的代码结构

 

我们先运行看一下:

 

3、下面根据上面的目录编写生成镜像的命令 

点击保存

 

4、下面我们点击运行测试一下 

由上可知,编译镜像成功!

5、下面我们把后端其他的镜像也一起构建,我们使用并行的方式 

点击添加并行阶段:

 可以发现上面一个一个添加太慢了,我们直接编辑Jenkinsfile文件:

 

我们直接找到这部分进行修改,具体内容如下:

 

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          git(url: 'https://gitee.com/kgf897570/ruoyi-cloud.git', branch: 'master', credentialsId: 'ruoyi-cloud-gitee', changelog: true, poll: false)
          sh 'ls'
        }

      }
    }

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

      }
    }

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

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

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

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

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

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

          }
        }
      }
    }

    stage('推送镜像仓库') {
      when {
        branch 'master'
      }
      steps {
        container('maven') {
          sh 'docker tag  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
          sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
        }

      }
    }

    stage('部署到dev环境') {
      steps {
        input(id: 'deploy-to-dev', message: 'deploy to dev?')
        kubernetesDeploy(configs: 'deploy/dev-ol/**', enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
      }
    }

    stage('deploy to production') {
      steps {
        input(id: 'deploy-to-production', message: 'deploy to production?')
        kubernetesDeploy(configs: 'deploy/prod-ol/**', enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'docker.io'
    DOCKERHUB_NAMESPACE = 'docker_username'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'devops-java-sample'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

 最后结果如下:

下面我们直接点击运行试一下:

 

可以发现运行成功 

 


六、开始定义流水线之推送到镜像仓库

1、直接编辑Jenkinsfile文件,在environment定义环境变量,可以直接使用$来引用。

2、创建登录凭证: 

 

 

  

3、修改推送镜像的Jenkinsfile文件部分

 stage('推送镜像仓库') {
      agent none
      steps {
        container('maven') {
           withCredentials([usernamePassword(credentialsId : 'aliyu-ruoyi' ,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-auth:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-auth:SNAPSHOT-$BUILD_NUMBER ' //打上标签
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-auth:SNAPSHOT-$BUILD_NUMBER ' //推送到阿里云仓库
          }
        }

      }
    }

4、下面我们将环境变量以及推送镜像部分的修改放到流水线的Jenkinsfile中

 

 5、下面我们保存然后运行一下

由上可知登录阿里云仓库以及打版本号都已经成功

 

推送失败了,没有权限是我们的阿里云凭证搞错了,修改后重新推送:

 

成功,查看阿里云仓库:

 

  

6、上面完整的Jenkinsfile内容如下

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          git(url: 'https://gitee.com/kgf897570/ruoyi-cloud.git', branch: 'master', credentialsId: 'ruoyi-cloud-gitee', changelog: true, poll: false)
          sh 'ls'
        }

      }
    }

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

      }
    }

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

          }
        }

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

          }
        }

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

          }
        }

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

          }
        }

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

          }
        }

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

          }
        }

      }
    }

    stage('推送镜像仓库') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyu-ruoyi' ,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-auth:latest $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-auth:SNAPSHOT-$BUILD_NUMBER '
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-auth:SNAPSHOT-$BUILD_NUMBER '
          }

        }

      }
    }

    stage('部署到dev环境') {
      steps {
        input(id: 'deploy-to-dev', message: 'deploy to dev?')
        kubernetesDeploy(configs: 'deploy/dev-ol/**', enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
      }
    }

    stage('deploy to production') {
      steps {
        input(id: 'deploy-to-production', message: 'deploy to production?')
        kubernetesDeploy(configs: 'deploy/prod-ol/**', enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
      }
    }

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

7、创建并行推送镜像到阿里云仓库

先创建一个并行的模板:

 然后将Jenkinsfile的内容拷贝出来进行手动修改:

 

 

开始将我们所有的后台服务都进行编写推送:

 ​​​​​​​

点击运行测试推送:

 

由上可知推送成功,我们去仓库查看:

 

 下面开始部署项目

 


六、开始定义流水线之部署项目到k8s

1、编写流水线步骤

 

在这里插入图片描述

 

 

上面的就是凭证ID名称的来源,要保持一致 

 

 

2、给每个微服务准备一个deployment.yml文件:

yaml文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ruoyi-auth
  name: ruoyi-auth
  namespace: ormis   #一定要写名称空间
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: ruoyi-auth
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ruoyi-auth
    spec:
      imagePullSecrets:
        - name: kgf-aliyun-hub  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-auth:SNAPSHOT-$BUILD_NUMBER
          imagePullPolicy: Always
          name: ruoyi-auth
          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-auth
  name: ruoyi-auth
  namespace: ormis
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: ruoyi-auth
  sessionAffinity: None
  type: ClusterIP

 上面的kgf-aliyun-hub凭证要提前在项目中建好:

 3、下面我们运行流水线测试一下看看是否可以部署成功

修改一下Jenkinsfile文件:

 

再次部署:

 

成功,下面到项目中看一下:

 

4、下面我们将其他几个服务创建并行部署 

我们先简单创建一个模板:

 

直接编辑Jenkinsfile文件:

 

 

 5、点击运行测试

 

后端全部部署成功! 


七、开始定义流水线之部署前端项目到k8s

1、创建前端服务的流水线

 如果指定路径下存在Jenkinsfile,将会为我们自动创建流水线

 

 

2、查看应用负载 

 创建一个对外的svc

 

访问: 

 

 访问成功:

3、前端用到的相关配置文件

3.1、deploy.yaml

内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ruoyi-ui
  name: ruoyi-ui
  namespace: ormis   #一定要写名称空间
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: kgf-aliyun-hub  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$DOCKERHUB_NAMESPACE/ruoyi-ui:SNAPSHOT-$BUILD_NUMBER
          imagePullPolicy: Always
          name: ruoyi-ui
          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-ui
  name: ruoyi-ui
  namespace: ormis
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: ruoyi-ui
  sessionAffinity: None
  type: ClusterIP

 3.2、Jenkinsfile文件

内容如下:

pipeline {
  agent {
    node {
      label 'nodejs'
    }

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

      }
    }

    stage('项目编译') {
      agent none
      steps {
        container('nodejs') {
          sh 'ls -l'
          sh 'cd ruoyi-ui/ && ls -al'
          sh 'cd ruoyi-ui/ && npm install --registry=https://registry.npm.taobao.org'
          sh 'cd ruoyi-ui/ && ls -al && npm run build:prod'
          sh 'cd ruoyi-ui/ && 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 : 'aliyu-ruoyi' ,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')
      }
    }

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

 3.3、Dockerfile文件

 内容如下:

# 基础镜像
FROM nginx
# author
MAINTAINER ruoyi
 
# 挂载目录
VOLUME /home/ruoyi/projects/ruoyi-ui
# 创建目录
RUN mkdir -p /home/ruoyi/projects/ruoyi-ui
# 指定路径
WORKDIR /home/ruoyi/projects/ruoyi-ui
# 复制conf文件到路径
COPY ./nginx/conf/nginx.conf /etc/nginx/nginx.conf
# 复制html文件到路径
COPY ./dist /home/ruoyi/projects/ruoyi-ui

3.4、nginx.conf文件

内容如下:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  _;

		location / {
            root   /home/ruoyi/projects/ruoyi-ui;
			try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }
		
		location /prod-api/{
			proxy_set_header Host $http_host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header REMOTE-HOST $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_pass http://ruoyi-gateway-svc.ormis:8080/;
		}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}# requirepass 123456

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值