SpringCloud项目迁移到k8s集群 十八岁 2026-08-01 2026-08-01
SpringCloud项目迁移到k8s集群 一、项目迁移需求分析 现有一个SpringCloud项目需要迁移至Kubernetes,该项目采用Eureka注册中心,并采用前后端分离框架。该项目首页域名为demo.test.com,域名的主路径/转发至项目的前端,路径/receiveapi转发至网关服务,其他服务注册至Eureka,由网关服务进行流量转发。
1.1迁移Eureka集群 1.1.1代码构建及容器化 代码地址:https://gitee.com/liujunweipy/demo-eureka
构建命令:mvn clean package
Java 版本:jdk 1.8
构建镜像:registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3
下载源代码:
1 2 3 4 5 6 7 8 9 # 下载代码 [root@k8s-master01 18-SpringCloud]# git clone https://gitee.com/liujunweipy/demo-eureka.git Cloning into 'demo-eureka'... remote: Enumerating objects: 24, done. remote: Counting objects: 100% (24/24), done. remote: Compressing objects: 100% (15/15), done. remote: Total 24 (delta 6), reused 24 (delta 6), pack-reused 0 (from 0) Receiving objects: 100% (24/24), 6.82 KiB | 2.27 MiB/s, done. Resolving deltas: 100% (6/6), done.
执行构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # 把maven构建所依赖的插件持久化 [root@k8s-master01 18-SpringCloud]# mkdir -p /data/m2 # 运行一个maven临时容器进行代码的构建 # --rm : 自动清理。这意味退出容器后,Docker 会自动删除这个容器实例。这非常适合临时性的任务。 # -v:s 数据卷挂载,将宿主机的目录挂载到容器内,把宿主机`pwd `/demo-eureka目录挂载到容器的/mnt,把宿主机的/data/m2目录挂载到容器的/root/.m2目录。 # bash: 这是容器启动后立即执行的命令。它覆盖了镜像默认的 CMD 或 ENTRYPOINT。 [root@k8s-master01 18-SpringCloud]# docker run -ti --rm -v `pwd`/demo-eureka:/mnt -v /data/m2:/root/.m2 registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3 bash Unable to find image 'registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3' locally 3.5.3: Pulling from k8s-liujunwei/maven cc1a78bfd46b: Pull complete d2c05365ee2a: Pull complete 231cb0e216d3: Pull complete 3d2aa70286b8: Pull complete 276ddd61a47b: Pull complete 2c60f2a0b551: Pull complete 4abbe5585c9b: Pull complete aaeb39f0b473: Pull complete a1ec96bfaf16: Pull complete 16d38ec4eb12: Pull complete ff6759072b35: Pull complete 37a68c3b1fc7: Pull complete Digest: sha256:d5c6b61f886178a925283918ac8984f963d279c9a3fdae813d6fc462fef1899c Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3 root@70830096ac9f:/# # 进入到代码目录执行构建命令 root@70830096ac9f:/# cd /mnt/ root@70830096ac9f:/mnt# mvn clean package Downloading from central: https://repo.maven.apache.org/maven2/com/google/guava/guava/19.0/guava-19.0.jar Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-util/7.0-beta/asm-util-7.0-beta.jar (81 kB at 3.5 kB/s) Downloaded from central: https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6/jdom2-2.0.6.jar (305 kB at 11 kB/s) Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-model/3.3.9/maven-model-3.3.9.jar (164 kB at 5.6 kB/s) Downloaded from central: https://repo.maven.apache.org/maven2/org/vafer/jdependency/2.1.1/jdependency-2.1.1.jar (186 kB at 6.0 kB/s) Downloaded from central: https://repo.maven.apache.org/maven2/com/google/guava/guava/19.0/guava-19.0.jar (2.3 MB at 42 kB/s) [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 23:18 min [INFO] Finished at: 2025-12-14T07:41:21Z [INFO] ------------------------------------------------------------------------
查看构建后的产物:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # 构建完成后会在target目录中产生一个jar包, root@70830096ac9f:/mnt# ls -l total 12 -rw-r--r-- 1 root root 856 Dec 14 06:56 README.en.md -rw-r--r-- 1 root root 945 Dec 14 06:56 README.md -rw-r--r-- 1 root root 2399 Dec 14 06:56 pom.xml drwxr-xr-x 3 root root 18 Dec 14 06:56 src drwxr-xr-x 6 root root 189 Dec 14 07:41 target root@70830096ac9f:/mnt# cd target/ root@70830096ac9f:/mnt/target# ls -l total 46080 drwxr-xr-x 3 root root 86 Dec 14 07:37 classes drwxr-xr-x 3 root root 25 Dec 14 07:37 generated-sources drwxr-xr-x 2 root root 28 Dec 14 07:39 maven-archiver drwxr-xr-x 3 root root 35 Dec 14 07:37 maven-status -rw-r--r-- 1 root root 47179265 Dec 14 07:41 spring-cloud-eureka-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 3964 Dec 14 07:39 spring-cloud-eureka-0.0.1-SNAPSHOT.jar.original # 因为做了目录映射,所以在宿主机的/root/18-SpringCloud/demo-eureka/target也有相同的文件 [root@k8s-master01 target]# ll total 46080 drwxr-xr-x 3 root root 86 Dec 14 15:37 classes drwxr-xr-x 3 root root 25 Dec 14 15:37 generated-sources drwxr-xr-x 2 root root 28 Dec 14 15:39 maven-archiver drwxr-xr-x 3 root root 35 Dec 14 15:37 maven-status -rw-r--r-- 1 root root 47179265 Dec 14 15:41 spring-cloud-eureka-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 3964 Dec 14 15:39 spring-cloud-eureka-0.0.1-SNAPSHOT.jar.original
用spring-cloud-eureka-0.0.1-SNAPSHOT.jar制作镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # 进入项目目录 [root@k8s-master01 18-SpringCloud]# cd demo-eureka/ # 准备Dockerfile [root@k8s-master01 demo-eureka]# cat Dockerfile FROM registry.cn-beijing.aliyuncs.com/k8s-liujunwei/openjdk:8u111-jdk WORKDIR /home/app COPY target/*.jar ./app.jar CMD ["java", "-jar", "app.jar"] # 制作镜像 [root@k8s-master01 demo-eureka]# docker build -t registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-eureka:v0.0.1 . # 查看制作好的镜像 [root@k8s-master01 demo-eureka]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-eureka v0.0.1 f47e60a46b3c About a minute ago 690MB # 推送到我自己的阿里云镜像仓库 [root@k8s-master01 demo-eureka]# docker push registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-eureka:v0.0.1 The push refers to repository [registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-eureka] c8badce1e55f: Pushed 3ae57a88572b: Pushed 35c20f26d188: Mounted from k8s-liujunwei/openjdk c3fe59dd9556: Mounted from k8s-liujunwei/openjdk 6ed1a81ba5b6: Mounted from k8s-liujunwei/openjdk a3483ce177ce: Mounted from k8s-liujunwei/openjdk ce6c8756685b: Mounted from k8s-liujunwei/openjdk 30339f20ced0: Mounted from k8s-liujunwei/openjdk 0eb22bfb707d: Mounted from k8s-liujunwei/openjdk a2ae92ffcd29: Mounted from k8s-liujunwei/openjdk v0.0.1: digest: sha256:aa2efcc1a7676f47b611a4f511abd5e4cb09ace4a1ae8efd9c704477c748843a size: 2419
1.1.2将demo-eureka 部署到k8s 在这个场景下(StatefulSet + Eureka 集群),必须要用 Headless Service。不能用普通 Service。
如果使用普通 Service(即有 ClusterIP 的 Service),Eureka 集群大概率会组建失败,或者数据同步出现严重问题。
为什么 Eureka 必须用Headless?
Eureka Server 之间的数据同步(Replication)是 Peer-to-Peer(点对点) 的,而不是简单的 Client-Server 模式。
如果用了普通 Service:
假设配置的地址是普通的 Service 地址 http://eureka-svc:8761。
Eureka-0 启动了,它想把自己注册给伙伴。
它向 eureka-svc 发送了一个请求:“嘿,我是 Eureka-0,这是我的数据,请同步一下。”
K8s Service (总机) 拦截了这个请求,进行负载均衡 。
灾难发生 :Service 可能会把这个请求转回给 Eureka-0 自己 (因为 Eureka-0 也是 Service 后端的 Pod 之一)。
或者,Service 把请求转给了 Eureka-1。下一次心跳,它又转给了 Eureka-2。
后果 :Eureka-0 认为它只有一个 Peer(就是那个 Service IP),它无法建立稳定的、全网状的(Mesh)连接。集群状态会变得混乱,数据不一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 kind: Service apiVersion: v1 metadata: name: demo-eureka namespace: eureka spec: clusterIP: None ports: - port: 8761 targetPort: 8761 selector: app: demo-eureka --- kind: Service apiVersion: v1 metadata: name: demo-eureka-nodeport namespace: eureka spec: type: NodePort ports: - port: 8761 targetPort: 8761 selector: app: demo-eureka --- kind: StatefulSet apiVersion: apps/v1 metadata: name: demo-eureka namespace: eureka labels: app: demo-eureka spec: replicas: 3 selector: matchLabels: app: demo-eureka serviceName: demo-eureka podManagementPolicy: Parallel template: metadata: labels: app: demo-eureka spec: containers: - name: demo-eureka image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-eureka:v0.0.1 ports: - containerPort: 8761 env: - name: EUREKA_PORT value: "8761" - name: SPRING_PROFILES_ACTIVE value: "k8s" - 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 - name: EUREKA_SERVER_ENABLE_SELF_PRESERVATION value: "false" - name: EUREKA_SERVER_EVICTION_INTERVAL_TIMER_IN_MS value: "500" resources: requests: cpu: 100m memory: 128Mi limits: cpu: 1000m memory: 1Gi imagePullPolicy: Always
部署服务:
1 2 3 4 5 # 将eureka服务部署到独立的命名空间中 [root@k8s-master01 springcloud]# kubectl create ns eureka # 创建服务 [root@k8s-master01 springcloud]# kubectl create -f demo-eureka.StatefulSet.yaml
检查pod状态:
1 2 3 4 5 6 7 8 9 [root@k8s-master01 springcloud]# kubectl get po -n eureka NAME READY STATUS RESTARTS AGE demo-eureka-0 1/1 Running 0 5s demo-eureka-1 1/1 Running 0 5s demo-eureka-2 1/1 Running 0 5s [root@k8s-master01 springcloud]# kubectl get svc -n eureka NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-eureka ClusterIP None <none> 8761/TCP 14s demo-eureka-nodeport NodePort 10.96.117.7 <none> 8761:31183/TCP 14s
浏览器可以通过demo-eureka-nodeport暴露的31183端口进行访问,如下图:
1.2迁移网关服务 1.2.1代码构建及容器化 代码地址:https://gitee.com/liujunweipy/demo-receive
构建命令:mvn clean package
Java 版本:jdk 1.8
构建镜像:registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3
下载源代码:
1 2 3 4 5 6 7 8 9 # 下载代码 [root@k8s-master01 18-SpringCloud]# git clone https://gitee.com/liujunweipy/demo-receive.git Cloning into 'demo-receive'... remote: Enumerating objects: 56, done. remote: Counting objects: 100% (56/56), done. remote: Compressing objects: 100% (36/36), done. remote: Total 56 (delta 9), reused 56 (delta 9), pack-reused 0 (from 0) Receiving objects: 100% (56/56), 9.52 KiB | 1.36 MiB/s, done. Resolving deltas: 100% (9/9), done.
执行构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 把maven构建所依赖的插件持久化 [root@k8s-master01 18-SpringCloud]# mkdir -p /data/m2 # 运行一个maven临时容器进行代码的构建 # --rm : 自动清理。这意味退出容器后,Docker 会自动删除这个容器实例。这非常适合临时性的任务。 # -v:s 数据卷挂载,将宿主机的目录挂载到容器内,把宿主机`pwd `/demo-eureka目录挂载到容器的/mnt,把宿主机的/data/m2目录挂载到容器的/root/.m2目录。 # bash: 这是容器启动后立即执行的命令。它覆盖了镜像默认的 CMD 或 ENTRYPOINT。 [root@k8s-master01 18-SpringCloud]# docker run -ti --rm -v `pwd`/demo-receive:/mnt -v /data/m2/:/root/.m2 registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3 bash root@7ceb1cf6a3da:/# # 进入到代码目录执行构建命令 root@7ceb1cf6a3da:/# cd /mnt/ root@7ceb1cf6a3da:/mnt# ls -l total 4 -rw-r--r-- 1 root root 2170 Dec 15 04:22 pom.xml drwxr-xr-x 3 root root 18 Dec 15 04:22 src # 代码构建 root@70830096ac9f:/mnt# mvn clean package [INFO] --- spring-boot-maven-plugin:2.1.9.RELEASE:repackage (repackage) @ receive --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 42.790 s [INFO] Finished at: 2025-12-15T04:29:04Z [INFO] ------------------------------------------------------------------------
查看构建后的产物:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 构建完成后会在target目录中产生一个jar包, root@7ceb1cf6a3da:/mnt# ls -l total 4 -rw-r--r-- 1 root root 2170 Dec 15 04:22 pom.xml drwxr-xr-x 3 root root 18 Dec 15 04:22 src drwxr-xr-x 6 root root 165 Dec 15 04:29 target root@7ceb1cf6a3da:/mnt# ls -l target/ total 38112 drwxr-xr-x 3 root root 101 Dec 15 04:28 classes drwxr-xr-x 3 root root 25 Dec 15 04:28 generated-sources drwxr-xr-x 2 root root 28 Dec 15 04:29 maven-archiver drwxr-xr-x 3 root root 35 Dec 15 04:28 maven-status -rw-r--r-- 1 root root 39016394 Dec 15 04:29 receive-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 4181 Dec 15 04:29 receive-0.0.1-SNAPSHOT.jar.original # 因为做了目录映射,所以在宿主机的/root/18-SpringCloud/demo-receive/target也有相同的文件 [root@k8s-master01 target]# ll total 38112 drwxr-xr-x 3 root root 101 Dec 15 12:28 classes drwxr-xr-x 3 root root 25 Dec 15 12:28 generated-sources drwxr-xr-x 2 root root 28 Dec 15 12:29 maven-archiver drwxr-xr-x 3 root root 35 Dec 15 12:28 maven-status -rw-r--r-- 1 root root 39016394 Dec 15 12:29 receive-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 4181 Dec 15 12:29 receive-0.0.1-SNAPSHOT.jar.original
用receive-0.0.1-SNAPSHOT.jar制作镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 进入项目目录 [root@k8s-master01 18-SpringCloud]# cd demo-receive/ # 准备Dockerfile [root@k8s-master01 demo-eureka]# cat Dockerfile FROM registry.cn-beijing.aliyuncs.com/k8s-liujunwei/openjdk:8u111-jdk WORKDIR /home/app COPY target/*.jar ./app.jar CMD ["java", "-jar", "app.jar"] # 制作镜像 [root@k8s-master01 demo-receive]# docker build -t registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-receive:v0.0.1 . # 查看制作好的镜像 [root@k8s-master01 demo-receive]# docker images|grep demo-re registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-receive v0.0.1 922d7b988708 38 seconds ago 682MB # 推送到我自己的阿里云镜像仓库 [root@k8s-master01 demo-receive]# docker push registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-receive:v0.0.1
1.2.2将网关服务部署到k8s 准备网关服务的deployment资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [root@k8s-master01 springcloud ] kind: Deployment apiVersion: apps/v1 metadata: name: demo-receive namespace: eureka spec: replicas: 2 selector: matchLabels: app: demo-receive template: metadata: labels: app: demo-receive spec: containers: - name: demo-receive image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-receive:v0.0.1 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "k8s" - name: SERVER_PORT value: "8080" - name: EUREKA_SERVER_URL 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: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m"
准备网关服务的service资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cat demo-receive-svc.yaml kind: Service apiVersion: v1 metadata: name: demo-receive-svc namespace: eureka labels: app: demo-receive-svc spec: type: ClusterIP selector: app: demo-receive ports: - name: http port: 8080 targetPort: 8080
准备网关服务的Ingress:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 cat demo-receive-ingress.yaml kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: demo-receive-ingress namespace: eureka 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-svc port: number: 8080
创建上述资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 创建网关的deployment服务 [root@k8s-master01 springcloud]# kubectl create -f demo-receive.deploy.yaml deployment.apps/demo-receive created # 创建网关的svc服务 [root@k8s-master01 springcloud]# kubectl create -f demo-receive-svc.yaml service/demo-receive-svc created # [root@k8s-master01 springcloud]# kubectl create -f demo-receive-ingress.yaml ingress.networking.k8s.io/demo-receive-ingress created # 查看创建的服务 [root@k8s-master01 springcloud]# kubectl get po -n eureka NAME READY STATUS RESTARTS AGE demo-eureka-0 1/1 Running 0 22h demo-eureka-1 1/1 Running 0 22h demo-eureka-2 1/1 Running 0 22h demo-receive-c98d88558-59tb9 1/1 Running 0 14s demo-receive-c98d88558-flzxn 1/1 Running 0 14s [root@k8s-master01 springcloud]# kubectl get svc -n eureka NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-eureka ClusterIP None <none> 8761/TCP 27m demo-eureka-nodeport NodePort 10.96.12.172 <none> 8761:31335/TCP 27m demo-receive-svc ClusterIP 10.96.105.27 <none> 8080/TCP 105s [root@k8s-master01 springcloud]# kubectl get ingress -n eureka NAME CLASS HOSTS ADDRESS PORTS AGE demo-receive-ingress nginx demo.test.com 192.168.0.84,192.168.0.85,192.168.0.86 80 102s
检查网关服务是否注册到eureka:
1.3迁移其他SpringBoot服务 1.3.1代码构建及容器化 代码地址:https://gitee.com/liujunweipy/demo-handler
构建命令:mvn clean package
Java 版本:jdk 1.8
构建镜像:registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3
下载源代码:
1 2 3 4 5 6 7 8 9 # 下载代码 [root@k8s-master01 18-SpringCloud]# git clone https://gitee.com/liujunweipy/demo-handler.git Cloning into 'demo-handler'... remote: Enumerating objects: 77, done. remote: Counting objects: 100% (77/77), done. remote: Compressing objects: 100% (48/48), done. remote: Total 77 (delta 13), reused 77 (delta 13), pack-reused 0 (from 0) Receiving objects: 100% (77/77), 13.16 KiB | 539.00 KiB/s, done. Resolving deltas: 100% (13/13), done.
执行构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # 把maven构建所依赖的插件持久化 [root@k8s-master01 18-SpringCloud]# mkdir -p /data/m2 # 运行一个maven临时容器进行代码的构建 # --rm : 自动清理。这意味退出容器后,Docker 会自动删除这个容器实例。这非常适合临时性的任务。 # -v:s 数据卷挂载,将宿主机的目录挂载到容器内,把宿主机`pwd `/demo-eureka目录挂载到容器的/mnt,把宿主机的/data/m2目录挂载到容器的/root/.m2目录。 # bash: 这是容器启动后立即执行的命令。它覆盖了镜像默认的 CMD 或 ENTRYPOINT。 [root@k8s-master01 18-SpringCloud]# docker run -ti --rm -v `pwd`/demo-handler:/mnt -v /data/m2/:/root/.m2 registry.cn-beijing.aliyuncs.com/k8s-liujunwei/maven:3.5.3 bash root@41920c905cd7:/# # 进入到代码目录执行构建命令 root@41920c905cd7:/# cd /mnt/ root@41920c905cd7:/mnt# ls -l total 4 -rw-r--r-- 1 root root 2170 Dec 15 10:57 pom.xml drwxr-xr-x 3 root root 18 Dec 15 10:57 src # 代码构建 root@41920c905cd7:/mnt# mvn clean package [INFO] Scanning for projects... [INFO] [INFO] ------------------------< com.handler:handler >------------------------- [INFO] Building handler 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 13.462 s [INFO] Finished at: 2025-12-15T11:06:45Z [INFO] ------------------------------------------------------------------------ root@41920c905cd7:/mnt#
查看构建后的产物:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 构建完成后会在target目录中产生一个jar包, root@41920c905cd7:/mnt# ls -l total 4 -rw-r--r-- 1 root root 2170 Dec 15 10:57 pom.xml drwxr-xr-x 3 root root 18 Dec 15 10:57 src drwxr-xr-x 6 root root 165 Dec 15 11:06 target root@41920c905cd7:/mnt# ls -l target/ total 38112 drwxr-xr-x 3 root root 101 Dec 15 11:06 classes drwxr-xr-x 3 root root 25 Dec 15 11:06 generated-sources -rw-r--r-- 1 root root 39016738 Dec 15 11:06 handler-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 4525 Dec 15 11:06 handler-0.0.1-SNAPSHOT.jar.original drwxr-xr-x 2 root root 28 Dec 15 11:06 maven-archiver drwxr-xr-x 3 root root 35 Dec 15 11:06 maven-status # 因为做了目录映射,所以在宿主机的/root/18-SpringCloud/demo-handler/target也有相同的文件 [root@k8s-master01 18-SpringCloud]# ll demo-handler/target/ total 38112 drwxr-xr-x 3 root root 101 Dec 15 19:06 classes drwxr-xr-x 3 root root 25 Dec 15 19:06 generated-sources -rw-r--r-- 1 root root 39016738 Dec 15 19:06 handler-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 4525 Dec 15 19:06 handler-0.0.1-SNAPSHOT.jar.original drwxr-xr-x 2 root root 28 Dec 15 19:06 maven-archiver drwxr-xr-x 3 root root 35 Dec 15 19:06 maven-status
用handler-0.0.1-SNAPSHOT.jar制作镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # 进入项目目录 [root@k8s-master01 18-SpringCloud]# cd demo-handler/ # 准备Dockerfile [root@k8s-master01 demo-eureka]# cat Dockerfile FROM registry.cn-beijing.aliyuncs.com/k8s-liujunwei/openjdk:8u111-jdk WORKDIR /home/app COPY target/*.jar ./app.jar CMD ["java", "-jar", "app.jar"] # 制作镜像 [root@k8s-master01 demo-receive]# docker build -t registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-handler:v0.0.1 . # 查看制作好的镜像 [root@k8s-master01 demo-handler]# docker images|grep handler registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-handler v0.0.1 d1648160e57f 15 seconds ago 682MB # 推送到我自己的阿里云镜像仓库 [root@k8s-master01 demo-handler]# docker push registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-handler:v0.0.1 The push refers to repository [registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-handler] 6915ab2a13e7: Pushed 3ae57a88572b: Mounted from k8s-liujunwei/demo-receive 35c20f26d188: Mounted from k8s-liujunwei/demo-receive c3fe59dd9556: Mounted from k8s-liujunwei/demo-receive 6ed1a81ba5b6: Mounted from k8s-liujunwei/demo-receive a3483ce177ce: Mounted from k8s-liujunwei/demo-receive ce6c8756685b: Mounted from k8s-liujunwei/demo-receive 30339f20ced0: Mounted from k8s-liujunwei/demo-receive 0eb22bfb707d: Mounted from k8s-liujunwei/demo-receive a2ae92ffcd29: Mounted from k8s-liujunwei/demo-receive v0.0.1: digest: sha256:d425170eec6c660a296d4e2697584f3920e3dbc5b0f042bcbd47f9dbeb39c445 size: 2419
1.3.2将demo-handler部署到k8s 准备deployment资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 kind: Deployment apiVersion: apps/v1 metadata: name: demo-handler namespace: eureka spec: replicas: 2 selector: matchLabels: app: demo-handler template: metadata: labels: app: demo-handler spec: containers: - name: demo-handler image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-handler:v0.0.1 ports: - containerPort: 8080 env: - name: SERVER_PORT value: "8080" - name: SPRING_PROFILES_ACTIVE value: "k8s" - 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: 1000m memory: 1024Mi requests: cpu: 500m memory: 512Mi
创建资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@k8s-master01 springcloud]# kubectl create -f demo-handler-deploy.yaml deployment.apps/demo-handler created # 查看pod状态 [root@k8s-master01 springcloud]# kubectl get po -n eureka NAME READY STATUS RESTARTS AGE demo-eureka-0 1/1 Running 0 5h33m demo-eureka-1 1/1 Running 0 5h33m demo-eureka-2 1/1 Running 0 5h33m demo-handler-579c66cb44-85js2 1/1 Running 0 52s demo-handler-579c66cb44-cldbw 1/1 Running 0 64s demo-receive-54bf5ddb4d-btm25 1/1 Running 0 177m demo-receive-54bf5ddb4d-hjfbq 1/1 Running 0 177m
查看服务是否注册到eureka:
1.4迁移前端服务 1.4.1前端项目构建及容器化 代码地址:https://gitee.com/liujunweipy/demo-ui
构建命令:npm install –registry=https://registry.npmmirror.com && npm run build
Node版本:16.17+
构建镜像:registry.cn-beijing.aliyuncs.com/k8s-liujunwei/node:16.20
下载源代码:
1 2 3 4 5 6 7 8 9 # 下载代码 [root@k8s-master01 18-SpringCloud]# git clone https://gitee.com/liujunweipy/demo-ui.git Cloning into 'demo-ui'... remote: Enumerating objects: 43, done. remote: Counting objects: 100% (43/43), done. remote: Compressing objects: 100% (26/26), done. remote: Total 43 (delta 14), reused 43 (delta 14), pack-reused 0 (from 0) Receiving objects: 100% (43/43), 26.09 KiB | 861.00 KiB/s, done. Resolving deltas: 100% (14/14), done.
执行构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 [root@k8s-master01 18-SpringCloud]# docker run -ti --rm -v `pwd`/demo-ui:/mnt/ registry.cn-beijing.aliyuncs.com/k8s-liujunwei/node:16.20 bash Unable to find image 'registry.cn-beijing.aliyuncs.com/k8s-liujunwei/node:16.20' locally 16.20: Pulling from k8s-liujunwei/node 311da6c465ea: Pull complete ee7d78be1eb9: Pull complete Digest: sha256:c94b82f9827cab6e421b350965a9ef11b25b13ffbd1030536203d541f55dcbe2 Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/k8s-liujunwei/node:16.20 root@8933ee58783b:/# # 进入项目目录 root@8933ee58783b:/# cd /mnt/ root@8933ee58783b:/mnt# ls -l total 96 -rw-r--r-- 1 root root 440 Dec 15 13:45 README.md -rw-r--r-- 1 root root 357 Dec 15 13:45 index.html -rw-r--r-- 1 root root 78659 Dec 15 13:45 package-lock.json -rw-r--r-- 1 root root 335 Dec 15 13:45 package.json drwxr-xr-x 2 root root 22 Dec 15 13:45 public drwxr-xr-x 4 root root 85 Dec 15 13:45 src -rw-r--r-- 1 root root 157 Dec 15 13:45 vite.config.js # 构建前端代码 root@8933ee58783b:/mnt# npm install --registry=https://registry.npmmirror.com npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: '@vitejs/plugin-vue@5.0.4', npm WARN EBADENGINE required: { node: '^18.0.0 || >=20.0.0' }, npm WARN EBADENGINE current: { node: 'v16.20.2', npm: '8.19.4' } npm WARN EBADENGINE } added 54 packages in 7s 10 packages are looking for funding run `npm fund` for details npm notice npm notice New major version of npm available! 8.19.4 -> 11.7.0 npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.7.0 npm notice Run npm install -g npm@11.7.0 to update! npm notice root@8933ee58783b:/mnt# 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 5.02s # 构建完成,查看构建后的产物 root@8933ee58783b:/mnt# ls -l dist/ total 8 drwxr-xr-x 2 root root 57 Dec 15 14:25 assets -rw-r--r-- 1 root root 456 Dec 15 14:25 index.html -rw-r--r-- 1 root root 1497 Dec 15 14:25 vite.svg root@8933ee58783b:/mnt#
构建前端镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 准备一个nginx的配置文件,用来替换镜像中默认的配置文件,使用默认的也可以 [root@k8s-master01 demo-ui]# cat /root/18-SpringCloud/demo-ui/default.conf server { listen 80; listen [::]:80; server_name localhost; gzip on; gzip_types text/plain application/javascript text/css; root /usr/share/nginx/html; index index.html; location / { add_header Cache-Control "no-cache, no-store"; try_files $uri $uri/ /index.html; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 30d; } }
准备Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@k8s-master01 demo-ui]# cat /root/18-SpringCloud/demo-ui/Dockerfile FROM registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine # 1. (可选) 设置时区为上海,方便查看 Nginx 日志时间 RUN apk add --no-cache tzdata && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone # 2. 先删除 Nginx 默认的配置文件,防止冲突 RUN rm -rf /etc/nginx/conf.d/* # 3. 复制你的自定义配置 COPY default.conf /etc/nginx/conf.d/default.conf # 4. 复制构建产物 COPY dist /usr/share/nginx/html # 5. (可选) 这是一个好习惯,显式声明端口,虽然 Nginx 默认就是 80 EXPOSE 80 # 6. (可选) 显式启动命令 CMD ["nginx", "-g", "daemon off;"]
制作前端镜像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [root@k8s-master01 demo-ui]# docker build -t registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui:v0.0.1 . [+] Building 98.4s (11/11) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 734B 0.0s => [internal] load metadata for registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.27-alpine 0.9s ... => [2/5] RUN apk add --no-cache tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone 91.0s => [3/5] RUN rm -rf /etc/nginx/conf.d/* 0.6s => [4/5] COPY default.conf /etc/nginx/conf.d/default.conf 0.1s => [5/5] COPY dist /usr/share/nginx/html => => writing image sha256:863e9465728d1a67e24a72fa11c009702ccc2d4c78a6ed4152222dd74525ae79 0.0s => => naming to registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui:v0.0.1 # 镜像已经制作完毕 [root@k8s-master01 demo-ui]# docker images|grep 'demo-ui' registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui v0.0.1 863e9465728d 6 minutes ago 43.5MB # 将制作好的前端镜像推送到阿里云镜像仓库 [root@k8s-master01 demo-ui]# docker push registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui:v0.0.1 The push refers to repository [registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui] 67ee358a8f38: Pushed 277aadeb1168: Pushed 8831ee1ed178: Pushed 81ad19c3658b: Pushed a51b172d7184: Mounted from k8s-liujunwei/nginx b7486fe26981: Mounted from k8s-liujunwei/nginx 320c8baef084: Mounted from k8s-liujunwei/nginx d2cef4a1b224: Mounted from k8s-liujunwei/nginx 4275164ce225: Mounted from k8s-liujunwei/nginx 6e92270dbfe6: Mounted from k8s-liujunwei/nginx b5d2e1fcf1ad: Mounted from k8s-liujunwei/nginx af9a70194aa4: Mounted from k8s-liujunwei/nginx v0.0.1: digest: sha256:c298d37e2f537fc8b3735f8fd94cb78bd798c91160103e3e1211733851375cd2 size: 2821
检查镜像仓库是否有该镜像:
1.4.2部署前端项目到k8s 准备前端资源文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 cat demo-ui-deploy.yaml kind: Deployment apiVersion: apps/v1 metadata: name: demo-ui namespace: eureka labels: app: demo-ui spec: replicas: 1 selector: matchLabels: app: demo-ui template: metadata: labels: app: demo-ui spec: containers: - name: demo-ui image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/demo-ui:v0.0.1 ports: - containerPort: 80 resources: limits: cpu: 1000m memory: 1Gi requests: cpu: 100m memory: 256Mi --- kind: Service apiVersion: v1 metadata: name: demo-ui namespace: eureka labels: app: demo-ui spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: app: demo-ui --- kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: demo-ui-ingress namespace: eureka spec: ingressClassName: nginx rules: - host: demo.test.com http: paths: - path: / pathType: ImplementationSpecific backend: service: name: demo-ui port: number: 80
创建资源:
1 2 3 4 [root@k8s-master01 springcloud]# kubectl create -f demo-ui-deploy.yaml deployment.apps/demo-ui created service/demo-ui created ingress.networking.k8s.io/demo-ui-ingress created
查看pod运行情况:
1 2 3 4 5 6 7 8 9 10 11 [root@k8s-master01 springcloud]# kubectl get po -n eureka NAME READY STATUS RESTARTS AGE demo-eureka-0 1/1 Running 0 22h demo-eureka-1 1/1 Running 0 22h demo-eureka-2 1/1 Running 0 22h demo-handler-579c66cb44-85js2 1/1 Running 0 16h demo-handler-579c66cb44-hd57s 1/1 Running 0 41s demo-receive-54bf5ddb4d-btm25 1/1 Running 0 19h demo-receive-54bf5ddb4d-wkqxb 1/1 Running 0 52s demo-ui-56f5c5d4db-cz88x 1/1 Running 0 18s demo-ui-56f5c5d4db-vfdsg 1/1 Running 0 117s
浏览器访问测试demo.test.com,测试环境需要添加hosts解析:
到此项目迁移完成!