【kubernetes】使用KubeSphere devops部署我的微服务系统

KubeSphere Devops

入门使用KubeSphere的Devops功能部署"我的微服务系统"
(内容学习于尚硅谷云原生课程)

kubesphere devops官方文档:
https://v3-1.docs.kubesphere.io/zh/docs/devops-user-guide/how-to-use/create-a-pipeline-using-jenkinsfile/

代码准备

暂时部署这4个服务,auth服务、crm服务、gateway服务、前端ui服务

在这里插入图片描述
在这里插入图片描述

Dockerfile

前端kwsphere

# 基础镜像
FROM nginx
# author
MAINTAINER kw

# 挂载目录
VOLUME /home/kw-microservices/ui/kwsphere
# 创建目录
RUN mkdir -p /home/kw-microservices/ui/kwsphere
# 指定路径
WORKDIR /home/kw-microservices/ui/kwsphere

# 复制conf文件到路径
COPY ./nginx.conf /etc/nginx/nginx.conf
# 复制html文件到路径
COPY ./dist /home/kw-microservices/ui/kwsphere

nginx配置,内容来源于ruoyi

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  localhost;

        location / {
            root   /home/kw-microservices/ui/kwsphere;
            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://kw-gateway:8080/;
        }

        # 避免actuator暴露
        if ($request_uri ~ "/actuator") {
            return 403;
        }

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

后端

后端这个3个服务的dockefile的内容是一样的

# 基础镜像
FROM  openjdk:8-jre
# author
MAINTAINER kw

