当前位置: 首页 > news >正文

基于 CI/CD 平台将应用程序自动部署到 Kubernetes 集群

序:核心背景与需求

在现代软件开发与运维体系中,基于 CI/CD 平台将应用程序自动部署到 Kubernetes 集群的项目,源于以下核心背景与需求:

1. 技术与行业趋势驱动

  • 容器化普及:Docker 等容器技术实现了应用与运行环境的 “封装一致”,解决了 “开发环境能跑,生产环境报错” 的历史难题,成为应用交付的标准载体。
  • Kubernetes 主导编排:随着应用向分布式、微服务架构演进,Kubernetes 凭借对容器的自动化编排能力(部署、扩缩容、自愈等),成为大规模容器化应用的 “标配管理平台”。
  • CI/CD 需求升级:市场对软件迭代速度、交付稳定性的要求急剧提升,传统 “手动编译→打包→上传→部署” 的流程效率低下、易出错,必须通过 ** 持续集成(CI,代码提交后自动编译、测试)持续部署(CD,测试通过后自动发布到生产环境)** 实现全链路自动化。

2. 企业面临的核心痛点

  • 环境一致性问题:开发、测试、生产环境的依赖、配置差异,导致应用部署后行为不一致,排查成本高。
  • 手动运维效率低下:应用容器化后,若仍依赖人工操作部署到 Kubernetes,在集群规模扩大(如百级、千级容器)时,运维成本呈指数级增长,且无法保障部署时效性与准确性。
  • 迭代周期长:从代码开发到用户可用的链路冗长,需经历 “提交→等待人工编译→等待人工测试→等待人工部署” 等环节,难以快速响应业务需求。

3. 项目核心目标

通过搭建 CI/CD 自动化流水线,实现从 “代码提交” 到 “Kubernetes 集群部署” 的全流程自动化:

  • 开发者提交代码后,自动触发编译、单元测试、镜像构建
  • 镜像自动推送到私有镜像仓库(如内网 Registry);
  • 最终自动将应用部署到 Kubernetes 集群,并完成服务暴露、健康检查等运维配置,实现 “代码提交即部署,快速验证且稳定交付”。

4. 技术栈协同逻辑

项目需整合多类技术形成闭环:

  • 版本控制(Git):作为代码仓库,触发 CI/CD 流程的 “源头”;
  • CI/CD 平台(Jenkins/GitLab CI 等):作为 “中枢”,编排 “编译→测试→镜像构建→部署” 的自动化步骤;
  • 容器化(Docker):封装应用与依赖,生成标准镜像;
  • 私有镜像仓库:存储构建好的镜像,供 Kubernetes 拉取;
  • Kubernetes:作为 “运行时平台”,负责应用容器的调度、扩缩容与高可用管理。

简言之,该项目是容器化、编排技术与自动化交付流程的结合,旨在解决传统部署的效率与稳定性问题,支撑企业快速迭代、规模化运维的需求。

