news 2026/9/17 13:04:23

CentOS 7.3 使用 kubeadm 部署 Kubernetes 1.17.3 完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS 7.3 使用 kubeadm 部署 Kubernetes 1.17.3 完整实战

先声明一个背景:这篇文章记录的是一套在 CentOS 7.3 上用 kubeadm 部署 Kubernetes 1.17.3 的完整过程。这套组合现在看确实不算新,但对于很多还在维护老系统、或者想理解 k8s 基础架构原理的同学来说,反而是很好的学习样本——版本老不代表思路过时,kubeadm 的初始化流程、组件协作方式、网络插件选型,这些核心逻辑到今天依然适用。文章会从环境规划、系统初始化、Docker 安装、kubeadm 部署、网络插件、节点加入、常见问题排查一路走下来,适合刚接触 Kubernetes 的初学者,也适合正在整理部署文档的运维同行参考。

1. 部署前的思路与整体规划

1.1 为什么选 CentOS 7.3 搭配 Kubernetes 1.17.3

先说说选型。Kubernetes 1.17.3 是 2020 年初发布的版本,在那时候算是比较稳定的一个分支。CentOS 7.3 的内核是 3.10.0-514,docker 用的还是社区版 19.03.x,这一套组合在当时的生产环境里经过了不少验证。放到现在来看,如果你手头有物理机或者云主机是这个系统版本,不想折腾升级系统,那么 1.17.3 依然是可以跑起来的,只是需要注意后续的版本兼容和证书续期问题。

我在实际部署中体会最深的一点是:部署 Kubernetes 之前,先想清楚你要用这个集群做什么。如果只是学习,那就尽量用默认参数,按官方文档走一遍;如果要上生产,那么节点划分、网络模式、存储方案都要提前规划。这篇文章按“单 Master 多 Node”的架构来做,属于最标准的小规模集群模式。

1.2 主机规划与网络拓扑

我准备了 3 台虚拟机来做演示,具体配置如下:

主机名IP 地址角色配置
k8s-master192.168.100.100master4C8G,100G磁盘
k8s-node1192.168.100.101node4C8G,100G磁盘
k8s-node2192.168.100.102node4C8G,100G磁盘

这里要提醒一下,Master 节点建议至少 2C4G,否则 kube-apiserver 和 etcd 跑起来后内存会非常紧张。Node 节点的配置可以根据业务负载来定,但如果你是练习环境,1C2G 也能跑,只是调度 pod 之后会比较吃力。

网络方面我选择的模式是 Flannel VXLAN,这个在后面会详细说。集群网段规划为:

  • Pod 网段:10.244.0.0/16
  • Service 网段:10.96.0.0/12

这两个网段不能和宿主机网段冲突,这是 kubeadm 初始化时的硬性要求。

1.3 部署前需要理解的核心概念

在真正敲命令之前,把几个关键组件搞清楚很有必要。Kubernetes 集群由控制平面和工作节点组成,控制平面包含 kube-apiserver、kube-controller-manager、kube-scheduler、etcd,工作节点包含 kubelet、kube-proxy 和容器运行时。kubeadm 的作用就是把这些组件以静态 Pod 的方式部署到 Master 上,省去了手工二进制安装的复杂过程。

另外推荐先了解一下 Pod、Deployment、Service 这三个核心资源。Pod 是最小调度单元,Deployment 负责管理 Pod 的副本数和滚动更新,Service 提供稳定的访问入口。后面验证集群功能时会用到。

2. 系统初始化:这些坑不踩,后面只会更多

2.1 修改主机名与 hosts 解析

我习惯先给每台机器设置主机名,方便后续 kubectl 查看节点信息。分别在三台机器上执行:

# k8s-master 上执行 hostnamectl set-hostname k8s-master # k8s-node1 上执行 hostnamectl set-hostname k8s-node1 # k8s-node2 上执行 hostnamectl set-hostname k8s-node2

然后统一编辑 /etc/hosts,把三台机器的对应关系写进去:

cat >> /etc/hosts << EOF 192.168.100.100 k8s-master 192.168.100.101 k8s-node1 192.168.100.102 k8s-node2 EOF

这一步别看简单,它能避免很多因为 DNS 解析引起的通信问题。我在早期部署时偷懒没配 hosts,结果 kubelet 在注册节点时经常超时,排查了老半天。

2.2 关闭防火墙、SELinux 与 swap

CentOS 7 默认的 firewalld 和 SELinux 对 Kubernetes 的网络和文件访问限制比较大,建议先关掉。三台机器都执行:

# 关闭 firewalld systemctl stop firewalld systemctl disable firewalld # 关闭 SELinux setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 关闭 swap swapoff -a sed -i '/ swap / s/^/#/' /etc/fstab

关于 swap,kubelet 在 1.17 版本里默认检测到 swap 开启时是会报错的,虽然可以通过配置参数忽略,但生产环境一般还是不建议开 swap。关掉之后需要重启或者用 free -h 验证一下是否生效。

2.3 加载内核模块与调整系统参数

Kubernetes 的网络组件需要 iptables 能正确处理桥接流量,所以要加载 br_netfilter 模块并设置相关内核参数。这也是很容易被忽略的一步。

modprobe br_netfilter cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl -p /etc/sysctl.d/k8s.conf

执行 sysctl -p 后可以用 lsmod | grep br_netfilter 确认模块是否加载成功。这一步的核心目的是保证 Pod 之间的流量能正确经过 iptables 规则,如果不设置,网络插件很容易出现“Pod 之间 ping 不通”的奇怪问题。

2.4 配置时间同步

集群的时间同步很重要,etcd 和 kubelet 的证书校验都对时间敏感,时间偏差过大会导致各种诡异的认证失败。我用 chrony 来做时间同步:

yum install -y chrony systemctl start chronyd systemctl enable chronyd timedatectl set-timezone Asia/Shanghai chronyc sources -v

如果你的环境无法访问外网,可以配置内网的 NTP 服务器,关键是要保证所有节点的时间一致。

3. Docker 运行时安装与配置

3.1 安装 Docker 19.03.x

Kubernetes 1.17.3 官方推荐的 Docker 版本是 19.03.x。这里有一个经验是:不要一上来就装最新版 Docker,必须和 k8s 版本匹配,否则 kubelet 可能无法正常和容器运行时通信。

我使用阿里云的镜像源来安装,顺便解决网络加速问题:

# 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 # 配置阿里云 docker yum 源 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装指定版本 yum list docker-ce --showduplicates | sort -r yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io-1.2.13

安装完成后设置开机自启并启动:

systemctl start docker systemctl enable docker docker --version

3.2 配置镜像加速器

国内拉取 Docker Hub 镜像比较慢,建议配置阿里云加速器。在 /etc/docker/daemon.json 里写入加速地址,同时设置 cgroup 驱动为 systemd。

mkdir -p /etc/docker cat > /etc/docker/daemon.json << EOF { "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"], "exec-opts": ["native.cgroupdriver=systemd"] } EOF systemctl daemon-reload systemctl restart docker

这里特别强调 cgroupdriver 一定要配成 systemd,因为 kubelet 默认使用 systemd cgroup driver,如果 Docker 还用 cgroupfs,两者不一致会导致 kubelet 报错,Node 状态显示 NotReady。

3.3 Docker 与 Kubernetes 的兼容性补充

我碰到过不少人在部署后才发现 kubelet 和 docker 的 cgroup driver 不匹配,结果 kubelet 日志里不停刷“failed to run Kubelet”这种错误。其实在配置 Docker 时多写两行就能避免。另外,Docker 的存储驱动我建议保留默认的 overlay2,这是目前最稳的组合。

如果你打算后续升级 Kubernetes 版本,这里安装 Docker 时最好先记录一下版本号,因为某些 k8s 版本对 Docker 版本有明确的支持范围,升级前要对照官方版本支持矩阵检查。

4. Kubernetes 组件安装:yum 源与版本锁定

4.1 配置阿里云 Kubernetes yum 源

Kubernetes 的官方 yum 源在国内访问不稳定,我用的是阿里云镜像源。创建 /etc/yum.repos.d/kubernetes.repo 文件:

cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF

4.2 安装 kubeadm、kubelet、kubectl

固定版本安装很重要,注意这里不能用最新版:

yum install -y kubeadm-1.17.3 kubelet-1.17.3 kubectl-1.17.3

安装完成后需要设置 kubelet 开机自启,但先不启动,要等 kubeadm init 之后才能正常起来:

systemctl enable kubelet

4.3 验证组件是否安装成功

kubeadm version kubelet --version kubectl version --client

三条命令都应该显示 1.17.3 的版本信息。需要留意的是,kubectl version 这里如果显示出 server 版本为空,是正常的,因为集群还没初始化。

5. Master 节点初始化:关键参数与镜像拉取

5.1 提前准备镜像列表

kubeadm init 会从镜像仓库拉取一组组件镜像,包括 kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、etcd、pause、coredns。在 1.17.3 版本中这些镜像的默认仓库是 k8s.gcr.io,国内无法直接访问,所以需要先查看并修改为国内可用的镜像地址。

