当前位置: 首页>前端>正文

不是微服务的可以K8S部署吗 k8s部署微服务案例spring


文章目录

  • 前言
  • 一、使用到的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 是由一个或多个 容器组成。
  2. K8s的Controller是管理和运行容器的对象,Deployment是Controller最常用的一种,主要的作用包括:1、定义并维持一组pod的期望数量;2、配置Pod的发布方式(MaxUnavailable以及MaxSurge字段);3、支持回滚操作,可记录多个前置版本。Deployment中定义了ReplicaSet,确定pod数量。主要字段如下:

不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring,第1张

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的访问规则
  2. 不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_微服务_02,第2张


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

二、Springboot基础服务部署

本文采用Deployment+Service的方式进行部署,先对SpringBoot项目进行打包,然后编写Dockerfile文件,制作镜像,并上传到私有镜像仓库上。

构建镜像的文件夹内容包含Dockerfile、entrypoint.sh以及相应的jar包。

不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring_03,第3张

  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:
     s: # 使用的容器信息
      - name: gateway
        image: 192.168.1.180:5000/aengus/gateway:v1.6
        # 拉取镜像策略:本地镜像不存在,从仓库取。有Always:中从仓库取。Never:总从本地取。
        imagePullPolicy: IfNotPresent 
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: keyston-auth
        image: 192.168.1.180:5000/aengus/auth:v1.7
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: file-starter
        image: 192.168.1.180:5000/aengus/file:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: flow-starter
        image: 192.168.1.180:5000/aengus/flow:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: message-starter
        image: 192.168.1.180:5000/aengus/message:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: org-starter
        image: 192.168.1.180:5000/aengus/org:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: system-starter
        image: 192.168.1.180:5000/aengus/system:v1.6
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: keyston-user
        image: 192.168.1.180:5000/aengus/user:v1.9
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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:
     s:
      - name: thingmax-script
        image: 192.168.1.180:5000/aengus/script:v1.1
        imagePullPolicy: IfNotPresent
        ports:
        - protocol: TCP
         Port: 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镜像的目录:

不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring boot_04,第4张

  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 [ "" = "nginx" -o "" = "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 "
  • default.conf.template文件提供基础服务的访问规则配置
  • : /docker-entrypoint.d/ is not empty, will attempt to perform configuration" echo >&3 "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 last; } location /support-static { rewrite ^/support-static(.*)$ /support/support-static 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 last; } location /thingmax-static { rewrite ^/thingmax-static(.*)$ /thingmax/thingmax-static 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 last; } location /process-model-static { rewrite ^/process-model-static(.*)$ /process-model/process-model-static 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 last; } location /visual-model-static { rewrite ^/visual-model-static(.*)$ /visual-model/visual-model-static 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 last; } location /service-center-static { rewrite ^/service-center-static(.*)$ /service-center/service-center-static 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 last; } location /message-center-static { rewrite ^/message-center-static(.*)$ /message-center/message-center-static 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 last; } location /file-service-static { rewrite ^/file-service-static(.*)$ /file-service/file-service-static 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 last; } location /runtime-static { rewrite ^/runtime-static(.*)$ /runtime/runtime-static 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 last; } location /main/project-preview-static { rewrite ^/main/project-preview-static(.*)$ /project-preview/project-preview-static last; } # 列表请求转发 location /prod-api/systemApi/project/getByCode/code { rewrite ^/prod-api/(.*)/code /prod-api//$PROJECT_CODE last; } location /prod-api/systemApi/application/getByCode/appCode { rewrite ^/prod-api/(.*)/appCode /prod-api//$APP_CODE last; } location /prod-api/systemApi/appMenu/getMenusByAppCode/appCode { rewrite ^/prod-api/(.*)/appCode /prod-api//$APP_CODE last; } location /main/user-permissions-static { rewrite ^/main/user-permissions-static(.*)$ /user-permissions/user-permissions-static last; } location /user-permissions-static { rewrite ^/user-permissions-static(.*)$ /user-permissions/user-permissions-static 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 last; } location /system-monitoring-static { rewrite ^/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static 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中 }: 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 "
  • 生成的default.conf文件:
  • : Launching $f"; "$f" else # warn on shell scripts without exec bit echo >&3 "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 last; } location /support-static { rewrite ^/support-static(.*)$ /support/support-static 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 last; } location /thingmax-static { rewrite ^/thingmax-static(.*)$ /thingmax/thingmax-static 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 last; } location /process-model-static { rewrite ^/process-model-static(.*)$ /process-model/process-model-static 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 last; } location /visual-model-static { rewrite ^/visual-model-static(.*)$ /visual-model/visual-model-static 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 last; } location /service-center-static { rewrite ^/service-center-static(.*)$ /service-center/service-center-static 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 last; } location /message-center-static { rewrite ^/message-center-static(.*)$ /message-center/message-center-static 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 last; } location /file-service-static { rewrite ^/file-service-static(.*)$ /file-service/file-service-static 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 last; } location /runtime-static { rewrite ^/runtime-static(.*)$ /runtime/runtime-static 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 last; } location /main/project-preview-static { rewrite ^/main/project-preview-static(.*)$ /project-preview/project-preview-static last; } # 列表请求转发 location /prod-api/systemApi/project/getByCode/code { rewrite ^/prod-api/(.*)/code /prod-api//HEU last; } location /prod-api/systemApi/application/getByCode/appCode { rewrite ^/prod-api/(.*)/appCode /prod-api// last; } location /prod-api/systemApi/appMenu/getMenusByAppCode/appCode { rewrite ^/prod-api/(.*)/appCode /prod-api// last; } location /main/user-permissions-static { rewrite ^/main/user-permissions-static(.*)$ /user-permissions/user-permissions-static last; } location /user-permissions-static { rewrite ^/user-permissions-static(.*)$ /user-permissions/user-permissions-static 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 last; } location /system-monitoring-static { rewrite ^/system-monitoring-static(.*)$ /system-monitoring/system-monitoring-static 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文件 }: Ignoring $f, not executable"; fi ;; *) echo >&3 "
  • item文件举例
  • : Ignoring $f";; esac done echo >&3 "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; }: Configuration complete; ready for start up" else echo >&3 "

    3.1 项目前端nginx

    : No files found in /docker-entrypoint.d/, skipping configuration" fi fi exec "$@"
      需要在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:
         s:
          - name: nginxmain
            image: 192.168.1.180:5000/aengus/nginxmain:v2.8
            imagePullPolicy: IfNotPresent
            securityContext:
              privileged: true
            ports:
              - protocol: TCP
               Port: 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

  • 静态资源服务器制作镜像Dockerfile
    1. 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配置文件
  • html的内容包括:child、design_main和running_main,分别存放子应用、开发态主应用和运行态主应用的dist包。

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_不是微服务的可以K8S部署吗_05,第5张

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

    使用volumeMounts的方式进行挂载,将内容挂载到NFS服务器对应的目录下。

  • 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:
         s:
          - name: nginxstatic
            image: 192.168.1.180:5000/aengus/nginxstatic:v1.0
            imagePullPolicy: IfNotPresent
            securityContext:
              privileged: true
            ports:
              - protocol: TCP
               Port: 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

    四、动态项目部署

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

    制作静态资源服务器Docker镜像的目录:

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring boot_06,第6张

    静态资源服务器文件挂载地址:

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_kubernetes_07,第7张

      项目发布过程中,需要使用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

    #!/bin/sh
    
    ROOT_DIR=
    TEMP_DIR=
    TEMPLATE=
    IMAGE_NAME=
    IMAGE_TAG=
    
    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
    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"]

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

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

      4.2 项目启动

    • 查出存于mysql数据库中的模板文件。
    • 通过获取租户、项目下的每个应用的名称、版本,以及配置的nacos_url、app_root等环境变量,通过变量替换,生成需要的yaml文件。
  • 执行kubectl apply -f xxx.yaml 部署应用。
  • 应用发布主要的命令的buildThingmax.sh脚本内容如下:

  • 查询应用页面JSON并复制到k8s的nfs目录。
  • thingmax操作的根目录/runtime内容如下:

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring boot_08,第8张

    thingmax目录下内容包括Dockerfile文件、start.sh启动脚本以及运行态jar包thingmax-runtimer.jar:

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring boot_09,第9张

    dist/tpDist 目录下包括aplication-preview (应用预览)和 nginx-static(静态资源服务器):

    不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_kubernetes_10,第10张

    system目录作为临时目录。

    Dockerfile文件内容:

  • 菜单型项目将项目下所有的页面JSON复制到k8s的nfs目录。
  • start.sh脚本内容:

  • 更新前端项目nginx容器。
  • 更新静态资源服务器。
  • 项目启动的核心内容在于使用k8s部署应用发布时生成的镜像并进行相关文件的导出与分发,执行流程如下:

    • 同步流程、菜单、数据字典等数据到运行态数据库。
    • 模板文件
    • 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" s: - name: {{name}} image: {{image}} imagePullPolicy: IfNotPresent ports: - protocol: TCP Port: 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=projectCode

      总结

        不是微服务的可以K8S部署吗 k8s部署微服务案例spring,不是微服务的可以K8S部署吗 k8s部署微服务案例spring_spring_11,第11张

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

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


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


        https://www.xamrdz.com/web/2pd1964337.html

        相关文章: