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

“后端服务+前端页面服务 + 后端数据库服务“如何部署到K8s集群

将 “后端服务 + 前端页面服务 + 后端数据库服务” 部署到 K8s 集群,核心是通过K8s 核心资源(Deployment、Service、Ingress 等) 实现组件解耦、弹性伸缩和统一调度,同时需兼顾数据持久化、网络访问、配置管理等关键需求。以下是分步骤的完整部署方案,含资源清单示例和核心注意事项。

一、部署前准备

1. 环境前提

  • 已搭建可用的 K8s 集群(单节点 / 多节点均可,生产环境建议≥3 节点,需支持StorageClass用于数据持久化);
  • 本地安装kubectl并配置集群访问权限(kubectl config use-context <集群名称>);
  • 所有服务已打包为 Docker 镜像(前端、后端、数据库),并推送到镜像仓库(如 Docker Hub、Harbor、阿里云 ACR 等);
  • 可选:安装 Ingress 控制器(如 Nginx Ingress),用于统一入口访问(生产环境必备)。

2. 核心组件规划

组件K8s 资源类型核心需求
前端页面服务Deployment(部署)+ Service(暴露)+ Ingress(域名访问)静态资源(HTML/CSS/JS),无状态,需反向代理
后端服务Deployment(部署)+ Service(暴露)无状态(建议),需连接数据库,需环境变量配置
后端数据库StatefulSet(有状态部署)+ Service(无头服务 / 集群 IP)+ PersistentVolumeClaim(数据持久化)有状态,数据需持久化,固定网络标识

数据库用StatefulSet而非Deployment:因为数据库是有状态服务(数据与实例绑定、需固定网络名称),StatefulSet能保证 Pod 名称、主机名固定,且与PVC一一对应,避免数据丢失。

二、分步部署实现

第一步:部署后端数据库服务(以 MySQL 为例)

1. 数据持久化:创建 PVC(绑定存储)

先通过PersistentVolumeClaim(PVC)申请存储资源(依赖集群已存在StorageClass,如standardnfs-storage等)。

创建mysql-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mysql-pvc  # PVC名称,供StatefulSet引用namespace: app-namespace  # 建议创建独立命名空间隔离应用
spec:accessModes:- ReadWriteOnce  # 仅单节点读写(数据库通常单实例,集群化需调整)resources:requests:storage: 10Gi  # 申请10GB存储storageClassName: "standard"  # 替换为集群实际的StorageClass名称(kubectl get sc查看)

应用 PVC:

bash

kubectl apply -f mysql-pvc.yaml
2. 配置管理:创建 ConfigMap/Secret(存储配置和密码)
  • Secret:存储敏感信息(如数据库密码,Base64 编码);
  • ConfigMap:存储非敏感配置(如数据库连接参数、字符集)。
(1)创建 Secret 存储数据库密码

先将密码编码(例如密码Root@123456):

bash

echo -n "Root@123456" | base64  # 输出:Um9vdEAxMjM0NTY=

创建mysql-secret.yaml

yaml

apiVersion: v1
kind: Secret
metadata:name: mysql-secretnamespace: app-namespace
type: Opaque
data:mysql-root-password: Um9vdEAxMjM0NTY=  # Base64编码后的密码mysql-user-password: Um9vdEAxMjM0NTY=  # 普通用户密码(可选)

应用 Secret 和 ConfigMap:

kubectl apply -f mysql-secret.yaml -f mysql-configmap.yaml
3. 部署数据库:创建 StatefulSet 和 Service