kubeadm config images list --kubernetes-version=v1.17.3

我在部署时发现,直接用 kubeadm init 默认参数,会因为镜像拉取失败而中断。常见做法是在 init 时带上 --image-repository 参数,或者手动从阿里云等镜像仓库拉取镜像并重新打 tag。

建议改成:

kubeadm init \ --kubernetes-version=v1.17.3 \ --image-repository=registry.aliyuncs.com/google_containers \ --apiserver-advertise-address=192.168.100.100 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12

注意 registry.aliyuncs.com/google_containers 这个地址是社区常用的镜像同步源,里面各个版本的镜像基本都有,用起来比较省心。如果你所在的环境无法访问外网,那么就要用私有镜像仓库,提前把镜像打包传到内网节点上。

5.2 执行 kubeadm init

确认参数没问题后,在 Master 节点执行:

kubeadm init \ --kubernetes-version=v1.17.3 \ --image-repository=registry.aliyuncs.com/google_containers \ --apiserver-advertise-address=192.168.100.100 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12

这个命令的执行过程其实就是控制平面组件的部署过程。kubeadm 会先后完成这几个动作:

  1. 预检系统环境,比如检查内核参数、端口占用、swap 状态。
  2. 生成 PKI 证书体系,包括 CA 证书、apiserver 证书、etcd 证书等。
  3. 生成 kubeconfig 配置文件,用于 kubectl 访问集群。
  4. 将控制平面组件以静态 Pod 方式写入 /etc/kubernetes/manifests 目录。
  5. 等待 apiserver 就绪后,部署 etcd 和 coredns。

执行成功后,输出末尾会有一串提示信息,其中最重要的是第三条 join 命令,用于 Node 节点加入集群。你需要把它保存下来,格式类似:

kubeadm join 192.168.100.100:6443 --token xxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxx

5.3 配置 kubectl

kubeadm init 执行完后,需要把管理员的 kubeconfig 复制到当前用户的家目录下,否则 kubectl 无法连接 apiserver。

mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config

然后执行 kubectl get nodes,如果节点状态还是 NotReady,不要急,这是正常的,等网络插件安装完成后就会变为 Ready。

5.4 控制平面组件状态检查技巧

初始化过程中,我习惯用以下命令确认组件是否正常:

kubectl get pods -n kube-system -o wide kubectl get cs

如果某个 Pod 一直处于 Pending 或 CrashLoopBackOff 状态,可以用 kubectl describe pod -n kube-system 和 kubectl logs -n kube-system 组合排错。大多数情况下是镜像拉取失败或配置参数不匹配。

6. 网络插件部署:选 Flannel 还是 Calico

6.1 网络插件的作用与选型对比

Kubernetes 要求所有 Pod 之间可以直接互相通信,这个网络模型是通过 CNI 插件实现的。常见的插件有两种:

插件网络模式优点适用场景
FlannelVXLAN简单、轻量、易排查小规模集群、学习环境
CalicoBGP性能高、支持网络策略生产环境、需要细粒度访问控制

我这次选择 Flannel,因为它和 10.244.0.0/16 的 Pod 网段搭配起来最省事,配置简单,踩坑率低。如果你要上生产并且对安全隔离有要求,再考虑 Calico。

6.2 部署 Flannel

Flannel 的 yaml 文件可以从官方 GitHub 仓库获取,但在国内访问 raw.githubusercontent.com 不稳定,我建议用下面这种方式:

wget https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml

如果下载失败,可以用国内 mirror 地址,或者在有网络的环境下载后上传到服务器。下载后先编辑文件,确认里面 net-conf.json 配置的 Network 是 10.244.0.0/16,要和 kubeadm init 时保持一致。

kubectl apply -f kube-flannel.yml

等 Flannel 的 Pod 都处于 Running 状态后,再查看节点:

kubectl get pods -n kube-system -o wide kubectl get nodes

正常情况下,大约一两分钟内所有节点都会变成 Ready。

6.3 Flannel 部署后的验证

节点 Ready 只是第一步,更可靠的验证方式是创建几个测试 Pod,看它们之间的网络和 DNS 是否正常。可以跑一个简单的 busybox 容器:

kubectl run test-pod --image=busybox --restart=Never -- sleep 3600 kubectl exec -it test-pod -- nslookup kubernetes.default.svc.cluster.local

如果 DNS 解析正常,说明 kube-dns/coredns 和网络插件都工作正常。这一步其实很多人会跳过,但我觉得很有必要,特别是排查“Pod 创建成功但业务访问不通”这类问题时,提前验证能快速缩小排查范围。

