devops-发布vue前端项目

回到目录

将使用jenkins+k8s发布前端项目

1 环境准备

node环境

在部署jenkins的服务器上搭建node环境

node版本

# 1.拉取
https://nodejs.org/download/release/v20.4.0/node-v20.4.0-linux-x64.tar.gz

# 2.解压到/usr/local目录下
sudo tar xf v20.4.0.tar.gz -C /usr/local
#   重命名为node20
mv v20.4.0 node20

# 3.配置环境变量
vim /etc/profile
export PATH=$PATH:/usr/local/node20/bin
#   文件生效
source /etc/profile

# 4.软连接
sudo ln -s /usr/local/node20/bin/npm /usr/local/bin/
sudo ln -s /usr/local/node20/bin/node /usr/local/bin/

# 5.验证
node -v
npm -v

验证环境没有问题后,将文件移动到jenkins的目录下

因为是docker部署的jenkins,挂载目录是/usr/local/docker/docker-jenkins/data,所以必须将node环境移动到该目录下,jenkins才能加载到

mv node20 /usr/local/docker/docker-jenkins/data

jenkins中下载nodejs插件

插件中搜索 nodejs

安装完成后重启,再次进入

在全局工具配置中,找到nodejs

安装目录为docker中jenkins的node目录,可进入docker jinkens容器中查看

2 项目构建

前提:在gitlab中创建一个vue项目,并确保该项目在本地能正常运行

我的项目结构如下,需要添加Dockerfile和jenkinsfile以及deploy目录

 

创建完成后编写jenkinsfile