创建mysql-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysqlnamespace: app-namespace
spec:serviceName: mysql-service  # 关联的无头Service名称(固定网络标识)replicas: 1  # 单实例(生产环境可集群化,需调整)selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:8.0  # 镜像地址(替换为你的私有仓库镜像,如harbor.com/mysql:8.0)ports:- containerPort: 3306  # MySQL默认端口env:# 从ConfigMap读取非敏感配置- name: MYSQL_DATABASEvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_DATABASE- name: MYSQL_USERvalueFrom:configMapKeyRef:name: mysql-configkey: MYSQL_USER# 从Secret读取敏感配置- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretkey: mysql-root-password- name: MYSQL_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretkey: mysql-user-password# 挂载PVC(数据持久化)volumeMounts:- name: mysql-datamountPath: /var/lib/mysql  # MySQL数据存储目录# 健康检查livenessProbe:exec:command: ["mysqladmin", "ping", "-uroot", "-p$(MYSQL_ROOT_PASSWORD)"]initialDelaySeconds: 30periodSeconds: 10readinessProbe:exec:command: ["mysql", "-uroot", "-p$(MYSQL_ROOT_PASSWORD)", "-e", "SELECT 1"]initialDelaySeconds: 5periodSeconds: 5# 关联PVC(与StatefulSet名称+volume名称匹配,自动绑定mysql-pvc)volumeClaimTemplates: []  # 若已手动创建PVC,此处留空;若自动创建,需配置spec# 手动绑定已创建的PVC(关键)volumes:- name: mysql-datapersistentVolumeClaim:claimName: mysql-pvc  # 引用第一步创建的PVC
---
# 无头Service(供后端服务内部访问,固定DNS:mysql-service.app-namespace.svc.cluster.local)
apiVersion: v1
kind: Service
metadata:name: mysql-servicenamespace: app-namespace
spec:clusterIP: None  # 无头服务(无集群IP,通过DNS解析Pod IP)selector:app: mysqlports:- port: 3306targetPort: 3306

应用 StatefulSet 和 Service:

kubectl apply -f mysql-statefulset.yaml

验证数据库部署

# 查看Pod状态(Running表示正常)
kubectl get pods -n app-namespace -l app=mysql
# 查看PVC绑定状态(Bound表示成功)
kubectl get pvc -n app-namespace
# 进入Pod测试数据库连接
kubectl exec -it mysql-0 -n app-namespace -- mysql -uroot -pRoot@123456

第二步:部署后端服务(以 Java SpringBoot 为例)

后端服务为无状态服务,用Deployment部署,通过Service暴露内部访问,依赖数据库的无头 Service(mysql-service.app-namespace.svc.cluster.local)。

1. 创建后端配置(ConfigMap)

创建backend-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:name: backend-confignamespace: app-namespace
data:SPRING_DATASOURCE_URL: "jdbc:mysql://mysql-service.app-namespace.svc.cluster.local:3306/app_db?useSSL=false&serverTimezone=Asia/Shanghai"SPRING_DATASOURCE_USERNAME: "app_user"SPRING_PROFILES_ACTIVE: "prod"  # 环境标识
2. 创建后端 Deployment 和 Service

创建backend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: backend-servicenamespace: app-namespace
spec:replicas: 2  # 2个副本(弹性伸缩)selector:matchLabels:app: backendtemplate:metadata:labels:app: backendspec:containers:- name: backendimage: your-registry/backend-app:v1.0  # 替换为你的后端镜像地址ports:- containerPort: 8080  # 后端服务端口(如SpringBoot默认8080)env:# 从ConfigMap读取非敏感配置- name: SPRING_DATASOURCE_URLvalueFrom:configMapKeyRef:name: backend-configkey: SPRING_DATASOURCE_URL- name: SPRING_DATASOURCE_USERNAMEvalueFrom:configMapKeyRef:name: backend-configkey: SPRING_DATASOURCE_USERNAME# 从Secret读取数据库密码(复用mysql-secret)- name: SPRING_DATASOURCE_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretkey: mysql-user-password# 健康检查livenessProbe:httpGet:path: /actuator/health  # SpringBoot健康检查端点(需开启actuator)port: 8080initialDelaySeconds: 60periodSeconds: 10readinessProbe:httpGet:path: /actuator/healthport: 8080initialDelaySeconds: 30periodSeconds: 5resources:limits:cpu: "1"memory: "1Gi"requests:cpu: "500m"memory: "512Mi"
---
# 后端Service(ClusterIP类型,仅集群内部访问)
apiVersion: v1
kind: Service
metadata:name: backend-servicenamespace: app-namespace
spec:type: ClusterIPselector:app: backendports:- port: 8080targetPort: 8080

应用配置和部署:

bash

kubectl apply -f backend-configmap.yaml -f backend-deployment.yaml

验证后端部署:

bash

