基于 CI/CD(Jenkins)将 Spring Boot 应用自动部署到 Kubernetes 集群

项目背景

随着微服务架构在企业级应用中的广泛普及,Spring Boot 凭借其 "开箱即用、简化配置" 的特性,成为微服务开发的主流框架;同时,Kubernetes(简称 K8s)作为容器编排领域的标准平台,能高效解决容器化应用的部署、扩缩容、服务发现、故障自愈等问题,二者结合已成为微服务落地的核心技术方案。

然而,传统的 Spring Boot 应用部署模式(如手动打包 Jar 包、上传至服务器、手动配置容器、手动部署到 K8s 集群)存在显著痛点:

  1. 手动操作繁琐且易出错:从代码提交到最终部署需经历 "代码编译→单元测试→打包镜像→推送镜像→K8s 资源配置应用" 等多步操作,手动执行不仅效率低,还易因人为疏忽(如配置写错、镜像版本混淆)导致部署失败;
  2. 环境一致性难以保障:开发、测试、生产环境的依赖版本、配置参数若手动维护,易出现 "开发环境能运行,生产环境报错" 的 "环境不一致" 问题;
  3. 迭代效率低,无法适配快速业务需求:当业务迭代频繁(如每日多次版本更新)时,手动部署周期长(通常需数十分钟甚至数小时),难以满足 "快速验证、快速上线" 的业务需求;
  4. 缺乏流程管控与可追溯性:手动部署无统一的流程记录,若出现部署故障,难以快速定位是 "代码问题""构建问题" 还是 "部署配置问题",排查成本高。

为解决上述痛点,需构建一套自动化的 CI/CD(持续集成 / 持续部署)流程,而 Jenkins 作为开源领域最成熟的 CI/CD 工具,具备丰富的插件生态(如 Git 插件、Maven 插件、Docker 插件、Kubernetes 插件),可无缝串联 "代码管理→持续集成→镜像构建→持续部署至 K8s" 的全链路,因此本项目核心目标为:基于 Jenkins 搭建 CI/CD 流水线,实现 Spring Boot 应用从 "代码提交至 Git 仓库" 到 "自动部署至 K8s 集群运行" 的全流程自动化,消除手动操作,保障环境一致性,提升部署效率与稳定性,支撑业务快速迭代

项目核心技术栈及角色:

  • 代码管理:Git(存储 Spring Boot 应用代码及 K8s 资源配置文件);
  • CI/CD 工具:Jenkins(编排流水线,触发代码拉取、Maven 构建、Docker 镜像打包 / 推送、K8s 资源部署);
  • 应用框架:Spring Boot(微服务应用开发框架,提供业务功能);
  • 容器化工具:Docker(将 Spring Boot 应用打包为标准化镜像,保障环境一致性);
  • 容器编排平台:Kubernetes(管理 Docker 镜像的运行,实现应用的高可用、扩缩容、故障自愈)。

一、环境准备(Host1、Host2 与基础服务)

