七、SpringCloud 项目迁移至 K8s

发布于:2025-07-04 ⋅ 阅读:(13) ⋅ 点赞:(0)

七、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

web访问

在这里插入图片描述

此博客来源于:https://edu.51cto.com/lecturer/11062970.html