一、基础环境配置(所有节点)

        1. 域名解析(/etc/hosts

        在涉及的主机(如 Jenkins 主机 host1、K8s 节点 host2、GitLab 服务器)上配置内网域名解析,方便服务间访问:

[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 registry.abc.com
192.168.197.9 jenkins-host    # Jenkins 所在主机 IP
192.168.197.9 gitlab.abc.com  # GitLab 服务器 IP
192.168.197.91 k8s.abc.com     # K8s 集群节点(host2)IP

        2. Docker 配置国内镜像源(加速镜像拉取)

        在 host1(Jenkins 主机,需构建 Docker 镜像)和 host2(K8s 节点,需拉取镜像)上,修改 Docker 守护进程配置:

[root@host1 ~]# vi /etc/docker/daemon.json
[root@host1 ~]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://9fbd5949cbc94e4a9581e33b9077c811.mirror.swr.myhuaweicloud.com","https://jnh8ca4k.mirror.aliyuncs.com","https://mirror.ccs.tencentyun.com","https://registry.docker-cn.com"],"insecure-registries": ["192.168.197.9:5000","registry.abc.com:5000"],"live-restore": true
}
[root@host1 ~]# sudo systemctl daemon-reload
[root@host1 ~]# sudo systemctl restart docker

        host2 上同步操作:

[root@host2 ~]# sudo vi /etc/hosts
[root@host2 ~]# 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 registry.abc.com
192.168.197.9 jenkins-host    # Jenkins 所在主机 IP
192.168.197.9 gitlab.abc.com  # GitLab 服务器 IP
192.168.197.91 k8s.abc.com     # K8s 集群节点(host2)IP
[root@host2 ~]# sudo vi /etc/docker/daemon.json
[root@host2 ~]# sudo cat /etc/docker/daemon.json
{"registry-mirrors": ["https://9fbd5949cbc94e4a9581e33b9077c811.mirror.swr.myhuaweicloud.com","https://jnh8ca4k.mirror.aliyuncs.com","https://mirror.ccs.tencentyun.com","https://registry.docker-cn.com"],"insecure-registries": ["192.168.197.9:5000","registry.abc.com:5000"],"live-restore": true
}
[root@host2 ~]# sudo systemctl daemon-reload
[root@host2 ~]# sudo systemctl restart docker
[root@host2 ~]# sudo docker run -d --restart=always -p 5000:5000 --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
44cf07d57ee4: Pull complete 
bbbdd6c6894b: Pull complete 
8e82f80af0de: Pull complete 
3493bf46cdec: Pull complete 
6d464ea18732: Pull complete 
Digest: sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373
Status: Downloaded newer image for registry:2
27101e645df048203dba9a00fb36f55a84328dd6d2297af327c091be15702dc0
[root@host2 ~]# sudo firewall-cmd --add-port=5000/tcp --permanent
FirewallD is not running
[root@host2 ~]# curl http://registry.abc.com:5000/v2/
{}

二、GitLab 代码仓库准备

        1. 创建项目(之前有跳过)

        在 GitLab 中创建名为 k8s-demo 的空白项目(若无 GitLab,可临时用本地仓库,生产建议用 GitLab/Gitee)。

[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]# git init
已重新初始化已存在的 Git 仓库于 /root/k8s-demo/.git/
[root@host1 k8s-demo]# touch spring-boot-hello.yaml

        2. 本地初始化代码(host1 操作)

        克隆仓库并添加项目文件:

# 切换到项目目录(如 ~/ch08)
cd ~/ch08
# 克隆 GitLab 仓库(替换为实际 GitLab 地址)
git clone ssh://git@gitlab.abc.com:2222/root/k8s-demo.git
cd k8s-demo

        3. 添加核心文件

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

FROM openjdk:11-jre-slim  # 基于国内镜像源加速拉取的 OpenJDK 镜像
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

(2)pom.xml(Maven 构建配置)

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.5</version><relativePath/></parent><groupId>com.abc</groupId><artifactId>spring-boot-hello</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-hello</name><properties><java.version>11</java.version></properties><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 控制器)

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!";}
}

(4)src/main/java/com/abc/hello/SpringBootHelloApplication.java(启动类)

package com.abc.hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootHelloApplication {public static void main(String[] args) {SpringApplication.run(SpringBootHelloApplication.class, args);}
}

(5)kube.yaml(Kubernetes 资源配置)

apiVersion: apps/v1
kind: Deployment
metadata:name: sbdemo-deploy
spec:replicas: 1selector:matchLabels:app: spring-boot-hellotemplate:metadata:labels:app: spring-boot-hellospec:containers:- name: spring-boot-helloimage: registry.abc.com:5000/spring-boot-hello  # 内网私有仓库地址ports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:name: sbdemo-svc
spec:type: NodePortselector:app: spring-boot-helloports:- port: 8080targetPort: 8080nodePort: 30008  # 暴露到主机的端口(30000-32767 区间)

(6)Jenkinsfile(Jenkins 流水线脚本)

