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

使用 Kubernetes Agent Server 实现 GitOps

目录

温习 GitOps

极狐GitLab Kubernetes Agent

极狐GitLab GitOps workflow

极狐GitLab KAS 的配置

创建极狐GitLab  agent

创建 agent token

Kubernetes 上安装 agent(agentk)

极狐GitLab GitOps workflow 实践

写在最后


温习 GitOps


GitOps 的核心不是 Git,而是以声明式系统为基座,以 Git 为单一可信源,通过将应用程序和基础设施代码化(一切皆代码),进行云原生应用程序和基础设施部署管理。更多关于 GitOps 的内容,可以查看公众号文章GitOps 系列|云原生时代,你还不懂 GitOps?

极狐GitLab Kubernetes Agent 恰巧就是实现 GitOps workflow 的一个特性功能,在 13.x 版本中陆续引入。

本文将通过理论加实践的方式对极狐GitLab GitOps workflow 进行剖析,方便大家对其有个全方位的认知。

极狐GitLab Kubernetes Agent


极狐GitLab Kubernetes Agent 是一个位于 Kubernetes 集群侧的组件,能够以安全、云原生的方式来实现极狐GitLab 和 Kubernetes 的集成。主要实现的功能有:

  • 将极狐GitLab 与防火墙或 NAT(网络地址转换)后的 Kubernetes 集群进行集成;

  • “pull” 模式的 GitOps workflow;

  • 对应用在集群上的资源进行追踪;

  • 对集群的 API 端点进行实时访问;

  • 基于容器网络策略的报警生成;

  • CI/CD 隧道作用,以使用户能够从 GitLab CI/CD 中访问 Kubernetes 集群,即使 GitLab Runner 和集群之间没有网络连接。

更多的功能和特性还在开发过程中,感兴趣的可以查看 Roadmap。

接下来将重点分析如何使用极狐GitLab Kubernetes Agent 来实现 GitOps workflow。

极狐GitLab GitOps workflow


极狐GitLab GitOps workflow 的示意图如下

图片

上述列出了完成实践所需的组件

  • 极狐GitLab 服务(如使用极狐Saas 则地址为 GitLab-10万企业使用的一站式DevOps平台_GitLab中文官网);

  • 一个运行正常且安装了极狐GitLab Kubernetes Agent 的 Kubernetes 集群(Agent 安装过程后续会讲);

  • 一个配置仓库,包含 config.yaml 文件,里面定义了 agent 需要去跟集群侧做同步的 Project 信息;

  • 一个清单仓库,包含了往 Kubernetes 集群上部署资源的清单文件。

最终的目的就是:一旦部署清单仓库中的清单文件发生了变更,则此变更能够自动同步至集群侧。

可以将 config.yaml 文件和部署资源清单文件存放在同一个极狐GitLab Project 里面,这是 Project 可以是 Public 的,也可以是 Private的,而且这也是官方推荐方式。当然,也可以用不同的 Project 来分别存储config.yaml文件和部署清单文件,此时,需要注意的是,存放部署清单文件的 Project 必须是 Public 的,而存放config.yaml文件的 Project 则可以是 Public 或 Private 的,具体原因可以查看 issue。

从上述示意图中看到,要完成整个流程,需要两个重要组件的配合:agentk 和 kas。其中 agentk 代表极狐GitLab Kubernetes Agent,是位于 Kubernetes 集群侧的组件,主要用来和 kas 进行交互。kas 代表极狐GitLab Kubernetes Agent Server,是位于极狐GitLab 侧的组件,主要实现的功能有:

  • 接受来自 agentk 侧的请求;

  • 对 agentk 做权限验证(这一步是通过查询极狐 GitLab RoR 来完成);

  • 通过查询 Gitaly 来获取 agent 的配置信息;

  • 将来自极狐GitLab RoR 的请求与正确的 agentk 的现有连接进行匹配,然后将请求转发给 agentk,且将响应转发回来;

  • 通过和 Gitaly 通信来对存储部署清单的 Project 进行轮询,从而实现 GitOps。

整体的架构示意图如下:

图片

从架构图中可以看出,要想实现极狐GitLab GitOps workflow,需要对 agentk 和 kas 进行安装配置。