# 查看Pod状态
kubectl get pods -n app-namespace -l app=backend
# 测试后端服务(集群内部访问)
kubectl exec -it <任意前端Pod名称> -n app-namespace -- curl http://backend-service:8080/actuator/health

第三步:部署前端页面服务(以 Vue/React 静态资源为例)

前端为静态资源,通常用 Nginx 镜像打包(将静态文件放入 Nginx 的/usr/share/nginx/html目录),通过Ingress暴露外网访问,并配置反向代理指向后端 Service。

1. 前端镜像打包(关键步骤)

需先将前端代码打包为 Docker 镜像,示例Dockerfile

# 构建阶段(用Node镜像打包静态资源)
FROM node:16-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build  # 打包静态资源到dist目录# 运行阶段(用Nginx镜像部署)
FROM nginx:alpine
# 复制打包后的静态资源到Nginx
COPY --from=build /app/dist /usr/share/nginx/html
# 替换Nginx配置(配置反向代理到后端)
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

其中nginx.conf(核心是反向代理后端服务):

server {listen 80;server_name localhost;root /usr/share/nginx/html;index index.html;# 前端路由刷新404问题(SPA应用必备)location / {try_files $uri $uri/ /index.html;}# 反向代理后端接口(前端请求/api/*转发到后端Service)location /api/ {proxy_pass http://backend-service.app-namespace.svc.cluster.local:8080/;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 X-Forwarded-Proto $scheme;}
}

构建并推送镜像:

bash

docker build -t your-registry/frontend-app:v1.0 .
docker push your-registry/frontend-app:v1.0
2. 部署前端 Deployment 和 Service

创建frontend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: frontend-servicenamespace: app-namespace
spec:replicas: 2  # 2个副本(高可用)selector:matchLabels:app: frontendtemplate:metadata:labels:app: frontendspec:containers:- name: frontendimage: your-registry/frontend-app:v1.0  # 替换为你的前端镜像地址ports:- containerPort: 80resources:limits:cpu: "500m"memory: "512Mi"requests:cpu: "200m"memory: "256Mi"
---
# 前端Service(ClusterIP类型,供Ingress转发)
apiVersion: v1
kind: Service
metadata:name: frontend-servicenamespace: app-namespace
spec:type: ClusterIPselector:app: frontendports:- port: 80targetPort: 80

应用部署:

bash

kubectl apply -f frontend-deployment.yaml

第四步:配置 Ingress(统一入口访问)

通过 Ingress 实现外网访问前端页面,同时转发后端接口(可选,也可让前端直接通过 Ingress 访问后端)。

1. 确保 Ingress 控制器已安装

若未安装,以 Nginx Ingress 为例(K8s 1.24+):

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml

验证 Ingress 控制器:

bash

kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
2. 创建 Ingress 资源

创建app-ingress.yaml

yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: app-ingressnamespace: app-namespaceannotations:# Nginx Ingress注解(可选,如开启gzip、设置缓存)nginx.ingress.kubernetes.io/gzip-enabled: "true"nginx.ingress.kubernetes.io/ssl-redirect: "false"  # 测试环境关闭HTTPS,生产环境开启
spec:ingressClassName: nginx  # 关联Ingress控制器(必须,kubectl get ingressclass查看)rules:# 前端页面访问规则(如通过app.example.com访问)- host: app.example.com  # 替换为你的域名(本地测试可修改/etc/hosts绑定Ingress控制器IP)http:paths:- path: /pathType: Prefixbackend:service:name: frontend-serviceport:number: 80# 后端接口访问规则(可选,如通过api.example.com访问)- host: api.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: backend-serviceport:number: 8080

应用 Ingress:

bash

kubectl apply -f app-ingress.yaml

验证 Ingress:

bash

kubectl get ingress -n app-namespace
# 查看Ingress地址(ADDRESS列,即Ingress控制器的IP)
3. 访问测试
  • 本地测试:修改/etc/hosts(Linux/Mac)或C:\Windows\System32\drivers\etc\hosts(Windows),添加:

    plaintext

    <Ingress控制器IP>  app.example.com  api.example.com
    
  • 浏览器访问http://app.example.com:看到前端页面,且接口请求(/api/*)能正常转发到后端,连接数据库返回数据。

