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

Kubernetes 控制器深度解析:DaemonSet

在 Kubernetes 集群中,DaemonSet 是专门用于管理 “节点级服务” 的核心控制器,其核心目标是确保集群中所有(或指定)节点运行且仅运行一个 Pod 副本。无论是日志收集、节点监控,还是存储服务,只要需要在每个节点部署统一组件,DaemonSet 都是最优选择。本文将从概念原理、资源清单、实战案例到运维操作,全面拆解 DaemonSet 的核心能力。

一、DaemonSet 核心概念与原理

1.1 什么是 DaemonSet?

DaemonSet控制器的设计理念是“节点伴随式部署”:当集群新增节点时,Daemonset会自动在新节点上创建指定Pod;当节点从集群移除时,对应的Pod也会被自动删除;若删除DaemonSet,其管理的所有Pod会被批量清理。

核心特征

  • 单节点单副本:每个节点最多运行一个 DaemonSet Pod(避免资源浪费与功能冲突);

  • 节点自动适配:无需手动调度,DaemonSet 自动感知节点变化并同步 Pod 状态;

  • 节点级资源绑定:Pod 通常需挂载节点本地资源(如 /var/log/dev 设备),实现对节点的监控或控制。

1.2 DaemonSet 工作原理

DaemonSet控制器通过“监听-调和”机制维护集群状态,核心流程如下:

1.监听对象

  • DaemonSet 对象:获取用户定义的 “期望状态”(如 Pod 模板、节点选择器);

  • Node 对象:监控节点的新增、删除、状态变更(如 Ready/NotReady);

  • Pod 对象:检查每个节点上是否存在符合条件的 Pod,避免重复创建或遗漏。

2.调和逻辑(syncLoop 循环)

  • 对每个 “健康节点”(如 Ready 状态且匹配节点选择器),检查是否存在 DaemonSet Pod:

    • 若不存在:根据 Pod 模板创建 Pod,并调度到该节点;

    • 若已存在:检查 Pod 镜像、配置是否与 DaemonSet 一致,不一致则触发更新;

  • 对 “非健康节点”(如 NotReady 或已删除),清理对应的 DaemonSet Pod,避免无效资源占用。

1.3 DaemonSet 典型应用场景

DaemonSet专为“节点级服务”设计,以下是常见的三类场景:

场景类型典型组件核心需求
日志收集Fluentd、Filebeat、Logstash每个节点需收集本地日志(如 /var/log、容器日志),统一上报至日志平台
节点监控Prometheus Node Exporter、Collectd每个节点需暴露硬件 / 系统指标(如 CPU 使用率、内存占用),供监控系统采集
存储服务Glusterd、Ceph OSD每个节点需提供存储能力(如本地磁盘管理),构建分布式存储集群
网络插件Calico、Flannel(agent 组件)每个节点需运行网络代理,实现 Pod 网络互通

1.4 DaemonSet vs Deployment:核心区别