pipeline {agent anystages {stage('Build') {steps {// Maven 构建(跳过测试加速)sh 'mvn -B -DskipTests clean package'// 构建 Docker 镜像(关联 Maven 打包的 JAR)sh 'docker build --build-arg JAR_FILE=target/spring-boot-hello-0.0.1-SNAPSHOT.jar -t registry.abc.com:5000/spring-boot-hello .'// 推送镜像到内网私有仓库sh 'docker push registry.abc.com:5000/spring-boot-hello'}}stage('Deploy') {steps {// 通过 SSH 传输配置文件并部署到 K8s 集群sshPublisher(publishers: [sshPublisherDesc(configName: 'K8SHost',  // Jenkins 中配置的 SSH 服务器名transfers: [sshTransfer(cleanRemote: false,excludes: '',execCommand: 'cd ~/spring-boot-hello && kubectl delete -f kube.yaml || true && kubectl apply -f kube.yaml',execTimeout: 120000,flatten: false,makeEmptyDirs: false,noDefaultExcludes: false,patternSeparator: '[, ]+',remoteDirectory: 'spring-boot-hello',remoteDirectorySDF: false,removePrefix: '',sourceFiles: '**/kube.yaml')],usePromotionTimestamp: false,useWorkspaceInPromotion: false,verbose: false)])}}}
}

三、Jenkins 配置

        1. 安装必要插件

        进入 Jenkins → Manage Jenkins → Manage Plugins,安装:

  • Maven Integration(Maven 项目支持)
  • Publish Over SSH(SSH 远程部署支持)

        2. 系统配置(Manage Jenkins → Configure System

(1)Maven 配置

  • 找到 Maven 区域,点击 “Add Maven”,命名为 Maven-3.8.6(可选择 “Install automatically” 或指定本地 Maven 路径)。

(2)Publish Over SSH 配置

  • 找到 Publish Over SSH 区域,点击 “Add → SSH Server”:
    • NameK8SHost(与 Jenkinsfile 中 configName 一致)。
    • Hostnamek8s.abc.com(K8s 节点 host2 的主机名 / IP)。
    • Usernameroot(或 K8s 节点上有权限的用户)。
    • 点击 “Advanced”,勾选 “Use password authentication, or use a different key”,填写 K8s 节点的 SSH 密码
    • Remote Directory~(或指定部署目录,如 /root)。
    • 点击 “Test Configuration”,显示 Success 则配置正常。

四、推送代码到 GitLab

        将所有文件提交并推送到 GitLab 仓库:

cd ~/ch08/k8s-demo
git add .
git commit -m "Init K8s CI/CD project with domestic mirrors"
git push origin main

五、Jenkins 创建流水线项目

        1. 新建任务

  • 进入 Jenkins → New Item,选择 “Pipeline”,命名为 k8s-demo → 点击 “OK”。

        2. 配置流水线

  • Pipeline → Definition:选择 Pipeline script from SCM
  • SCM:选择 Git
  • Repository URL:填写 GitLab 仓库地址(如 ssh://git@gitlab.abc.com:2222/root/k8s-demo.git)。
  • Branch Specifier*/main(或 */master,根据仓库分支名调整)。
  • Script PathJenkinsfile(与项目中文件名一致)。

        3. 执行构建

点击 “Save” 保存配置,然后点击 “Build Now” 启动流水线。

六、验证部署(K8s 节点 host2 操作)

        1. 查看 Kubernetes 资源

kubectl get deployments  # 应看到 sbdemo-deploy(READY 1/1)
kubectl get pods         # 应看到 sbdemo-deploy-xxx(STATUS Running)
kubectl get services     # 应看到 sbdemo-svc(TYPE NodePort,PORT(S) 8080:30008/TCP)

        2. 访问服务

curl 127.0.0.1:30008
# 预期输出:Hello! Please test K8S CI/CD!

关键说明

  • 国内镜像源:通过 daemon.json 的 registry-mirrors 加速 OpenJDK、Maven 等基础镜像的拉取,避免依赖 Docker Hub 外网速度。

  • 私有仓库registry.abc.com:5000 需确保是 HTTP 服务,且 Docker 配置了 insecure-registries,否则镜像推送 / 拉取会失败。

  • SSH 部署:Jenkins 需能通过 SSH 免密(或密码)登录 K8s 节点,并具备 kubectl 操作权限。

  • 动态调整:需根据实际环境修改域名、IP、仓库地址、K8s 资源配置(如 NodePort 端口、镜像名)。

通过以上步骤,即可实现基于国内镜像源的从代码提交到 Kubernetes 部署的全流程自动化 CI/CD。

代码部分过程:

Activate the web console with: systemctl enable --now cockpit.socketLast login: Mon Sep 29 17:54:00 2025 from 192.168.197.1
[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 registry.abc.com
192.168.197.9 jenkins-host    # Jenkins 所在主机 IP
192.168.197.9 gitlab.abc.com  # GitLab 服务器 IP
192.168.197.91 k8s.abc.com     # K8s 集群节点(host2)IP
[root@host1 ~]# vi /etc/docker/daemon.json
[root@host1 ~]# cat /etc/docker/daemon.json
{"registry-mirrors": ["https://9fbd5949cbc94e4a9581e33b9077c811.mirror.swr.myhuaweicloud.com","https://jnh8ca4k.mirror.aliyuncs.com","https://mirror.ccs.tencentyun.com","https://registry.docker-cn.com"],"insecure-registries": ["192.168.197.9:5000","registry.abc.com:5000"],"live-restore": true
}
[root@host1 ~]# sudo systemctl daemon-reload
[root@host1 ~]# sudo systemctl restart docker
[root@host1 ~]# cd ~/ch08
[root@host1 ch08]# cd
[root@host1 ~]# 
[root@host1 ~]# 
[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]# git init
已重新初始化已存在的 Git 仓库于 /root/k8s-demo/.git/
[root@host1 k8s-demo]# touch spring-boot-hello.yaml
[root@host1 k8s-demo]# git add .
[root@host1 k8s-demo]# git commit -m "Initial commit"
作者身份未知*** 请告诉我您是谁。运行git config --global user.email "you@example.com"git config --global user.name "Your Name"来设置您账号的缺省身份标识。
如果仅在本仓库设置身份标识,则省略 --global 参数。致命错误:无法自动探测邮件地址(得到 'root@host1.(none)')
[root@host1 k8s-demo]# 
[root@host1 k8s-demo]# 
[root@host1 k8s-demo]# cd ~/ch08
[root@host1 ch08]# git clone ssh://git@192.168.197.9.com:2222/root/k8s-demo.git
正克隆到 'k8s-demo'...
ssh: Could not resolve hostname 192.168.197.9.com: Name or service not known
致命错误:无法读取远程仓库。请确认您有正确的访问权限并且仓库存在。
[root@host1 ch08]# 
[root@host1 ch08]# cd
[root@host1 ~]# git config --global user.name "root"
[root@host1 ~]# git config --global user.email "root@host1.local"
[root@host1 ~]# git config --list | grep user
user.name=root
user.email=root@host1.local
[root@host1 ~]# cd ~/k8s-demo
[root@host1 k8s-demo]# git add .  
[root@host1 k8s-demo]# git commit -m "Initial commit: Add spring-boot-hello.yaml" 
[master(根提交) 00e64fa] Initial commit: Add spring-boot-hello.yaml1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 spring-boot-hello.yaml
[root@host1 k8s-demo]# 

http://www.dtcms.com/a/426594.html

相关文章:

  • QT示例 使用QTcpSocket和QTcpServer类实现TCP的自定义消息头、消息体通信示例
  • YDWE编辑器系列教程一:编辑器界面
  • 外贸网站怎么找客户名城建设有限公司网站
  • Linux 系统基础配置:主机名、IP、主机映射、防火墙
  • AI 重构实体经济:2025 传统产业的智能转型革命
  • 【金仓数据库产品体验官】KingbaseES-Oracle兼容性体验
  • 初探 ansible 部署 devops 持续集成持续交付
  • 【VBA】点击按钮,实现将Excel表A数据按格式填入表B
  • 微硕WST8205A双N沟MOSFET,汽车阅读灯静音负载开关
  • LabVIEW与PLC 汽车驻车制动自动调整
  • 【办公类-115-01】20250920职称资料上传01——多个jpg转同名PDF(如:荣誉证书)并自动生成单一文件夹
  • 基于Kafka+ElasticSearch+MongoDB+Redis+XXL-Job日志分析系统(学习)
  • 【龙泽科技】智能网联汽车智能传感器测试装调仿真教学软件
  • JAVA:Spring Boot 集成 BouncyCastle 实现加密算法
  • 石家庄住房和城乡建设局官方网站app模板下载网站
  • gRPC从0到1系列【9】
  • IDEA 2024 中创建 Maven 项目的详细步骤
  • 2025 AI 图景:从工具革命到生态重构的五大趋势
  • 网站开发者模式下载视频wordpress如何添加备案号
  • UNIX下C语言编程与实践22-UNIX 文件其他属性获取:stat 结构与 localtime 函数的使用
  • UNIX下C语言编程与实践15-UNIX 文件系统三级结构:目录、i 节点、数据块的协同工作机制
  • 青浦做网站的公司网站开发语言html5 php
  • 【分布式中间件】RabbitMQ 功能详解与高可靠实现指南
  • SOME/IP-SD报文结构和交互详解
  • 给贾维斯加“手势控制”:从原理到落地,打造多模态交互的本地智能助
  • 电商数据分析优化清理大师
  • 论文阅读:《Self-Supervised Continual Graph Learning in Adaptive Riemannian Spaces》
  • Qt事件处理全解析
  • 深入理解 LLM 分词器:BPE、WordPiece 与 Unigram
  • 【大模型评估】大模型评估的五类数据