1. Host2:安装 Kubernetes(使用轻量版 k3s

K3s 是轻量级 Kubernetes 发行版,适合测试环境快速部署。

bash 复制代码
[root@host2 ~]# curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn sh -s - \
--system-default-registry "registry.cn-hangzhou.aliyuncs.com"
[INFO]  Finding release for channel stable
[INFO]  Using v1.33.4+k3s1 as release
[INFO]  Downloading hash rancher-mirror.rancher.cn/k3s/v1.33.4-k3s1/sha256sum-amd64.txt
[INFO]  Downloading binary rancher-mirror.rancher.cn/k3s/v1.33.4-k3s1/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Finding available k3s-selinux versions
[WARN]  Failed to get available versions of k3s-selinux..defaulting to k3s-selinux-1.2-2.el9.noarch.rpm
Rancher K3s Common (stable)                                          582  B/s | 1.5 kB     00:02    
上次元数据过期检查:0:00:01 前,执行于 2025年09月30日 星期二 20时38分05秒。
依赖关系解决。
=====================================================================================================
 软件包               架构            版本                  仓库                                大小
=====================================================================================================
安装:
 k3s-selinux          noarch          1.6-1.el9             rancher-k3s-common-stable           22 k

事务概要
=====================================================================================================
安装  1 软件包

总下载:22 k
安装大小:96 k
下载软件包:
k3s-selinux-1.6-1.el9.noarch.rpm                                      24 kB/s |  22 kB     00:00    
-----------------------------------------------------------------------------------------------------
总计                                                                  24 kB/s |  22 kB     00:00     
Rancher K3s Common (stable)                                          2.6 kB/s | 2.4 kB     00:00    
导入 GPG 公钥 0xE257814A:
 Userid: "Rancher (CI) <ci@rancher.com>"
 指纹: C8CF F216 4551 26E9 B9C9 18BE 925E A29A E257 814A
 来自: https://rpm.rancher.io/public.key
导入公钥成功
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                      1/1 
  运行脚本: k3s-selinux-1.6-1.el9.noarch                                                         1/1 
  安装    : k3s-selinux-1.6-1.el9.noarch                                                         1/1 
  运行脚本: k3s-selinux-1.6-1.el9.noarch                                                         1/1 
  验证    : k3s-selinux-1.6-1.el9.noarch                                                         1/1 

已安装:
  k3s-selinux-1.6-1.el9.noarch                                                                       

完毕!
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s
[root@host2 ~]# systemctl status k3s -l
● k3s.service - Lightweight Kubernetes
     Loaded: loaded (/etc/systemd/system/k3s.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-09-30 20:41:31 CST; 1min 33s ago
       Docs: https://k3s.io
    Process: 1997940 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
    Process: 1997948 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
   Main PID: 1997949 (k3s-server)
      Tasks: 142
     Memory: 829.9M (peak: 830.7M)
        CPU: 1min 5.303s
     CGroup: /system.slice/k3s.service
             ├─1997949 "/usr/local/bin/k3s server"
             ├─1999656 "containerd "
             ├─2006198 /var/lib/rancher/k3s/data/9ba85800b7128afafe1105efe9e7a1dac1fbb1c762c61fb2a99>
             ├─2006205 /var/lib/rancher/k3s/data/9ba85800b7128afafe1105efe9e7a1dac1fbb1c762c61fb2a99>
             ├─2006212 /var/lib/rancher/k3s/data/9ba85800b7128afafe1105efe9e7a1dac1fbb1c762c61fb2a99>
             ├─2006217 /var/lib/rancher/k3s/data/9ba85800b7128afafe1105efe9e7a1dac1fbb1c762c61fb2a99>
             └─2006261 /var/lib/rancher/k3s/data/9ba85800b7128afafe1105efe9e7a1dac1fbb1c762c61fb2a99>

9月 30 20:42:37 host2 k3s[1997949]: I0930 20:42:37.913532 1997949 garbagecollector.go:787] "failed t>
9月 30 20:42:39 host2 k3s[1997949]: W0930 20:42:39.698023 1997949 handler_proxy.go:99] no RequestInf>
9月 30 20:42:39 host2 k3s[1997949]: E0930 20:42:39.698264 1997949 controller.go:113] "Unhandled Erro>
9月 30 20:42:39 host2 k3s[1997949]: I0930 20:42:39.699592 1997949 controller.go:126] OpenAPI Aggrega>
9月 30 20:42:39 host2 k3s[1997949]: W0930 20:42:39.699663 1997949 handler_proxy.go:99] no RequestInf>
9月 30 20:42:39 host2 k3s[1997949]: E0930 20:42:39.699709 1997949 controller.go:102] "Unhandled Erro>
9月 30 20:42:39 host2 k3s[1997949]:         loading OpenAPI spec for "v1beta1.metrics.k8s.io" failed>
9月 30 20:42:39 host2 k3s[1997949]:         , Header: map[Content-Type:[text/plain; charset=utf-8] X>
9月 30 20:42:39 host2 k3s[1997949]:  >
9月 30 20:42:39 host2 k3s[1997949]: I0930 20:42:39.701348 1997949 controller.go:109] OpenAPI Aggrega>

