无缝部署您的应用程序:将 Jenkins Pipelines 与 ArgoCD 集成

在 DevOps 领域,自动化是主要目标之一。这包括自动化软件部署方式。与其依赖某人在部署软件的机器上进行 rsync/FTP/编写软件,不如使用 CI/CD 的概念。

CI,即持续集成,是通过代码提交创建工件的步骤。这可以是 Docker 镜像,使用 Git 仓库主分支中的提交进行部署。

CD,即持续部署/交付,是部署工件的步骤。这可以是任何操作,例如在机器上运行 docker pull 和 docker run 的部署系统,指示 AWS Lambda 将代码更新到 S3 存储桶中的最新代码,或者指示 Kubernetes 集群更新现有部署以使用新镜像。

在本文中,我将快速介绍如何设置触发 ArgoCD 的 Jenkins 流水线。ArgoCD 是一个基于 Git 仓库中的清单更新 Kubernetes 集群的 CD 工具。它可以部署标准 Kubernetes 清单,并使用 Kustomize 更新清单或 Helm 图表。

先决条件

要将 Jenkins 与 ArgoCD 结合使用,您需要执行以下操作:-

  • 在 Jenkins 工作器/运行器上安装 argocd-cli
  • 在 ArgoCD 中创建一个 Jenkins 部署角色,该角色有权更新应用程序
  • 在基于 Git 的版本控制系统中,ArgoCD 可以访问一个或多个代码库(例如 GitHub、Gitlab、Gitea 或无前端的 Git)
  • Jenkins 工作器/运行器需要能够通过 API 访问 ArgoCD,因此请确保设置了正确的防火墙规则

 安装ArgoCD CLI

我们使用 Packer 为 Jenkins 工作器配置/准备镜像。因此,添加其他工具非常简单。但是,如果您运行的是静态工作器,则只需确保 argocd 二进制文件安装在 Jenkins 用户可运行的位置即可。例如:

$ pwd
/home/jenkins## Download the tool 
$ curl -LO https://github.com/argoproj/argo-cd/releases/download/v1.2.0/argocd-linux-amd64 ## Move it to the /usr/local/bin
$ sudo mv argocd-linux-amd64 /usr/local/bin/argocd## Ensure it is exectutable
$ sudo chmod 755 /usr/local/bin/argocd## Check it works
$ argocd version
argocd: v1.2.0+674978cBuildDate: 2019-09-04T21:26:04ZGitCommit: 674978cd587701b39e81fce6d5c960b6d76d5882GitTreeState: cleanGoVersion: go1.12.6Compiler: gcPlatform: linux/amd64
argocd-server: v1.2.0+674978cBuildDate: 2019-09-04T21:27:17ZGitCommit: 674978cd587701b39e81fce6d5c960b6d76d5882GitTreeState: cleanGoVersion: go1.12.6Compiler: gcPlatform: linux/amd64Ksonnet Version: 0.13.1

ArgoCD Jenkins 部署角色


要在 ArgoCD 中创建部署角色,请转到 ArgoCD 仪表板,点击侧边栏上的齿轮图标(进入设置),然后转到“项目”。
在“项目中”,选择您的应用程序正在运行的项目。如果您尚未创建任何项目,则默认为“默认”。
在项目中,转到“角色”,然后点击“添加角色”。

 在角色中,您可以为角色指定您想要的名称和描述,以便将来更容易理解其用途。您可以在此处应用细粒度的策略来定义 Jenkins 可以执行的操作(例如,仅创建、仅更新、仅同步现有应用程序)。或者,您可以授予其完全访问权限,但显然在生产环境中不建议这样做。)

完成上述所有操作后,您需要创建一个 JWT(JSON Web Token)。它用于对用户进行身份验证,确保只有客户端(在本例中为 Jenkins)才能承担此角色并使用其权限。这可以在 Web UI 中完成,也可以通过 CLI 完成。

要从 CLI 创建 JWT,您需要执行 argocd proj role create-token {PROJECT-NAME} {PROJECT-ROLE} 命令,示例如下:

$ argocd proj role create-token default jenkins-deploy-role
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1Njg3MjEyMjEsImlzcyI6ImFyZ29jZCIsIm5iZiI6MTU2ODcyMTIyMSwic3ViIjoicHJvajpkZWZhdWx0OmplbmtpbnMtZGVwbG95LXJvbGUifQ.UyXNZtdbDyllzGl7PbLPhMgqNMFE1oJqONaLHV8RK-k

将令牌添加到 Jenkins


要将令牌添加到 Jenkins 本身(以便在流水线中使用),首先转到您的 Jenkins 实例,然后在侧边栏上找到“凭据”,然后选择“系统”,再选择“全局凭据”。点击添加凭据,如下图所示。

允许ArgoCD 访问代码库

ArgoCD 需要访问的代码库是托管 Kubernetes 清单的代码库。您可以将清单与代码放在同一个代码库中,也可以将它们放在一个完全独立的代码库中。

您可以通过多种方式进行设置。您可以使用 SSH 或 HTTPS 连接到您的版本控制系统。我选择了 SSH。

再次转到 ArgoCD 的“设置”页面,但不要点击“项目”,而是点击“代码库”。在这里,点击“使用 SSH 连接代码库”。

  

ninjamac@192 ~ % ssh-keygen -o -f argocd-deploy -C "argocd@example.com"
Generating public/private ed25519 key pair.
Enter passphrase for "argocd-deploy" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in argocd-deploy
Your public key has been saved in argocd-deploy.pub
The key fingerprint is:
SHA256:nAuYAjALq9QIGII14J1vtjZfEboOQE4+Q985bu5BjuU argocd@example.com
The key's randomart image is:
+--[ED25519 256]--+
|@+o              |
|O++..            |
|++ B     .       |
|o.* oo..o..      |
|. .*o=.BS.       |
|   .* O.o..      |
|     * E..       |
|    . B o        |
|      .=         |
+----[SHA256]-----+

获取私钥(在本例中为 argocd-deploy)的内容,并将其粘贴到 ArgoCD 的 SSH 私钥数据字段中。提供 Kubernetes 清单所在仓库的 URL(如果您使用 HTTPS 连接,则为 HTTPS URL;如果使用 SSH 连接,则为 SSH URL)。

您需要公钥(在本例中为 argocd-deploy.pub)来在您选择的 Git 服务器中设置部署密钥。

防火墙规则


您的 Jenkins 工作器/运行器需要能够访问 ArgoCD API。我们将其暴露在 TCP:443 端口(即标准 HTTPS)上,因此您需要确保您的防火墙允许其通过。

Kubernetes 清单


如上所述,您可以使用标准 Kubernetes 清单、Kustomize 和/或 Helm 图表来部署您的应用程序。我使用 Kustomize 来更新 Kubernetes 部署中使用的 Docker 镜像哈希值。如果没有 Kustomize,即使您的 Docker 镜像仓库(私有或公共)中有新的镜像可用,部署也不会更新。

这是因为 Kubernetes API 认为部署没有发生变化。标签与以前相同,因此它不知道需要执行任何操作。

从 Kubernetes v1.15 版本开始,它们现在支持滚动重启。与 ImagePullPolicy: Always 结合使用,这将强制部署获取新镜像。

在 Kubernetes v1.15 之前的版本中,Deployment 永远不会更新。使用 :latest 并非最佳实践,因此引用实际哈希值可能是一个好主意。

清单示例


我最基本的 Kubernetes 清单如下:-

## ------------------- Debian Deployment ------------------- #kind: Deployment
apiVersion: apps/v1
metadata:labels:k8s-app: debian-testname: debian-test
spec:replicas: 1revisionHistoryLimit: 10selector:matchLabels:k8s-app: debian-testtemplate:metadata:labels:k8s-app: debian-testspec:containers:- name: debian-testimage: docker.io/rockwang415/k8s-debian-test:latest imagePullPolicy: Alwaysresources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80protocol: TCPlivenessProbe:httpGet:scheme: HTTPpath: /port: 80initialDelaySeconds: 30timeoutSeconds: 30---
## ------------------- Debian Service ------------------- #kind: Service
apiVersion: v1
metadata:labels:k8s-app: debian-testname: debian-test
spec:ports:- port: 80targetPort: 80type: NodePortselector:k8s-app: debian-test

我们使用 Docker 镜像仓库来存放镜像。如您所见,上面的镜像标签为 :latest。不过,我们也使用 Kustomize 来根据部署情况进行更改。我们的 kustomization.yaml 文件非常简单:-

resources:
- debian-test.yaml


从 v1.2.0 开始,ArgoCD 可以原生地利用 Kustomize(如果您指定了正确的参数),因此无需在此 YAML 文件中添加任何其他内容。

Jenkins Pipeline


现在所有先决条件都已满足,您已将 ArgoCD 连接到您的仓库并创建了清单,接下来您可以创建一个 Jenkinsfile 来部署应用程序。

pipeline {agent {node {label 'testing'}}stages {       stage('Prepare') {steps {checkout([$class: 'GitSCM',branches: [[name: "origin/master"]],doGenerateSubmoduleConfigurations: false,submoduleCfg: [],userRemoteConfigs: [[url: 'ssh://git@git.example.com/argocd-test/argocd-test.git']]])}}stage('Docker_Build') {steps {// Build the Docker imagesh '''# Login to Docker registrydocker login -u <docker-username> -p <docker-password> <docker-registry-url># Build the imagedocker build . -t k8s-debian-test'''}}stage('Deploy_K8S') {steps {withCredentials([string(credentialsId: "jenkins-argocd-deploy", variable: 'ARGOCD_AUTH_TOKEN')]) {sh '''ARGOCD_SERVER="argocd-prod.example.com"APP_NAME="debian-test-k8s"CONTAINER="k8s-debian-test"REGION="eu-west-1"# Tag the docker imagedocker tag $CONTAINER:latest <docker-registry-url>/$CONTAINER:latest# Push the image to Docker registrydocker push <docker-registry-url>/$CONTAINER:latestIMAGE_DIGEST=$(docker image inspect <docker-registry-url>/$CONTAINER:latest -f '{{join .RepoDigests ","}}')# Customize image ARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app set $APP_NAME --kustomize-image $IMAGE_DIGEST# Deploy to ArgoCDARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app sync $APP_NAME --forceARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app wait $APP_NAME --timeout 600'''}}}}
}

docker hub 登录


这用于登录 docker hub,检索 Docker 镜像(例如,基础 Debian 镜像),然后根据我们的 Dockerfile 进行标记和推送。如果您使用的是标准镜像或您自己的私有镜像仓库,则可以忽略这些部分。

镜像摘要


由于某种原因,Docker 镜像摘要并不总是显示在 docker images --digests 中。相反,我们会检查最新推送到 docker hub的镜像,并检索 .RepoDigests 标签。这将提供以下内容:

ninjamac@192 ~ % docker image inspect rockwang415/k8s-debian-test -f '{{join .RepoDigests ","}}'
rockwang415/k8s-debian-test@sha256:b662d828445b39ac0a659ec77b629a75d1b298a6c76afdf5296cff64806fc638

ArgoCD


由于我们的 ArgoCD API 和仪表板位于 AWS 应用负载均衡器前端,我们目前在所有 ArgoCD 命令前都添加了 --grpc-web 前缀,例如 argocd --grpc-web app sync TEST --force。这是因为 AWS 应用负载均衡器默认不支持 GRPC。如果您在 ArgoCD 前端的负载均衡器/入口支持 GRPC,请从所有命令中移除该前缀。

自定义镜像

ARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app set $APP_NAME --kustomize-image $IMAGE_DIGEST


上述命令将 Kubernetes 清单中的镜像设置为生成的镜像摘要变量。由于 ArgoCD 默认支持 Kustomize,它可以自行操作清单。这意味着我们不会因为镜像标签始终不变而导致 Deployment 始终不更新。

这是一个非常棒的功能,意味着我们不需要像 ArgoCD 一样在 Jenkins 工作进程中同时运行 Kustomize 二进制文件。

同步应用程序

ARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app sync $APP_NAME --force
ARGOCD_SERVER=$ARGOCD_SERVER argocd --grpc-web app wait $APP_NAME --timeout 600

 上述代码只是要求 ArgoCD 触​​发 Kubernetes 部署应用程序。在 ArgoCD 中,这将使用 Git 仓库中的 Manifest 文件,该文件已通过 Kustomize 更新以使用新的镜像标签。然后,它将根据 Jenkins 生成的镜像部署应用程序的新版本。

运行Jenkins Pipeline 

下面是运行后的结果

Kubernetes Output

Pre-ArgoCD Run

kubectl get pods
NAME                                     READY   STATUS      RESTARTS   AGE
debian-test-8648f969ff-hrsvp             1/1     Running     0          4d22h

Post-ArgoCD Run

kubectl get pods
NAME                                     READY   STATUS      RESTARTS   AGE
debian-test-7664c648bb-sq6h7             1/1     Running     0          22s

Jenkins Console Output - ArgoCD


+ ARGOCD_SERVER=argocd-prod.example.com argocd \ --grpc-web app set debian-test-k8s \ --kustomize-image rockwang415/k8s-debian-test@sha256:###SHA256-IMAGE-HASH###+ ARGOCD_SERVER=argocd-prod.example.com argocd --grpc-web app sync debian-test-k8s --force
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS   HEALTH        HOOK  MESSAGE
2025-05-017T13:05:27+00:00   apps  Deployment     default           debian-test    Synced  Healthy              
2025-05-017T13:05:27+00:00            Service     default           debian-test    Synced  Healthy              
2025-05-017T13:05:27+00:00   apps  Deployment     default           debian-test  OutOfSync  Healthy              Name:               debian-test-k8s
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd-prod.example.com/applications/debian-test-k8s
Repo:               git@git.example.com:yeti/argocd-test.git
Target:             HEAD
Path:               yaml
Sync Policy:        <none>
Sync Status:        Synced to HEAD (f5f91ad)
Health Status:      ProgressingOperation:          Sync
Sync Revision:      f5f91ad16296ecab90f337e5dbf3f4f927b61799
Phase:              Succeeded
Start:              2025-05-01 13:05:27 +0000 UTC
Finished:           2025-05-01 13:05:29 +0000 UTC
Duration:           2s
Message:            successfully synced (all tasks run)GROUP  KIND        NAMESPACE  NAME         STATUS  HEALTH       HOOK  MESSAGEService     default    debian-test  Synced  Healthy            service/debian-test unchanged
apps   Deployment  default    debian-test  Synced  Progressing        deployment.apps/debian-test configured
+ ARGOCD_SERVER=argocd-prod.example.com argocd --grpc-web app wait debian-test-k8s --timeout 600
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS   HEALTH            HOOK  MESSAGE
2025-05-01T13:05:29+00:00            Service     default           debian-test    Synced  Healthy                  service/debian-test unchanged
2025-05-01T13:05:29+00:00   apps  Deployment     default           debian-test    Synced  Progressing              deployment.apps/debian-test configuredName:               debian-test-k8s
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd-prod.example.com/applications/debian-test-k8s
Repo:               git@git.example.com:yetiops/argocd-test.git
Target:             HEAD
Path:               yaml
Sync Policy:        <none>
Sync Status:        Synced to HEAD (f5f91ad)
Health Status:      HealthyOperation:          Sync
Sync Revision:      f5f91ad16296ecab90f337e5dbf3f4f927b61799
Phase:              Succeeded
Start:              2025-05-01 13:05:27 +0000 UTC
Finished:           2025-05-01 13:05:29 +0000 UTC
Duration:           2s
Message:            successfully synced (all tasks run)GROUP  KIND        NAMESPACE  NAME         STATUS  HEALTH   HOOK  MESSAGEService     default    debian-test  Synced  Healthy        service/debian-test unchanged
apps   Deployment  default    debian-test  Synced  Healthy        deployment.apps/debian-test configured

ArgoCD Dashboard

 总结


我们为什么要使用 Jenkins 和 ArgoCD?Jenkins 非常擅长构建工件、整合代码提交,并接受来自 GitHub 或 GitLab 等平台的 Webhook 来启动作业。然而,ArgoCD 能够更好地控制镜像的部署方式,因为所有内容都可以在原生 Kubernetes 清单中描述。

这消除了将 Kubernetes 直接暴露给 Jenkins 的需要,也无需操作 kubectl 命令来部署(或使用额外的插件)。

ArgoCD 还为我们提供了部署进度的实时视图,以及在需要时可以回滚到的位置。它还以 Kubernetes 为中心(即部署和服务如何关联)的方式展示它们,因此开发人员和运维团队可以更轻松地了解所有内容是如何关联的。

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

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

相关文章

4.2.3 Thymeleaf标准表达式 - 5. 片段表达式

在本次实战中&#xff0c;我们通过 Thymeleaf 的片段表达式实现了模板的模块化和复用。首先&#xff0c;我们定义了一个导航栏片段 navbar&#xff0c;并通过参数 activeTab 动态高亮当前激活的标签。然后&#xff0c;我们在多个页面&#xff08;如主页、关于页和联系页&#x…

网安面试经(1)

1.说说IPsec VPN 答&#xff1a;IPsec VPN是利用IPsec协议构建的安全虚拟网络。它通过加密技术&#xff0c;在公共网络中创建加密隧道&#xff0c;确保数据传输的保密性、完整性和真实性。常用于企业分支互联和远程办公&#xff0c;能有效防范数据泄露与篡改&#xff0c;但部署…

【C++/Qt shared_ptr 与 线程池】合作使用案例

以下是一个结合 std::shared_ptr 和 Qt 线程池&#xff08;QThreadPool&#xff09;的完整案例&#xff0c;展示了如何在多线程任务中安全管理资源&#xff0c;避免内存泄漏。 案例场景 任务目标&#xff1a;在后台线程中处理一个耗时的图像检测任务&#xff0c;任务对象通过 …

【Unity】 HTFramework框架(六十五)ScrollList滚动数据列表

更新日期&#xff1a;2025年5月16日。 Github 仓库&#xff1a;https://github.com/SaiTingHu/HTFramework Gitee 仓库&#xff1a;https://gitee.com/SaiTingHu/HTFramework 索引 一、ScrollList滚动数据列表二、使用ScrollList1.快捷创建ScrollList2.ScrollList的属性3.自定义…

经典案例 | 筑基与跃升:解码制造企业产供销协同难题

引言 制造企业如何在投产初期突破管理瓶颈&#xff0c;实现高效运营&#xff1f;G公司作为某大型集团的新建子公司&#xff0c;面对产供销流程缺失、跨部门协同低效等难题&#xff0c;选择与AMT企源合作开展流程优化。 项目通过端到端流程体系搭建、标准化操作规范制定及长效管…

【Python 操作 MySQL 数据库】

在 Python 中操作 MySQL 数据库主要通过 pymysql 或 mysql-connector-python 库实现。以下是完整的技术指南&#xff0c;包含连接管理、CRUD 操作和最佳实践&#xff1a; 一、环境准备 1. 安装驱动库 pip install pymysql # 推荐&#xff08;纯Python实现&#xff0…

记录vsCode连接gitee并实现项目拉取和上传

标题 在 VSCode 中上传代码到 Gitee 仓库 要在 VSCode 中将代码上传到 Gitee (码云) 仓库&#xff0c;你可以按照以下步骤操作&#xff1a; 准备工作 确保已安装 Git确保已安装 VSCode拥有 Gitee 账号并创建了仓库 可以参考该文章的部分&#xff1a;idea实现与gitee连接 操…

【信息系统项目管理师】第6章:项目管理概论 - 31个经典题目及详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 第一节 PMBOK的发展【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】第二节 项目基本要素【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】第三节 项目经…

简单介绍C++中线性代数运算库Eigen

Eigen 是一个高性能的 C 模板库&#xff0c;专注于线性代数、矩阵和向量运算&#xff0c;广泛应用于科学计算、机器学习和计算机视觉等领域。以下是对 Eigen 库的详细介绍&#xff1a; 1. 概述 核心功能&#xff1a;支持矩阵、向量运算&#xff0c;包括基本算术、矩阵分解&…

生产级编排AI工作流套件:Flyte全面使用指南 — Core concepts Launch plans

生产级编排AI工作流套件&#xff1a;Flyte全面使用指南 — Core concepts Launch plans Flyte 是一个开源编排器&#xff0c;用于构建生产级数据和机器学习流水线。它以 Kubernetes 作为底层平台&#xff0c;注重可扩展性和可重复性。借助 Flyte&#xff0c;用户团队可以使用 P…

Python 之类型注解

类型注解允许开发者显式地声明变量、函数参数和返回值的类型。但是加不加注解对于程序的运行没任何影响&#xff08;是非强制的&#xff0c;且类型注解不影响运行时行为&#xff09;&#xff0c;属于 有了挺好&#xff0c;没有也行。但是大型项目按照规范添加注解的话&#xff…

rocketmq并发消费

netty的handler 在netty的网络模型中&#xff0c;在想bootstrap设置handler时&#xff0c; 都是在等待 事件 的到来&#xff0c;才会被调用的方法&#xff0c;都是被动的&#xff0c; 服务端等待 request 的到来&#xff0c;进行read, 然后主动调用writeAndFlush写出去。 客户…

React 播客专栏 Vol.9|React + TypeScript 项目该怎么起步?从 CRA 到配置全流程

&#x1f44b; 欢迎回到《前端达人 React 播客书单》第 9 期&#xff08;正文内容为学习笔记摘要&#xff0c;音频内容是详细的解读&#xff0c;方便你理解&#xff09;&#xff0c;请点击下方收听 你是不是常在网上看到 .tsx 项目、Babel、Webpack、tsconfig、Vite、CRA、ESL…

【PmHub后端篇】PmHub中基于自定义注解和AOP的服务接口鉴权与内部认证实现

1 引言 在现代软件开发中&#xff0c;尤其是在微服务架构下&#xff0c;服务接口的鉴权和内部认证是保障系统安全的重要环节。本文将详细介绍PmHub中如何利用自定义注解和AOP&#xff08;面向切面编程&#xff09;实现服务接口的鉴权和内部认证&#xff0c;所涉及的技术知识点…

芯片测试之X-ray测试

原理&#xff1a; X-ray是利用阴极射线管产生高能量电子与金属靶撞击&#xff0c;在撞击过程中&#xff0c;因电子突然减速&#xff0c;其损失的动能会以X-Ray形式放出。而对于样品无法以外观方式观测的位置&#xff0c;利用X-Ray穿透不同密度物质后其光强度的变化&#xff0c;…

QBasic 一款古老的编程语言在现代学习中的价值(附程序)

QBasic&#xff08;Quick Beginner’s All-purpose Symbolic Instruction Code&#xff09;是微软公司于 1991 年推出的一款简单易学的编程语言&#xff0c;作为BASIC语言的变种&#xff0c;它曾广泛应用于教育领域和初学者编程入门。尽管在当今Python、Java等现代编程语言主导…

【八股战神篇】Java高频基础面试题

1 面向对象编程有哪些特性&#xff1f; 面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称 OOP&#xff09;是一种以对象为核心的编程范式&#xff0c;它通过模拟现实世界中的事物及其关系来组织代码。OOP 具有三大核心特性&#xff1a;封装、继承、多态。…

科学养生指南:解锁健康生活新方式

在快节奏的现代生活中&#xff0c;健康养生成为人们关注的焦点。想要拥有良好的身体状态&#xff0c;无需依赖复杂的传统理论&#xff0c;通过科学的生活方式&#xff0c;就能轻松实现养生目标。​ 规律运动是健康的基石。每周进行 150 分钟以上的中等强度有氧运动&#xff0c…

OpenCV阈值处理完全指南:从基础到高级应用

引言 阈值处理是图像处理中最基础、最常用的技术之一&#xff0c;它能够将灰度图像转换为二值图像&#xff0c;为后续的图像分析和处理奠定基础。本文将全面介绍OpenCV中的各种阈值处理方法&#xff0c;包括原理讲解、代码实现和实际应用场景。 一、什么是阈值处理&#xff1…

Java8到24新特性整理

本文整理了 Java 8 至 Java 24 各版本的新特性&#xff0c;内容包括每个版本的新增功能分类&#xff08;如语法增强、性能优化、工具支持等&#xff09;、详细的代码示例&#xff0c;并结合官方文档资料&#xff0c;分析每项特性的应用场景及优缺点。Java 8 发布于 2014 年&…