K8s部署微服务(springboot+vue)
文章目录
前言
本文主要记录K8s部署微服务项目(springboot后台+vue前端,动态部署自定义项目),也包括对网关、鉴权、用户等基础模块的部署。k8s部署项目,即创建相应的资源有命令行创建和yaml文件创建两种方式,由于命令行创建配置麻烦,且不具备复用性,因此本文均采用yaml文件创建资源的方式。
一、使用到的K8s资源
1.1 Deployment
- 介绍Deployment之前首先介绍Pod。Pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建部署的最小资源对象模型,也是在k8s上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展pod对象的,控制器对象是用来管控 Pod 对象的,Service 或者Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod提供存储等等,k8s 不会直接处理容器,而是 管理Pod,Pod 是由一个或多个 容器组成。
- K8s的Controller是
管理和运行容器的对象
,Deployment是Controller最常用的一种,主要的作用包括:1、定义并维持一组pod的期望数量;2、配置Pod的发布方式(MaxUnavailable以及MaxSurge字段);3、支持回滚操作,可记录多个前置版本。Deployment中定义了ReplicaSet,确定pod数量。主要字段如下:
1.2 Service
- 在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包。
- 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"] # 容器启动执行的命令
- 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镜像的目录:
- 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"]
- 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 "$@"
- 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中
}
- 生成的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文件
}
- 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容器。
- 更新静态资源服务器。
- 同步流程、菜单、数据字典等数据到运行态数据库。
- 模板文件
- 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部署文件。
更多推荐
所有评论(0)