极狐GitLab KAS 的配置


首先,要在极狐GitLab 侧创建一个与存储 config.yaml 文件的配置仓库相关联的 agent 记录。这个过程分两步走:创建 agent 和生成 agent token(后面的步骤会用到)。

创建极狐GitLab  agent

可以使用 GraphQL 来完成创建工作,关于 GraphQL 的更多内容可以查看极狐GitLab GraphQL API 使用方法。当然最快速的方法就是使用 GraphQL Explorer 来完成创建工作。

在 GraphQL Explorer 的页面中输入创建 agent 的语法,然后运行即可。如在左侧输入如下 GraphQL 语法:

mutation createAgent {
# agent-name should be the same as specified above in the config.yaml
createClusterAgent(input: { projectPath: "your-configuration-project-path", name: "agent-name-you-specified-in-config.yaml" }) {clusterAgent {idname}errors
}
}

点击运行按钮之后,在右侧会会出现返回结果,如:

{"data": {"createClusterAgent": {"clusterAgent": {"id": "gid://gitlab/Clusters::Agent/43","name": "gitops"},"errors": []}}
}

整体效果如下:

图片

上述步骤创建了一个名为gitops,且与 your-configuration-project-path 这个 project 相关联的 agent,agent 的 ID 为 gid://gitlab/Clusters::Agent/43。接下来就需要为这个 agent 创建一个 agent token了。

创建 agent token

和创建 Agent 一样,利用 GraphQL Explorer 页面,在左侧输入 agent token 创建的 GraphQL 语法:

mutation createToken {clusterAgentTokenCreate(input: {clusterAgentId: "gid://gitlab/Clusters::Agent/43"description: "GitLab Kubernetes Agent Server Demo"name: "gitops"}) {secret # This is the value you need to use on the next steptoken {createdAtid}errors}}

clusterAgentId为创建 agent 时候的返回值,如gid://gitlab/Clusters::Agent/43。name为指定的 agent 名称,本文为 gitops。

点击运行之后,在右侧会返回 agent token:

{"data": {"clusterAgentTokenCreate": {"secret": "generated-agent-token","token": {"createdAt": "2021-08-17T13:22:31+08:00","id": "gid://gitlab/Clusters::AgentToken/37"},"errors": []}}
}

结果中的 secret 即为 agent token。在后续会用到。

紧接着,就需要在 Kubernetes 集群侧安装 agent 了。

Kubernetes 上安装 agent(agentk)

在 Kubernetes 上安装 agent 时,有三个必要参数:

  • your-agent-token(上述步骤已经获取);

  • Agent 所在的 namespace,这个自定义即可,本文用 gitlab-kubernetes-agent;

  • Kubernetes Agent Server(KAS)的地址。以极狐GitLab 用户为例,地址为 wss://kas.gitlab.cn

接下来可以用如下命令进行一键式安装

$ docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token --kas-address=wss://kas.gitlab.cn --agent-version stable --namespace gitlab-kubernetes-agent | kubectl apply -f -

将上述的--agent-token指定为前面步骤获取的值,同时用--namespace指定 agent 安装的 namespace,然后执行上述命令

$ docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --agent-token=your-agent-token  --kas-address=wss://kas.gitlab.cn --agent-version stable --namespace gitlab-kubernetes-agent | kubectl apply -f -
stable: Pulling from gitlab-org/cluster-integration/gitlab-agent/cli
Digest: sha256:a34079259440dcb627947e4df26fe5462829a3d6622d031ea0129e5953b70281
Status: Image is up to date for registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable
namespace/gitlab-kubernetes-agent created
serviceaccount/gitlab-agent created
clusterrole.rbac.authorization.k8s.io/cilium-alert-read created
clusterrole.rbac.authorization.k8s.io/gitlab-agent-gitops-read-all created
clusterrole.rbac.authorization.k8s.io/gitlab-agent-gitops-write-all created
clusterrolebinding.rbac.authorization.k8s.io/cilium-alert-read created
clusterrolebinding.rbac.authorization.k8s.io/gitlab-agent-gitops-read-all created
clusterrolebinding.rbac.authorization.k8s.io/gitlab-agent-gitops-write-all created
secret/gitlab-agent-token-8ccgb67gb2 created
deployment.apps/gitlab-agent created

安装完毕,可在gitlab-kubernetes-agent namespace 下查看 agent pod:

$ kubectl -n gitlab-kubernetes-agent get pods
NAME                            READY   STATUS    RESTARTS   AGE
gitlab-agent-866cc7fb95-5dgc2   1/1     Running   0          42s

查看 pods 的 log,如果成功的话会看到下面的内容:

{"level":"info","time":"2021-08-17T05:31:44.009Z","msg":"Cluster successfully synced","mod_name":"gitops","project_id":"your-configruation-project"}

说明 agent 在 Kubernetes 集群侧安装成功,且 agent 已和 config Project 同步成功。接下来就可以进行 GitOps workflow 实践了。

极狐GitLab GitOps workflow 实践


实践的前提条件

  • 一个运行良好的极狐GitLab 实例(方便期间,推荐使用极狐GitLab Saas 产品,也即 GitLab-10万企业使用的一站式DevOps平台_GitLab中文官网);

  • 一个运行良好的 Kubernetes 集群(本文使用 Desktop 自带的 Kubernets 集群)。

根据上面的理论介绍,极狐GitLab GitOps workflow 需要有存放 config.yaml 文件和部署清单文件的 Project。两个可以用不同的 Project,也可以用同一个 Project,本次实践是将全部文件存放在同一个极狐GitLab Project 下面。目录结构如下:

├── .gitlab
│   └── agents
│       └── gitops
│           └── config.yaml
├── README.md
└── deployment└── deployment.yaml

其中 .gitlab/agents/gitops/ 是 config.yaml 文件存放的路径,gitops 是创建的 agent 名称,config.yaml 文件的内容如下:

gitops:manifest_projects:- id: "your-jihu-GitLab-project-which-you-want-to-be-listened-by-agent"paths:- glob: '/**/*.yaml'
observability:logging:level: debug

其中 id 表示存放部署清单文件的 Project 路径,glob 表示 agent 要监听的文件,可以监听所有的文件,也可以监听某个目录下的文件。具体的语法可以在这儿查看。而 deployment 目录下存放的则是需要部署的清单文件,本文以部署 nginx 来做示范,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentnamespace: gitlab-kubernetes-agent 
spec:selector:matchLabels:app: nginxreplicas: 1template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80

上述内容会在 gitlab-kubernetes-agent namesace 下面部署一个名为 nginx-deployment 的 deployment,且 pod 副本数为 1。

$ kubectl -n gitlab-kubernetes-agent get deploy,pods
NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gitlab-agent       1/1     1            1           4h3m
deployment.apps/nginx-deployment   1/1     1            1           4hNAME                                    READY   STATUS    RESTARTS   AGE
pod/gitlab-agent-866cc7fb95-5dgc2       1/1     Running   0          4h3m
pod/nginx-deployment-66b6c48dd5-mzwdb   1/1     Running   0          4h

接下来我们将 deployment.yaml 文件中的 replicas 修改为 2,来触发极狐GitLab GitOps workflow。观察 agent 的 log 可以看到如下内容:

$ kubectl -n gitlab-kubernetes-agent logs -f gitlab-agent-866cc7fb95-5dgc2
{"level":"info","time":"2021-08-17T09:34:58.406Z","msg":"Applying resource Deployment/nginx-deployment in cluster: https://10.96.0.1:443, namespace: gitlab-kubernetes-agent","mod_name":"gitops","project_id":"jihulab/marketing/technical-marketing/devops-demo"}
{"level":"info","time":"2021-08-17T09:34:58.502Z","msg":"Synced","mod_name":"gitops","project_id":"jihulab/marketing/technical-marketing/devops-demo","resource_key":"apps/Deployment/gitlab-kubernetes-agent/nginx-deployment","sync_result":"deployment.apps/nginx-deployment configured"}

同时查看 nginx-deployment 的 pod 数量变化:

$ kubectl -n gitlab-kubernetes-agent get pods -w
NAME                                READY   STATUS    RESTARTS   AGE
gitlab-agent-866cc7fb95-5dgc2       1/1     Running   0          4h5m
nginx-deployment-66b6c48dd5-mzwdb   1/1     Running   0          4h2m
nginx-deployment-66b6c48dd5-hpwqd   0/1     Pending   0          0s
nginx-deployment-66b6c48dd5-hpwqd   0/1     Pending   0          0s
nginx-deployment-66b6c48dd5-hpwqd   0/1     ContainerCreating   0          0s
nginx-deployment-66b6c48dd5-hpwqd   1/1     Running             0          2s

可以看到有新的 pod 被创建,当前 nginx-deployment 下的 pod 副本数是 2,这和部署清单文件里面描述的是一致的。也再次证明:当部署清单文件发生任何变更的时候,变更会被自动同步至 Kubernetes 集群侧

写在最后


极狐GitLab 在设计 kas 和 agentk 的时候,倾向于把功能逻辑添加在 kas 中,而不是 agentk 中。尽量保持了 agentk 的精简,以便能够减少对于升级的需要,这也减少了维护人员的升级工作负担。因为在 gitlab.cn 中,kas 是由极狐GitLab 来管理的,所以功能的添加和版本的升级都是极狐侧来完成,而无需要求用户同步升级 agentk。这一点,其实在类似 agent/server 的设计架构中还是值得借鉴的。

相关文章:

使用 Kubernetes Agent Server 实现 GitOps

目录 温习 GitOps 极狐GitLab Kubernetes Agent 极狐GitLab GitOps workflow 极狐GitLab KAS 的配置 创建极狐GitLab agent 创建 agent token Kubernetes 上安装 agent(agentk) 极狐GitLab GitOps workflow 实践 写在最后 温习 GitOps GitOps …...

Day12 qt QMianWindow,资源文件,对话框,布局方式,常用ui控件

QMianWindow 概述 QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏( menu bar )、多 个工具栏 (tool bars) 、多个铆接部件 (dock widgets) 、一个状态栏 (status bar) 及 一个中心部件 (central widget) 许多应用程序的基础…...

Python实现广义线性回归模型(statsmodels GLM算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 广义线性模型(Generalized Linear Model,简称GLM)是一种广泛应用于回归分析和分类问题的统…...

GNSEC 2022年第8届全球下一代软件工程线上峰会-核心PPT资料下载

一、峰会简介 新一代软件工程是指利用新的理论、方法和技术,在软件开发、部署、运维等过程中,实现软件的可控、可预测、可维护的软件生产方式。它涵盖了多个领域,如软件开发、测试、部署、运维等,旨在提高软件生产效率和质量。 …...

nVisual能为数据中心解决什么问题?

nVisual通过可视化的管理方式,使数据中心管理者能够有效且高效地管理数据中心的资产、线缆、容量、变更;使数据中心管理者能够获得如下问题的答案,以便能够快速做出更好、更明智的决策: 1.资产管理 我们有什么&#x…...

Android--Jetpack--Databinding详解

不经一番寒彻骨,怎得梅花扑鼻香 一,定义 DataBinding, 又名数据绑定,是Android开发中非常重要的基础技术,它可以将UI组件和数据模型连接起来,使得在数据模型发生变化时,UI组件自动更新。是 MVVM 模式在 An…...

Node.js入门指南(完结)

目录 接口 介绍 RESTful json-server 接口测试工具 会话控制 介绍 cookie session token 上一篇文章我们介绍了MongoDB,这一篇文章是Node.js入门指南的最后一篇啦!主要介绍接口以及会话控制。 接口 介绍 接口是前后端通信的桥梁 &#xff0…...

MySQL和Java通用加密解密方式

加密方式使用 AES 加密,再转成 Base64。 SQL -- 加密 update your_table set your_columnto_base64(aes_encrypt(your_column, "password"));-- 解密 select aes_decrypt(from_base64(your_column) ,"password") from your_table; 使用原生 …...

若依前端APP版使用教程

1 增加页面流程 新增Page>新增API>新增组件>新增样式>新增路径(page.json) {"path": "pages/mes/pro/feedback/index","style": {"navigationBarTitleText": "工单报工"}} <template><view class&quo…...

2023 年工程师不可错过的 AI 主要发展趋势

从对未来的好奇到关键的企业工具&#xff0c;人工智能的发展证明了它对工程师的价值。不久前&#xff0c;Gartner 预测&#xff0c;采用人工智能工程实践来构建和管理自适应人工智能系统的企业&#xff0c;在实施人工智能模型方面的表现将优于同行至少 25%&#xff0c;这为各组…...

记录 | 安装地平线工具链install_ai_toolchain.sh出现cython版本问题报错解决

安装地平线工具链 install_ai_toolchain.sh&#xff1a; cd ddk/package/host/ai_toolchain bash install_ai_toolchain.sh出现报错&#xff1a; Requirement already satisfied: packaging>20.0 in /root/.local/lib/python3.8/site-packages (from matplotlib>2.1.0-…...

Java8流操作

Java8流操作 1. 双层Map一层List 1. 双层Map一层List 代码片 // 开始分组Map<String, Map<Object, List<ProjectGeographyVO>>> collect4 vos.stream()// 注释了下行没用市级项目,只有区// .filter(data -> String.valueOf(data.getCode()).length() …...

vue-socket.io以及原生websocket的使用

vue3使用socket.io 1、安装 npm install vue-socket.io2、创建socket.js文件 export const registerSockets (sockets, proxy) > {sockets &&Object.keys(sockets).forEach((t) > {// console.log(t);// "subscribe" ! t &&// "un…...

谷歌推出功能最强大的大语言模型Gemini;大规模语言模型:从理论到实践

&#x1f989; AI新闻 &#x1f680; 谷歌推出功能最强大的大语言模型Gemini 摘要&#xff1a;谷歌正式推出其迄今为止功能最强大、最通用的大语言模型Gemini。Gemini在许多测试中表现出了最先进的性能&#xff0c;在大部分基准测试中击败了OpenAI的GPT-4。谷歌发布了三种不同…...

Android studio 工程的 module 依赖关系图绘制 、 Android Module 依赖关系的可视化实现

整体步骤&#xff1a; 1、利用gradle脚本生成dot&#xff1b; 2、利用graphviz将dot可视化转为图片 利用gradle脚本生成dot 下载projectDependencyGraph.gradle脚本 下载 projectDependencyGraph.gradle &#xff0c;放在项目根目录&#xff0c; 源码如下&#xff1a; t…...

Qt之QGraphicsView —— 笔记1.2:将QGraphicsView放置主窗口上,绘制简单图元(附完整源码)

效果 相关类介绍 QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。QGraphicsView在可滚动视口中可视化。QGraphicsView将滚动其视口,以确保该点在视图中居中。 QGraphicsScene类 提供了一个用于管理大量二维图形项的场景。请注意,QGraphicsScene没有自己的视…...

linux的权限管理

在Linux系统中&#xff0c;文件和目录的权限管理是通过用户、组以及其他用户对文件和目录的读&#xff08;r&#xff09;、写&#xff08;w&#xff09;和执行&#xff08;x&#xff09;权限来实现的。以下是有关Linux权限管理的详细解释&#xff1a; 文件和目录权限&#xff1…...

什么是 performance_schema ?

MySQL的performance_schema是运行在较低级别的用于监控MySQL Server运行过程中的资源消耗、资源等待等情况的一个功能特性&#xff0c;它具有以下特点。 performance_schema提供了一种在数据库运行时实时检查Server内部执行情况的方法。performance_schema数据库中的表使用per…...

软件多开助手的创新使用:在同一设备上玩转多个游戏

软件多开助手&#xff1a;在同一设备上玩转多个游戏的创新使用 随着科技的不断发展&#xff0c;手机和电脑已经成为我们生活中必不可少的工具。众多游戏爱好者也越来越追求在同一设备上同时体验多个游戏的乐趣。而软件多开助手的出现为这一需求提供了创新的解决方案。 传统上…...

[linux] 输出文本文件的最后一列并去重

使用 awk 命令来实现这个需求。下面是一个示例命令&#xff1a; awk -F , {print $NF} a.txt | sort -u解释一下这个命令&#xff1a; awk -F , {print $NF} a.txt&#xff1a;使用逗号作为字段分隔符&#xff08;-F ,&#xff09;&#xff0c;打印每行的最后一个字段&#x…...

探秘书匠策AI:毕业论文写作的“智慧引擎”

在学术探索的征途中&#xff0c;毕业论文如同一座巍峨的山峰&#xff0c;让无数学生既敬畏又向往。它不仅是对所学知识的综合检验&#xff0c;更是学术生涯的重要里程碑。然而&#xff0c;面对这座大山&#xff0c;许多人常常感到力不从心&#xff0c;选题迷茫、文献难觅、结构…...

Nunchaku FLUX.1 CustomV3部署案例:AI绘画培训课程实训环境标准化镜像交付方案

Nunchaku FLUX.1 CustomV3部署案例&#xff1a;AI绘画培训课程实训环境标准化镜像交付方案 1. 引言&#xff1a;当AI绘画遇上教育培训的规模化挑战 如果你正在运营一个AI绘画培训班&#xff0c;或者负责一个数字艺术学院的课程设计&#xff0c;你肯定遇到过这样的难题&#x…...

嵌入式系统中的累加和校验算法原理与实现

1. 累加和校验算法概述在嵌入式系统开发中&#xff0c;数据通信的可靠性至关重要。想象一下&#xff0c;当你通过无线模块控制一台工业机器人时&#xff0c;如果传输的运动指令数据出现错误&#xff0c;可能导致机械臂做出完全不可预测的动作&#xff0c;轻则损坏产品&#xff…...

大模型风口已至!普通人如何逆袭拿高薪?学员真实案例告诉你答案!

在人工智能飞速发展的今天&#xff0c;大模型已成为科技行业的核心赛道&#xff0c;无数人渴望抓住这波风口实现职业跃迁。而我们的大模型学员&#xff0c;用一份份亮眼的 offer&#xff0c;交出了完美答卷&#xff01; &#x1f31f; 平凡起点&#xff0c;非凡逆袭 他们中有**…...

Qwen3-TTS WebUI使用技巧:长文本自动分段+情感一致性保持方法

Qwen3-TTS WebUI使用技巧&#xff1a;长文本自动分段情感一致性保持方法 Qwen3-TTS-12Hz-1.7B-CustomVoice 是一款强大的语音合成模型&#xff0c;支持10种主要语言和多种方言语音风格&#xff0c;具备出色的上下文理解能力和情感表达能力。但在处理长文本时&#xff0c;如何保…...

3步解决字幕处理90%的麻烦:BiliBiliCCSubtitle效率革命

3步解决字幕处理90%的麻烦&#xff1a;BiliBiliCCSubtitle效率革命 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 开篇&#xff1a;三个真实场景的效率反差 场景…...

数据安全与性能瓶颈困扰企业?湖南天硕SSD固态硬盘带来航天级稳定体验

在数字化转型加速的今天&#xff0c;企业数据量呈指数级增长&#xff0c;随之而来的数据安全风险与存储性能瓶颈已成为众多企业&#xff0c;尤其是对数据可靠性要求极高的B端用户&#xff08;如企业采购负责人、技术总监&#xff09;面临的共同挑战。传统存储方案在应对复杂业务…...

5个Windows运行Android应用方案测评:普通用户的轻量级跨平台解决方案

5个Windows运行Android应用方案测评&#xff1a;普通用户的轻量级跨平台解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 在数字化办公与娱乐日益融合的今天&am…...

周末高质量遛娃,你真的找对地方了吗?

“周末想高质量遛娃&#xff0c;却不知找对地方了没&#xff1f;” 周末对于家长来说&#xff0c;是陪伴孩子的黄金时间&#xff0c;都希望能给孩子一段既有趣又有意义的时光。但究竟哪里才是高质量遛娃的好去处呢&#xff1f;下面就为您详细解答。遛娃地点基础认知类Q&#xf…...

从零到实战:用QCustomPlot在QT中绘制动态曲线图(含OpenGL加速配置)

从零到实战&#xff1a;用QCustomPlot在QT中绘制动态曲线图&#xff08;含OpenGL加速配置&#xff09; 第一次接触QT绘图功能时&#xff0c;我被它的灵活性震撼到了——直到尝试绘制实时动态数据&#xff0c;才意识到性能优化的重要性。QCustomPlot这个轻量级库完美平衡了易用性…...