K8s部署微服务(springboot+vue)

news2024/11/25 6:32:24

文章目录

  • 前言
  • 一、使用到的K8s资源
    • 1.1 Deployment
    • 1.2 Service
  • 二、Springboot基础服务部署
    • 2.1 网关gateway
    • 2.2 鉴权auth
    • 2.3 文件file
    • 2.4 流程flow
    • 2.5 消息message
    • 2.6 组织org
    • 2.7 系统通用system
    • 2.8 用户user
    • 2.9 Node
  • 三、Vue前端部署
    • 3.1 项目前端nginx
    • 3.2 静态资源服务nginx
  • 四、动态项目部署
    • 4.1 应用发布
    • 4.2 项目启动
    • 4.3 前端nginx挂载地址
  • 总结


前言

本文主要记录K8s部署微服务项目(springboot后台+vue前端,动态部署自定义项目),也包括对网关、鉴权、用户等基础模块的部署。k8s部署项目,即创建相应的资源有命令行创建和yaml文件创建两种方式,由于命令行创建配置麻烦,且不具备复用性,因此本文均采用yaml文件创建资源的方式。


一、使用到的K8s资源

1.1 Deployment

  1. 介绍Deployment之前首先介绍Pod。Pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建部署的最小资源对象模型,也是在k8s上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展pod对象的,控制器对象是用来管控 Pod 对象的,Service 或者Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成。
  2. K8s的Controller是管理和运行容器的对象,Deployment是Controller最常用的一种,主要的作用包括:1、定义并维持一组pod的期望数量;2、配置Pod的发布方式(MaxUnavailable以及MaxSurge字段);3、支持回滚操作,可记录多个前置版本。Deployment中定义了ReplicaSet,确定pod数量。主要字段如下:

在这里插入图片描述

1.2 Service

  1. 在k8s中,使用pod运行应用,可以通过Pod的Ip访问,但是pod的ip不固定带来了不方便,为解决这个问题,k8s提出了Service资源,Service提供同一个服务的多个pod进行聚合,并提供统一的入口进行访问。Service是一个概念,真正起作用的是kube-proxy服务,每个节点都运行了一个kube-proxy服务,当创建Service时,就会通过API Server向etcd写入创建的Service的信息,而kube-proxy会基于监听机制发现这种Service的变化,然后会将最新的Service信息转换为对应的访问规则。简而言之, Service就是通过ports定义了一组pod的访问规则
    在这里插入图片描述

常用的Service类型是NodePort,用于对外暴露应用端口。其中port指service的端口,即k8s中服务之间的访问端口(用于集群内部其他pod访问本pod);targetport是pod容器的端口(容器的端口,与制作容器时暴露的端口一致);NodePort是容器在node节点的端口(外部机器可访问的端口),默认范围为:30000-32767。

二、Springboot基础服务部署

本文采用Deployment+Service的方式进行部署,先对SpringBoot项目进行打包,然后编写Dockerfile文件,制作镜像,并上传到私有镜像仓库上。
构建镜像的文件夹内容包含Dockerfile、entrypoint.sh以及相应的jar包。
在这里插入图片描述

  1. Dockerfile文件。
FROM 192.168.1.180:5000/jdk:1.8 # 指定基础镜像,必须为第一条指令,这里使用私有镜像仓库的jdk1.8
MAINTAINER cjh # 用户信息
# Label 指定标签
LABEL version="1.0"
LABEL author="CJH"
LABEL company="HEU"
# Copy files
COPY gateway.jar /starter.jar # 将Dockerfile所在文件夹下的.jar复制到容器的根目录下
COPY /entrypoint.sh /entrypoint.sh # 复制entrypoint.sh文件
RUN chmod +x /entrypoint.sh # 重要!赋予entrypoint.sh文件可执行权限
ENV TZ=Asia/Shanghai # 指定时区环境变量
USER 0 # root用户
VOLUME ["/data","/log"] # 创建在本地主机或者其他容器可以挂载的数据卷
# Start
ENTRYPOINT ["/entrypoint.sh"] # 容器启动执行的命令
  1. entrypoint.sh文件,用于读取环境变量,设置启动jar的参数。
#!/bin/bash
# JVM参数
JAVA_OPTS='-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8'
# SpringBoot 启动参数
BOOT_OPTS=''


# server.port
if [ -n "$SERVER_PORT" ]
then
    BOOT_OPTS="$BOOT_OPTS --server.port=$SERVER_PORT";
    
fi