对比维度DaemonSetDeployment
副本调度逻辑按节点分配,每个节点 1 个副本按 “副本数” 分配,节点可运行多个副本
调度方式自动绑定节点,无需 nodeSelector 也能全量部署依赖调度器随机分配,需 nodeSelector 才定向到指定节点
适用服务类型节点级服务(如监控、日志)集群级服务(如 Web、API)
资源依赖通常挂载节点本地资源(hostPath多依赖共享存储(如 PVC、ConfigMap)
更新策略支持 RollingUpdate(默认)、OnDelete支持 RollingUpdate(默认)、Recreate

二、DaemonSet 资源清单编写技巧

DaemonSet 资源清单的核心是 “Pod 模板定义” 与 “节点选择逻辑”,需严格遵循 Kubernetes API 规范。以下从字段解析到完整示例,拆解清单编写要点。

2.1 核心字段解析

通过 kubectl explain ds 和 kubectl explain ds.spec 可查看所有字段,重点关注以下必填 / 核心配置:

字段层级字段名作用说明
apiVersion-固定为 apps/v1(K8s 1.9+ 版本统一)
kind-固定为 DaemonSet,声明资源类型
metadatanameDaemonSet 名称(如 fluentd-elasticsearch
metadatanamespace命名空间(建议将节点级组件放在 kube-system,如监控、日志组件)
metadatalabelsDaemonSet 自身标签,用于资源筛选(如 k8s-app: fluentd-logging
spec.selector(必填)matchLabels标签选择器,需与 spec.template.metadata.labels 完全匹配(否则无法关联 Pod)
spec.template(必填)-Pod 模板,定义 DaemonSet 管理的 Pod 配置(与 Deployment 的 Pod 模板格式一致)
spec.updateStrategytype更新策略:RollingUpdate(默认,滚动更新)、OnDelete(手动删除后更新)
spec.updateStrategy.rollingUpdatemaxUnavailable滚动更新时允许不可用的最大 Pod 数(默认 1,支持百分比如 10%
spec.revisionHistoryLimit-保留的历史版本数(默认 10,可减少以节省资源)
spec.template.spectolerations污点容忍(关键!用于在有污点的节点部署,如控制节点)
spec.template.speccontainers容器配置(镜像、端口、资源、挂载等)
spec.template.specvolumes卷配置(常用 hostPath 挂载节点本地目录)

2.2 完整资源清单示例(部署 Fluentd 日志收集)

以 “在所有节点部署 Fluentd 收集日志” 为例,编写 DaemonSet 清单(daemonset-fluentd.yaml),包含节点容忍、本地目录挂载、资源限制等关键配置:

apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluentd-elasticsearch  # DaemonSet 名称namespace: kube-system       # 部署在系统命名空间,便于管理节点级组件labels:k8s-app: fluentd-logging   # 自定义标签,用于筛选资源
spec:# 标签选择器:关联符合条件的 Pod(必须与 template.metadata.labels 一致)selector:matchLabels:name: fluentd-elasticsearch# 更新策略:默认 RollingUpdate,maxUnavailable=1(每次更新 1 个节点,避免集群日志断流)updateStrategy:rollingUpdate:maxUnavailable: 1type: RollingUpdate# 保留 5 个历史版本,便于回滚(默认 10,可根据需求调整)revisionHistoryLimit: 5# Pod 模板:定义每个节点上运行的 Pod 配置template:metadata:labels:name: fluentd-elasticsearch  # 与 selector.matchLabels 一致spec:# 污点容忍:允许在控制节点(如 master/control-plane)部署# 控制节点默认有 node-role.kubernetes.io/control-plane 污点,需容忍才能调度tolerations:- key: node-role.kubernetes.io/control-planeeffect: NoSchedule  # 容忍策略:不调度新 Pod 到该节点,但已存在的 Pod 不驱逐- key: node-role.kubernetes.io/master  # 兼容旧版本 K8s(master 节点标签)effect: NoSchedule# 容器配置:Fluentd 核心配置containers:- name: fluentd-elasticsearch  # 容器名称image: docker.io/library/fluentd:v2.5.1  # 容器镜像(建议提前拉取到所有节点)imagePullPolicy: IfNotPresent  # 镜像拉取策略:本地有则不拉取# 资源限制:避免 Fluentd 占用过多节点资源resources:limits:memory: 200Mi  # 最大内存限制requests:cpu: 100m      # 最小 CPU 请求memory: 200Mi  # 最小内存请求# 卷挂载:挂载节点本地目录,用于收集日志volumeMounts:- name: varlog  # 卷名称,与 spec.volumes.name 一致mountPath: /var/log  # 容器内挂载路径:收集节点系统日志- name: varlibdockercontainers  # 卷名称mountPath: /var/lib/docker/containers  # 容器内挂载路径:收集容器日志readOnly: true  # 只读挂载,避免修改节点容器数据# 优雅关闭:停止前等待 30 秒,确保日志完全上传terminationGracePeriodSeconds: 30# 卷定义:关联节点本地资源volumes:- name: varlog  # 与 volumeMounts.name 一致hostPath:path: /var/log  # 节点本地目录:系统日志路径- name: varlibdockercontainers  # 与 volumeMounts.name 一致hostPath:path: /var/lib/docker/containers  # 节点本地目录:容器日志路径

2.3 关键配置说明

(1)污点容忍(tolerations)

Kubernetes 控制节点(如 control-plane)默认会打上污点(node-role.kubernetes.io/control-plane:NoSchedule),阻止普通 Pod 调度。若需在控制节点部署 DaemonSet(如监控控制节点),必须添加对应的容忍配置,否则 Pod 会处于 Pending 状态。

(2)hostPath 卷挂载

DaemonSet 通常需访问节点本地资源,hostPath 是最常用的卷类型,需注意:

  • 路径一致性:确保所有节点的本地路径存在(如 /var/log 是所有 Linux 节点的默认日志路径);
  • 权限控制:若挂载目录需写入权限(如日志采集),需确保容器内用户有对应权限(可通过 securityContext 配置 runAsUser);
  • containerd 日志路径:若集群使用 containerd 容器运行时,容器日志路径可能为 /var/log/containers/ 或 /var/log/pods/,需根据实际路径调整挂载配置。
(3)资源限制(resources)

节点级组件(如 Fluentd、Node Exporter)若不限制资源,可能因日志量突增或内存泄漏占用过多节点资源,导致节点不可用。建议根据节点配置合理设置 limits 和 requests(如 100m CPU + 200Mi 内存)。

三、DaemonSet 实战:部署与验证

以 “部署 Fluentd 日志收集” 为例,完整演示 DaemonSet 的创建、验证与核心功能验证。

3.1 前置准备

1.镜像预处理:由于 DaemonSet 需在所有节点部署 Pod,建议提前将镜像拉取到每个节点(避免多节点同时拉取导致网络压力):

# 在所有节点执行(以 containerd 为例)
ctr -n k8s.io images pull docker.io/library/fluentd:v2.5.1
# 或导入本地镜像(若镜像已下载到本地)
ctr -n k8s.io images import fluentd-v2.5.1.tar.gz

2.节点状态检查:确保所有节点处于 Ready 状态:

kubectl get nodes
# 输出示例(3 个节点均为 Ready)
# NAME   STATUS   ROLES           AGE   VERSION
# hd1    Ready    control-plane   30d   v1.27.0
# hd2    Ready    <none>          30d   v1.27.0
# hd3    Ready    <none>          30d   v1.27.0

3.2 创建 DaemonSet

# 应用资源清单
kubectl apply -f daemonset-fluentd.yaml# 验证 DaemonSet 创建结果
kubectl get ds -n kube-system -l k8s-app=fluentd-logging
# 输出示例(DESIRED=3,CURRENT=3,READY=3 表示所有节点部署成功)
# NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   AGE
# fluentd-elasticsearch    3         3         3       3            3           2m

3.3 验证 Pod 部署状态

DaemonSet 会在每个节点创建一个 Pod,Pod 名称格式为 DaemonSet 名-随机字符串(如 fluentd-elasticsearch-7xq2z):

# 查看所有 DaemonSet Pod,包含节点信息
kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o wide
# 输出示例(3 个 Pod 分别运行在 hd1、hd2、hd3 节点)
# NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE
# fluentd-elasticsearch-7xq2z   1/1     Running   0          3m   10.244.0.5    hd1    <none>
# fluentd-elasticsearch-9f2k3   1/1     Running   0          3m   10.244.1.6    hd2    <none>
# fluentd-elasticsearch-p4s7x   1/1     Running   0          3m   10.244.2.7    hd3    <none>

3.4 验证核心功能(日志收集)

Fluentd 挂载了节点的 /var/log 目录,可进入 Pod 验证是否成功读取节点日志:

# 进入其中一个 Fluentd Pod(替换为实际 Pod 名称)
kubectl exec -it -n kube-system fluentd-elasticsearch-7xq2z -- sh# 在 Pod 内查看挂载的节点日志(如 /var/log/messages)
cat /var/log/messages
# 若能看到节点系统日志,说明卷挂载成功,日志收集功能正常

3.5 验证节点自动适配

新增一个节点(如 hd4),验证 DaemonSet 是否自动在新节点部署 Pod:

# 1. 新增节点 hd4 并加入集群(过程略)
# 2. 查看节点状态(确保 hd4 为 Ready)
kubectl get nodes# 3. 查看 DaemonSet Pod(hd4 节点会自动创建 Pod)
kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o wide
# 输出会新增一行:fluentd-elasticsearch-xxxxxx   1/1     Running   0          1m   10.244.3.8    hd4    <none>

四、DaemonSet 运维操作:更新、回滚与删除

DaemonSet 的运维需围绕 “节点级服务稳定性” 展开,重点关注更新策略、版本回滚与资源清理。

4.1 镜像更新

DaemonSet 支持两种更新策略:RollingUpdate(默认)和 OnDelete,需根据业务场景选择。

4.1.1 RollingUpdate(滚动更新)

默认策略,按 maxUnavailable 配置批量更新 Pod(如 maxUnavailable=1 表示每次更新 1 个节点),避免所有节点同时离线导致服务中断。

操作步骤

# 方式 1:kubectl set image(推荐,直接指定新镜像)
# 格式:kubectl set image daemonset/<DaemonSet名> <容器名>=<新镜像> -n <命名空间>
kubectl set image daemonset/fluentd-elasticsearch fluentd-elasticsearch=docker.io/library/fluentd:v2.6.0 -n kube-system# 方式 2:编辑 DaemonSet 配置(适合需修改多字段场景)
kubectl edit daemonset fluentd-elasticsearch -n kube-system
# 在编辑器中修改 spec.template.spec.containers[0].image 为 fluentd:v2.6.0,保存退出# 查看更新进度(-w 实时监控 Pod 重建过程)
kubectl get pods -n kube-system -l name=fluentd-elasticsearch -w
# 输出示例(Pod 按节点分批重建,旧 Pod 先删除,新 Pod 再创建):
# NAME                          READY   STATUS        RESTARTS   AGE
# fluentd-elasticsearch-7xq2z   1/1     Terminating   0          10m  # 旧 Pod 终止
# fluentd-elasticsearch-9x8y7   0/1     Pending       0          0s   # 新 Pod 创建
# fluentd-elasticsearch-9x8y7   0/1     ContainerCreating   0          2s
# fluentd-elasticsearch-9x8y7   1/1     Running             0          5s  # 新 Pod 就绪
# ...(其他节点 Pod 依次更新)

4.1.2 OnDelete(手动触发更新)

若服务对中断敏感(如存储节点代理),可将更新策略改为 OnDelete:只有手动删除旧 Pod,DaemonSet 才会创建新镜像的 Pod,便于逐个节点验证稳定性。

操作步骤

  1. 修改更新策略

kubectl edit daemonset fluentd-elasticsearch -n kube-system
# 将 spec.updateStrategy.type 改为 OnDelete,保存退出:
# spec:
#   updateStrategy:
#     type: OnDelete  # 替换默认的 RollingUpdate

2.更新镜像配置

kubectl set image daemonset/fluentd-elasticsearch fluentd-elasticsearch=fluentd:v2.6.0 -n kube-system
# 此时 Pod 不会自动更新,需手动删除

3.手动触发更新(逐个节点验证):

# 1. 删除第一个节点的旧 Pod(如 hd2 节点的 Pod)
kubectl delete pod -n kube-system fluentd-elasticsearch-9f2k3
# 2. 验证新 Pod 启动并使用新镜像
kubectl get pod -n kube-system fluentd-elasticsearch-xxxxxx -o jsonpath='{.spec.containers[0].image}'
# 输出:docker.io/library/fluentd:v2.6.0(确认新镜像生效)
# 3. 重复步骤 1-2,更新其他节点 Pod

4.2 版本回滚

若更新后出现问题(如镜像崩溃、功能异常),可通过 DaemonSet 的 “历史版本” 回滚到上一个稳定状态。DaemonSet 会保留 revisionHistoryLimit(默认 10)个历史版本,通过 kubectl rollout 命令管理。

操作步骤

  1. 查看历史版本

# 查看 DaemonSet 的所有历史版本
kubectl rollout history daemonset fluentd-elasticsearch -n kube-system
# 输出示例:
# daemonsets "fluentd-elasticsearch"
# REVISION  CHANGE-CAUSE
# 1         kubectl apply --filename=daemonset-fluentd.yaml --record=true  # 初始版本(v2.5.1)
# 2         kubectl set image daemonset/fluentd-elasticsearch ...  # 更新后的版本(v2.6.0)

2.查看指定版本的详细配置(可选,确认回滚目标):

# 查看版本 1 的详细配置(如镜像、资源限制)
kubectl rollout history daemonset fluentd-elasticsearch -n kube-system --revision=1

3.执行回滚

# 方式 1:回滚到上一个版本(快捷命令,适合从最新版回滚)
kubectl rollout undo daemonset fluentd-elasticsearch -n kube-system# 方式 2:回滚到指定版本(如回滚到版本 1)
kubectl rollout undo daemonset fluentd-elasticsearch -n kube-system --to-revision=1

4.验证回滚结果

# 查看 Pod 镜像是否恢复为旧版本(v2.5.1)
kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o jsonpath='{range .items[*]}{.metadata.name}{": "}{.spec.containers[0].image}{"\n"}{end}'
# 输出示例(所有 Pod 均恢复为 v2.5.1):
# fluentd-elasticsearch-7xq2z: docker.io/library/fluentd:v2.5.1
# fluentd-elasticsearch-9f2k3: docker.io/library/fluentd:v2.5.1

4.3 Pod 清理与 DaemonSet 删除

4.3.1 临时清理单个节点的 Pod(保留 DaemonSet)

若需在某个节点临时停止 DaemonSet 服务(如节点维护),可直接删除该节点的 Pod,且禁止 DaemonSet 自动重建(需通过 kubectl cordon 或节点污点实现):

# 1. 标记节点为“不可调度”(避免 DaemonSet 重新创建 Pod)
kubectl cordon hd3  # hd3 为目标节点名# 2. 删除该节点的 DaemonSet Pod
kubectl delete pod -n kube-system $(kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o jsonpath='{range .items[?(@.spec.nodeName=="hd3")]}{.metadata.name}{"\n"}{end}')# 3. 验证 Pod 未重建(hd3 节点无对应 Pod)
kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o wide | grep hd3# 4. 节点维护完成后,恢复调度(DaemonSet 会自动重建 Pod)
kubectl uncordon hd3

4.3.2 彻底删除 DaemonSet(含所有 Pod)

若不再需要 DaemonSet 服务,删除 DaemonSet 会自动清理其管理的所有 Pod,但不会删除挂载的节点本地资源(如 /var/log 目录):

# 删除 DaemonSet(会批量删除所有 Pod)
kubectl delete daemonset fluentd-elasticsearch -n kube-system# 验证删除结果(DaemonSet 和 Pod 均不存在)
kubectl get ds -n kube-system | grep fluentd-elasticsearch  # 无输出
kubectl get pods -n kube-system | grep fluentd-elasticsearch  # 无输出

4.4 节点包含 / 排除:指定节点部署 DaemonSet

默认情况下,DaemonSet 会在所有健康节点部署 Pod。若需仅在部分节点部署(如 “只在存储节点部署 Glusterd”),可通过 节点选择器(nodeSelector) 或 节点亲和性(nodeAffinity) 实现。

4.4.1 方式 1:nodeSelector(简单匹配,适合固定标签)
  1. 为目标节点打标签(如为所有 “监控节点” 打 node-role=monitor 标签):

kubectl label nodes hd2 hd3 node-role=monitor  # hd2、hd3 为目标节点

2.编辑 DaemonSet,添加 nodeSelector

kubectl edit daemonset fluentd-elasticsearch -n kube-system
# 在 spec.template.spec 下添加 nodeSelector:
# spec:
#   template:
#     spec:
#       nodeSelector:
#         node-role: monitor  # 仅在带该标签的节点部署
#       tolerations:  # 保留原有容忍配置
#       - key: node-role.kubernetes.io/control-plane
#         effect: NoSchedule

3.验证结果(仅 hd2、hd3 节点有 Pod,hd1 节点无 Pod):

kubectl get pods -n kube-system -l name=fluentd-elasticsearch -o wide
4.4.2 方式 2:nodeAffinity(复杂匹配,适合多条件)

若需更灵活的节点选择(如 “排除标签为 node-role=control-plane 的节点”),可使用 nodeAffinity 的 requiredDuringSchedulingIgnoredDuringExecution(调度时必须满足,运行中忽略标签变化)

kubectl edit daemonset fluentd-elasticsearch -n kube-system
# 添加节点亲和性配置:
spec:template:spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: node-role.kubernetes.io/control-planeoperator: DoesNotExist  # 排除控制节点(无该标签的节点才会被调度)tolerations:- key: node-role.kubernetes.io/control-planeeffect: NoSchedule

五、DaemonSet 关键注意事项与最佳实践

5.1 避免常见问题

  1. 控制节点部署失败:控制节点(如 control-plane)默认有 node-role.kubernetes.io/control-plane 污点,需在 tolerations 中添加对应容忍,否则 Pod 会处于 Pending 状态。

  2. 镜像拉取超时:DaemonSet 需在所有节点拉取镜像,建议提前通过 ctr images pull 或 docker pull 将镜像同步到每个节点,避免多节点同时拉取导致网络拥堵。

  3. hostPath 权限问题:若挂载的节点目录(如 /var/log)权限为 root:root,需在容器 securityContext 中配置 runAsUser: 0(以 root 用户运行),否则会因权限不足无法读取日志:

spec:template:spec:containers:- name: fluentd-elasticsearchimage: fluentd:v2.5.1securityContext:runAsUser: 0  # 以 root 用户运行容器

5.2 最佳实践

  1. 命名空间选择:节点级组件(如日志、监控、网络插件)建议部署在 kube-system 命名空间,便于集中管理和权限控制。

  2. 资源限制必须配置:严禁不设置 resources.limits,避免 DaemonSet Pod 因内存泄漏或日志量突增占用节点全部资源(如 Fluentd 建议设置 limits: { memory: 200Mi })。

  3. 历史版本保留精简:若集群节点多(如 100+ 节点),revisionHistoryLimit 建议设为 3-5(默认 10),减少 etcd 存储占用。

  4. 更新前先验证:对敏感服务(如存储代理),更新前先通过 OnDelete 策略在 1-2 个非核心节点验证新镜像稳定性,确认无误后再批量更新。

六、总结

DaemonSet 是 Kubernetes 管理 “节点级服务” 的核心控制器,其核心价值在于 “自动适配节点、单节点单副本、绑定本地资源”,完美解决日志收集、节点监控、存储代理等场景的部署需求。

掌握 DaemonSet 需重点关注:

  • 配置核心tolerations(控制节点部署)、hostPath(本地资源挂载)、nodeSelector(节点筛选);
  • 运维关键:滚动更新(避免中断)、版本回滚(故障恢复)、节点包含 / 排除(灵活部署);
  • 最佳实践:提前同步镜像、配置资源限制、精简历史版本。

通过 DaemonSet 与 StatefulSet、Deployment 的配合,可实现 Kubernetes 集群中 “无状态服务、有状态服务、节点级服务” 的全场景覆盖,构建稳定、高效的容器化平台。

点赞+收藏+关注,下期我们不见不散

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

相关文章:

  • 38.应用层协议HTTP(一)
  • VMware虚拟机ubuntu20.04共享文件夹无法使用
  • PyTorch 神经网络工具箱核心知识点总结
  • 豆包Seedream 4.0:全面测评、玩法探索与Prompt解读
  • STM32_02_GPIO
  • Flink SlotSharingGroup 机制详解
  • Final Cut Pro X fcpx音视频剪辑编辑(Mac中文)
  • 【LeetCode_88】合并两个有序数组
  • PromptPilot 发布:AI 提示词工程化新利器,首月零元体验
  • MySQL-详解数据库中的触发器
  • JVM调优实战及常量池详解
  • 字典树(Trie)
  • AI浏览器概述:Browser Use、Computer Use、Fellou
  • 「docker」三、3分钟快速安装docker
  • Altium Designer(AD)自定义PCB形状
  • 基于ZYNQ的创世SD NAND卡读写TXT文本实验
  • 文心快码入选2025人工智能AI4SE“银弹”标杆案例
  • 什么是SDN(Software Defined Netwok)
  • GitLab-如何基于现有项目仓库,复制出新的项目仓库
  • 本科大二第三周学习周报
  • 三、自定义Button模板触发器(纯XAML)
  • tar 将多个文件或目录打包成一个单独的归档文件
  • 2025新版 WSL2 + Docker Desktop 下载安装详细全流程指南 实现容器化管理,让开发效率起飞
  • 【LangChain4j】大模型实战-SpringBoot(阿里云百炼控制台)
  • Spring Security / Authorization Server 核心类中英文对照表
  • SqlHelper自定义的Sql工具类
  • 每周读书与学习->初识JMeter 元件(二)
  • 西门子 S7-200 SMART PLC 实操案例:中断程序的灵活应用定时中断实现模拟量滤波(上)
  • 测试分类(1)
  • 广州创科——湖北房县汪家河水库除险加固信息化工程(续集)