pipeline{
    agent any


    environment {
    		//gitlab访问凭证
        GIT_CREDENTIAL_ID = 'gitlab-root'
        //gitlab地址
        GIT_REPO_URL = '10.1.9.23:28080'
        //gitlab分组
        GIT_GROUP = 'devops'
        //gitlab项目名称
        GIT_NAME = 'fitmentfront'
        //harbor凭证
        HARBOR_ID = 'harbor-admin'
        //harbor地址
        HARBOR_URL = '39.10.18.1:8858'
        //harbor项目
        HARBOR_REPO = 'repo'
        //发送delpoment.yml到k8s服务器上的地址
        K8S_FILE_PATH = '/opt/k8s/deployfile'
        //gitlab发送到服务器的目录
        GITLAB_DEPLOYMENT_FILE = 'deploy'
    }

     parameters {
				//git插件 分支参数
        gitParameter(
                branchFilter: '.*',
                defaultValue: "${env.BRANCH_NAME ?: 'main'}",
                name: 'BRANCH_NAME',
                type: 'PT_BRANCH',
		description: '请选择要发布的分支'
            )
            //git插件 标签参数
	gitParameter(
                branchFilter: '.*',
                defaultValue: "${env.TAG_NAME ?: 'v:1.0.0'}",
                name: 'TAG_NAME',
                type: 'PT_TAG',
		description: '请选择要发布的标签'
            )
    }


    stages{
       stage("基本信息输出"){
            steps{
                echo '选定待发布信息'
                echo "项目地址    ${GIT_REPO_URL}"
                echo "项目组      ${GIT_GROUP}"
                echo "项目名      ${GIT_NAME}"
                echo "分支        ${BRANCH_NAME}"
                echo "TAG        ${TAG_NAME}"
            }
        }

        stage('拉取gitlab代码') {
            steps {
            		//拉取gitlab代码,选择分支
                checkout scmGit(
                    branches: [
                        [name: env.BRANCH_NAME]
                    ],
                    extensions: [],
                    userRemoteConfigs: [
                        [
                            credentialsId: env.GIT_CREDENTIAL_ID,
                            url: "http://${env.GIT_REPO_URL}/${env.GIT_GROUP}/${env.GIT_NAME}.git"
                        ]
                    ]
                )
                echo '拉取gitlab代码  --SUCCESS'
            }
        }

        stage("编译"){
            steps{
                nodejs('node') {
                    // some block
                    sh '''
                       npm install --registry=https://registry.npmmirror.com
                       npm run build
                    '''
                }
            }
        }
        

         stage("构建镜像"){
            steps {
            		//docker制作镜像
            		//将maven打包的jar移动到docker目录下
            		//使用dockerfile进行构建镜像,镜像名称为 项目名:标签
                sh """
                    echo $PWD
                    docker build -t ${env.GIT_NAME}:${env.TAG_NAME} .
                """
                echo '通过docker制作镜像  --SUCCESS'
            }

        }

        stage('推送镜像到harbor') {
            steps {
            		//使用harbor凭证推送镜像
                withCredentials([
                    usernamePassword(
                        credentialsId: env.HARBOR_ID,
                        passwordVariable: 'DOCKER_PASSWORD',
                        usernameVariable: 'DOCKER_USERNAME'
                    )
                ]) {
                		//打标签为远程仓库标签
                		//登陆到harbor
                		//推送镜像
                    sh """
                        docker tag ${env.GIT_NAME}:${env.TAG_NAME} ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}
                        echo "\$DOCKER_PASSWORD" | docker login -u "\$DOCKER_USERNAME" -p "\$DOCKER_PASSWORD" ${env.HARBOR_URL}
                        docker push ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}
                    """
                }
                echo '推送镜像到harbor  --SUCCESS'
            }
        }

        stage('发送k8s部署yml文件至目标服务器') {
            steps {
                //请空文件夹下所有文件内容
                sh """
                    ssh root@10.199.99.200 rm -rf $K8S_FILE_PATH/*
                """
            		//使用ssh插件 发送deploy目录下的部署yml文件到目标服务器
            		//须提前配置ssh免密登陆
                sshPublisher(
                    publishers: [
                        sshPublisherDesc(
                            configName: 'k8s',
                            transfers: [
                                sshTransfer(
                                    cleanRemote: false,
                                    excludes: '',
                                    execCommand: '',
                                    execTimeout: 120000,
                                    flatten: false,
                                    makeEmptyDirs: false,
                                    noDefaultExcludes: false,
                                    patternSeparator: '[, ]+',
                                    remoteDirectory: '',
                                    remoteDirectorySDF: false,
                                    removePrefix: '',
                                    sourceFiles: "${env.GITLAB_DEPLOYMENT_FILE}/*yaml"
                                )
                            ],
                            usePromotionTimestamp: false,
                            useWorkspaceInPromotion: false,
                            verbose: false
                        )
                    ]
                )
                echo '发送yml文件至目标服务器  --SUCCESS'
            }
        }

        stage('远程执行k8s部署yaml命令') {
            steps {
            		//替换发送过来的部署文件
            		//部署
                sh """
                    ssh root@10.19.99.200 sed -i'' "s#REGISTRY#${env.HARBOR_URL}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yaml
                    ssh root@10.19.99.200 sed -i'' "s#DOCKERHUB_NAMESPACE#${env.HARBOR_REPO}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yaml
                    ssh root@10.19.99.200 sed -i'' "s#APP_NAME#${env.GIT_NAME}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yaml
                    ssh root@10.19.99.200 sed -i'' "s#BUILD_NUMBER#${env.TAG_NAME}#" /${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yaml
                    ssh root@10.19.99.200 kubectl apply -f ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/
                """
                echo '远程执行k8s部署yaml命令  --SUCCESS'
            }
        }

    }
}

 Dockerfile

FROM node:14-alpine AS build
WORKDIR /build/fitment
COPY . .
RUN npm install --registry=https://registry.npmmirror.com && npm run build

FROM nginx:1.22
WORKDIR /app/fitment
COPY --from=build /build/fitment/dist .
EXPOSE 80

deploy中的deployment.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: fitment
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: fitment-conf
  namespace: fitment
  labels:
    app: nginx-conf
