目的需求描述
本次项目采用Kubernetes进行容器编排,部署Spring Boot与Vue前后端分离架构的应用。通过Ingress - nginx作为集群的统一入口,实现外部流量的高效路由与分发,为用户提供便捷的访问体验,有效提升系统的可扩展性和稳定性。
整体配置

| K8S Node IP | 部署服务 | 备注 | Ingress-Nginx(域名) |
|---|---|---|---|
| 100.100.157.10(master01) | Ingress-nginx | 统一入口 | |
| 100.100.157.11(work01) | SpringBoot | 后端项目 | api.joydevelop.com |
| 100.100.157.12(work02) | vue | 前端项目 | k8s.joydevelop.com |
| 100.100.157.13 | mysql/harbor | 数据库/镜像仓库 |
- 以上基础软件数据库,这里就不过多解释如何安装,直接从编译,打包,构建镜像开始哈。
- 前端项目demo:https://gitee.com/he-xinyu-hxy/java-word.git(main分支)
- 后端项目demo:https://gitee.com/he-xinyu-hxy/vue-word.git(master 分支)
一、后端sringboot项目部署准备
1.构建后端java sringboot镜像
(1)通过 IDEA 打开后端项目,记得调整一下配置文件,将 MySQL URL调整为部署MySQL的 内网IP地址

(2)编译,打jar包。
打包完毕后,可以看到 target 目录下生成的 Jar 文件:

(3)镜像构建
将JAR包上传到服务器work节点的 /root/hxy/packages/k8s-demo/java 目录上,然后 在/root/hxy/packages/k8s-demo/java 目录上编写 Dockerfile 文件,用于 JAR 包镜像构建.
Dockerfile 内容如下:
[root@k8s-master01 java]# ll
总用量 28792
-rw-r--r-- 1 root root 851 5月 10 15:27 apiVersion:
-rw-r--r-- 1 root root 869 5月 10 17:00 backend.yaml
-rw-r--r-- 1 root root 29467046 5月 10 14:54 course-system.jar
-rw-r--r-- 1 root root 401 5月 10 14:58 Dockerfile
[root@k8s-master01 java]# cat Dockerfile
# 基于阿里云镜像仓库的 OpenJDK 8 镜像
FROM registry.cn-hongkong.aliyuncs.com/o0l/openjdk:8-jdk
# 设置工作目录为 /app
WORKDIR /app
# 将本地的 <jar 包名称> 复制到容器的 /app 目录下,并命名为 app.jar
COPY course-system.jar /app/app.jar
# 暴露容器的 8085 端口
EXPOSE 8085
# 容器启动时执行命令,运行 app.jar 文件
CMD ["java", "-jar", "app.jar"]执行构建命令:
docker build -t java-app:v1 .查看镜像:
[root@k8s-master01 java]# docker images |grep java-app |tail -1
java-app v1 954f79a70771 5 hours ago 556MB打标签,推送harbor:
docker tag java-app:v1 100.100.157.10:5000/k8s/k8s-demo/java-app:v1
docker push 100.100.157.10:5000/k8s/k8s-demo/java-app:v1
(4)harbor docker配置
注意:在项目部署之前,先要保证K8S每一台服务器的/etc/docker/daemon.json都配置上了 Harbor 的内网IP和端口号,否则会导致K8S集群无法成功拉取Harbor私有镜像:
[root@k8s-master01 java]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
],
"insecure-registries":["http://harbor地址:断绝"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl daemon-reload && systemctl restart docker二、前端vue项目部署准备
在构建镜像之前,先要调整一下Vue\js项目的后端接口URL配置信息(.env.production或config.js),我的后端域名是http://api.joydevelop.com。

(1)vue项目镜像编译、打包
在项目根目录下执行
1、安装依赖
npm install
2、编译打包
npm run build(2)编写dockerfile
然后将打包后的
dist文件夹上传到work1的/opt目录,然后在 /opt 目录上编写Dockerfile文件,用于 Vue.js 项目镜像构建:Dockerfile内容如下:
[root@k8s-work01 opt]# cat Dockerfile
# 基础镜像 Nginx
FROM registry.cn-hongkong.aliyuncs.com/o0l/nginx:latest
# 拷贝当前目录的文件到指定文件夹下,改文件夹为镜像中的文件夹
COPY ./dist /usr/share/nginx/html
# 拷贝nginx.conf文件到镜像下,替换掉原有的nginx.conf
COPY ./nginx.conf /etc/nginx/nginx.conf(3)接着在work1 /opt 目录下,创建 nginx.conf 文件,内容如下(记得调整内网IP地址):
[root@k8s-work01 opt]# cat nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 前端服务 - 80 端口
server {
listen 80;
server_name k8s.joydevelop.com;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
}
# 后端服务 - 8085 端口
server {
listen 8085;
server_name api.k8s.joydevelop.com; #后端域名
location / {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
###这个代理:后端容器内部域名解析。
proxy_pass http://backend-service.k8s-demo.svc.cluster.local:8085;
}
}
}(4)执行前端构建
docker build -f Dockerfile -t frontend-project .(5)将构建好的 Vue.js 镜像上传到 Harbor 中:
[root@k8s-work01 opt]# docker images |grep fron
frontend-project latest 4974bff2fb12 3 hours ago 203MB
[root@k8s-work01 opt]# docker images |grep vue
100.100.157.10:5000/k8s/k8s-demo/vue-app v1 4974bff2fb12 3 hours ago 203MB
docker tag frontend-project:latest 100.100.157.10:5000/k8s/k8s-demo/vue-app:v1
docker push 100.100.157.10:5000/k8s/k8s-demo/vue-app:v1
三、前后端项目部署
1.配置namespace命名空间(前后端项目统一归类)
命名空间namespace主要是用于 K8S 集群中资源隔离的,所以在这里我为项目创建一个命名空间k8s-demo,命令如下:
kubectl create k8s-demo2.配置前端Deploement\Service
[root@k8s-master01 vue]# cat frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment 名称
name: frontend-deployment
# 命名空间
namespace: k8s-demo
labels:
app: frontend-label
spec:
# 生成 Pod 数量
replicas: 1
# Pod 标签选择器,用于匹配管理
selector:
matchLabels:
app: frontend-label
template:
# Pod 标签,必须与 selector 匹配
metadata:
labels:
app: frontend-label
spec:
containers:
# 容器名
- name: frontend
# Harbor 前端镜像地址
image: 100.100.157.10:5000/k8s/k8s-demo/vue-app:v6
imagePullPolicy: Always
# 容器端口
ports:
- containerPort: 80
# 指定容器的资源请求和限制
resources:
requests:
memory: 300Mi
cpu: 200m
limits:
memory: 500Mi
cpu: 400m
---
kind: Service
apiVersion: v1
metadata:
name: frontend-service
namespace: k8s-demo
labels:
app: frontend-label
spec:
selector:
app: frontend-label
# Service 类型:ClusterIP、NodePort、LoadBalancer
# 这里使用 ClusterIP,代表只在集群内部通讯(实际企业中也是用 ClusterIP)
# NodePort可以将Service对外暴露访问(一般没人用)
type: ClusterIP
ports:
- protocol: TCP
# 容器端口
port: 80
# Service 端口
targetPort: 803.配置后端Deploement\Service
[root@k8s-master01 java]# cat backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-deployment
namespace: k8s-demo
labels:
app: backend-label
spec:
replicas: 1
selector:
matchLabels:
app: backend-label
template:
metadata:
labels:
app: backend-label
spec:
containers:
- name: backend
image: 100.100.157.10:5000/k8s/k8s-demo/java-app:v1
imagePullPolicy: Always
ports:
- containerPort: 8085
resources:
requests:
memory: 300Mi
cpu: 200m
limits:
memory: 500Mi
cpu: 400m
---
kind: Service
apiVersion: v1
metadata:
name: backend-service
namespace: k8s-demo
labels:
app: backend-label
spec:
selector:
app: backend-label
type: ClusterIP
ports:
- protocol: TCP
port: 8085
targetPort: 80854.启动前后端容器
最后,通过下述命令对前端、后端项目进行启动:
kubectl apply -f frontend.yaml && kubectl apply -f backend.yaml
验证容器状态
[root@k8s-master01 java]# kubectl get pod -o wide -n k8s-demo
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
backend-deployment-8479b777ff-6dczj 1/1 Running 0 4h50m 10.244.1.90 k8s-work01 <none> <none>
frontend-deployment-6bbb84c65c-qcr6g 1/1 Running 0 4h11m 10.244.1.92 k8s-work01 <none> <none>四、配置Ingress-nginx
直接通过 K8S Service 的NordPort模式可以完成服务对外提供访问的要求,但是真正企业级场景来说,更多的是使用Ingress-Nginx构建应用入口,所以这里还需要部署一下Ingress-Nginx。
1.部署步骤
2.Kubernetes Ingress 资源配置
重点:
核心概念是什么?
- 用于定义外部流量如何路由到集群内部的服务。
- 统一入口
- 路径匹配
- 服务发现
为什么要这样配置?
基于域名的路由:
- 访问
http://k8s.joydevelop.com/*→ 所有请求路由到前端服务- 访问
http://api.joydevelop.com/*→ 所有请求路由到后端服务服务隔离:
- 前端服务完全独立,处理静态资源和用户界面
- 后端 API 服务通过专用域名暴露,便于管理和安全控制
[root@k8s-master01 k8s-demo]# cat ingress-project.yaml |egrep -v "#|^$"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: k8s-demo
spec:
ingressClassName: nginx
rules:
- host: k8s.joydevelop.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.joydevelop.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8085然后通过下述命令进行 Ingress-Nginx 创建启动:
kubectl apply -f ingress-project.yaml五、访问测试
因是虚拟机环境,需在本机做host域名解析
yuzi@bogon ~ % cat /etc/hosts |grep 157 100.100.157.10 api.joydevelop.com 100.100.157.10 k8s.joydevelop.com
1.浏览器访问前端域名

2.验证后端数据交换