7. Node 节点加入集群

7.1 准备工作

Node 节点和 Master 节点的系统初始化步骤完全一致,包括关闭防火墙、SELinux、swap,加载内核模块,安装 Docker,安装 kubeadm/kubelet/kubectl。我在第 2、3、4 小节的步骤需要在每一台 Node 上都重复执行一次。

7.2 执行 kubeadm join

在 Node 节点上,使用 Master 初始化时输出的 join 命令:

kubeadm join 192.168.100.100:6443 \ --token xxxxxx \ --discovery-token-ca-cert-hash sha256:xxxxxxxx

如果当时忘记保存 join 命令,可以在 Master 节点上重新生成:

kubeadm token create --print-join-command

7.3 验证节点加入状态

在 Master 上执行:

kubectl get nodes -o wide

看到 k8s-node1 和 k8s-node2 的状态为 Ready 就说明加入成功。如果出现 NotReady,可以到 Node 节点上查看 kubelet 日志:

journalctl -u kubelet -f

最常遇到的问题有两类:一是 kubelet 的 cgroupdriver 与 docker 不一致,这个在前面配置 docker 时已经解决;二是节点无法拉取 kube-proxy 或 pause 镜像,需要同样配置镜像加速器或手动拉取。

8. 集群功能验证与应用部署测试

8.1 用 Deployment 部署一个 web 服务

节点都 Ready 后,我们部署一个简单的 Nginx 应用来验证集群调度和服务暴露功能。

kubectl create deployment nginx-demo --image=nginx:1.17 kubectl expose deployment nginx-demo --type=NodePort --port=80 --target-port=80

然后查看 Service:

kubectl get svc nginx-demo

如果端口映射到 30080 之类的 NodePort,那么通过任意节点的 IP 加端口就能访问到 Nginx 页面。这一步能验证整个链路是否打通:用户请求 -> Service -> Pod -> 容器。

8.2 验证副本扩容与滚动更新

kubectl scale deployment nginx-demo --replicas=3 kubectl get pods -o wide

可以看到 Pod 被调度到了不同的 Node 上。接着做一次滚动更新:

kubectl set image deployment/nginx-demo nginx=nginx:1.19 kubectl rollout status deployment/nginx-demo

如果滚动更新顺利完成,说明 kubelet 和 apiserver 之间的协调逻辑正常。这在实际使用中是核心功能,平时维护业务时经常用到。

8.3 验证控制平面高可用性(单 Master 场景的局限)

当前是单 Master 架构,控制平面没有高可用,但我们可以验证 apiserver 的稳定性。比如连续执行 kubectl get nodes 多次,观察是否有连接抖动;或者重启 Docker 服务后,看集群是否能在几分钟内自动恢复。

单 Master 最怕的是 Master 宕机,整个集群的控制面就不可用了。如果你要上生产,建议至少做三节点 Master 高可用,这需要额外配置负载均衡器和 etcd 集群。这篇文章的架构更适用于学习和非关键业务。

9. 部署过程中常见的坑与排查思路

9.1 问题速查表

我在多次部署和帮同事排障过程中,整理了一张高频问题表:

现象可能原因排查方向
kubeadm init 卡在拉镜像网络无法访问 gcr.io使用 --image-repository 或镜像加速
节点状态 NotReady网络插件未部署检查 Flannel/Calico Pod 状态
Pod 一直 ContainerCreating镜像拉取失败describe pod 查看事件
kubelet 服务启动失败cgroupdriver 不一致修改 docker daemon.json
DNS 解析异常coredns 未运行或网络插件问题查看 coredns 日志
join 时 token 超时token 默认 24h 过期用 kubeadm token create 重新生成

9.2 kubelet 与 apiserver 之间的证书问题

1.17 版本默认证书有效期是一年。集群跑了一段时间后,可能会遇到 kubelet 或组件证书过期的问题,表现形式通常是 kubectl get nodes 时报证书过期,或者 kubelet 日志里出现 x509 certificate has expired 之类的错误。解决办法是执行 kubeadm alpha certs renew all 来续期证书,然后重启相关组件。2. 24 年以后的版本命令有变化,但 1.17 里这个命令还是有效的。

9.3 资源不足导致 Pod 调度失败

如果 Node 配置较低,创建 Pod 时可能出现 0/1 nodes are available 的情况。用 kubectl describe node 查看节点资源使用率,并留意是否有污点。kubeadm 默认会给 Master 加一个 NoSchedule 污点,所以普通 Pod 不会调度到 Master 上,如果你希望在 Master 上跑业务 Pod,需要手动去掉这个污点。