data:
  nginx.conf: |
    server {
        listen  80;
        server_name localhost;

        location / {
            root /app/fitment;
            index index.html index.htm;
        }

        location /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://fitmentback.fitment/; #设置监控后端启动的端口

        }

        error_page 500 502 503 504 /50x.html;

        location = /50x.html {
            root    html;
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: fitmet-ui
    component: fitment-devops
    tier: front
  name: fitmet-ui
  namespace: fitment
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: fitmet-ui
      component: fitment-devops
      tier: front
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 100%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: fitmet-ui
        component: fitment-devops
        tier: front
    spec:
      imagePullSecrets:
        - name: harbor-secret
      containers:
        - name: fitmet-ui
          image: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:BUILD_NUMBER
          imagePullPolicy: Always
          ports:
            - containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 30
            timeoutSeconds: 5
            failureThreshold: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 20
            timeoutSeconds: 5
            failureThreshold: 3
            periodSeconds: 10
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
            requests:
              cpu: 100m
              memory: 100Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - name: nginx-conf
              mountPath: /etc/nginx/conf.d/
      volumes:
        - name: nginx-conf
          configMap:
            name: fitment-conf
            items:
            - key: nginx.conf
              path: nginx.conf   
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: fitmet-ui
    component: fitment-devops
  name: fitmet-ui
  namespace: fitment
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: fitmet-ui
    component: fitment-devops
    tier: front
  sessionAffinity: None
  type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fitment-ui-ingress
  namespace: fitment
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: fitment.fooleryang.cn # 域名配置,可以使用通配符 *
    http:
      paths: # 相当于 nginx 的 location 配置,可以配置多个
      - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service:
            name: fitmet-ui # 代理到哪个 service
            port:
              number: 80 # service 的端口
        path: /

3 jenkins创建项目

在vue项目的准备工作完成后【本地运行正常,各个文件准备完成、提交到gitlab中】,创建jenkins流水线项目

执行构建,然后停止【目的:拉取源码的jenkinsfile,得到参数化构建配置】

执行第一次构建后参数化配置即会出现

再次选择tag进行构建

 构建完成后,去k8s中查看相应pod,发现处于运行状态

[root@k8s-master k8s]# kubectl get all -n fitment
NAME                            READY   STATUS    RESTARTS   AGE
pod/fitmet-ui-76c68f444-thm74   1/1     Running   0          23m

NAME                TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/fitmet-ui   NodePort   10.106.206.48   <none>        80:30800/TCP   37m

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/fitmet-ui   1/1     1            1           37m

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/fitmet-ui-76c68f444   1         1         1       37m

访问

可以用配置的ingress进行访问,也可以使用nodeport进行访问

成功访问,说明发布成功

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/58731.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式的应用及示例解析

正则表达式&#xff08;Regular Expression&#xff0c;简称Regex&#xff09;是由特殊字符组成的模式字符串&#xff0c;用于匹配和搜索文本中的特定模式。它在数据处理、文本搜索和替换等方面广泛应用。本文将介绍正则表达式的基本语法&#xff0c;并提供常见的正则表达式示例…

关于数据权限的设计

在项目实际开发中我们不光要控制一个用户能访问哪些资源&#xff0c;还需要控制用户只能访问资源中的某部分数据。 控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC&#xff0c;但是控制用户只能访问某部分资源&#xff08;即我们常说的数据权限&#xff09;使用R…

iTOP-RK3588开发板Ubuntu 系统交叉编译 Qt 工程-命令行交叉编译

使用源码 rk3588_linux/buildroot/output/rockchip_rk3588/host/bin/qmake 交叉编译 QT 工程。 最后烧写编译好的 buildroot 镜像&#xff0c;将编译好的 QT 工程可执行程序在 buildroot 系统上运行。 交叉编译 QT 工程如下所示&#xff0c;首先进入 QLed 的工程目录下。 然后…

什么样的跨网文件安全交换系统 可实现安全便捷的文件摆渡?

进入互联网时代&#xff0c;网络的运算和数据管理能力助力各个行业高速发展&#xff0c;但同样带来了一些网络安全隐患&#xff0c;网络攻击、数据窃取、敏感信息泄露等问题。为此&#xff0c;我国出台了系列政策来全面提升银各行业系统网络安全整体防护水平&#xff0c;其中“…

机器学习笔记之优化算法(四)线搜索方法(步长角度;非精确搜索)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索] 引言回顾&#xff1a;精确搜索步长及其弊端非精确搜索近似求解最优步长的条件反例论述 引言 上一节介绍了从精确搜索的步长角度观察了线搜索方法&#xff0c;本节将从非精确搜索的步长角度重新观察线搜…

纯靠TikTok解压玩具,21岁小伙成功登顶福布斯!

APA的报告说&#xff0c;每年有四千万左右的大人也在受到焦虑的困扰。看来&#xff0c;在Z世代中有90%的人因压力大出现心理或身体症状的现象并不稀奇了。 近几年越来越严重&#xff0c;大家都在四处找寻解压的良方。TikTok上的“#decompression”&#xff08;减压&#xff09…

实时数据监测与三维可视化:数字孪生技术引领工业互联网发展

