K8S + Jenkins 做CICD

前言

这里会做整体CICD的思路和流程的介绍,会给出核心的Jenkins pipeline脚本,最后会演示一下 实验/实操 结果
由于整体内容较多,所以不打算在这里做每一步的详细演示 - 本文仅作自己的实操记录和日后回顾用
要看保姆式教学的可以划走了,没有K8S基础的也可以划走了

正文

1. 整体实现思路

  1. 在K8S集群中部署Jenkins服务(我这里实验用的是 Jenkins 2.486版本),给Jenkins分配对应的NFS、PV、PVC、SA、NS、SVC等资源,挂载Jenkins配置文件到服务器
  2. 在Jenkins中安装 kubernetes、blue ocean 插件
  3. 配置Jenkins和K8S集群正常通信
  4. 配置 pod template - 这里的 pod template 实际上就是对 Jenkins agent(以前叫 Jenkins slave) 的配置,用于完成git代码拉取、mvn打包、docker镜像上传等操作
  5. 新建流水线任务,加入自己的pipeline脚本

CICD流程:

  1. 开发提交代码到代码仓库 gitlab/github/gitee - 我这里用的github
  2. 开启任务 -> jenkins 检测到代码更新,调用 k8s api 在 k8s 中创建 jenkins slave pod
  3. Jenkins slave pod 拉取代码,通过 maven 把拉取的代码进行构建成 war 包或者 jar 包,上传代码到 Sonarqube,进行静态代码扫描
  4. 基于 jar 包构建 docker image,把镜像上传到镜像仓库 harbor 或 dockerhub - 我这里用的 dockerhub
  5. 基于镜像部署应用到开发环境
  6. 开发人员自测通过,在blue ocean 流水线中操作,发布到测试环境
  7. 测试团队测试通过,发布到生产环境

2. 插件简介

2.1 Kubernetes插件简介

Kubernetes 插件的目的是能够使用 Kubernetes 配合,实现动态配置 Jenkins 代理(使用 Kubernetes 调度机制来优化负载),在执行 Jenkins Job 构建时,Jenkins Master 会在 kubernetes 中创建一个 Slave Pod 代理来执行任务。
该 Slave Pod 中可以包含多种镜像,例如需要 Maven 编译可以使用 Maven 镜像执行任务。使用 NPM编译则可以使用 NPM镜像。操作 Kubernetes 可以使用 Kubectl 插件镜像。
所有 Job 中所需要的环境及其依赖都交由镜像提供,而不需要手动搭配这些环境。在 Slave Pod 执行完 Job 任务后,该Slave Pod将会自动删除。所以 Kubernetes Plugin 简单用法就是,在 Kubernetes 中启动 Jenkins Slave 代理,让代理执行 Jenkins Job,执行完后释放删除 Slave 释放资源。

Kubernetes插件使用 - Kubernetes Plugin的配置主要有两部分组成:

  • kubernetes的连接参数:主要用于配置如果连接kubernetes
  • kubernetes的pod模板:调用kubernetes创建jenkins slave使用的pod模板

在这里插入图片描述

2.2 Blue Ocean 插件简介

Blue Ocean 是 Jenkins 的一款现代化 UI 插件,旨在为持续集成/持续交付 (CI/CD) 提供更加直观、用户友好的界面和体验。

  • 全新的可视化流水线体验
    • Blue Ocean 提供了流水线运行过程的直观可视化,用户可以清晰地查看流水线的各个阶段(stage)、步骤(step)及其状态(成功、失败、运行中)。
    • 支持图形化展示流水线的分支、并行任务及错误点,便于快速诊断和调试。
  • 简化的流水线创建和编辑
    • 内置交互式流水线编辑器,支持通过拖放操作创建 Jenkinsfile,降低了学习曲线。
    • 用户无需编写复杂的脚本即可快速配置和生成流水线代码。
  • 强大的分支支持
    • 专为 Git 和其他分布式版本控制系统的多分支流水线设计。
    • 自动检测代码仓库中的分支和 Pull Request,独立运行每个分支的流水线任务。
  • 高效的协作能力
    • 在失败的任务或构建上添加评论,方便团队成员进行问题协作和修复。
    • 支持通过直观的界面查看构建日志、失败原因以及历史记录。
  • 插件生态集成
    • 与 Jenkins 的现有插件(如 Git、GitHub、Bitbucket、Docker 等)无缝集成。
    • 支持各种通知机制(如邮件、Slack、Webhook)来增强 CI/CD 流程。
  • 跨平台友好
    • 适配桌面端和移动端,用户可以随时随地查看流水线状态。
      在这里插入图片描述

