前言

本文主要记录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 是由一个或多个 容器组成。
  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. gateway的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 # nacos注册网址
            value: 192.168.1.181:8848
          - name: NACOS_DISCOVERY_NAMESPACE # nacos服务注册命名空间的环境变量
            value: 2a20a28f-6345-4ec7-ac28-ae525796736a
          - name: NACOS_CONFIG_NAMESPACE # nacos服务配置命名空间的环境变量
            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的内容包括: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文件等资源,目的在于减少前端打包体积,提升访问速度。
制作静态资源服务器Docker镜像的目录:
在这里插入图片描述
静态资源服务器文件挂载地址:
在这里插入图片描述

  • 静态资源服务器制作镜像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

四、动态项目部署

项目发布过程中,需要使用SCP跨服务器进行文件传输,因此需配置秘钥登录服务器

# 在分发文件的源服务器(181)执行以下命令,连续点击回车,生成公钥和私钥
ssh-keygen -t rsa
# 查看生成的公钥和私钥
ls ~/.ssh/id_*
/root/.ssh/id_rsa  /root/.ssh/id_rsa.pub
# 将公钥复制到被管理的服务器
ssh-copy-id root@192.168.1.180
# 测试设置是否生效
ssh root@192.168.1.180

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操作的根目录/runtime内容如下:
在这里插入图片描述

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挂载地址

在这里插入图片描述

挂载根目录必须命名为项目code即erp。
conf为nginx配置文件挂载目录,下有default.conf、default.conf.template以及应用的item配置文件。
html为主应用、子应用的前端打包文件,和构建镜像时的目录结构一致,其中html/child/application目录放置自定义项目的子应用。
nginxstatic为静态资源服务器挂载文件目录

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


总结

本文详细讲解了k8s部署Springboot后端项目、vue前端想项目,以及动态部署自定义项目的过程,并给出了相关的Docker构建文件、以及k8s部署文件。

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