基于 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 集群" 的全流程。

相关推荐
想不明白的过度思考者21 分钟前
Spring Boot 配置文件深度解析
java·spring boot·后端
yBmZlQzJ7 小时前
财运到内网穿透域名解析技术机制与中立评估
运维·经验分享·docker·容器·1024程序员节
一点晖光7 小时前
jenkins优化记录
运维·jenkins
yBmZlQzJ8 小时前
内网穿透工具通过端口转发实现内外网通信
运维·经验分享·docker·容器·1024程序员节
DeepHacking8 小时前
Overleaf 本地Docker部署
运维·docker·容器
隔壁阿布都8 小时前
使用LangChain4j +Springboot 实现大模型与向量化数据库协同回答
人工智能·spring boot·后端
llilian_169 小时前
总线授时卡 CPCI总线授时卡的工作原理及应用场景介绍 CPCI总线校时卡
运维·单片机·其他·自动化
古城小栈9 小时前
Spring Boot 数据持久化:MyBatis-Plus 分库分表实战指南
spring boot·后端·mybatis
好好生活_9 小时前
【Docker基础学习】从VM虚拟机到Docker
运维·docker
孤岛悬城9 小时前
46 Docker资源管理
docker·容器·云计算