Kubernetes(K8S) + Harbor + Ingress 部署 SpringBoot + Vue 前后端分离项目

文章目录
  • 1、环境准备
  • [2、搭建 K8S](#2、搭建 K8S)
  • [3、搭建 Harbor](#3、搭建 Harbor)
  • [4、搭建 MySQL](#4、搭建 MySQL)
  • [5、构建 SpringBoot 项目镜像](#5、构建 SpringBoot 项目镜像)
  • [6、构建 Vue.js 项目镜像](#6、构建 Vue.js 项目镜像)
  • 7、部署项目
    • [7.1、配置 NameSpace](#7.1、配置 NameSpace)
    • [7.2、配置 Deployment、Service](#7.2、配置 Deployment、Service)
    • [7.3、配置 Ingress-Nginx](#7.3、配置 Ingress-Nginx)
    • 7.4、访问测试

1、环境准备

本次整体项目部署使用的是阿里云ECS服务器,服务器地区选择的是香港(选择香港的原因 7.2 章节 Ingress 域名解析用的是阿里云的真实域名地址,如果地区是大陆服务器还需要域名备案),整体部署配置如下:

  • 服务器1:
    • 部署:K8S Master
    • 配置:CentOS 7.9,4核8G
  • 服务器2:
    • 部署:K8S Worker 1
    • 配置:CentOS 7.9,4核8G
  • 服务器3:
    • 部署:K8S Worker 2
    • 配置:CentOS 7.9,4核8G
  • 服务器4:
    • 部署:MySQL + Harbor
    • 配置:CentOS 7.9,2核4G
    • 开放端口:80、8080、3306、9999

整体部署架构图如下:

2、搭建 K8S

在服务器1,2,3搭建1主2从K8S集群,详细部署流程参照下述文章链接:https://xuzhibin.blog.csdn.net/article/details/139649056

3、搭建 Harbor

在服务器4上,进行Harbor部署,参考该链接:
https://blog.csdn.net/weixin_46594796/article/details/143113896

Harbor 搭建完毕后,要在 Harbor 中创建一个项目 名为test,留着后面操作 Docker 镜像使用:

4、搭建 MySQL

本次部署的前端项目、后端项目、数据库脚本 我已经上传到了 Github 上,请自行下载:
https://github.com/Binx98/test-project

在服务器4上,创建启动 MySQL 数据库容器:

复制代码
docker run -p 3306:3306 --name mysql 
-e MYSQL_ROOT_PASSWORD=root 
-d mysql:8.0

通过 Navicat 连接到创建好的 MySQL(账号密码都是root),先创建 test 数据库,然后将上面提供的 MySQL 数据初始化脚本 init.sql 执行加载完毕,数据导入成功后如下图:

5、构建 SpringBoot 项目镜像

通过 IDEA 打开后端项目,记得调整一下配置文件,将MySQL URL调整为部署MySQL的内网IP地址:

在 IDEA 控制台上,通过 Maven 完成 SpringBoot 项目打包操作:

复制代码
mvn clean package -Dmaven.test.skip=true

打包完毕后,可以看到 target 目录下生成的 Jar 文件:

将JAR包上传到服务器4的 /opt 目录上,然后在 /opt 目录上编写 BackendDockerfile 文件,用于 JAR 包镜像构建,BackendDockerfile 内容如下:

复制代码
# 基础镜像
FROM openjdk:17
# 宿主机文件 COPY 镜像
ADD backend-project.jar /backend-project.jar
# 容器启动时执行(类似CMD)
ENTRYPOINT ["java", "-jar", "backend-project.jar"]

然后在服务器4的/opt目录下,进行镜像构建,命令如下:

复制代码
cd /opt
docker build -f BackendDockerfile -t backend-project .

镜像构建完毕后,通过下述命令启动镜像,判断是否打包成功:

复制代码
docker run -d -p 8080:8080 backend-project

最后通过 公网IP地址:8080/api 访问测试接口,可以查看到后端服务部署成功:

然后将该 SpringBoot项目 镜像推送到 Harbor 当中:

复制代码
# 登录 Harbor,账号密码:admin/Harbor12345
docker login 服务器4内网IP:9999

# 为镜像打标签
docker tag backend-project:latest 服务器4内网IP:9999/test/backend-project:1.0

# 推送镜像到 Harbor
docker push 服务器4内网IP:9999/test/backend-project:1.0

镜像上传完毕后,可以在 Harbor 的 test 项目中查看刚刚上传的镜像:

6、构建 Vue.js 项目镜像

在构建镜像之前,先要调整一下 Vue.js 项目的后端接口URL配置信息(.env.production),使用域名/api,我的域名是k8s.joydevelop.com

调整完毕后,将 Vue.js 项目进行打包操作,控制台执行下述命令:

复制代码
npm run build:prod

然后将打包后的 dist 文件上传到服务器4 /opt 目录,然后在 /opt 目录上编写 FrontendDockerfile 文件,用于 Vue.js 项目镜像构建:

复制代码
# 基础镜像 Nginx
FROM nginx

# 拷贝当前目录的文件到指定文件夹下,改文件夹为镜像中的文件夹
COPY ./dist /usr/share/nginx/html

# 拷贝nginx.conf文件到镜像下,替换掉原有的nginx.conf
COPY ./nginx.conf /etc/nginx/nginx.conf

接着在服务器4 /opt 目录下,创建 nginx.conf 文件,内容如下(记得调整内网IP地址):

复制代码
worker_processes  1;

events {
  worker_connections  1024;
}

http {
  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  keepalive_timeout  65;

  server {
    listen       80;
    server_name  localhost;

    location / {
      root   /usr/share/nginx/html;
      try_files $uri $uri/ /index.html;
      index  index.html index.htm;
    }

    location /api/ {
      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 "";
      # 这里用的是 K8S Service 服务名访问方式(先按照我这么写!)
      proxy_pass http://backend-service.prod-env.svc.cluster.local:8080;
    }
  }
}

执行下述命令,完成 Vue.js 镜像构建:

复制代码
cd /opt
docker build -f FrontendDockerfile -t frontend-project .

最后,将构建好的 Vue.js 镜像上传到 Harbor 中:

复制代码
# 为镜像打标签
docker tag frontend-project:latest 服务器4内网IP:9999/test/frontend-project:1.0

# 推送镜像到 Harbor
docker push 服务器4内网IP:9999/test/frontend-project:1.0

镜像上传完毕后,可以在 Harbortest 项目中查看刚刚上传的镜像:

7、部署项目

注意:在项目部署之前,先要保证K8S每一台服务器(服务器1,2,3)的/etc/docker/daemon.json都配置上了 Harbor 的内网IP和端口号,否则会导致K8S集群无法成功拉取Harbor私有镜像:

复制代码
{
  "registry-mirrors": [
          "https://8er86g8v.mirror.aliyuncs.com",
          "https://docker.1panel.live/"
  ],
  "insecure-registries": ["服务器4内网IP:9999"]
}

然后服务器1,2,3通过下述命令重新加载配置:

复制代码
systemctl daemon-reload && systemctl restart docker

7.1、配置 NameSpace

命名空间namespace主要是用于 K8S 集群中资源隔离的,所以在这里我为项目创建一个命名空间prod-env,命令如下:

复制代码
kubectl create ns prod-env

7.2、配置 Deployment、Service

具体配置内容如下,注释写的很清楚,不多解释啦!

前端部署配置 frontend.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  # Deployment 名称
  name: frontend-deployment
  # 命名空间
  namespace: prod-env
  labels:
    app: frontend-label
spec:
  # 生成 Pod 数量
  replicas: 3
  # Pod 标签选择器,用于匹配管理
  selector:
    matchLabels:
      app: frontend-label
  template:
    # Pod 标签,必须与 selector 匹配
    metadata:
      labels:
        app: frontend-label
    spec:
      containers:
        # 容器名
      - name: frontend
        # Harbor 前端镜像地址
        image: 服务器4内网IP:9999/test/frontend-project:1.0
        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: prod-env
  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: 80

后端部署配置 backend.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-deployment
  namespace: prod-env
  labels:
    app: backend-label
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend-label
  template:
    metadata:
      labels:
        app: backend-label
    spec:
      containers:
      - name: backend
        image: 服务器4内网IP:9999/test/backend-project:1.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: 300Mi
            cpu: 200m
          limits:
            memory: 500Mi
            cpu: 400m
            
---

kind: Service
apiVersion: v1
metadata:
  name: backend-service
  namespace: prod-env
  labels:
    app: backend-label
spec:
  selector:
    app: backend-label
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080

最后,通过下述命令对前端、后端项目进行启动:

复制代码
kubectl apply -f frontend.yaml && kubectl apply -f backend.yaml

7.3、配置 Ingress-Nginx

直接通过 K8S Service 的 NordPort 模式可以完成服务对外提供访问的要求,但是真正企业级场景来说,更多的是使用 Ingress-Nginx 构建应用入口,所以这里还需要部署一下 Ingress-Nginx,请参考下述连接部署:https://xuzhibin.blog.csdn.net/article/details/143227591

按照上述部署完毕后其实有个问题,我们需要保证ingress-nginx-controller部署在 Master 节点上,否则无法进行正确的访问,所以还需要修改Ingress部署配置文件的一处位置,让其部署在主节点上:

修改完毕后,重新卸载安装 Ingress-Nginx

复制代码
# 删除 Ingress-Nginx
kubectl delete -f ingress-deploy.yaml

# 安装 Ingress-Nginx
kubectl apply -f ingress-deploy.yaml

此时可以看到,ingress-nginx-controller 部署在 k8s-master 上了:

部署完毕后,接下来要做的是配置一下 ingress-project.yaml 完成访问配置,由于我的服务器都在香港地区,所以这次我就用真实的域名解析到我的主服务器IP上(没有可用于名,就得通过修改 hosts 文件使用假域名测试了),配置内容如下:

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  # Ingress-Nginx 名称
  name: my-ingress
  namespace: prod-env
spec:
  # Ingress Class
  ingressClassName: nginx
  # 路由规则
  rules:
  # 域名
  - host: k8s.joydevelop.com
    http:
      paths:
      # 访问域名根路径,就会路由到 front-service 服务上
      - path: /
        pathType: Prefix
        backend:
          service:
            # 前端服务名称
            name: frontend-service
            # 服务端口
            port:
              number: 80
              
#      后端服务 Service 就不用暴露了,不需要直接把后端接口给别人调用啊!          
#      - path: /api
#        pathType: Prefix
#        backend:
#          service: 
#            name: backend-service
#            port: 
#              number: 8080

然后通过下述命令进行 Ingress-Nginx 创建启动:

复制代码
kubectl apply -f ingress-project.yaml

7.4、访问测试

最后,在浏览器上通过访问域名,可以看到 K8S 部署 SpringBoot + Vue.js 项目成功!

相关推荐
biyezuopinvip3 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
我是伪码农3 小时前
Vue 智慧商城项目
前端·javascript·vue.js
JavaGuide3 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot
figo10tf4 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
zhangyi_viva4 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
小书包酱4 小时前
在 VS Code中,vue2-vuex 使用终于有体验感增强的插件了。
vue.js·vuex
橙露4 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
程序员敲代码吗4 小时前
Spring Boot与Tomcat整合的内部机制与优化
spring boot·后端·tomcat
NuageL4 小时前
原始Json字符串转化为Java对象列表/把中文键名变成英文键名
java·spring boot·json
Zhencode4 小时前
Vue3 响应式依赖收集与更新之effect
前端·vue.js