# 挂载目录
VOLUME /home/kw-microservices
# 创建目录
RUN mkdir -p /home/kw-microservices
# 指定路径
WORKDIR /home/kw-microservices
# 复制jar文件到路径
COPY target/*.jar /home/kw-microservices/app.jar
# 启动网关服务
ENTRYPOINT ["java","-jar","app.jar"]

k8s deploy.yaml

前端kwsphere

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: kwsphere
  name: kwsphere
  namespace: my-server   #一定要写名称空间
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: kwsphere
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: kwsphere
    spec:
      imagePullSecrets:
        - name: aliyun-registry-secret  #提前在项目下配置访问阿里云的账号密码
      containers:
        - image: $REGISTRY/$DOCKERHUB_NAMESPACE/kwsphere:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER
#          readinessProbe:
#            httpGet:
#              path: /actuator/health
#              port: 8080
#            timeoutSeconds: 10
#            failureThreshold: 30
#            periodSeconds: 5
          imagePullPolicy: Always
          name: app
          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: kwsphere
  name: kwsphere
  namespace: my-server
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
      nodePort: 31234
  selector:
    app: kwsphere
  sessionAffinity: None
  type: NodePort

后端kw-gateway

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

后端kw-auth-server

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

后端kw-crm-server

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

环境准备

  • 阿里云镜像服务(电脑计算资源有限,暂时使用阿里云,后续搭建harbor)
  • k8s集群
  • KubeSphere DevOps

使用Docker部署服务测试

使用k8s部署,先用docker部署一次,测试镜像和服务访问是否有问题。
本次搭建的服务镜像Dockerfile文件配置,参考若依微服务系统代码。

创建DevOps工程

在这里插入图片描述

maven镜像地址配置

登录kubesphere管理员权限账号
在这里搜索devops
在这里插入图片描述
修改配置
在这里插入图片描述
增加maven国内镜像仓库地址配置

<mirrors>
 <mirror>  
        <id>alimaven</id>  
        <name>aliyun maven</name>  
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
        <mirrorOf>central</mirrorOf>          
 </mirror>
</mirrors>

访问凭证配置

  • gitee代码凭证
  • 阿里云镜像私有仓库访问凭证
  • k8s访问凭证
    在这里插入图片描述

创建流水线

下图为最终的4个流水线;
先部署成功一个,后面的服务直接复制流水线,通过修改Jenkinsfile,即可快速部署服务;
在这里插入图片描述

初学参考官方提供的流水线模板
在这里插入图片描述

编辑流水线Jenkinsfile

SpringBoot服务

后端kw-gateway

在这里插入图片描述

pipeline {
  agent {
    node {
      label 'maven'
    }

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

      }
    }

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

      }
    }

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

      }
    }

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

        }

      }
    }

    stage('部署dev环境') {
      agent none
      steps {
        container ('maven') {
                      withCredentials([
                          kubeconfigFile(
                          credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                          variable: 'KUBECONFIG')
                          ]) {
                          sh 'envsubst < deploy/gateway/deploy.yaml | kubectl apply -f -'
                      }
                 }
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'kubeconfig'
    REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'kk_hub'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'kw-gateway'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

后端kw-crm-server

在这里插入图片描述

pipeline {
  agent {
    node {
      label 'maven'
    }

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

      }
    }

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

      }
    }

    stage('构建镜像') {
      agent none
      steps {
        container('maven') {
          sh '''ls kw-modules/kw-crm-service/target -l
cat docker/micro-server/crm-server/Dockerfile'''
          sh 'docker build -f docker/micro-server/crm-server/Dockerfile -t kw-crm-server:latest ./kw-modules/kw-crm-service/'
        }

      }
    }

    stage('推送镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-docker-registry' ,passwordVariable : 'DOCKER_ALIYUN_PWD' ,usernameVariable : 'DOCKER_ALIYUN_USER' ,)]) {
            sh 'echo "$DOCKER_ALIYUN_PWD" | docker login $REGISTRY -u "$DOCKER_ALIYUN_USER" --password-stdin'
            sh 'docker tag kw-crm-server:latest  $REGISTRY/$DOCKERHUB_NAMESPACE/kw-crm-server:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/kw-crm-server:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('部署dev环境') {
      agent none
      steps {
        container('maven') {
          withCredentials([
                                                  kubeconfigFile(
                                                      credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                                                      variable: 'KUBECONFIG')
                                                      ]) {
                sh 'envsubst < deploy/crm-server/deploy.yaml | kubectl apply -f -'
              }

            }

          }
        }

      }
      environment {
        DOCKER_CREDENTIAL_ID = 'dockerhub-id'
        GITHUB_CREDENTIAL_ID = 'github-id'
        KUBECONFIG_CREDENTIAL_ID = 'kubeconfig'
        REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
        DOCKERHUB_NAMESPACE = 'kk_hub'
        GITHUB_ACCOUNT = 'kubesphere'
        APP_NAME = 'kw-crm-server'
      }
      parameters {
        string(name: 'TAG_NAME', defaultValue: '', description: '')
      }
    }

后端kw-auth-server

在这里插入图片描述

pipeline {
  agent {
    node {
      label 'maven'
    }

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

      }
    }

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

      }
    }

    stage('构建镜像') {
      agent none
      steps {
        container('maven') {
          sh '''ls kw-auth/kw-auth-server/target -l
cat docker/micro-server/auth-server/Dockerfile'''
          sh 'docker build -f docker/micro-server/auth-server/Dockerfile -t kw-auth-server:latest ./kw-auth/kw-auth-server/'
        }

      }
    }

    stage('推送镜像') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'aliyun-docker-registry' ,passwordVariable : 'DOCKER_ALIYUN_PWD' ,usernameVariable : 'DOCKER_ALIYUN_USER' ,)]) {
            sh 'echo "$DOCKER_ALIYUN_PWD" | docker login $REGISTRY -u "$DOCKER_ALIYUN_USER" --password-stdin'
            sh 'docker tag kw-auth-server:latest  $REGISTRY/$DOCKERHUB_NAMESPACE/kw-auth-server:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/kw-auth-server:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('部署dev环境') {
      agent none
      steps {
        container ('maven') {
                      withCredentials([
                          kubeconfigFile(
                          credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                          variable: 'KUBECONFIG')
                          ]) {
                          sh 'envsubst < deploy/auth-server/deploy.yaml | kubectl apply -f -'
                      }
                 }
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'kubeconfig'
    REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
    DOCKERHUB_NAMESPACE = 'kk_hub'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'kw-auth-server'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

Nodejs服务

前端kwsphere

在这里插入图片描述

pipeline {
  agent {
    node {
      label 'nodejs'
    }

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

      }
    }

    stage('项目编译dist') {
      agent none
      steps {
        container('nodejs') {
          sh 'npm config set user 0'
          sh 'npm config set unsafe-perm true'
          sh 'npm uninstall node-sass'
          sh 'npm i node-sass@4.14.1 --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ --unsafe-perm'
          sh 'npm install --prefix ./kw-ui/kwsphere --registry=https://registry.npm.taobao.org'
          sh 'npm --prefix ./kw-ui/kwsphere run build:prod'
          sh 'ls -l'
        }

      }
    }

    stage('构建镜像') {
      agent none
      steps {
        container('nodejs') {
          sh 'cat docker/micro-server/ui/Dockerfile'
          sh 'docker build -f docker/micro-server/ui/Dockerfile -t kwsphere:latest ./kw-ui/kwsphere/'
        }

      }
    }

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

        }

      }
    }

    stage('部署dev环境') {
      agent none
      steps {
        container('nodejs') {
          withCredentials([
                                                                                                              kubeconfigFile(
                                                                                                                            credentialsId: env.KUBECONFIG_CREDENTIAL_ID,
                                                                                                                            variable: 'KUBECONFIG')
                                                                                                                            ]) {
                sh 'envsubst < deploy/kwsphere/deploy.yaml | kubectl apply -f -'
              }

            }

          }
        }

      }
      environment {
        DOCKER_CREDENTIAL_ID = 'dockerhub-id'
        GITHUB_CREDENTIAL_ID = 'github-id'
        KUBECONFIG_CREDENTIAL_ID = 'kubeconfig'
        REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
        DOCKERHUB_NAMESPACE = 'kk_hub'
        GITHUB_ACCOUNT = 'kubesphere'
        APP_NAME = 'kwsphere'
      }
      parameters {
        string(name: 'TAG_NAME', defaultValue: '', description: '')
      }
    }

问题记录

Kubernetes Deploy插件问题

尚硅谷教程中的k8s deploy插件运行没问题,但在目前搭建过程中不好使了,会报错;

#没有找到
Starting Kubernetes deployment
Loading configuration: /home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere-ui/deploy/gateway/deploy.yml
ERROR: ERROR: java.lang.RuntimeException: io.kubernetes.client.openapi.ApiException: Bad Request

 "message": "the export parameter, deprecated since v1.14, is no longer supported",

在这里插入图片描述

问了kubespere群中的大佬,说是该插件已废弃,官网有新示例。

就是不能再用这个插件了
在这里插入图片描述
改用shell命令运行

sh 'envsubst < deploy/kwsphere/deploy.yaml | kubectl apply -f -'

service指定nodeport报错

#k8s指定端口报错
The Service "kwsphere" is invalid: spec.ports[0].nodePort: Invalid value: 43113: provided port is not in the valid range. The range of valid ports is 30000-32767

前端服务build报错

#npm install报错
#解决,install之前,运行这两个命令
npm config set user 0 
npm config set unsafe-perm true

Unable to save binary /home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/node-sass/vendor/linux-x64-64 : { Error: EACCES: permission denied, mkdir '/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/node-sass/vendor'
    at Object.mkdirSync (fs.js:757:3)
    at sync (/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/mkdirp/index.js:74:13)
    at Function.sync (/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/mkdirp/index.js:80:24)
    at checkAndDownloadBinary (/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/node-sass/scripts/install.js:114:11)
    at Object.<anonymous> (/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/node-sass/scripts/install.js:157:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
  errno: -13,
  syscall: 'mkdir',
  code: 'EACCES',
  path:
   '/home/jenkins/agent/workspace/kw-devopsw2gh4/kubesphere/kw-ui/kwsphere/node_modules/node-sass/vendor' }
#又报错,解决:流水线 步骤中添加执行如下命令
#npm uninstall node-sass
#npm i node-sass@4.14.1 --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ --unsafe-perm

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.14.1 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the node-sass@4.14.1 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2023-08-27T08_57_22_270Z-debug.log
script returned exit code 1

代码多目录build node.js服务问题

我的前后端代码在一个工程中,导致在运行npm命令,找不到package.json文件
尝试在构建过程中,先执行cd命令,进入到前端代码的目录下,但是不好使,
最后找到npm命令如何指定package.json文件路径解决

#使用--prefix参数
npm install --prefix ./kw-ui/kwsphere --registry=https://registry.npm.taobao.org
npm --prefix ./kw-ui/kwsphere run build:prod

结语

以上仅仅是入门学习使用,devops流水线,还有很多地方可以简化配置

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

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

相关文章

Vue2+Vue3笔记(尚硅谷张天禹老师)day02

声明:只是记录&#xff0c;初心是为了让页面更好看,会有错误,我并不是一个会记录的人&#xff0c;所以有点杂乱无章的感觉&#xff0c;我先花点时间把视频迅速过掉&#xff0c;再来整理这些杂乱无章的内容 组件化编程 按照视频来的话&#xff0c;这里应该有一些概念的东西&…

多线程应用——阻塞队列

阻塞队列 文章目录 阻塞队列1.队列的概念2.阻塞队列3.现实中的例子4.消息队列5.使用队列的优势1.解耦2.削峰填谷3.异步操作 6.实现 1.队列的概念 一种先进先出的数据结构 2.阻塞队列 队列写元素是从队尾插入&#xff0c;从对头取出 当插入元素时&#xff0c;先判断一下队列…

com.squareup.okhttp3:okhttp 组件安全漏洞及健康度分析

组件简介 维护者square组织许可证类型Apache License 2.0首次发布2016 年 1 月 2 日最新发布时间2023 年 4 月 23 日GitHub Star44403GitHub Fork9197依赖包5,582依赖存储库77,217 com.squareup.okhttp3:okhttp 一个开源的 HTTP 客户端库&#xff0c;可以用于 Android 和 Jav…

知识图谱项目实践

目录 步骤 SpaCy Textacy——Text Analysis for Cybersecurity Networkx Dateparser 导入库 写出页面的名称 ​编辑 自然语言处理 词性标注 可能标记的完整列表 依存句法分析&#xff08;Dependency Parsing&#xff0c;DEP&#xff09; 可能的标签完整列表 实例理…

Unity 之 参数类型之值类型参数的用法

文章目录 基本数据类型结构体结构体的进一步补充 总结&#xff1a; 当谈论值类型参数时&#xff0c;我们可以从基本数据类型和结构体两个方面详细解释。值类型参数指的是以值的形式传递给函数或方法的数据&#xff0c;而不是引用。 基本数据类型 基本数据类型的值类型参数&…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,动态数组(重点推荐))七(129)

需求&#xff1a;前端根据后端的返回数据&#xff1a;画统计图&#xff1b; 说明&#xff1a; 1.X轴为地域&#xff0c;Y轴为地域出现的次数&#xff1b; 2. 动态展示&#xff08;有地域展示&#xff0c;没有不展示&#xff0c;且高低排序&#xff09; Demo案例&#xff1a; …

硬件SPI口扩展

在工控板设计中&#xff0c;经常会遇到扩展IO。具有相同的功能电路板接口相同&#xff0c;所以很容易采用排线方式连接到CPU主控板上&#xff0c;这种排线连接&#xff0c;我称之为总线。 现在的CPU引脚多&#xff0c;不扩展IO&#xff0c;使用模拟SPI&#xff0c;也可以实现&…

获取Linux内核源码

在嵌入式平台上做Linux开发的时候&#xff0c;我们用的kernel都是芯片厂家移植到自家平台上的&#xff0c;但是最初的原生Linux内核的源码是从哪里来的呢&#xff1f;下面我们介绍一下怎么获取原生的Linux源码。 从Linux社区获取内核kernel源码 Linux社区的官方网站是 https:…

.netcore grpc日志记录配置

一、日志记录配置概述 通过配置文件appsettings.json进行配置通过Program.cs进行配置通过环境变量进行配置客户端通过日志通道进行配置 二、实战案例 配置环境变量:Logging__LogLevel__GrpcDebug配置Appsettings.json配置Program.cs配置客户端工厂以上截图是目前为止已知的可…

基于MQTT协议的物联网网关实现远程数据采集及监控

在数字化时代的浪潮中&#xff0c;工业界正面临着前所未有的变革与机遇。而在这场变革中&#xff0c;基于MQTT协议的物联网网关崭露头角&#xff0c;成为连接工业设备、实现远程数据采集与监控的利器。其中&#xff0c;HiWoo Box作为一款出色的工业边缘网关&#xff0c;引领着这…

c语言每日一练(13)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;上学期间将看学业情况更新。 五道选择题&#xff1a; 1、程序运行的结果…

9、监测数据采集物联网应用开发步骤(7)

源码将于最后一遍文章给出下载 监测数据采集物联网应用开发步骤(6) 串口(COM)通讯开发 本章节测试使用了 Configure Virtual Serial Port Driver虚拟串口工具和本人自写的串口调试工具&#xff0c;请自行baidu下载对应工具 在com.zxy.common.Com_Para.py中添加如下内容 #RS…

RabbitMQ 的快速使用

docker部署rabbitmq # management才有管理页面 docker pull rabbitmq:management# 新建容器并运行 docker run \-e RABBITMQ_DEFAULT_USERadmin \ -e RABBITMQ_DEFAULT_PASSadmin \ -v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \-itd \ra…

DNS指向别名还是IP

现在有一台服务器dbprod126&#xff0c;ip是172.22.100.4 现在有一个需求&#xff0c;需要在dns中对dbprod126建一个别名wondadb3r的记录&#xff0c;也就是ping wondadb3r的时候显示的是dbprod126的ip&#xff0c;目前有两​种方法&#xff0c;主要使用方法1指向别名&#xf…

SQL-basics

SQL 一些常用的查询语句用法 SQL 中的聚合函数 SQL 中的子查询 SQL 使用实例 SELECT F_NAME , L_NAME FROM EMPLOYEES WHERE ADDRESS LIKE ‘%Elgin,IL%’; SELECT F_NAME , L_NAME FROM EMPLOYEES WHERE B_DATE LIKE ‘197%’; SELECT * FROM EMPLOYEES WHERE (SALARY BET…

优化爬虫请求:如何选择合适的爬虫ip轮换策略?

在进行爬虫任务时&#xff0c;使用隧道爬虫ip并采用合适的轮换策略可以提高稳定性和效率。选择合适的隧道爬虫ip轮换策略可以优化您的爬虫请求过程。 1、考量目标网站特点 不同网站对于频繁请求可能有不同限制或反爬机制。 了解目标网站是否存在IP封禁、验证码等问题&#xff…

WebGIS的一些学习笔记

一、简述计算机网络的Internet 概念、网络类型分类、基本特征和功用是什么 计算机网络的Internet 概念 计算机网络是地理上分散的多台独立自主的计算机遵循约定的通讯协议&#xff0c;通过软、硬件互连以实现交互通信、资源共享、信息交换、协同工作以及在线处理等功能的系统…

AI聊天机器人平台Poe发布更新;自然语言理解课程概要

&#x1f989; AI新闻 &#x1f680; AI聊天机器人平台Poe发布更新 突破功能限制 增加企业级服务 摘要&#xff1a;知名问答网站Quora旗下的AI聊天机器人平台Poe发布了一系列更新&#xff0c;包括推出Mac应用、支持同时进行多个对话、接入Meta的Llama 2模型等功能。用户只需支…

【LeetCode】剑指 Offer <二刷>(5)

目录 题目&#xff1a;剑指 Offer 10- II. 青蛙跳台阶问题 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 11. 旋转数组的最小数字 - 力…

AD16 基础应用技巧(一些 “偏好“ 设置)

1. 修改铺铜后自动更新铺铜 AD16 铺铜 复制 自动变形 偏好设置 将【DXP】中的【参数选择】。 将【PCB Editor】中的【General】&#xff0c;然后勾选上【Repour Polygons After Modification】。 2. PCB直角走线处理与T型滴泪 一些没用的AD技巧——AD PCB直角走线处理与…