[1]+  已停止               systemctl status k3s -l
[root@host2 ~]# kubectl get pods -A
NAMESPACE     NAME                                      READY   STATUS              RESTARTS   AGE
kube-system   coredns-c8fbf7479-q9hsc                   0/1     ContainerCreating   0          98s
kube-system   helm-install-traefik-27njx                0/1     ContainerCreating   0          99s
kube-system   helm-install-traefik-crd-d2k7r            0/1     ContainerCreating   0          99s
kube-system   local-path-provisioner-65c47647b6-kl2z4   0/1     ContainerCreating   0          98s
kube-system   metrics-server-64f5cd9f57-72pfx           0/1     ContainerCreating   0          98s
[root@host2 ~]# cat > /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
docker.io:
endpoint:
- "http://hub-mirror.c.163.com"
- "https://docker.mirrors.ustc.edu.cn"
- "https://registry.docker-cn.com"
EOF
[root@host2 ~]# systemctl restart k3s
bash 复制代码
[root@host2 ~]# kubectl get pods -A
NAMESPACE     NAME                                      READY   STATUS             RESTARTS   AGE
kube-system   coredns-c8fbf7479-q9hsc                   1/1     Running            0          26m
kube-system   helm-install-traefik-27njx                0/1     Completed          2          26m
kube-system   helm-install-traefik-crd-d2k7r            0/1     Completed          0          26m
kube-system   local-path-provisioner-65c47647b6-kl2z4   1/1     Running            0          26m
kube-system   metrics-server-64f5cd9f57-72pfx           0/1     Running            0          26m
kube-system   svclb-traefik-8819915c-9znxb              2/2     Running            0          19m
kube-system   traefik-59465f6f5d-4jpsl                  0/1     ImagePullBackOff   0          2m3s
kube-system   traefik-856869ccc9-f72c7                  1/1     Running            0          2m3s
[root@host2 ~]# sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
[root@host2 ~]# sudo chmod 644 ~/.kube/config

2. Host1:配置 hosts 与重启 Jenkins

bash 复制代码
[root@host1 ~]# sudo vi /etc/hosts
[root@host1 ~]# sudo cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.197.91  k8s.abc.com
[root@host1 ~]# sudo docker restart jenkins
Error response from daemon: No such container: jenkins
[root@host1 ~]# docker ps -a | grep jenkins
[root@host1 ~]# docker images | grep jenkins
[root@host1 ~]# mkdir -p /root/jenkins_data
[root@host1 ~]# chmod 777 /root/jenkins_data
[root@host1 ~]# docker run -d \
  --name jenkins \                                      
  -p 8080:8080 \                                                    
  -p 50000:50000 \                                                           
  -v /root/jenkins_data:/var/jenkins_home \              
  -v /var/run/docker.sock:/var/run/docker.sock \                                     
  -v /usr/bin/docker:/usr/bin/docker \                                                      
  jenkins/jenkins:lts-jdk11
Unable to find image 'jenkins/jenkins:lts-jdk11' locally
lts-jdk11: Pulling from jenkins/jenkins
cdd62bf39133: Pull complete 
21f106ffc421: Pull complete 
39df2c5808cf: Pull complete 
d9d5ad5daae2: Pull complete 
21d9152ebad0: Pull complete 
ddc06df74615: Pull complete 
bf388b3d4868: Pull complete 
1f6fc1ff002b: Pull complete 
6201e887d163: Pull complete 
a3d60a50862f: Pull complete 
282c783b8e01: Pull complete 
ddf03cc24103: Pull complete 
Digest: sha256:6aa6c6bd7da914bf5333305c8102cb26965ea4b227e37f4269315725a2b0cd81
Status: Downloaded newer image for jenkins/jenkins:lts-jdk11
5ef61c95f7c6352d28edd517fad6f5d15af66de7a6c3bb730b8005b0228103ad
docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint jenkins (3d819d291479573b7ac27597faef4e78a66782a1b52fd11d1bf6af0d684e3d44): Bind for 0.0.0.0:8080 failed: port is already allocated

Run 'docker run --help' for more information
[root@host1 ~]# docker ps | grep jenkins
[root@host1 ~]# docker ps | grep jenkins
[root@host1 ~]# ss -ltnp | grep 8080
LISTEN 0      4096         0.0.0.0:8080       0.0.0.0:*    users:(("docker-proxy",pid=3363,fd=7))
LISTEN 0      4096            [::]:8080          [::]:*    users:(("docker-proxy",pid=3370,fd=7))
[root@host1 ~]# docker rm jenkins 2>/dev/null || true
jenkins
[root@host1 ~]# docker run -d \
  --name jenkins \
  -p 8081:8080 \                          
  -p 50000:50000 \
  -v /root/jenkins_data:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  jenkins/jenkins:lts-jdk11
bd2ece777c615e3b37ea0ba09bca445d1f4439ac2ea6feda4882ad0ee85ae474
[root@host1 ~]# docker ps | grep jenkins
bd2ece777c61   jenkins/jenkins:lts-jdk11   "/usr/bin/tini -- /u..."   18 seconds ago   Up 17 seconds          0.0.0.0:50000->50000/tcp, [::]:50000->50000/tcp, 0.0.0.0:8081->8080/tcp, [::]:8081->8080/tcp  
 jenkins
[root@host1 ~]# docker logs jenkins 2>&1 | grep "Initial password"
[root@host1 ~]# /var/jenkins_home/secrets/initialAdminPassword
-bash: /var/jenkins_home/secrets/initialAdminPassword: 没有那个文件或目录
[root@host1 ~]# cat /root/jenkins_data/secrets/initialAdminPassword
c6353040c7a9461e854c3c77aa0cb70d
[root@host1 ~]# 

3. 搭建私有 Docker 镜像仓库(可选,若需本地存储镜像)

二、Jenkins 配置(在 Host1 的 Jenkins 页面操作)

1. 安装必要插件

  • 进入 Jenkins → Manage JenkinsManage PluginsAvailable
  • 搜索并安装:Maven Integration(Maven 项目支持)、Publish Over SSH(SSH 远程部署)。

2. 配置 Maven

  • 进入 Jenkins → Manage JenkinsGlobal Tool Configuration
  • 找到 Maven 区域,点击 Add Maven ,命名为 Maven,选择 "Install automatically" 或指定本地 Maven 路径。

3. 配置 Publish Over SSH(远程部署到 Host2)

  • 进入 Jenkins → Manage JenkinsConfigure System
  • 找到 Publish over SSH 区域,点击 Add SSH Server ,配置如下:
    • NameK8SHost(与 Jenkinsfile 中 configName 对应)。
    • Hostname192.168.197.91(Host2 的 IP)。
    • Usernameroot(Host2 的登录用户)。
    • 点击 Advanced ,勾选 Use password authentication, or use a different key ,在 Passphrase/Password 中输入 Host2 的 root 密码。
    • 点击 Test Configuration ,显示 Success 则配置正确。

(自行操作,之前博客配置过)

三、准备 Spring Boot 项目与 CI/CD 配置

1. 初始化 Git 仓库(以本地 Git 为例,也可使用 GitLab/GitHub)

bash 复制代码
[root@host1 ~]# mkdir ~/k8s-demo && cd ~/k8s-demo
[root@host1 k8s-demo]# git init
bash: git: 未找到命令...
安装软件包"git-core"以提供命令"git"? [N/y] y


 * 正在队列中等待... 
 * 正在载入软件包列表。... 
下列软件包必须安装:
 git-core-2.47.3-1.el9.x86_64Core package of git with minimal functionality
继续更改? [N/y] y


 * 正在队列中等待... 
 * 正在等待认证... 
 * 正在队列中等待... 
 * 正在下载软件包... 
 * 正在请求数据... 
 * 正在测试更改... 
 * 正在安装软件包... 
提示: 使用 'master' 作为初始分支的名称。这个默认分支名称可能会更改。要在新仓库中
提示: 配置使用初始分支名,并消除这条警告,请执行:
提示:
提示: git config --global init.defaultBranch <名称>
提示:
提示: 除了 'master' 之外,通常选定的名字有 'main'、'trunk' 和 'development'。
提示: 可以通过以下命令重命名刚创建的分支:
提示:
提示: git branch -m <name>
已初始化空的 Git 仓库于 /root/k8s-demo/.git/

[root@host1 k8s-demo]# 

2. 添加项目文件

~/k8s-demo 目录下,创建以下文件:

(1)Dockerfile(构建 Spring Boot 镜像)

bash 复制代码
[root@host1 k8s-demo]# vi Dockerfile
[root@host1 k8s-demo]# cat Dockerfile
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/spring-boot-hello-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

(2)pom.xml(Maven 项目配置)

bash 复制代码
[root@host1 k8s-demo]# vi pom.xml
[root@host1 k8s-demo]# cat pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.abc</groupId>
  <artifactId>spring-boot-hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
    <relativePath/>
  </parent>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

(3)src/main/java/com/abc/hello/HelloController.java(Spring Boot 源码)

bash 复制代码
[root@host1 k8s-demo]# vi src/main/java/com/abc/hello/HelloController.java

