七、SpringCloud 项目迁移至 K8s
文章目录
1、环境准备
1.1 集群规划
主机名称 | 物理IP | 系统 | 资源配置 | 说明 |
---|---|---|---|---|
k8s-master01 | 192.168.200.50 | Rocky9.4 | 2C4C40G | Master节点 |
k8s-node01 | 192.168.200.51 | Rocky9.4 | 2C4C40G | Node01节点 |
k8s-node02 | 192.168.200.52 | Rocky9.4 | 2C4C40G | Node02节点 |
harbor | 192.168.200.53 | Rocky9.4 | 2C4C40G | harbor&docker节点 |
1.2 SpringCloud 项目架构及迁移需求分析
现有一共 SpringCloud 项目需要迁移至K8s,该项目采用 Eureka 注册中心,并采用前后端分离框架。
该项目首页域名为
demo.test.com
,域名的主路径/
转发项目的前端,路径receiveapi
转发至网关服务,其他服务注册至 Eureka ,由网关服务进行流量转发。
2、迁移 Eureka 集群
2.1 构建及容器化
# 下载代码:
[root@habor ~]# git clone https://gitee.com/dukuan/demo-eureka.git
# 创建java缓存目录并挂载进容器里
[root@habor ~]# mkdir -p /data/m2
# 创建容器
[root@habor ~]# docker run --ulimit nofile=65535:65535 -it --rm -v `pwd`/demo-eureka:/mnt/ -v /data/m2/:/root/.m2 crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/maven:3.5.3 bash
# 执行构建:
root@ac8d29c13770:/# cd /mnt/
root@ac8d29c13770:/mnt# ls
README.en.md README.md pom.xml src
root@ac8d29c13770:/mnt# mvn clean package
....
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:49 min
[INFO] Finished at: 2025-06-21T08:07:22Z
[INFO] ------------------------------------------------------------------------
# 构建完成后,查看构建产物:
root@ac8d29c13770:/mnt# ls target/*.jar
target/spring-cloud-eureka-0.0.1-SNAPSHOT.jar
# 编写dockerfile文件
[root@habor ~]# cd demo-eureka/
[root@habor demo-eureka]# vim Dockerfile
[root@habor demo-eureka]# cat Dockerfile
FROM crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/jdk:8u211-jmap
WORKDIR /home/tomcat
COPY target/*.jar ./
CMD java -jar ./*.jar
# 制作镜像
[root@habor demo-eureka]# docker build -t crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-eureka:v1 .
# 推送镜像到镜像仓库
[root@habor demo-eureka]# docker push crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-eureka:v1
2.2 部署至 K8s
# StatefulSet 部署 Eureka 集群
[root@k8s-master01 ~]# vim demo-eureka.yaml
[root@k8s-master01 ~]# cat demo-eureka.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: demo-eureka
name: demo-eureka
annotations:
app: demo-eureka
spec:
replicas: 3
serviceName: demo-eureka
podManagementPolicy: Parallel
selector:
matchLabels:
app: demo-eureka
template:
metadata:
creationTimestamp: null
labels:
app: demo-eureka
annotations:
app: demo-eureka
spec:
containers:
- image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-eureka:v1
name: demo-eureka
ports:
- name: http-web
containerPort: 8761
protocol: TCP
env:
- name: SPRING_PROFILES_ACTIVE
value: k8s
- name: SERVER_PORT
value: '8761'
- name: EUREKA_SERVER_ADDRESS
value: >-
http://demo-eureka-0.demo-eureka:8761/eureka/,http://demo-eureka-1.demo-eureka:8761/eureka/,http://demo-eureka-2.demo-eureka:8761/eureka/
resources:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@k8s-master01 ~]# kubectl create -f demo-eureka.yaml
[root@k8s-master01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
demo-eureka-0 1/1 Running 0 64s
demo-eureka-1 1/1 Running 0 64s
demo-eureka-2 1/1 Running 0 64s
2.3 创建通信Service
# 用于集群通讯的 Service 文件
[root@k8s-master01 ~]# vim demo-eureka-svc.yaml
[root@k8s-master01 ~]# cat demo-eureka-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: demo-eureka
name: demo-eureka
spec:
ports:
- name: http-web
protocol: TCP
port: 8761
targetPort: 8761
clusterIP: None
selector:
app: demo-eureka
type: ClusterIP
# 用于图形界面的 Service 文件
[root@k8s-master01 ~]# vim eureka-svc.yaml
[root@k8s-master01 ~]# cat eureka-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: eureka
name: eureka
spec:
ports:
- name: http-web
protocol: TCP
port: 8761
targetPort: 8761
selector:
app: demo-eureka
type: NodePort
[root@k8s-master01 ~]# kubectl create -f demo-eureka-svc.yaml
[root@k8s-master01 ~]# kubectl create -f eureka-svc.yaml
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-eureka ClusterIP None <none> 8761/TCP 10s
eureka NodePort 10.111.57.249 <none> 8761:31394/TCP 5s
访问 web 界面 (任意节点:31394)
3、迁移网关服务
3.1 构建及容器化
# 下载代码:
[root@habor ~]# git clone https://gitee.com/dukuan/demo-receive.git
# 创建容器
[root@habor ~]# docker run --ulimit nofile=65535:65535 -it --rm -v `pwd`/demo-receive:/mnt/ -v /data/m2/:/root/.m2 crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/maven:3.5.3 bash
# 执行构建:
root@bb5a4bf9745a:/# cd /mnt/
root@bb5a4bf9745a:/mnt# mvn clean package
....
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.845 s
[INFO] Finished at: 2025-06-21T09:55:56Z
[INFO] ------------------------------------------------------------------------
# 构建完成后,查看构建产物:
root@bb5a4bf9745a:/mnt# ls target/*.jar
target/receive-0.0.1-SNAPSHOT.jar
# 编写dockerfile文件
[root@habor demo-receive]# vim Dockerfile
[root@habor demo-receive]# cat Dockerfile
FROM crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/jdk:8u211-jmap
WORKDIR /home/tomcat
COPY target/*.jar ./
CMD java -jar ./*.jar
# 制作镜像
[root@habor demo-receive]# docker build -t crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-receive:v1 .
# 推送镜像到镜像仓库
[root@habor demo-receive]# docker push crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-receive:v1
3.2 部署至 K8s
# 部署文件
[root@k8s-master01 ~]# vim demo-receive.yaml
[root@k8s-master01 ~]# cat demo-receive.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demo-receive
name: demo-receive
annotations:
app: demo-receive
spec:
replicas: 2
selector:
matchLabels:
app: demo-receive
template:
metadata:
creationTimestamp: null
labels:
app: demo-receive
annotations:
app: demo-receive
spec:
containers:
- image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-receive:v1
name: demo-receive
ports:
- name: http-web
containerPort: 8080
protocol: TCP
env:
- name: SPRING_PROFILES_ACTIVE
value: k8s
- name: SERVER_PORT
value: '8080'
- name: EUREKA_SERVER_ADDRESS
value: >-
http://demo-eureka-0.demo-eureka:8761/eureka/,http://demo-eureka-1.demo-eureka:8761/eureka/,http://demo-eureka-2.demo-eureka:8761/eureka/
resources:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
lifecycle: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@k8s-master01 ~]# kubectl create -f demo-receive.yaml
[root@k8s-master01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
....
demo-receive-85dfc76bc-9d9kn 1/1 Running 0 60s
demo-receive-85dfc76bc-hwfgg 1/1 Running 0 60s
3.3 创建Service
# 用于集群通讯的 Service 文件
[root@k8s-master01 ~]# vim demo-receive-svc.yaml
[root@k8s-master01 ~]# cat demo-receive-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: demo-receive
name: demo-receive
spec:
ports:
- name: http-web
protocol: TCP
port: 8080
targetPort: 8080
selector:
app: demo-receive
[root@k8s-master01 ~]# kubectl create -f demo-receive-svc.yaml
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
....
demo-receive ClusterIP 10.99.146.126 <none> 8080/TCP 16s
....
3.4 创建Ingress
[root@k8s-master01 ~]# cat demo-receive-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-receive
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: 'nginx'
rules:
- host: demo.test.com
http:
paths:
- path: /receiveapi(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: demo-receive
port:
number: 8080
[root@k8s-master01 ~]# kubectl create -f demo-receive-ingress.yaml
[root@k8s-master01 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-receive nginx demo.test.com 192.168.200.52 80 17m
4、迁移其他 springboot 服务
4.1 构建及容器化
# 下载代码:
[root@habor ~]# git clone https://gitee.com/dukuan/demo-handler.git
# 创建容器
[root@habor ~]# docker run --ulimit nofile=65535:65535 -it --rm -v `pwd`/demo-handler:/mnt/ -v /data/m2/:/root/.m2 crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/maven:3.5.3 bash
root@aa9aa1f3f326:/# cd /mnt/
root@aa9aa1f3f326:/mnt# ls
pom.xml src
root@aa9aa1f3f326:/mnt# mvn clean package
....
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 21.673 s
[INFO] Finished at: 2025-06-21T14:28:27Z
[INFO] ------------------------------------------------------------------------
# 构建完成后,查看构建产物:
root@aa9aa1f3f326:/mnt# ls target/*.jar
target/handler-0.0.1-SNAPSHOT.jar
# 编写dockerfile文件
[root@habor ~]# cd demo-handler/
[root@habor demo-handler]# vim Dockerfile
[root@habor demo-handler]# cat Dockerfile
FROM crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/jdk:8u211-jmap
WORKDIR /home/tomcat
COPY target/*.jar ./
CMD java -jar ./*.jar
# 制作镜像
[root@habor demo-handler]# docker build -t crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-handler:v1 .
# 推送镜像到镜像仓库
[root@habor demo-handler]# docker push crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-handler:v1
4.2 部署至 K8s
# 部署文件:
[root@k8s-master01 ~]# vim demo-handler.yaml
[root@k8s-master01 ~]# cat demo-handler.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demo-handler
name: demo-handler
annotations:
app: demo-handler
spec:
replicas: 2
selector:
matchLabels:
app: demo-handler
template:
metadata:
creationTimestamp: null
labels:
app: demo-handler
annotations:
app: demo-handler
spec:
containers:
- image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-handler:v1
name: demo-handler
ports:
- name: http-web
containerPort: 8080
protocol: TCP
env:
- name: SPRING_PROFILES_ACTIVE
value: k8s
- name: SERVER_PORT
value: '8080'
- name: EUREKA_SERVER_ADDRESS
value: >-
http://demo-eureka-0.demo-eureka:8761/eureka/,http://demo-eureka-1.demo-eureka:8761/eureka/,http://demo-eureka-2.demo-eureka:8761/eureka/
resources:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
lifecycle: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@k8s-master01 ~]# kubectl create -f demo-handler.yaml
[root@k8s-master01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
....
demo-handler-c975bcc7f-647j4 1/1 Running 0 86s
....
5、迁移前端服务
5.1 构建及容器化
# 下载代码:
[root@habor ~]# git clone https://gitee.com/dukuan/demo-ui.git
# 创建容器
[root@habor ~]# docker run --ulimit nofile=65535:65535 -it --rm -v `pwd`/demo-ui:/mnt/ crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/node:16.17.0-apline-cnpm sh
/ # cd /mnt/
/mnt # ls
Dockerfile index.html public vite.config.js
README.md package.json src
# 执行构建
/mnt # npm install --registry=https://registry.npmmirror.com && npm run build
....
> demo-ui@0.0.0 build
> vite build
vite v5.2.0 building for production...
✓ 58 modules transformed.
dist/index.html 0.46 kB │ gzip: 0.29 kB
dist/assets/index-BYh5Cz0w.css 1.27 kB │ gzip: 0.65 kB
dist/assets/index-BZep8zp5.js 83.61 kB │ gzip: 33.25 kB
✓ built in 2.49s
# 构建完成后,查看构建产物:
/mnt # ls dist/
assets index.html vite.svg
# 编写dockerfile文件
[root@habor ~]# cd demo-ui/
[root@habor demo-ui]# cat Dockerfile
FROM crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/nginx:1.22.1-alpine3.17
COPY dist /usr/share/nginx/html
# 制作镜像
[root@habor demo-ui]# docker build -t crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-ui:v1 .
# 推送镜像到镜像仓库
[root@habor demo-ui]# docker push crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-ui:v1
5.2 部署至 K8s
[root@k8s-master01 ~]# vim demo-ui.yaml
[root@k8s-master01 ~]# cat demo-ui.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demo-ui
name: demo-ui
annotations:
app: demo-ui
spec:
replicas: 1
selector:
matchLabels:
app: demo-ui
template:
metadata:
creationTimestamp: null
labels:
app: demo-ui
annotations:
app: demo-ui
spec:
containers:
- image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/demo-ui:v1
name: demo-ui
ports:
- name: http-web
containerPort: 80
protocol: TCP
resources:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi
lifecycle: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@k8s-master01 ~]# kubectl create -f demo-ui.yaml
[root@k8s-master01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
....
demo-ui-748589dcfb-vnnj5 1/1 Running 0 52s
5.3 创建通信Service
[root@k8s-master01 ~]# vim demo-ui-svc.yaml
[root@k8s-master01 ~]# cat demo-ui-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: demo-ui
name: demo-ui
spec:
ports:
- name: http-web
protocol: TCP
port: 80
targetPort: 80
selector:
app: demo-ui
[root@k8s-master01 ~]# kubectl create -f demo-ui-svc.yaml
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
....
demo-ui ClusterIP 10.98.14.85 <none> 80/TCP 6s
5.4 创建Ingress
[root@k8s-master01 ~]# vim demo-ui-ingress.yaml
[root@k8s-master01 ~]# cat demo-ui-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ui
spec:
ingressClassName: 'nginx'
rules:
- host: demo.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-ui
port:
number: 80
[root@k8s-master01 ~]# kubectl create -f demo-ui-ingress.yaml
[root@k8s-master01 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-receive nginx demo.test.com 192.168.200.52 80 17m
demo-ui nginx demo.test.com 192.168.200.52 80 29m
此博客来源于:https://edu.51cto.com/lecturer/11062970.html