三、核心注意事项

1. 数据持久化

  • 数据库必须用StatefulSet + PVC,避免 Pod 重建导致数据丢失;
  • 生产环境建议使用分布式存储(如 GlusterFS、Ceph)或云厂商存储(如 AWS EBS、阿里云 OSS),确保高可用。

2. 网络访问

  • 内部服务通信优先使用Service名称.命名空间.svc.cluster.local(K8s 内部 DNS 解析),避免硬编码 Pod IP;
  • Ingress 仅暴露必要端口(80/443),生产环境需配置 HTTPS(添加tls字段,引用 Secret 存储证书)。

3. 配置与敏感信息

  • 非敏感配置(如数据库地址、环境变量)用ConfigMap,敏感信息(密码、密钥)用Secret
  • 生产环境建议使用SealedSecret或云厂商密钥管理服务(如 AWS KMS),避免 Secret 明文泄露。

4. 高可用与弹性伸缩

  • 后端、前端服务为无状态,可通过kubectl scale deployment <名称> --replicas=3扩展副本数;
  • 数据库单实例风险高,生产环境可部署 MySQL 集群(如主从复制)或使用云数据库(RDS),K8s 仅部署应用层。

5. 监控与日志

  • 部署 Prometheus + Grafana 监控 Pod、Service 状态(CPU / 内存 / 网络);
  • 部署 ELK Stack(Elasticsearch + Logstash + Kibana)收集 Pod 日志,便于问题排查。

四、常用运维命令

bash

# 查看命名空间下所有资源
kubectl get all -n app-namespace# 查看Pod日志(后端为例)
kubectl logs -f <backend-pod-name> -n app-namespace# 进入Pod调试
kubectl exec -it <pod-name> -n app-namespace -- /bin/bash# 重启Deployment(更新配置后)
kubectl rollout restart deployment backend-service -n app-namespace# 查看PVC使用情况
kubectl describe pvc mysql-pvc -n app-namespace

http://www.dtcms.com/a/601963.html

相关文章:

  • 网站开发会用到定时器功能长沙公司网络推广
  • LangGraph 中 State 状态模式详解
  • 8-Arm PEG-Acrylate,八臂聚乙二醇丙烯酸酯的溶解性
  • 企业网站设计建设服务器怎么能在网上卖货
  • K8s新手入门:从“Pod创建“到“服务暴露“,3个案例理解容器编排
  • 关于《大学物理》网站资源建设的思路vs2013做网站教程
  • WPF 、WebView2 、WebView2 、CoreWebView2 、HostObject 是什么?它们之间有什么关系?
  • 大连最好的做网站的公司wordpress国产网校
  • C语言编译器 | 如何高效使用和优化C语言编译器
  • C语言指针深度剖析(2):从“数组名陷阱”到“二级指针操控”的进阶指南
  • 中企动力做网站 知乎网站后台系统是用什么做的
  • Linux内核信号传递机制完全解析:从force_sig_info到kick_process的完整路径
  • 佛山新网站建设哪家好建筑方案设计流程步骤
  • 计算机工作原理
  • 北京做网站建设比较好的公司上海网站建设企业名录
  • AEC-Q100 stress实验详解#3——HTSL(高温储存寿命测试)
  • 洋洋点建站wordpress判断是否登录
  • 做的好的农产品网站怎样开通微商城平台
  • Python | 变量如何定义,数据类型介绍
  • 12. 2 雅可比法
  • 【OpenCV + VS】图像通道的均值和方差计算
  • (5)框架搭建:Qt实战项目之主窗体菜单栏
  • 网页C语言在线编译 | 快速、便捷的编程体验
  • 网站免费注册建站培训班
  • WebSpoon9.0(KETTLE的WEB版本)编译 + tomcatdocker部署 + 远程调试教程
  • 万网的网站建设好吗北京模板网站建站
  • Leaflet入门,Leaflet如何修复瓦片之间有白线问题
  • Unity一分钟思路---UI任务条:宝箱位置如何准确卡在百分比位置上
  • 在线做爰a视频网站个人网站搭建详细步骤
  • 网站开发 工作量云台山旅游景区网站建设内容