随着工业互联网的快速发展&#xff0c;数字孪生技术作为其中的重要组成部分&#xff0c;正逐渐引起广泛关注。数字孪生是将实体世界的实时数据与数字模型相结合&#xff0c;形成实体与数字世界的虚拟镜像&#xff0c;为工业互联网带来了前所未有的效率和质量提升。 首先&#x…

手机python编程软件怎么用,手机python编程软件下载

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;手机python编程软件保存的代码在哪里&#xff0c;手机python编程软件怎么运行&#xff0c;现在让我们一起来看看吧&#xff01; 原标题&#xff1a;盘点几个在手机上可以用来学习编程的软件 前天在悟空问答的时候&#…

给你一个网站如何测试?

主要围绕&#xff0c;功能&#xff0c;页面 UI &#xff0c;兼容&#xff0c;性能&#xff0c;安全&#xff0c;这几个方面去聊&#xff0c;首先是制定测试计划&#xff0c;确定测试范围和测试策略&#xff0c;一般包括以下几个部分&#xff1a;功能性测试&#xff1b;界面测试…

160. 相交链表

160. 相交链表 题目方法1双指针方法2哈希表 题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结…

【网络】数据链路层

目录 一、以太网 二、以太网帧格式 三、 MTU 1、MTU概念 2、 MTU对IP协议的影响 3、MTU对UDP协议的影响 4、 MTU对于TCP协议的影响 四、MAC地址 五、 ARP协议 1、ARP协议的作用 2、ARP协议的工作流程 3、ARP数据报的格式 4、中间人 数据链路层解决的&#xff0c;是…

自动化测试的优缺点

围绕测试自动化有很多议论&#xff0c;组织正在进行大量投资以利用测试自动化的好处。测试自动化可以指使用软件工具自动执行测试、将实际结果与预期结果进行比较以及报告差异/错误的过程。实施测试自动化的主要原因之一是减少手动工作和相关风险&#xff0c;同时测试重复性任务…

实例详解如何选择滤波算法

在机器视觉中,图像滤波器无处不在。例如,它们用于减少图像噪声,改善对比度或检测边缘。本文将向您介绍MVTec HALCON中一些最常用的滤波器,它们是如何工作的以及可以用于什么。 mean_image:均值滤波器 首先,我们读取具有背景纹理的示例图像。我们的目标是在不改变实际信…

load、unload和pagehide、pageshow

一、load、unload和pagehide、pageshow的主要应用 1&#xff09;load 和 unload 事件监听web页面的进入和离开&#xff0c;一般用于页面的首次加载、刷新和关闭等操作的监听&#xff1b; 2&#xff09;pageshow 和 pagehide 事件多用于监听浏览器的前进和后退等。 二、pagesh…

【C++】——类和对象

目录 面向过程和面向对象的初步认识类的引入类的定义类的访问限定符及封装类的作用域类的实例化this指针类的6个默认成员函数构造函数析构函数 面向过程和面向对象的初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析求解问题的步骤&#xff0c;通过函数调用…

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)

因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护&#xff0c;固采用 PhpSpreadsheet 效果如图&#xff1a; 第一步&#xff1a;首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下&#xff1a; composer r…

【计算机视觉 | 目标检测 | 图像分割】arxiv 计算机视觉关于目标检测和图像分割的学术速递(7 月 31 日论文合集)

文章目录 一、检测相关(9篇)1.1 Semi-Supervised Object Detection in the Open World1.2 Multi-layer Aggregation as a key to feature-based OOD detection1.3 Non-invasive Diabetes Detection using Gabor Filter: A Comparative Analysis of Different Cameras1.4 Local …

ABAP 自定义搜索功能 demo1

ABAP 自定义搜索功能 demo1 效果&#xff1a; 双击选中行则为选中对应发票 实现 1定义 定义屏幕筛选参数 SELECTION-SCREEN BEGIN OF SCREEN 9020. SELECT-OPTIONS:s1_belnr FOR rbkp-belnr, s1_gjahr FOR rbkp-gjahr, s1_lifnr FOR rbkp-lifnr, s1_erfna FOR rbkp-erfnam, …

详解AMQP协议

目录 1.概述 1.1.简介 1.2.抽象模型 2.spring中的amqp 2.1.spring amqp 2.2.spring boot amqp 1.概述 1.1.简介 AMQP&#xff0c;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议。 百度百科上的介绍&#xff1a; 一个提供统一消息服务的应用层标准高…