kubectl taint nodes k8s-master node-role.kubernetes.io/master-

不过我个人建议学习阶段也别去掉,尽量模拟生产环境。

9.4 镜像拉取失败的三个层面

镜像拉取失败是部署中最常见的问题。遇到时可以分三个层面排查:一是 Docker 本身能不能访问镜像仓库,手动 docker pull 试一下;二是 docker daemon 的 registry-mirrors 配置是否生效;三是 kubelet 拉取镜像时使用的认证信息是否充足,如果是私有仓库需要提前配置 imagePullSecret。

我踩过一次比较深的坑:Docker 配置了加速器,但 kubeadm 拉取 k8s.gcr.io 的镜像时依然超时,后来发现是因为加速器只对 docker.io 生效,对 gcr.io 无效。所以 1.17 部署直接采用阿里云 google_containers 这个仓库地址是更省心的做法,相当于从源头上绕开了 gcr.io。

10. 一些实操心得与后续扩展建议

10.1 关于版本选型再啰嗦两句

如果你现在要搭建一个新集群,我其实更推荐使用更新版本的 Kubernetes,比如 1.20 以上的版本,因为 1.17 之后功能演进很显著,比如 GPU 调度、API 优先级等特性都更强了。但如果你是因为维护历史项目而搜到这篇文章,那你需要重点关注的是集群当前状态的平稳迁移,而不是把最新特性背下来。老版本集群的关键操作是提前备份 etcd 和 kubeadm 配置,再做原地升级或迁移到新集群。

10.2 建议把整套部署流程脚本化

部署完成后,我强烈建议你把系统初始化和 kubeadm init 命令整理成 Shell 脚本,这样在添加新节点或者重建环境时会节省大量时间。我分享一段简单的心得:

# install_k8s_base.sh 示例 #!/bin/bash systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config swapoff -a modprobe br_netfilter ...

脚本化不仅是为了省时间,更是为了减少手工操作带来的失误。Kubernetes 部署对每一步的次序和参数都比较敏感,脚本至少能保证每次执行的结果是一致的。

10.3 Dashboard 的安装与访问限制

很多人部署完集群后会想装 Dashboard,我这边提一句 1.17 版本可以这样安装:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

安装完成后通过 kubectl proxy 方式访问,而不是直接暴露 NodePort,这样更安全。默认情况下 Dashboard 需要 token 登录,创建一个管理员用户即可。注意 Dashboard 只是管理工具,不要在公网直接暴露端口,除非你清楚安全风险。

10.4 监控与日志应该尽早规划

集群部署完成只是第一步,接下来考虑监控和日志会更有价值。1.17 版本可以配合 Prometheus 和 Grafana 做监控,用 EFK 或 Loki 做日志收集。我在生产实践中发现,问题往往不是出在部署过程,而是出在集群运行半年后的资源增长、日志膨胀、证书过期这些“慢性病”上。提前把监控做起来,能省很多事。

10.5 最后一个小技巧

排查 Kubernetes 问题时,学会用 kubectl get events --sort-by=.metadata.creationTimestamp 来按时间顺序查看集群事件,比逐个查组件日志更高效。这条命令帮助我快速定位过不少疑难杂症,比如某个控制器反复重启、某个调度器无法分配资源等。如果你刚开始接触 Kubernetes,建议把常用的 kubectl describe、kubectl logs、kubectl get events 这三个命令练熟,排查问题能快不少。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 13:03:59

WSL2 + VS Code + Codex CLI:打造 Windows 下的 AI 编程开发环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 13:03:27

AXI跨Die互连实战:从LVDS到UCIe的物理层重构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 12:59:33

SAM本地部署实战:ViT选型、显存优化与自动分割调参

SAM 这个词这两年出现的频率太高了&#xff0c;高到什么程度呢——很多时候它已经不是"一个模型"的意思&#xff0c;而是变成了"分割"这个动作的代名词。我自己第一次接触 segment anything 是在做一个遥感地块提取的小项目&#xff0c;当时想的是拿它当个…

作者头像 李华
网站建设 2026/9/17 12:57:50

YOLOv11叶片计数实战:从数据准备到生长状态评估的全流程方案

简介&#xff1a;面向农业科研人员与计算机视觉开发者&#xff0c;这份PDF文档系统讲解基于YOLOv11的多作物叶片计数与生长状态评估完整方案&#xff0c;可有效缓解传统农业表型分析中目标检测效率低、人工成本高的痛点。文档共48页&#xff0c;单个PDF约2.26MB&#xff0c;支持…

作者头像 李华