3. pipeline脚本示例

env.BRANCH_NAME = 'master'
node('devops') {stage('Clone') {echo "1.下载代码"withCredentials([usernamePassword(credentialsId: 'github', usernameVariable: 'gitHubUser', passwordVariable: 'gitHubToken')]) {git url: "https://${gitHubUser}:${gitHubToken}@github.com/cqweiheng/myspringboot.git"}script {build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()}}stage('Test') {echo "2.代码扫描"}stage('Build') {echo "3.构建docker镜像"	// 执行 Maven 构建,生成 jar 文件sh 'mvn clean package -Dmaven.test.skip=true'// 打包成镜像sh "docker build -t cqweiheng/test:myspringboot-${build_tag} ."}stage('Push') {echo "4.推送镜像"withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]) {sh "docker login -u ${dockerHubUser} -p ${dockerHubPassword}"// 这里可以改用 harbor//sh "docker login 192.168.86.100 -u ${harborUser} -p ${harborPassword}"sh "docker push cqweiheng/test:myspringboot-${build_tag}"}}stage('Deploy to dev') {echo "5.发布到 dev 环境"sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-dev.yaml"sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-dev.yaml"sh "cat k8s-dev.yaml"sh "kubectl apply -f k8s-dev.yaml"sh "sleep 10"sh "kubectl get pods -n dev"}	stage('Deploy to test') {	def userSelected = input(id: 'userSelected',message: '确认发布到【测试】环境?',parameters: [[$class: 'ChoiceParameterDefinition',choices: "确认\n取消",name: '请选择']])echo "用户选择:${userSelected}"if (userSelected == "确认") {sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-test.yaml"sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-test.yaml"sh "cat k8s-test.yaml"sh "kubectl apply -f k8s-test.yaml"sh "sleep 10"sh "kubectl get pods -n test"} else {//exitecho "用户选择不发布到测试环境,本次部署流程终止。"currentBuild.result = 'ABORTED'error("用户选择取消发布到测试环境。")}}stage('Deploy to pro') {	def userSelected = input(id: 'userSelected',message: '确认发布到【生产】环境?',parameters: [[$class: 'ChoiceParameterDefinition',choices: "确认\n取消",name: '请选择']]// 仅允许指定用户操作 - 通过授权,仅测试团队可以操作//,submitter: 'test-user,test-group')echo "用户选择:${userSelected}"if (userSelected == "确认") {sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s-prod.yaml"sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s-prod.yaml"sh "cat k8s-prod.yaml"sh "kubectl apply -f k8s-prod.yaml --record"sh "sleep 10"sh "kubectl get pods -n prod"}}
}

4. 演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在 deploy to test 这里就停住了,等待授权
开发人员在 dev 环境自测完毕后,确认发布到测试环境,由测试团队进行验证
在这里插入图片描述

发布到生产这里可以通过添加 submitter 来控制用户权限,比如仅测试团队可以提交
在这里插入图片描述
在这里插入图片描述
到这里整个流程就结束了
从下图中可以看到Jenkins slave这个 pod 生命周期结束
在命名空间 dev, test, prod 中分别生成了新的 pod
在这里插入图片描述

访问一下,自己写的一个springboot 应用 -> OK的
在这里插入图片描述

5. 闲聊

  1. 这里 svc 用的 NodePort,实际生产中如果做四层负载的话,应该会用 LoadBalance
  2. 做版本回滚的话,可以新起一个pipeline,调用shell脚本,选择版本号后进行回滚操作
    参考:
    #查看历史版本
    kubectl rollout history deployment/<deployment_name>
    #回退到指定版本
    kubectl rollout undo deployment/<deployment_name> --to-revision=<revision_number>
    
  3. 这里是用的单个集群,将开发、测试和生产环境部署在 同一个 K8S 集群中,并通过 Namespace 来区分不同环境。这种方式简单高效,但需要合理的规划和配置,确保资源隔离和环境安全性。
    比如按 namespace 做资源配额,按 单个pod 做资源限制
    #按 namespace 做资源限制
    apiVersion: v1
    kind: ResourceQuota
    metadata:name: resource-quotanamespace: dev
    spec:hard:pods: "20"                  # 最大允许 20 个 Podrequests.cpu: "4"           # 总 CPU 请求限制 4 核requests.memory: "8Gi"      # 总内存请求限制 8GBlimits.cpu: "8"             # 总 CPU 限制 8 核limits.memory: "16Gi"       # 总内存限制 16GB#按 单个pod 做资源限制 - 防止单个 Pod 占用过多资源
    apiVersion: v1
    kind: LimitRange
    metadata:name: limitsnamespace: dev
    spec:limits:- default:cpu: "500m"memory: "512Mi"defaultRequest:cpu: "200m"memory: "256Mi"type: Container
    
  4. Jenkins 的 Pipeline 可以通过不同的 kubeconfig 文件操作不同的集群。再直白点就是,可以通过 kubeconfig 文件 做服务器隔离、集群隔离的CICD 发布到dev、test、prod环境 - 当然这个我还没实际操作过
    顺带搜了一下,大约是这样做的,下面的内容仅供参考
    #1.为每个集群(dev 和 test)生成独立的 kubeconfig 文件
    kubectl config view --raw > kubeconfig-dev.yaml
    kubectl config view --raw > kubeconfig-test.yaml
    #2.将这些 kubeconfig 文件上传到 Jenkins 的凭据管理系统,确保安全性
    #在 Jenkins 中添加 kubeconfig 凭据
    #	打开 Jenkins Dashboard。
    #	进入 "Manage Jenkins" > "Credentials"。
    #	添加凭据:
    #		Kind:Secret file
    #		File:上传 kubeconfig-dev.yaml 和 kubeconfig-test.yaml。
    #		ID:分别命名为 kubeconfig-dev 和 kubeconfig-test。#3.在 Jenkins Pipeline 中使用 kubeconfig 文件
    #利用 withCredentials 加载对应的 kubeconfig 文件,动态切换集群。
    pipeline {
    agent any
    stages {stage('Deploy to Dev') {steps {script {echo "Deploying to Dev Cluster..."withCredentials([file(credentialsId: 'kubeconfig-dev', variable: 'KUBECONFIG')]) {// 使用 kubeconfig-dev 操作 dev 集群sh 'kubectl apply -f k8s-dev.yaml'sh 'kubectl get pods -n dev'}}}}stage('Deploy to Test') {steps {script {input "Confirm deployment to Test environment?"echo "Deploying to Test Cluster..."withCredentials([file(credentialsId: 'kubeconfig-test', variable: 'KUBECONFIG')]) {// 使用 kubeconfig-test 操作 test 集群sh 'kubectl apply -f k8s-test.yaml'sh 'kubectl get pods -n test'}}}}
    }
    

}
```
这种就是各集群的资源、权限完全独立,不会相互影响。即使某一环境出现问题,其他环境仍可正常工作。

适合场景
- 多集群部署:开发、测试、生产环境分布在不同的 Kubernetes 集群中。
- 跨区域服务器管理:如不同集群位于不同的云平台(阿里云、腾讯云、AWS 等)。
- 严格隔离需求:需要通过不同的 kubeconfig 文件实现权限和资源隔离。

6. 踩过的坑

6.1 FailedCreatePodSandbox - error getting clusterInfomation: connection is unauthorized

在这里插入图片描述
这个错误纠结了好久,最开始解题思路有误
看日志一直以为是授权出了问题
做了如下尝试,又检查了calico插件,发现全都是正常的
第二天Google搜了一下:
https://devopscube.com/clusterinformation-connection-unauthorized/
重启calico后OK,气不气?

#授权
kubectl create clusterrolebinding calico-access-jenkins-admin \--clusterrole=calico-kube-controllers \--serviceaccount=devops:jenkins-admin#绑定token - vim jenkins-admin-token.yaml
apiVersion: v1
kind: Secret
metadata:name: jenkins-admin-tokennamespace: devopsannotations:kubernetes.io/service-account.name: jenkins-admin
type: kubernetes.io/service-account-token
#kubectl apply -f jenkins-admin-token.yaml#验证是否生效
kubectl -n devops describe secret $(kubectl -n devops get secret | grep jenkins-admin | awk '{print $1}')
curl -k -H "Authorization: Bearer <your-token>" https://<kube-apiserver>:6443/apis/crd.projectcalico.org/v1/clusterinformations#能正常访问说明权限没有问题
kubectl --token=<your-token> get clusterinformation -o yaml

6.2 jenkins svc 没有暴露50000 端口

这个好像没什么可说的,加上就好了
在这里插入图片描述

6.3 Jenkins slave 构建镜像时提示 docker: not found

在这里插入图片描述
这个东西也搞了一阵子,后来自己基于
FROM jenkins/agent:latest
添加了 docker.io、maven-3.9.5、kubectl v1.31.2
然后打包成自己的Jenkins slave镜像使用,整个流程才正常跑通
这个镜像我推送到了 dockerhub 上,有需要的同学可以直接拿来用(不过由于版本问题,估计大概率也只有我自己用,哈哈)
镜像:cqweiheng/test:jenkins-agent-with-docker-v4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476868.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nvm安装node遇到的若干问题(vscode找不到npm文件、环境变量配置混乱、npm安装包到D盘)

问题一&#xff1a;安装完nvm后需要做哪些环境变量的配置&#xff1f; 1.打开nvm文件夹下的setting文件&#xff0c;设置nvm路径和安装node路径&#xff0c;并添加镜像。 root: D:\software\nvm-node\nvm path: D:\software\nvm-node\nodejs node_mirror: https://npmmirror.c…

shell脚本(五)

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

如何使用ChatGPT整理和收集论文实验数据?

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 使用ChatGPT整理和收集论文实验数据&#xff0c;需要通过一些具体的方法和提示词。以下几个步骤和技巧&#xff0c;告诉你如何借助ChatGPT更好地完成工作&#xff1a; 1. 数据格式化和…

PDF电子发票信息转excel信息汇总

PDF电子发票信息提取&#xff0c;支持将pdf发票文件夹下的剩所有发票&#xff0c;转为excel格式的信息&#xff0c;对于发票量比较大&#xff0c;不好统计&#xff0c;需要一个一个去统计的情况&#xff0c;可节省2个点以上的时间&#xff0c;一次下载&#xff0c;终身有效。 使…

小鹏汽车智慧材料数据库系统项目总成数据同步

1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构&#xff1a; 这几个表总数为100多万&#xff0c;经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图&#xff1a; 界面&#xff1a; SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…

嵌入式硬件实战基础篇(二)-稳定输出3.3V的太阳能电池-无限充放电

引言&#xff1a;本内容主要用作于学习巩固嵌入式硬件内容知识&#xff0c;用于想提升下述能力&#xff0c;针对学习稳压芯片和电容以及电池之间的运用&#xff0c;对于硬件PCB以及原理图的练习和前面硬件篇的实际运用&#xff1b;太阳能是一种清洁、可再生的能源&#xff0c;广…

【海思Hi3519DV500】双目网络相机套板硬件规划方案

Hi3519DV500双目网络相机套板是针对该芯片设计的一款 IP 编码板 PCBA&#xff0c;硬件接口支持双目sensor 接入&#xff0c;SDIO3.0 接口、USB2.0、USB3.0、UART 接口以及丰富的 IO 扩展应用&#xff0c;可根据各种使用场景设计相应扩展板&#xff0c;丰富外围接口&#xff0c;…

淘宝商品评论爬虫:Java实现指南

在当今的互联网时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是用户生成的内容&#xff0c;如商品评论&#xff0c;对于理解消费者行为和市场趋势具有重要意义。淘宝作为中国最大的电商平台之一&#xff0c;拥有海量的商品评论数据。本文将介绍如何使用Java编写一个简单…

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中&#xff0c;校运会不仅是…

tensorflow案例7--数据增强与测试集, 训练集, 验证集的构建

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 这次主要是学习数据增强, 训练集 验证集 测试集的构建等等的基本方法, 数据集还是用的上一篇的猫狗识别;基础篇还剩下几个, 后面的难度会逐步提升;欢迎…

SpringBoot多环境+docker集成企业微信会话存档sdk

SpringBoot多环境docker集成企业微信会话存档sdk 文章来自于 https://developer.work.weixin.qq.com/community/article/detail?content_id16529801754907176021 SpringBoot多环境docker集成企业微信会话存档sdk 对于现在基本流行的springboot环境&#xff0c;官方文档真是比…

VSCode快速生成vue组件模版

1&#xff0c;点击设置&#xff0c;找到代码片段 2&#xff0c;搜索vue&#xff0c;打开vue.json 3&#xff0c;添加模版 vue2模板 "vue2": {"prefix": "vue2","body": ["<template>"," <div>$0</di…

【爬虫】Firecrawl对京东热卖网信息爬取(仅供学习)

项目地址 GitHub - mendableai/firecrawl: &#x1f525; Turn entire websites into LLM-ready markdown or structured data. Scrape, crawl and extract with a single API. Firecrawl更多是使用在LLM大模型知识库的构建&#xff0c;是大模型数据准备中的一环&#xff08;在…

VXLAN说明

1. 什么是 VXLAN &#xff1f; VXLAN&#xff08;Virtual Extensible LAN&#xff0c;虚拟扩展局域网&#xff09;是一种网络虚拟化技术&#xff0c;旨在通过在现有的物理网络上实现虚拟网络扩展&#xff0c;从而克服传统 VLAN 的一些限制。 VXLAN 主要用于数据中心、云计算环…

RTL8211F 1000M以太网PHY指示灯

在RK3562 Linux5.10 SDK里面已支持该芯片kernel-5.10/drivers/net/phy/realtek.c&#xff0c;而默认是没有去修改到LED配置的&#xff0c;我们根据硬件设计修改相应的寄存器配置&#xff0c;该PHY有3个LED引脚&#xff0c;我们LED0不使用&#xff0c;LED1接绿灯&#xff08;数据…

主IP地址与从IP地址:深入解析与应用探讨

在互联网的浩瀚世界中&#xff0c;每台联网设备都需要一个独特的身份标识——IP地址。随着网络技术的不断发展&#xff0c;IP地址的角色日益重要&#xff0c;而“主IP地址”与“从IP地址”的概念也逐渐进入人们的视野。这两个术语虽然看似简单&#xff0c;实则蕴含着丰富的网络…

【Redis】基于Redis实现秒杀功能

业务的流程大概就是&#xff0c;先判断优惠卷是否过期&#xff0c;然后判断是否有库存&#xff0c;最好进行扣减库存&#xff0c;加入全局唯一id&#xff0c;然后生成订单。 一、超卖问题 真是的场景下可能会有超卖问题&#xff0c;比如开200个线程进行抢购&#xff0c;抢100个…

计算机网络socket编程(4)_TCP socket API 详解

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(4)_TCP socket API 详解 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

Jmeter数据库压测之达梦数据库的配置方法

目录 1、概述 2、测试环境 3、数据库压测配置 3.1 安装jmeter 3.2 选择语言 3.3 新建测试计划 3.4 配置JDBC连接池 3.5 配置线程组 3.6 配置测试报告 3.7 执行测试 1、概述 Jmeter是Apache组织开发的基于Java的压力测试工具&#xff0c;用于对软件做压力测试。 它最…

RAG与微调:大模型落地的最佳路径选择(文末赠书)

一、大模型技术发展现状 自2022年底ChatGPT掀起AI革命以来&#xff0c;大语言模型&#xff08;LLM&#xff09;技术快速迭代发展&#xff0c;从GPT-4到Claude 2&#xff0c;从文心一言到通义千问&#xff0c;大模型技术以惊人的速度发展。然而&#xff0c;在企业实际应用场景中…