[1]+  已停止               vi src/main/java/com/abc/hello/HelloController.java
[root@host1 k8s-demo]# mkdir -p src/main/java/com/abc/hello/
[root@host1 k8s-demo]# chmod -R u+w src/
[root@host1 k8s-demo]# vi src/main/java/com/abc/hello/HelloController.java
[root@host1 k8s-demo]# cat src/main/java/com/abc/hello/HelloController.java
package com.abc.hello;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello! Please test K8S CI/CD!\n";
    }
}
[ro

(4)kube.yaml(Kubernetes 资源配置:Deployment + Service)

bash 复制代码
[root@host1 k8s-demo]# vi kube.yaml
[root@host1 k8s-demo]# cat kube.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sbdemo-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-hello
  template:
    metadata:
      labels:
        app: spring-boot-hello
    spec:
      containers:
      - name: spring-boot-hello
        image: registry.abc.com:5000/spring-boot-hello
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: sbdemo-svc
spec:
  type: NodePort
  selector:
    app: spring-boot-hello
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30008

(5)Jenkinsfile(流水线配置:构建 + 推送镜像 + 远程部署)

bash 复制代码
[root@host1 k8s-demo]# vi Jenkinsfile
[root@host1 k8s-demo]# cat Jenkinsfile
pipeline {
    agent any
    tools {
        maven 'Maven'  // 对应 Jenkins 中配置的 Maven 名称
    }
    stages {
        stage('Build') {
            steps {
                // 1. Maven 打包
                sh 'mvn -B -DskipTests clean package'
                // 2. 构建 Docker 镜像
                sh 'docker build -t registry.abc.com:5000/spring-boot-hello .'
                // 3. 推送镜像到私有仓库
                sh 'docker push registry.abc.com:5000/spring-boot-hello'
            }
        }
        stage('Deploy') {
            steps {
                // 通过 SSH 向 Host2 传输 kube.yaml 并执行部署命令
                sshPublisher(publishers: [
                    sshPublisherDesc(
                        configName: 'K8SHost',  // 对应 Publish Over SSH 中配置的名称
                        transfers: [
                            sshTransfer(
                                cleanRemote: false,
                                excludes: '',
                                execCommand: 'cd /root/spring-boot-hello && kubectl delete -f kube.yaml || true && kubectl apply -f kube.yaml',
                                execTimeout: 120000,
                                flatten: false,
                                makeEmptyDirs: false,
                                noDefaultExcludes: false,
                                patternSeparator: '[, ]+',
                                remoteDirectory: '/root/spring-boot-hello',
                                remoteDirectorySDF: false,
                                removePrefix: '',
                                sourceFiles: '**/kube.yaml'
                            )
                        ],
                        usePromotionTimestamp: false,
                        useWorkspaceInPromotion: false,
                        verbose: false
                    )
                ])
            }
        }
    }
}

3. 提交代码到 Git 仓库

bash 复制代码
[root@host1 k8s-demo]# git add .
[root@host1 k8s-demo]# git commit -m "Init K8S CI/CD demo"
作者身份未知

*** 请告诉我您是谁。

运行

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

来设置您账号的缺省身份标识。
如果仅在本仓库设置身份标识,则省略 --global 参数。

致命错误:无法自动探测邮件地址(得到 'root@host1.(none)')
[root@host1 k8s-demo]# git config --global user.name "root"
[root@host1 k8s-demo]# git config --global user.email "2243678135@qq.com"
[root@host1 k8s-demo]# git commit -m "Init K8S CI/CD demo"
[master(根提交) 1390477] Init K8S CI/CD demo
 5 files changed, 122 insertions(+)
 create mode 100644 Dockerfile
 create mode 100644 Jenkinsfile
 create mode 100644 kube.yaml
 create mode 100644 pom.xml
 create mode 100644 src/main/java/com/abc/hello/HelloController.java

四、Jenkins 流水线项目创建与执行

  1. 进入 Jenkins → 新建任务 → 选择 流水线 → 命名为 k8s-demo确定
  2. 流水线 配置区域,选择 从 SCM ,SCM 选择 Git,填写仓库 URL (即上一步的 Git 仓库地址),分支指定main
  3. 点击 保存 ,然后点击 立即构建,触发流水线。

五、验证部署结果(在 Host2 上执行)

1. 查看 Kubernetes 资源

bash 复制代码
# 查看 Pod(需显示 Running)
[root@host2 ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
my-app-pod-7b5d9f8d46-xxxx   1/1     Running   0          2m

# 查看 Deployment(需显示 AVAILABLE 1/1)
[root@host2 ~]# kubectl get deploy
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
my-app-deploy   1/1     1            1           3m

# 查看 Service(需显示 NodePort 为 30008)
[root@host2 ~]# kubectl get svc
NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
my-app-svc   NodePort   10.96.xxx.xxx   <none>        8080:30008/TCP   4m

2. 访问 Spring Boot 应用

bash 复制代码
[root@host2 ~]# curl http://localhost:30008
Hello! Please test K8S CI/CD!

关键注意事项

  • 私有仓库访问 :确保 Host2 的 Docker 已配置 insecure-registries,能拉取私有仓库镜像。
  • SSH 权限 :Host1 通过 Jenkins 的 Publish Over SSH 能免密(或密码)登录 Host2 的 root 用户。
  • K8S 网络:NodePort 服务需确保端口(如 30008)未被占用,且防火墙允许访问。

按上述步骤执行后,即可完成 "Spring Boot 应用通过 Jenkins 自动部署到 Kubernetes 集群" 的全流程。

相关推荐
咖啡Beans2 小时前
SseEmitter + WebClient + Flux实现SSE事件流推送
java·spring boot·flux
小丁爱养花4 小时前
接口自动化测试 - pytest [1]
python·自动化·pytest
Lin_Aries_04214 小时前
在 Kubernetes 集群中运行并发布应用程序
运维·nginx·docker·云原生·容器·kubernetes·自动化
2501_920047034 小时前
k8s-pod的镜像升级与回滚
云原生·容器·kubernetes
zhangxuyu11185 小时前
全栈工程师项目练习记录
java·spring boot
码路工人5 小时前
第10章:K8s 数据持久化
docker·云原生·容器
richxu202510015 小时前
Java开发环境搭建之 9.使用Docker Compose 安装部署RabbitMQ
java·docker·java-rabbitmq
Achou.Wang6 小时前
Kubernetes 的本质:一个以 API 为中心的“元操作系统”
java·容器·kubernetes
麦兜*6 小时前
Redis多租户资源隔离方案:基于ACL的权限控制与管理
java·javascript·spring boot·redis·python·spring·缓存