###################
##   redis相关   ##
###################
# spring.redis.host
if [ -n "$REDIS_HOST" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.redis.host=$REDIS_HOST";
fi

# spring.redis.port
if [ -n "$REDIS_PORT" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.redis.port=$REDIS_PORT";
fi

# spring.redis.password
if [ -n "$REDIS_PASSWORD" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.redis.password=$REDIS_PASSWORD";
fi

# spring.redis.database
if [ -n "$REDIS_DATABASE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.redis.database=$REDIS_DATABASE";
fi

#########################
##   datasource相产关   ##
#########################
# spring.datasource.driver-class-name
if [ -n "$DATABASE_DRIVER" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.datasource.driver-class-name=$DATABASE_DRIVER";
fi

# spring.datasource.url
if [ -n "$DATABASE_URL" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.datasource.url=$DATABASE_URL";
fi

# spring.datasource.username
if [ -n "$DATABASE_USERNAME" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.datasource.username=$DATABASE_USERNAME";
fi

# spring.datasource.password
if [ -n "$DATABASE_PASSWORD" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.datasource.password=$DATABASE_PASSWORD";
fi

###################
##   nacos相关   ##
###################
# spring.cloud.nacos.discovery.server-addr
if [ -n "$NACOS_DISCOVERY_SERVER_ADDR" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.server-addr=$NACOS_DISCOVERY_SERVER_ADDR";
fi

# spring.cloud.nacos.discovery.ip
if [ -n "$NACOS_DISCOVERY_IP" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.ip=$NACOS_DISCOVERY_IP";
fi

# spring.cloud.nacos.discovery.port
if [ -n "$NACOS_DISCOVERY_PORT" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.port=$NACOS_DISCOVERY_PORT";
fi

# spring.cloud.nacos.discovery.group
if [ -n "$NACOS_DISCOVERY_GROUP" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.group=$NACOS_DISCOVERY_GROUP";
fi

# spring.cloud.nacos.discovery.namespace
if [ -n "$NACOS_DISCOVERY_NAMESPACE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.namespace=$NACOS_DISCOVERY_NAMESPACE";
fi

# spring.cloud.nacos.discovery.register.ip
if [ -n "$NACOS_DISCOVERY_REG_IP" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.register.ip=$NACOS_DISCOVERY_REG_IP";
fi

# spring.cloud.nacos.discovery.register.port
if [ -n "$NACOS_DISCOVERY_REG_PORT" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.discovery.register.port=$NACOS_DISCOVERY_REG_PORT";
fi

# spring.cloud.nacos.config.server-addr
if [ -n "$NACOS_CONFIG_SERVER_ADDR" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.config.server-addr=$NACOS_CONFIG_SERVER_ADDR";
fi
# spring.cloud.nacos.config.namespace
if [ -n "$NACOS_CONFIG_NAMESPACE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.cloud.nacos.config.namespace=$NACOS_CONFIG_NAMESPACE";
fi

###################
##   kafka相关   ##
###################
# spring.kafka.bootstrap-servers
if [ -n "$KAFKA_BOOTSTRAP_SERVERS" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.bootstrap-servers=$KAFKA_BOOTSTRAP_SERVERS";
fi

# spring.kafka.topic.topicConstraints
if [ -n "$KAFKA_TOPIC_CONSTRAINTS" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.topic.topicConstraints=$KAFKA_TOPIC_CONSTRAINTS";
fi

# spring.kafka.topic.topicServiceLog
if [ -n "$KAFKA_TOPIC_SERVICELOG" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.topic.topicServiceLog=$KAFKA_TOPIC_SERVICELOG";
fi

#kafka hostname
if [ -n "$KAFKA_HOSTNAME" ]
then
    echo "$KAFKA_BOOTSTRAP_SERVERS_IP $KAFKA_HOSTNAME" >> /etc/hosts;
fi

#kafka.producer.batch-size
if [ -n "$KAFKA_PRODUCER_BATCHSIZE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.producer.batch-size=$KAFKA_PRODUCER_BATCHSIZE";
fi

#kafka.producer.buffer-memory
if [ -n "$KAFKA_PRODUCER_BUFFERMEMORY" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.producer.buffer-memory=$KAFKA_PRODUCER_BUFFERMEMORY";
fi

#kafka.consumer.group-id
if [ -n "$KAFKA_CONSUMER_GROUPID" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.kafka.consumer.group-id=$KAFKA_CONSUMER_GROUPID";
fi
######################
##   MongoDB   ##
#####################
# spring.data.mongodb.database
if [ -n "$MONGDB_DATABASE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.data.mongodb.database=$MONGDB_DATABASE";
fi

# spring.data.mongodb.grid-fs-database
if [ -n "$MONGDB_GRID_FS_DATABASE" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.data.mongodb.grid-fs-database=$MONGDB_GRID_FS_DATABASE";
fi

# spring.data.mongodb.uri
if [ -n "$MONGDB_URI" ]
then
    BOOT_OPTS="$BOOT_OPTS --spring.data.mongodb.uri=$MONGDB_URI";
fi

######################
##   minio   ##
#####################
# minio.url
if [ -n "$MINIO_URL" ]
then
    BOOT_OPTS="$BOOT_OPTS --minio.url=$MINIO_URL";
fi

# minio.accessKey
if [ -n "$MINIO_ACCESSKEY" ]
then
    BOOT_OPTS="$BOOT_OPTS --minio.accessKey=$MINIO_ACCESSKEY";
fi

# minio.secretKey
if [ -n "$MINIO_SECRETKEY" ]
then
    BOOT_OPTS="$BOOT_OPTS --minio.secretKey=$MINIO_SECRETKEY";
fi

# minio.defaultBucket
if [ -n "$MINIO_DEFAULTBUCKET" ]
then
    BOOT_OPTS="$BOOT_OPTS --minio.defaultBucket=$MINIO_DEFAULTBUCKET";
fi

# minio.uploadBucket
if [ -n "$MINIO_UPLOADBUCKET" ]
then
    BOOT_OPTS="$BOOT_OPTS --minio.uploadBucket=$MINIO_UPLOADBUCKET";
fi

######################
##   其它自定义相关   ##
#####################
# routingRule
if [ -n "$ROUTING_RULE" ]
then
    BOOT_OPTS="$BOOT_OPTS --routingRule=$ROUTING_RULE";
fi
# initTable.sqlfile
if [ -n "$INITTABLE_SQLFILE" ]
then
    BOOT_OPTS="$BOOT_OPTS --initTable.sqlfile=$INITTABLE_SQLFILE";
fi
# initTable.jsonpath
if [ -n "$INITTABLE_JSONPATH" ]
then
    BOOT_OPTS="$BOOT_OPTS --initTable.jsonpath=$INITTABLE_JSONPATH";
fi
# export.json-directory
if [ -n "$EXPORT_JSON_DIRECTORY" ]
then
    BOOT_OPTS="$BOOT_OPTS --export.json-directory=$EXPORT_JSON_DIRECTORY";
fi

# tableSchema
if [ -n "$TABLESCHEMA" ]
then
    BOOT_OPTS="$BOOT_OPTS --tableSchema=$TABLESCHEMA";
fi
######################
##   阿里云短信   ##
#####################
# aliyun.access-key-id
if [ -n "$ALIYUN_ACCESSKEY_ID" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.access-key-id=$ALIYUN_ACCESSKEY_ID";
fi
# aliyun.access-key-secret
if [ -n "$ALIYUN_ACCESSKEY_SECRET" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.access-key-secret=$ALIYUN_ACCESSKEY_SECRET";
fi
# aliyun.endpoint
if [ -n "$ALIYUN_ENDPOINT" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.endpoint=$ALIYUN_ENDPOINT";
fi
# aliyun.region
if [ -n "$ALIYUN_REGION" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.region=$ALIYUN_REGION";
fi
# aliyun.note.sign-name
if [ -n "$ALIYUN_NOTE_SIGNNAME" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.note.sign-name=$ALIYUN_NOTE_SIGNNAME";
fi
# aliyun.note.template-code
if [ -n "$ALIYUN_NOTE_TEMPLATECODE" ]
then
    BOOT_OPTS="$BOOT_OPTS --aliyun.note.template-code=$ALIYUN_NOTE_TEMPLATECODE";
fi

# aliyun.note.template-code
if [ -n "$WORK_MODE" ]
then
    BOOT_OPTS="$BOOT_OPTS --workmode=$WORK_MODE";
fi

echo "BOOT_OPTS is '$BOOT_OPTS'";

#echo "47.104.139.172 hab0" >> /etc/hosts
# 启动
java ${JAVA_OPTS} -jar /starter.jar ${BOOT_OPTS}

由Deployment确定部署的pod数量、使用的镜像等;由Service对外统一暴露访问端口。并使用NFS进行资源挂载,使用env传递容器环境变量。下面对gateway.yaml给出详细注释,其他不再设注释。

2.1 网关gateway

apiVersion: v1 # 资源版本
kind: Service # 资源类型
metadata: # 元数据
  name: gateway # 资源名称
  namespace: peric718 # 命名空间
spec: # 详细配置
  ports: # 端口配置
  - port: 10000 # 内部访问端口
    name: gateway # 端口名称
    nodePort: 30001 # 对外暴露端口
  selector: # 选择器,用于指定当前资源作用于哪些pod
    app: gateway
  type: NodePort # 类型为NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gateway
  template: # pod副本创建模板。属性和Pod的属性一样
    metadata:
      labels: # 给要创建的pod打标签
        app: gateway 
    spec:
      containers: # 使用的容器信息
      - name: gateway
        image: 192.168.1.180:5000/aengus/gateway:v1.6
        # 拉取镜像策略:本地镜像不存在,从仓库取。有Always:中从仓库取。Never:总从本地取。
        imagePullPolicy: IfNotPresent 
        ports:
        - protocol: TCP
          containerPort: 10000 # 镜像映射出的端口
        env: # 镜像环境变量设置
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.2 鉴权auth

apiVersion: v1
kind: Service
metadata:
  name: keyston-auth
  namespace: peric718
spec:
  ports:
  - port: 10001
    name: keyston-auth
  selector:
    app: keyston-auth
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keyston-auth
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: keyston-auth
  template:
    metadata:
      labels:
        app: keyston-auth
    spec:
      containers:
      - name: keyston-auth
        image: 192.168.1.180:5000/aengus/auth:v1.7
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 10001
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.3 文件file

apiVersion: v1
kind: Service
metadata:
  name: file-starter
  namespace: peric718
spec:
  ports:
  - port: 9007
    name: file-starter
    nodePort: 30017
  selector:
    app: file-starter
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: file-starter
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: file-starter
  template:
    metadata:
      labels:
        app: file-starter
    spec:
      containers:
      - name: file-starter
        image: 192.168.1.180:5000/aengus/file:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 9007
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.4 流程flow

apiVersion: v1
kind: Service
metadata:
  name: flow-starter
  namespace: peric718
spec:
  ports:
  - port: 10011
    name: flow-starter
    nodePort: 30011
  selector:
    app: flow-starter
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: flow-starter
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: flow-starter
  template:
    metadata:
      labels:
        app: flow-starter
    spec:
      containers:
      - name: flow-starter
        image: 192.168.1.180:5000/aengus/flow:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 10011
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.5 消息message

apiVersion: v1
kind: Service
metadata:
  name: message-starter
  namespace: peric718
spec:
  ports:
  - port: 9003
    name: message-starter
    nodePort: 30023
  selector:
    app: message-starter
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: message-starter
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: message-starter
  template:
    metadata:
      labels:
        app: message-starter
    spec:
      containers:
      - name: message-starter
        image: 192.168.1.180:5000/aengus/message:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 9003
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.6 组织org

apiVersion: v1
kind: Service
metadata:
  name: org-starter
  namespace: peric718
spec:
  ports:
  - port: 10010
    name: org-starter
    nodePort: 30010
  selector:
    app: org-starter
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: org-starter
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: org-starter
  template:
    metadata:
      labels:
        app: org-starter
    spec:
      containers:
      - name: org-starter
        image: 192.168.1.180:5000/aengus/org:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 10010
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.7 系统通用system

apiVersion: v1
kind: Service
metadata:
  name: system-starter
  namespace: peric718
spec:
  ports:
  - port: 10004
    name: system-starter
    nodePort: 30004
  selector:
    app: system-starter
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-starter
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: system-starter
  template:
    metadata:
      labels:
        app: system-starter
    spec:
      containers:
      - name: system-starter
        image: 192.168.1.180:5000/aengus/system:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 10004
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.8 用户user

apiVersion: v1
kind: Service
metadata:
  name: keyston-user
  namespace: peric718
spec:
  ports:
  - port: 10002
    name: keyston-user
  selector:
    app: keyston-user
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keyston-user
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: keyston-user
  template:
    metadata:
      labels:
        app: keyston-user
    spec:
      containers:
      - name: keyston-user
        image: 192.168.1.180:5000/aengus/user:v1.9
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 10002
        env: 
          - name: NACOS_URL
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_DISCOVERRY_IP
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

2.9 Node

apiVersion: v1
kind: Service
metadata:
  name: thingmax-script
  namespace: peric718
spec:
  ports:
  - port: 19000
    name: thingmax-script
  selector:
    app: thingmax-script
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thingmax-script
  namespace: peric718
spec:
  replicas: 1
  selector:
    matchLabels:
      app: thingmax-script
  template:
    metadata:
      labels:
        app: thingmax-script
    spec:
      containers:
      - name: thingmax-script
        image: 192.168.1.180:5000/aengus/script:v1.1
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
          containerPort: 19000
        env: 
          - name: SERVER
            value: "19000"
          - name: BASEURL
            value: http://192.168.1.180:30001
          - name: THINGMAX_PATH
            value: http://localhost:8081/thingmax
          - name: NACOS_SERVER
            value: 192.168.1.181:8848
          - name: NACOS_NAMESPACE
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_REGISTER
            valueFrom:
              fieldRef:
                 fieldPath: status.podIP

三、Vue前端部署

Vue前端采用Nginx进行部署,首先对前端进行build打包,然后通过Dockerfile制作镜像,将镜像推送到私有仓库,通过yaml文件部署pods。
构建nginx前端Docker镜像的目录:
在这里插入图片描述

  1. nginx镜像的Dockerfile,其中docker-entrypoint.sh将default.conf.template文件转换为可使用的default.conf文件
FROM nginx:latest
# Label
LABEL version="v1.0"
LABEL author="CJH"
LABEL company="HEU"

# Add a file
ADD /html /usr/share/nginx/html
ADD /default.conf.template /etc/nginx/conf.d/default.conf.template
ADD /docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
# COPY nginx.conf /etc/nginx/nginx.conf
USER 0
VOLUME ["/data","/log"]

# Start the application
CMD ["nginx","-g" ,"daemon off;"]  # 启动nginx

ENTRYPOINT ["/docker-entrypoint.sh"]
  1. docker-entrypoint.sh文件,用于生成default.conf文件
#!/bin/sh
# vim:sw=4:ts=4:et
# 将操作系统变量写入nginx变量指令文件中

# envsubst {{ "MAIN_TYPE" "SERVER_ROOT" "PROJECT_CODE"}} < /default.conf.template > /etc/nginx/conf.d/default.conf
envsubst '{{$MAIN_TYPE $SERVER_ROOT $PROJECT_CODE $APP_CODE}}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf

# set -e

if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
    exec 3>&1
else
    exec 3>/dev/null
fi

if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
    if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
        echo >&3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"

        echo >&3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
        find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
            case "$f" in
                *.sh)
                    if [ -x "$f" ]; then
                        echo >&3 "$0: Launching $f";
                        "$f"
                    else
                        # warn on shell scripts without exec bit
                        echo >&3 "$0: Ignoring $f, not executable";
                    fi
                    ;;
                *) echo >&3 "$0: Ignoring $f";;
            esac
        done

        echo >&3 "$0: Configuration complete; ready for start up"
    else
        echo >&3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
    fi
fi

exec "$@"
  1. default.conf.template文件提供基础服务的访问规则配置
server {
    listen       9000;
    listen  [::]:9000;
    server_name  localhost;
    charset utf-8;
    client_max_body_size 0;#不做大小检查
    proxy_set_header Host $host:$server_port;
    # port_in_redirect off;
    absolute_redirect off;
    server_name_in_redirect off;
    proxy_send_timeout 300s;     # 设置发送超时时间,
    proxy_read_timeout 300s;	 # 设置读取超时时间。
    # 基座应用
    location /main {
        root /usr/share/nginx/html/$MAIN_TYPE;
        index index.html index.htm;
        client_max_body_size 20m;
        add_header Access-Control-Allow-Origin *;
        if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
            add_header Cache-Control max-age=7776000;
            add_header Access-Control-Allow-Origin *;
        }
        try_files $uri $uri/ /main/index.html;
    }

    location /main/support-static {
      rewrite ^/main/support-static(.*)$ /support/support-static$1 last;
    }

    location /support-static {
      rewrite ^/support-static(.*)$ /support/support-static$1 last;
    }

    # 支撑系统 (子应用)
    location /support {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /support/index.html;
    }

    location /main/thingmax-static {
      rewrite ^/main/thingmax-static(.*)$ /thingmax/thingmax-static$1 last;
    }

    location /thingmax-static {
      rewrite ^/thingmax-static(.*)$ /thingmax/thingmax-static$1 last;
    }

    # 事物建模 (子应用)
    location /thingmax {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /thingmax/index.html;
    }

    location /main/process-model-static {
      rewrite ^/main/process-model-static(.*)$ /process-model/process-model-static$1 last;
    }

    location /process-model-static {
      rewrite ^/process-model-static(.*)$ /process-model/process-model-static$1 last;
    }

    # 流程建模 (子应用)
    location /process-model {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /process-model/index.html;
    }

    location /main/visual-model-static {
      rewrite ^/main/visual-model-static(.*)$ /visual-model/visual-model-static$1 last;
    }

    location /visual-model-static {
      rewrite ^/visual-model-static(.*)$ /visual-model/visual-model-static$1 last;
    }

    # 可视化建模 (子应用)
    location /visual-model {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      proxy_set_header Host $host:$server_port;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|woff2|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /visual-model/index.html;
    }

    location /main/service-center-static {
      rewrite ^/main/service-center-static(.*)$ /service-center/service-center-static$1 last;
    }

    location /service-center-static {
      rewrite ^/service-center-static(.*)$ /service-center/service-center-static$1 last;
    }

    # 服务中心 (子应用)
    location /service-center {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /service-center/index.html;
    }

    location /main/message-center-static {
      rewrite ^/main/message-center-static(.*)$ /message-center/message-center-static$1 last;
    } 
    
    location /message-center-static {
      rewrite ^/message-center-static(.*)$ /message-center/message-center-static$1 last;
    }

    # 消息中心 (子应用)
    location /message-center {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /message-center/index.html;
    }

    location /main/file-service-static {
      rewrite ^/main/file-service-static(.*)$ /file-service/file-service-static$1 last;
    }

    location /file-service-static {
      rewrite ^/file-service-static(.*)$ /file-service/file-service-static$1 last;
    } 

    # 文件服务 (子应用)
    location /file-service {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /file-service/index.html;
    }
   
    location /main/runtime-static {
      rewrite ^/main/runtime-static(.*)$ /runtime/runtime-static$1 last;
    }

    location /runtime-static {
      rewrite ^/runtime-static(.*)$ /runtime/runtime-static$1 last;
    }

   # 项目构建 (子应用)
    location /runtime {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /runtime/index.html;
    }
    

    # 应用预览 (子应用)
    location /application-preview {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /application-preview/index.html;
    }
   
     # 项目预览 (子应用)
    location /project-preview {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /project-preview/index.html;
    }
    location /project-preview-static {
      rewrite ^/project-preview-static(.*)$ /project-preview/project-preview-static$1 last;
    }
    location /main/project-preview-static {
      rewrite ^/main/project-preview-static(.*)$ /project-preview/project-preview-static$1 last;
    }
    # 列表请求转发
    location /prod-api/systemApi/project/getByCode/code {
        rewrite ^/prod-api/(.*)/code /prod-api/$1/$PROJECT_CODE last;
    }

    location /prod-api/systemApi/application/getByCode/appCode {
        rewrite ^/prod-api/(.*)/appCode /prod-api/$1/$APP_CODE last;
    }

    location /prod-api/systemApi/appMenu/getMenusByAppCode/appCode {
        rewrite ^/prod-api/(.*)/appCode /prod-api/$1/$APP_CODE last;
    }


    location /main/user-permissions-static {
      rewrite ^/main/user-permissions-static(.*)$ /user-permissions/user-permissions-static$1 last;
    }

    location /user-permissions-static {
      rewrite ^/user-permissions-static(.*)$ /user-permissions/user-permissions-static$1 last;
    }

    # 用户权限 (子应用)
    location /user-permissions {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /user-permissions/index.html;
    }
   
    location /main/system-monitoring-static {
      rewrite ^/main/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static$1 last;
    }
      
    location /system-monitoring-static {
      rewrite ^/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static$1 last;
    }  
 
   # 系统监控 (子应用)
    location /system-monitoring {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /system-monitoring/index.html;
    }

    # 接口转发
    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;
        add_header backendIP $upstream_addr;
        add_header backendURL $request;
        proxy_pass $SERVER_ROOT;
    }

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    include /etc/nginx/conf.d/*.item; # 引入该文件夹下所有.item文件到当前的server中
}
  1. 生成的default.conf文件:
server {
    listen       9000;
    listen  [::]:9000;
    server_name  localhost;
    charset utf-8;
    client_max_body_size 0;#不做大小检查
    proxy_set_header Host $host:$server_port;
    # port_in_redirect off;
    absolute_redirect off;
    server_name_in_redirect off;
    proxy_send_timeout 300s;     # 设置发送超时时间,
    proxy_read_timeout 300s;	 # 设置读取超时时间。
    # 基座应用
    location /main {
        root /usr/share/nginx/html/running_main;
        index index.html index.htm;
        client_max_body_size 20m;
        add_header Access-Control-Allow-Origin *;
        if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
            add_header Cache-Control max-age=7776000;
            add_header Access-Control-Allow-Origin *;
        }
        try_files $uri $uri/ /main/index.html;
    }

    location /main/support-static {
      rewrite ^/main/support-static(.*)$ /support/support-static$1 last;
    }

    location /support-static {
      rewrite ^/support-static(.*)$ /support/support-static$1 last;
    }

    # 支撑系统 (子应用)
    location /support {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /support/index.html;
    }

    location /main/thingmax-static {
      rewrite ^/main/thingmax-static(.*)$ /thingmax/thingmax-static$1 last;
    }

    location /thingmax-static {
      rewrite ^/thingmax-static(.*)$ /thingmax/thingmax-static$1 last;
    }

    # 事物建模 (子应用)
    location /thingmax {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /thingmax/index.html;
    }

    location /main/process-model-static {
      rewrite ^/main/process-model-static(.*)$ /process-model/process-model-static$1 last;
    }

    location /process-model-static {
      rewrite ^/process-model-static(.*)$ /process-model/process-model-static$1 last;
    }

    # 流程建模 (子应用)
    location /process-model {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /process-model/index.html;
    }

    location /main/visual-model-static {
      rewrite ^/main/visual-model-static(.*)$ /visual-model/visual-model-static$1 last;
    }

    location /visual-model-static {
      rewrite ^/visual-model-static(.*)$ /visual-model/visual-model-static$1 last;
    }

    # 可视化建模 (子应用)
    location /visual-model {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      proxy_set_header Host $host:$server_port;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|woff2|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /visual-model/index.html;
    }

    location /main/service-center-static {
      rewrite ^/main/service-center-static(.*)$ /service-center/service-center-static$1 last;
    }

    location /service-center-static {
      rewrite ^/service-center-static(.*)$ /service-center/service-center-static$1 last;
    }

    # 服务中心 (子应用)
    location /service-center {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /service-center/index.html;
    }

    location /main/message-center-static {
      rewrite ^/main/message-center-static(.*)$ /message-center/message-center-static$1 last;
    } 
    
    location /message-center-static {
      rewrite ^/message-center-static(.*)$ /message-center/message-center-static$1 last;
    }

    # 消息中心 (子应用)
    location /message-center {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /message-center/index.html;
    }

    location /main/file-service-static {
      rewrite ^/main/file-service-static(.*)$ /file-service/file-service-static$1 last;
    }

    location /file-service-static {
      rewrite ^/file-service-static(.*)$ /file-service/file-service-static$1 last;
    } 

    # 文件服务 (子应用)
    location /file-service {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /file-service/index.html;
    }
   
    location /main/runtime-static {
      rewrite ^/main/runtime-static(.*)$ /runtime/runtime-static$1 last;
    }

    location /runtime-static {
      rewrite ^/runtime-static(.*)$ /runtime/runtime-static$1 last;
    }

   # 项目构建 (子应用)
    location /runtime {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /runtime/index.html;
    }
    

    # 应用预览 (子应用)
    location /application-preview {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /application-preview/index.html;
    }
   
     # 项目预览 (子应用)
    location /project-preview {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /project-preview/index.html;
    }
    location /project-preview-static {
      rewrite ^/project-preview-static(.*)$ /project-preview/project-preview-static$1 last;
    }
    location /main/project-preview-static {
      rewrite ^/main/project-preview-static(.*)$ /project-preview/project-preview-static$1 last;
    }
    # 列表请求转发
    location /prod-api/systemApi/project/getByCode/code {
        rewrite ^/prod-api/(.*)/code /prod-api/$1/HEU last;
    }

    location /prod-api/systemApi/application/getByCode/appCode {
        rewrite ^/prod-api/(.*)/appCode /prod-api/$1/ last;
    }

    location /prod-api/systemApi/appMenu/getMenusByAppCode/appCode {
        rewrite ^/prod-api/(.*)/appCode /prod-api/$1/ last;
    }


    location /main/user-permissions-static {
      rewrite ^/main/user-permissions-static(.*)$ /user-permissions/user-permissions-static$1 last;
    }

    location /user-permissions-static {
      rewrite ^/user-permissions-static(.*)$ /user-permissions/user-permissions-static$1 last;
    }

    # 用户权限 (子应用)
    location /user-permissions {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /user-permissions/index.html;
    }
   
    location /main/system-monitoring-static {
      rewrite ^/main/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static$1 last;
    }
      
    location /system-monitoring-static {
      rewrite ^/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static$1 last;
    }  
 
   # 系统监控 (子应用)
    location /system-monitoring {
      root /usr/share/nginx/html/child;
      add_header Access-Control-Allow-Origin *;
      if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
        add_header Cache-Control max-age=7776000;
        add_header Access-Control-Allow-Origin *;
      }
      try_files $uri $uri/ /system-monitoring/index.html;
    }

    # 接口转发
    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;
        add_header backendIP $upstream_addr;
        add_header backendURL $request;
        proxy_pass http://192.168.1.180:30001/;
    }

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    include /etc/nginx/conf.d/*.item;  # 引入.item文件
}
  1. item文件举例
    location /kucun {
        root /usr/share/nginx/html/child/application;
        add_header Access-Control-Allow-Origin *;
        if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
          add_header Cache-Control max-age=7776000;
          add_header Access-Control-Allow-Origin *;
        }
        try_files $uri $uri/ /kucun/index.html;
      }

将html放置到vue的Dockerfile同级目录下,html的内容包括:child、design_main和running_main,分别存放子应用、开发态主应用和运行态主应用的dist包。
在这里插入图片描述

3.1 项目前端nginx

使用volumeMounts的方式进行挂载,将内容挂载到NFS服务器对应的目录下。需要在NFS目录,和被挂载的目录下同时放置相关文件

apiVersion: v1
kind: Service
metadata:
  name: nginxmain
  namespace: peric718
spec:
  ports:
  - port: 9000
    name: nginxmain
    nodePort: 30040
  selector:
    app: nginxmain
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: nginxmain
  namespace: peric718
spec:
  replicas: 1
  revisionHistoryLimit: 3 
  strategy: 
    type: RollingUpdate 
    rollingUpdate: 
      maxUnavailable: 30% 
  selector:
    matchLabels:
      app: nginxmain
  template:
    metadata:
      labels:
        app: nginxmain
    spec:
      containers:
      - name: nginxmain
        image: 192.168.1.180:5000/aengus/nginxmain:v2.8
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        ports:
          - protocol: TCP
            containerPort: 9000
        volumeMounts:
          - name: html
            mountPath: /usr/share/nginx/html
          - name: conf
            mountPath: /etc/nginx/conf.d
        env:
          - name: TZ
            value: Asia/Shanghai
          - name: LANG
            value: en_US.UTF-8
          - name: MAIN_TYPE
            value: running_main
          - name: SERVER_ROOT
            value: http://192.168.1.180:30001/
          - name: PROJECT_CODE
            value: HEU
      volumes:
        - name: html
          nfs:
            server: 192.168.1.180
            path: /usr/project/data/nfs/heu/erp/html
        - name: conf
          nfs:
            server: 192.168.1.180
            path: /usr/project/data/nfs/heu/erp/conf

3.2 静态资源服务nginx

静态资源服务器用于存放静态图片、JSON文件等资源,目的在于减少前端打包体积,提升访问速度。

  • 静态资源服务器制作镜像Dockerfile
FROM nginx:latest
# Label
LABEL version="1.0"
LABEL author="YuLijia"
LABEL company="HSOFT"

# Add a file
ADD /static /usr/share/nginx/html/static
ADD /default.conf /etc/nginx/conf.d/default.conf
VOLUME ["/data","log"]

# Start the application
CMD ["nginx","-g" ,"daemon off;"]
  • default.conf配置文件
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~* \.(jpg|jpeg|gif|png|swf|rar|zip|css|js|map|svg|woff|ttf|txt|json)$ {
              root /usr/share/nginx/html/static;
              index index.html;
              add_header Access-Control-Allow-Origin *;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}


  • nginxstatic.yaml文件,使用volumeMounts进行挂载,挂载地址为180上NFS地址。
apiVersion: v1
kind: Service
metadata:
  name: nginxstatic
  namespace: peric718
spec:
  ports:
  - port: 80
    name: nginxstatic
    nodePort: 30065
  selector:
    app: nginxstatic
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: nginxstatic
  namespace: peric718
spec:
  replicas: 1
  revisionHistoryLimit: 3 
  strategy: 
    type: RollingUpdate 
    rollingUpdate: 
      maxUnavailable: 30% 
  selector:
    matchLabels:
      app: nginxstatic
  template:
    metadata:
      labels:
        app: nginxstatic
    spec:
      containers:
      - name: nginxstatic
        image: 192.168.1.180:5000/aengus/nginxstatic:v1.0
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        ports:
          - protocol: TCP
            containerPort: 80
        volumeMounts:
          - name: nginxstatic
            mountPath: /usr/share/nginx/html/static
      volumes:
        - name: nginxstatic
          nfs:
            server: 192.168.1.180
            path: /usr/project/data/nfs/heu/erp/nginxstatic/static

四、动态项目部署

4.1 应用发布

部署项目之前,需要将项目下的应用发布。发布应用的流程:

  • 构建要执行的shell命令。
  • 将/runtime/thingmax目录下的内容复制到临时目录下,并制作镜像。
  • 镜像打标签,推送到远程仓库。
  • 删除临时目录。
# 通过读取配置文件、查询应用版本,获得执行shell命令所需参数:
String shell = "sh " + tmRootDirectory + File.separator + tmShellFile + " " + tmRootDirectory + " " + uuid + " " + tmTemplateDirectory + " "+
                    imageName + " " + tagName ;
# 上述命令包含参数:1、执行thingmax操作的根目录下的脚本文件;2、执行thingmax操作的根目录;3、临时目录(处理完之后,就删除);4、thingmax模板文件目录;5、镜像名称;6、镜像标签名称。

# 执行的shell命令举例:
sh /runtime/buildThingmax.sh /runtime f33339c16a4b4c7692bfaf4eedf152dd thingmax kucun:v1.0.6 192.168.1.180:5000/kucun:v1.0.6

应用发布主要的命令的buildThingmax.sh脚本内容如下:

#!/bin/sh

ROOT_DIR=$1
TEMP_DIR=$2
TEMPLATE=$3
IMAGE_NAME=$4
IMAGE_TAG=$5

if [[ ! -d "$ROOT_DIR" ]]; then
    echo "error: rootDirectory is not exist "
else
    cd $ROOT_DIR
    cp -r $ROOT_DIR/$TEMPLATE/* $TEMP_DIR
    if [ $? -eq 0 ];then
                cd $TEMP_DIR
                result=`docker build -t $IMAGE_NAME .`
                echo $result
                if [[ $result =~ "Successfully built"  ]]
                then
                    echo "构建镜像成功"
                    docker tag $IMAGE_NAME $IMAGE_TAG
                    if [ $? -eq 0 ];then
                        echo "docker tag success"
                        docker push $IMAGE_TAG
                        if [ $? -eq 0 ];then
                            echo "push success"
                            cd ..
                        else
                            echo "error: push fail"
                            docker rmi $IMAGE_TAG
                            docker rmi $IMAGE_NAME
			                      cd ..
                            rm -rf $TEMP_DIR
                        fi
                    else
                        echo "error: docker tag fail"
                        docker rmi $IMAGE_NAME
                        cd ..
                        rm -rf $TEMP_DIR
                    fi
                else
                    echo "error: docker build fail"
                    cd ..
                    rm -rf $TEMP_DIR
                fi
    else
        echo "error: copy thingmax-starter.jar fail"
        rm -rf $TEMP_DIR
    fi
fi

thingmax操作的根目录内容如下:
在这里插入图片描述

thingmax目录下内容包括Dockerfile文件、start.sh启动脚本以及运行态jar包thingmax-runtimer.jar:
在这里插入图片描述
dist/tpDist 目录下包括aplication-preview (应用预览)和 nginx-static(静态资源服务器)两块内容:
在这里插入图片描述
system目录作为临时目录。

Dockerfile文件内容:

FROM 192.168.1.180:5000/jdk:1.8
MAINTAINER zhangyp <1121613304@qq.com>
WORKDIR /runtime
ENV LC_ALL=zh_CN.utf8
ENV LANG=zh_CN.utf8
ENV LANGUAGE=zh_CN.utf8
RUN localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
ENV APP_ROOT=/runtime/conf
ENV TZ=Asia/Shanghai

RUN mkdir -p "$APP_ROOT"
# 添加 文件到APP_ROOT 目录
#ADD ***.tar /runtime/conf
COPY config/*.json /runtime/conf/
COPY config/Thingmax/ /runtime/conf/Thingmax
COPY thingmax-runtimer.jar thingmax-starter.jar
COPY start.sh .
RUN chmod +x start.sh
ENTRYPOINT ["sh","start.sh"]

start.sh脚本内容:

#!/bin/bash
sleep 1
export THINGMAX=/runtime/thingmax-starter.jar
echo "---------------------thingmax 开始启动------------------------------"
nohup java -jar $THINGMAX
tail -f /dev/null
#/bin/sh

4.2 项目启动

项目启动的核心内容在于使用k8s部署应用发布时生成的镜像,执行流程如下:

  • 查出存于mysql数据库中的模板文件。
  • 通过获取租户、项目下的每个应用的名称、版本,以及配置的nacos_url、app_root等环境变量,通过变量替换,生成需要的yaml文件。
  • 执行kubectl apply -f xxx.yaml 部署应用。
  • 查询应用页面JSON并复制到k8s的nfs目录。
  • 菜单型项目将项目下所有的页面JSON复制到k8s的nfs目录。
  • 更新前端项目nginx容器。
  • 更新静态资源服务器。
  • 同步流程、菜单、数据字典等数据到运行态数据库。
  1. 模板文件
  • thingmaxTemplate
apiVersion: v1
kind: Service
metadata:
  name: {{name}}
  namespace: {{namespace}}
spec:
  ports:
  - port: 9000
    name: {{name}}
  selector:
    app: {{name}}
  type: NodePort

---
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: {{name}}
  namespace: {{namespace}}
spec:
  replicas: {{replicas}}
  revisionHistoryLimit: 3 
  strategy: 
    type: RollingUpdate 
    rollingUpdate: 
      maxUnavailable: 30% 
  selector:
    matchLabels:
      app: {{name}}
  template:
    metadata:
      labels:
        app: {{name}}
    spec:
      hostAliases:
      - ip: "47.104.139.172"
        hostnames:
        - "hab0"
      containers:
      - name: {{name}}
        image: {{image}}
        imagePullPolicy: IfNotPresent
        ports:
          - protocol: TCP
            containerPort: 9000
        env: 
          - name: NACOS_URL
            value: {{nacos_url}}
          - name: APP_ROOT
            value: {{app_root}}
  • nginxLocation
    location /{{APP_CODE}} {
        root /usr/share/nginx/html/child/application;
        add_header Access-Control-Allow-Origin *;
        if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
          add_header Cache-Control max-age=7776000;
          add_header Access-Control-Allow-Origin *;
        }
        try_files $uri $uri/ /{{APP_CODE}}/index.html;
      }

4.3 前端nginx挂载地址

在这里插入图片描述

conf为nginx配置文件挂载目录,下有default.conf、default.conf.template以及应用的item配置文件。
html为主应用、子应用的前端打包文件,和构建镜像时的目录结构一致,其中html/child/application目录放置自定义项目的子应用。

如果是菜单型项目,则直接访问html/running_main下的内容进入项目。如果是应用型项目,则首先进入主应用容器,然后点击里面的子应用,才能进入具体子应用。访问项目时需要加上参数code=projectCode


总结

本文详细讲解了k8s部署Springboot后端项目、vue前端想项目,以及动态部署自定义项目的过程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

迪杰斯特拉算法(求最短路径)

迪杰斯特拉算法&#xff08;求最短路径&#xff09; 迪杰斯特拉算法用于查找图中某个顶点到其它所有顶点的最短路径&#xff0c;该算法既适用于无向加权图&#xff0c;也适用于有向加权图。 注意&#xff0c;使用迪杰斯特拉算法查找最短路径时&#xff0c;必须保证图中所有边…

相对位置编码(二) Relative Positional Encodings - Transformer-XL

1. Motivation 在Transformer-XL中&#xff0c;由于设计了segments&#xff0c;如果仍采用transformer模型中的绝对位置编码的话&#xff0c;将不能区分处不同segments内同样相对位置的词的先后顺序。 比如对于segmenti&#xfffd;&#xfffd;&#xfffd;&#xfffd;&…

pycharm安装opencv-python报错

问题一 通过pycharm中的Terminal窗口安装opencv-python错误如下&#xff1a; 上图所示为部分错误&#xff0c;全部错误如下&#xff1a; Building wheel for opencv-contrib-python (PEP 517) ... errorERROR: Complete output from command D:\anzhuanglujing\Anaconda\python…

从零开始之PID控制

从零开始系列之PID控制&#xff0c;宗旨就是以说人话的方式讲述它&#xff0c;真正的做到从零开始&#xff0c;小白一看就会&#xff0c;一学就废。 一、什么是PID控制&#xff1f; PID控制&#xff08;比例-积分-微分控制&#xff09;由比例单元&#xff08;Proportional&…

玩耍的猫咪【 InsCode Stable Diffusion 美图活动一期】

1️⃣ 工具介绍 InsCode是一个集成了在线IDE、在线AI编程、在线算力租赁、在线项目部署以及在线SD 模型使用的综合代码开发平台。 Stable Diffusion是目前最火的AI绘画工具之一&#xff0c;它是一个免费开源的项目。通过Stable Diffusion&#xff0c;可以很轻松的通过文字描述…

上半年结束,下半年继续冲!

前言: 这周直播也把雷神写的Ffmpeg推流器讲解完了&#xff0c;而一同时&#xff0c;一转眼间&#xff0c;2023年已经过半&#xff0c;正式进入了下半年&#xff1a; 因为上半年已经开始在做解析Ffmpeg 最新版本的源码&#xff0c;所以下半年&#xff0c;我会继续坚持讲解Ffmpeg…

“GPT+健康医疗”赋能医疗行业“数智化”发展,景联文科技提供高质量医疗数据库

近日&#xff0c;ChatGPT这个代表着通用版的大型语言模型以其出色的表现在全球互联网上引人注目。它所使用的GPT技术基础为人工智能应用开启了全新的世界。 “大模型时代已经到来。它已变成基础设施&#xff0c;变成算力&#xff0c;变成生产力。大模型可能有通用技术&#xf…

C++杂谈-友元和操作符重载

1、友元- friend 我的理解&#xff1a;通过设置友元函数和友元类来让外部函数来访问私有成员&#xff0c;这样虽然破坏了类的封装型和隐藏性&#xff0c;但是提高了程序的运行效率&#xff08;减少了某些安全性检查的过程&#xff09;。 友元函数和友元类统称友元&#xff0c;…

Nginx+Tomcat(多实例)实现动静分离和负载均衡(四层、七层)

目录 一、Tomcat 多实例部署 二、反向代理的两种类型 三、NginxTomcat实现负载均衡和动静分离&#xff08;七层代理&#xff09; 1.动静分离和负载均衡原理 2.实现方法 3.部署实例 &#xff08;1&#xff09;部署Nginx负载均衡服务器 &#xff08;2&#xff09;配置Tom…

C++之GNU C的__attribute__常用属性(一百五十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

使用 ZBrush、Ornatrix 和 Substance 3D Painter 重现哈利波特中的凤凰

今天瑞云渲染小编给大家带来了Ramn Tapia 分享 Phoenix 项目背后的工作流程&#xff0c;解释了如何在 Ornatrix 中完成修饰&#xff0c;并展示了纹理化过程。 介绍 你好&#xff0c;有创造力的读者朋友们 我的名字是Ramn&#xff0c;但在数字艺术领域&#xff0c;我的名字是ra…

【 Android11 无线热点开发 】无线AP开与关、无线AP信息获取

前言 前面四篇文章介绍完了有线网络、无线网络的开发过程&#xff0c;下面介绍下Android 11上网络的终结篇&#xff0c;无线热点的开发流程。 相关文章 1、【 Android11 WiFi开发 一 】WiFi列表获取与展示 2、【 Android11 WiFi开发 二 】WiFi连接、断开 3、【 Android11 Wi…

软件为什么要进行故障演练?主要为了什么?

随着现代社会的高度信息化和软件的广泛应用&#xff0c;软件的质量和可靠性对于保障用户体验和信息安全显得尤为重要。为了保证软件的稳定运行和即时响应&#xff0c;软件故障演练成为软件开发和运维过程中的重要环节&#xff0c;那软件为什么要进行故障演练&#xff1f;主要为…

IIC(I2C)协议

I2C&#xff08;Inter-Integrated Circuit&#xff09;:是一种串行通信协议&#xff0c;用于在集成电路之间进行数据传输。它由飞利浦公司开发&#xff0c;并广泛应用在各种电子设备和传感器之间进行通信。 I2C通信协议由两根线组成&#xff1a; 一个是用于数据传输的串行数据线…

JVM关键知识点整理,从入门到提高到实践

文章目录 基础篇一、了解JVM内存结构程序计数器&#xff08;线程私有&#xff09;Java虚拟机栈&#xff08;线程私有&#xff09;本地方法栈&#xff08;线程私有&#xff09;方法区&#xff08;线程共享&#xff09;堆&#xff08;线程共享&#xff09;运行时常量池直接内存 二…

Android12之解决-Werror,-Wunused类似问题万能公式(一百五十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Unity3d跨平台原理是什么?

Unity3D的跨平台原理是通过提供统一的开发环境和工具、抽象化的底层接口、平台适配和优化&#xff0c;以及导出和发布功能来实现的。这让开发者们能够在一个平台上创建游戏&#xff0c;并轻松地将其移植和发布到其他支持的平台上&#xff0c;实现游戏的跨平台兼容性。 基于以下…

【大数据之Hadoop】三十七、Hadoop HA高可用

1、HA概述 实现高可用最关键的策略是消除单点故障。HA分成各个组件的HA机制&#xff1a;HDFS的HA和YARN的HA。   Hadoop2.0之前&#xff0c;在HDFS集群中NameNode存在单点故障&#xff08;SPOF&#xff09;。 NameNode主要在以下两个方面影响HDFS集群&#xff1a; &#xff…

Java设计模式之一:观察者模式

目录 一、什么是观察者模式 二、如何使用观察者模式 三、观察者模式的优势和使用场景 一、什么是观察者模式 观察者模式是一种常见的设计模式&#xff0c;用于在对象之间建立一对多的依赖关系。在该模式中&#xff0c;一个主题&#xff08;被观察者&#xff09;维护了一个观…

三相交流电相序检测器/三相交流电相序指示器电路设计

三相交流电相序检测器 在使用三相交流电动机时&#xff0c;需要知道所连接三相电源的相序&#xff0c;若相序不正确&#xff0c;则电动机的旋转方向将与所需的相反&#xff0c;从而导致安全事故。本电路的功能为检测三相交流电源的相序 &#xff0c;并在相序正确的前提下自动接…