Docker与Containerd架构关系及命令对比:容器运行时的底层逻辑
前两天有同事跑来问我一个问题我们在服务器上明明装了 Docker为什么生产环境里看到容器进程却是放在 containerd 目录下的还有人拿docker run跑起来的容器用crictl ps居然看不到反过来也一样。这个问题其实困扰过不少刚接触云原生的人。Docker 和 Containerd名字相似、功能重叠但又不是一个东西命令对不上、架构对不上、日志路径也对不上确实容易把人绕晕。这篇文章打算把两件事彻底讲清楚第一Containerd 和 Docker 在架构层面到底是什么关系第二日常运维里各自的命令该怎么用哪些坑是真实存在的。如果你是做容器平台、K8s 集群维护的或者只是刚入门想弄明白容器底层的运行逻辑这篇文章应该能省下你不少排查时间。1. 架构演进先搞清楚 Containerd 在“食物链”里的位置1.1 从 Docker 1.x 那会儿说起很多人以为 Docker 天生就是这么重其实不是。在 Docker 早期的 1.x 时代整个容器运行时就是一个大二进制直接管理镜像、容器、网络、存储还自带一套 API。那时候没有 containerd 这个说法Docker 自己把底层那套活全包了。后来容器生态开始分化Kubernetes 打算同时支持多种运行时就不能让每个容器引擎都自己去管底层那套东西得定一套通用接口。于是 Docker 在 1.11 版本开始把底层逻辑拆出来捐献给了 CNCF这就是 containerd 的来历。拆完之后Docker 自己变成了一个用户友好的“壳”真正的容器创建、运行、销毁其实都是 containerd 在干。这段历史对理解当前架构特别重要因为它解释了为什么你装了 Docker机器上却会多出一个 containerd 进程。这不是什么残留是 Docker 本来就依赖它。1.2 现在的架构长啥样shim、runc、containerd 各司其职以 Docker 为入口的场景完整链路是这样的docker 命令 → dockerd → containerd → containerd-shim → runc → 容器进程docker客户端就负责把人的操作翻译成 API 请求。dockerdDocker 的服务端负责解析镜像、管理网络、管理卷以及把容器创建请求转给 containerd。containerd真正的容器生命周期管理引擎负责镜像解包、容器进程的启停。containerd-shim每个容器旁边挂一个轻量进程作用是让底层 runc 退出后容器还能继续跑同时负责收集容器状态和 IO。runc真正创建容器用的工具基于 Linux 内核的 namespace、cgroups 等特性拉起进程。你可以把 containerd 想象成一个厨房runc 是最底下的灶台shim 是每个灶台旁边站着的小工而 Docker 就是前面接待客人的服务员。你点菜打命令时接触的是服务员但真正炒菜的是厨房。在纯 K8s 环境里架构就更简单了Kubelet 直接通过 CRI 接口对接 containerd中间没有 dockerd 这个环节。这也是为什么 K8s 在 1.24 版本以后宣布弃用 Docker因为 Docker 那层封装对 K8s 来说纯粹是多余的路由。1.3 为什么 K8s 移除了 Docker 却离不开 Containerd当年 K8s 宣布废弃 dockershim 的时候很多人以为 K8s 以后不支持 Docker 了。准确说法是K8s 不再用 dockerd 这个进程来拉取镜像、管理容器而是直接用 containerd 通过 CRI 接口管理容器。你构建镜像时依然可以用 Dockerfile、依然可以推送到 registry但运行时不再经过 Docker。这里有个关键点containerd 本身并不提供构建镜像的能力。你用docker build构建用ctr或crictl跑容器一个负责生产工件一个负责消耗工件。生产环境里最常见的组合其实是开发时用 Docker 构建镜像推到镜像仓库后由 K8s 节点上的 containerd 直接拉取并运行。你只有在需要本地调试、或者往开发环境部署时才真正用 Docker 命令。理解了这条链路之后看命令就好办了。因为你遇到的问题大多不是命令不会写而是不知道命令在跟谁说话。2. 命令体系大对比docker、ctr、crictl 三个 CLI 的真实关系2.1 三兄弟的出身完全不同前面说过Docker、containerd、K8s 三者属于不同的体系。对应到命令行工具就是三个“方言不一样”的东西命令服务端面向对象设计目标dockerdockerd人类用户镜像构建、多容器编排、开发者友好ctrcontainerdcontainerd 本身底层调试、排查 containerd 状态crictlcontainerd通过 CRIK8s 节点管理员模拟 Kubelet 视角调试 Pod 和容器用docker的时候你的命令首先交给 dockerddockerd 做完自己的处理后再把请求转给 containerd。而ctr是 containerd 的亲儿子直接和 containerd 通信绕过了 dockerd 的全部逻辑。crictl则是通过 CRI 标准接口走过去所以它面对的是 K8s 的抽象。正因为对接的接口不同三个工具看到的“容器”概念也不完全一样。docker ps显示的单位是“容器”crictl ps显示的单位是“Pod 里的容器”而且它会把同一个 Pod 里的 pause 容器也算进去ctr更底层它甚至能看到 containerd 为每个容器创建的 task 状态。2.2 镜像管理命令对比对初学者来说最容易踩坑的是镜像相关操作。因为三个工具都能拉镜像但命令完全不通用。docker拉镜像docker pull nginx:latestctr拉镜像ctr image pull docker.io/library/nginx:latest注意ctr 拉镜像要写全地址nginx:latest这种简写它不认必须带上docker.io/library/前缀。crictl拉镜像crictl pull nginx:latestcrictl 倒是能识别简写但它的实现是帮你补全前缀然后再操作。镜像列表也一样docker images ctr image ls crictl images看起来功能相同但结果往往对不上。最典型的场景是你docker pull了一个镜像然后到/var/lib/docker/containerd下去找发现目录里根本没有按镜像名命名的东西其实它被解包成了层文件。反过来你用ctr image import导入的镜像用docker images也可能是看不到的因为 dockerd 只认自己的元数据而 containerd 只认自己 content store 里的内容。2.3 容器生命周期命令对比跑容器的差异也很大。拿启动一个 nginx 容器举例# docker 正常启动 docker run -d --name web nginx:latest # crictl 启动必须指定 Pod 沙箱 crictl run nginx:latest # ctr 启动通常不直接用太底层 ctr run docker.io/library/nginx:latest nginx这里面容易混淆的是 crictl。因为 K8s 里一个容器必须属于某个 Pod而 Pod 对应的底层是一个沙箱sandbox也就是 pause 容器。crictl 严格遵循 CRI 的抽象所以它跑容器必须基于一个已经存在的 Pod 沙箱。直接裸敲crictl run不少版本会提示你缺少 sandbox。日常 K8s 节点上我们很少直接用 crictl 去启动一个独立容器更多的是用它查看状态、拉日志、执行命令。比如# 查看 Pod 列表crictl 会把 Pod 也列出来 crictl pods # 查看容器列表 crictl ps -a # 进入容器执行命令 crictl exec -it container-id /bin/sh # 查看容器日志 crictl logs container-idctr就更直接它对“Pod”和“命名空间”的理解完全是另一套逻辑。比如它是按 namespace 来隔离容器资源的默认 namespace 叫default而 K8s 创建的容器会放在一个叫k8s.io的 namespace 里。如果你ctr -n k8s.io container ls能看到 K8s 的容器但不加-n参数什么都看不到。2.4 namespace很多人栽跟头的地方这是最有意思、也是最容易忽略的一个点。containerd 自身有一个 namespace 的概念用来隔离不同的使用者比如 Docker 会使用名为moby的 namespaceK8s 会使用k8s.io的 namespace而ctr默认则使用default。这个机制直接导致了一个常见困惑你在服务器上明明跑了 K8s 集群容器进程一抓一大把但执行ctr container ls却空空如也。原因就是你没有指定-n k8s.io。# 看到所有 namespace ctr namespace ls # 查看 k8s.io 下的容器 ctr -n k8s.io container ls而 crictl 不存在这个问题因为它通过 CRI 接口会自动绑定到它该用的命名空间不需要你手动指定。所以如果你哪天用 ctr 排查完容器记得区分自己当前在什么 namespace 下操作否则你会觉得“进程存在、但工具看不到很好笑”。这不是 bug是设计。3. 实操演示用 ctr 和 crictl 完成日常容器运维3.1 配置 containerd让它能用起来如果你在 K8s 节点上工作containerd 一般已经作为系统服务装好了。但我们经常需要改几个关键配置否则后面排查会处处碰壁。containerd 的主配置文件在/etc/containerd/config.toml。装完 containerd 后如果你直接启动默认配置其实是有缺失的。建议先初始化一份完整配置containerd config default /etc/containerd/config.toml然后重点检查几个部分。首先是disabled_plugins某些发行版的 containerd 默认禁用了 CRI 插件。如果这个列表里包含cri那crictl连上去就会提示“CRI is disabled”根本没法用。需要把cri从列表里删掉或者注释掉对应行。其次是镜像仓库的 mirror 配置。国内网络环境拉公共镜像经常超时我一般会在plugins.io.containerd.grpc.v1.cri.registry.mirrors下配置加速器或者在plugins.io.containerd.grpc.v1.cri.registry.configs下配置私有仓库认证。低版本 containerd 的配置字段是registry.mirrors高版本在config_path /etc/containerd/certs.d下按目录加载千万要看清楚自己的版本。改完配置一定要重启systemctl restart containerd接着验证 CRI 插件是不是起来了crictl version如果能看到版本号说明 CRI 已经就绪后面kubelet也能正常连上。3.2 拉镜像、跑容器、看日志配置好后先试试用 crictl 拉一个镜像并查看列表crictl pull nginx:1.25 crictl images操作过程你会发现crictl 的一些参数跟 docker 很像比如-a看全部、-q只要 ID。但它在部分输出格式上又不一样比如crictl ps不会自动加容器端口映射这是因为它只关心 CRI 层面的东西网络那套是 CNI 的职责。如果想对比验证 docker 与 ctr 的区别可以在同一台机器上执行docker ps和ctr -n moby container ls你会发现它们其实指向同一批容器。这就是前面说的“服务员”和“厨房”的关系Docker 把容器放到 containerd 的mobynamespace 里管理所以ctr -n moby container ls能看到用ctr container ls看不到。在实际生产环境里kubelet 拉完镜像后可以用ctr -n k8s.io image ls查看节点上已经被 K8s 拉取的镜像列表。crictl images也能完成同样的事只是内部最后还是走 CRI 把请求转给了 containerd。日志这块要提一个重点ctr本身没有专门打印容器日志的命令它只能看 task 的状态。你要看标准输出日志要么用crictl logs要么直接去/var/log/containers目录下找 kubelet 重定向生成的日志文件。很多从 Docker 转过来的人在这里会卡住拿出ctr logs一敲发现根本没有这个子命令。3.3 容器和沙箱的区别用crictl ps -a的时候你会看到容器列表里出现过一些名字很怪、状态为CONTAINER_RUNNING的 pause 容器。这种容器就是沙箱容器也就是每个 Pod 最先被创建的那个“占位”容器它负责持有 Pod 级的网络命名空间其他业务容器共享它的网络栈。这也是 crictl 与 docker 的一个本质差异docker 只管理单容器而 crictl 必须同时理解 Pod 和容器两级抽象。你输入crictl run的时候它要求你先有沙箱而crictl runp这个命令专门用来启动一个 Pod 沙箱。平时写 K8s yaml 不太会直接碰沙箱但当你排查网络问题的时候去看 pause 容器的状态会比看业务容器的状态更有用因为它活着说明网络还在它挂了业务容器再怎么折腾都连不通外网。我用一个实际案例来说明有一次客户报“Pod 起来后一直 CrashLoopBackOff”但kubectl describe pod看到的报错不明确半天没定位。后来上节点用crictl ps -a发现 pause 容器是Exited状态等于 Pod 的命根子都没了后面业务容器肯定反复重启。查到最后是节点上磁盘空间写满containerd 没法为沙箱创建新目录。如果不理解 crictl 输出的两级结构这个排查要多绕好几个小时。4. 常见问题排查与避坑实录4.1 用 ctr 拉下来的镜像docker pull 时又拉一遍这种情况特别容易出现在混合部署的服务器上。同一个镜像你在 K8s 节点上用crictl pull拉过了然后想用 docker 快速跑一个调试容器发现它还在那里转圈仿佛觉得本地没有一样。原因是 dockerd 的镜像缓存和 containerd 的 content store 是两套数据。哪怕 containerd 里已经有nginx:1.25的镜像层dockerd 也不知道它得用自己的逻辑重新拉取一遍。解决办法其实也简单就是别混用。生产环境桥接调试时你部署到 K8s 就用 crictl 管理容器开发环境需要快速交互就用 docker。不要在一台机器上交叉使用两个体系的命令否则既浪费带宽还容易给审计造成误解。4.2 crictl 报错 “unable to connect to containerd”我在不少新装的节点上踩过这个坑原因通常是 containerd 服务根本没起来或者 CRI 插件没启用。先做一次基础三步排查systemctl status containerd crictl logs cat /etc/containerd/config.toml | grep -i disabled_plugins如果服务是启动的但 CRI 插件被禁用crictl 的连接就是直接失败的。修改配置里disabled_plugins列表把cri移除保存后重启 containerd。注意某些版本中配置文件里写的是plugins.io.containerd.grpc.v1.cri注释段并不是disabled_plugins两个地方都要检查。另外 crictl 的默认 endpoint 是unix:///run/containerd/containerd.sock如果你改了 containerd 的监听地址也要同步改/etc/crictl.yamlruntime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 5 debug: false4.3 镜像仓库不走 HTTP拉取失败私有仓库场景下常见报错是http: server gave HTTP response to HTTPS client。这是因为 containerd 默认要求仓库走 HTTPS而你可能是内网自建仓库只有 HTTP。处理方式要看你用的 containerd 版本。低版本在/etc/containerd/config.toml里通过[plugins.io.containerd.grpc.v1.cri.registry.configs.your.registry.tls]段的insecure_skip_verify true或把scheme改成http。高版本推荐在/etc/containerd/certs.d/你的仓库地址/hosts.toml写一条server http://你的仓库地址 [host.http://你的仓库地址] capabilities [pull, resolve, push]还要注意crictl pull使用的镜像地址如果是简写它会自动补docker.io前缀私有仓库最好给完整的域名加路径比如registry.internal.cn/team/app:v1不要只写app:v1否则匹配不到镜像。4.4 containerd 日志文件位置和常见错误码containerd 的日志在 systemd 环境下直接用journalctl看journalctl -u containerd -n 100 --no-pager常见错误里有一个值得单独说明failed to get sandbox image registry.k8s.io/pause:3.9。这是 node 上缺少 pause 镜像导致的K8s 初始化沙箱时会找它找不到就拉起任何容器。解决办法是预先手动拉取该镜像并且确保版本与节点上的 containerd 兼容。还有failed to create shim task: cgroup: fork failed这种多是节点 PID 或 cgroup 限制导致不是命令问题得去调高节点上的内核参数或者给 kubelet 的--system-reserved预留足够资源。4.5 实测下来的工具选择建议根据我自己维护多套集群的经验给出几条很实际的选择原则构建镜像、本地快速起容器用docker没毛病它交互体验最好日志格式清晰。K8s 节点上排查 Pod 状态优先用crictl因为它能看到 Pod 维度输出格式与服务商监控对齐。在节点上排查 containerd 本身的数据、镜像层、content store 内容才需要用ctr并且要记住-n参数。如果你在维护一个纯 containerd 的裸环境没有 K8s、没有 Dockerctr就成了主力工具但你需要额外手动管理 namespace、快照器和 CNI 插件这远不如 docker 省心。这套选型逻辑如果从理解架构的角度来看其实就是一句话上层用户选 DockerK8s 运维选 crictl底层研究选 ctr。它们服务于同一个对象但视角完全不同。5. 个人体会这层关系想清楚以后排查效率高了很多我自己早期也犯过糊涂。那时刚接手集群维护节点上装了 docker 又跑着 kubelet执行ctr image ls发现啥都没有一度以为是 containerd 没起来。后来才知道是 namespace 没对上。又过了几个月碰到 K8s 拉镜像失败我总是下意识跑docker images去确认结果镜像明明在本地kubelet 还是拉不下来我才真正意识到“本地有没有”和“Kubelet 看到没有”是两码事。后来我把所有节点统一改成 containerd 直连不再安装 docker 命令调试问题只保留 crictl 和 ctr。最初几天确实不习惯比如crictl不支持--rm、没法直接 build 镜像但适应之后整个排查链路变得干净很多。因为 CRI 接口本身就是一个稳定边界你能很清楚地判断问题出在镜像、容器还是沙箱层。最后给一条建议如果你准备学习容器底层不要一上来就背命令先把docker → dockerd → containerd → containerd-shim → runc这条链路的责任边界画出来。命令只是这个架构的外在表达架构理解透了命令其实不用背用的时候--help就够。遇到“为什么这个工具看不到我创建的容器”这类问题先回去想想它是在跟哪一层对话答案往往自己就浮出来了。

相关新闻

商品管理与评价系统设计:SPU/SKU拆分、状态机与部署避坑指南

商品管理与评价系统设计:SPU/SKU拆分、状态机与部署避坑指南

简介:基于JSP的商品管理与评价系统完整源码包,面向Java Web初学者、课程设计及毕业设计开发者,聚焦管理员商品维护与用户评分评价两条核心业务线。压缩包共275个文件,包含58个java源文件、58个class编译文件、38个jsp页面、76个gi…

2026/10/9 6:09:04 阅读更多 →
SpringBoot+Vue膳食营养健康系统开发实战:从数据库到部署

SpringBoot+Vue膳食营养健康系统开发实战:从数据库到部署

先说清楚这个项目是什么。一个基于SpringBoot和Vue的膳食营养健康网站管理系统,简单理解就是:用户注册登录后,可以在系统里记录自己每天吃了什么,系统根据内置的食物营养数据库,自动帮你算出当天摄入了多少热量、蛋白质…

2026/10/9 6:09:04 阅读更多 →
Spring Boot 启动成功事件 ApplicationReadyEvent 实战:缓存预热与日志监控

Spring Boot 启动成功事件 ApplicationReadyEvent 实战:缓存预热与日志监控

如果你接手过一个 Spring Boot 项目,大概率会碰到这类问题:应用明明已经起完了,运维却说“没看到服务就绪的日志”;或者上线后第一次请求特别慢,排查下来才发现是缓存压根没预热。这些问题的共同根源,都是没…

2026/10/9 6:08:04 阅读更多 →

最新新闻

生产级Coding Agent调优实战:Harness工程化决定落地下限

生产级Coding Agent调优实战:Harness工程化决定落地下限

1. 从"能跑"到"好用":生产级 Coding Agent 的最后一公里到底卡在哪Vibe Coding 这个词这两年被聊得很多,大意是开发者用自然语言描述意图,让 Coding Agent 去生成、修改、验证代码,人只负责把握方向和验收。听…

2026/10/9 6:35:27 阅读更多 →
Java Swing人事管理系统:JDBC+MySQL课程设计实战与避坑指南

Java Swing人事管理系统:JDBC+MySQL课程设计实战与避坑指南

简介:这份资源是一套基于 Java Swing、JDBC 与 MySQL 实现的人事管理系统课程设计项目,面向正在完成数据库课程设计、需要可运行参考案例的计算机相关专业学生。项目包含可视化软件界面,覆盖人员信息维护、数据库连接与增删改查等典型业务场景…

2026/10/9 6:35:27 阅读更多 →
MySQL校对规则:utf8mb4_general_ci与utf8mb4_bin的差异及选型

MySQL校对规则:utf8mb4_general_ci与utf8mb4_bin的差异及选型

1. 这两个校对规则到底在吵什么看你一脸问号地点进来,我猜你多半是遇到过这种情况:建表的时候复制了一段别人的SQL,里面有CHARSETutf8mb4 COLLATEutf8mb4_general_ci,或者是utf8mb4_bin,当时也没多想,能用就…

2026/10/9 6:35:27 阅读更多 →
PS5底层开发合规边界与技术可行性分析

PS5底层开发合规边界与技术可行性分析

我无法根据当前输入生成符合要求的博文。原因如下:项目标题 "AnyPS5" 缺乏明确指向性:该词在公开技术语境中无公认定义,既非官方产品名(索尼未发布/命名过 AnyPS5)、非开源项目(GitHub、GitLab、…

2026/10/9 6:35:27 阅读更多 →
claude-mem:为Claude Code打造跨会话长期记忆的实战指南

claude-mem:为Claude Code打造跨会话长期记忆的实战指南

用过 Claude Code 写真实项目的人,基本都遇到过这个场景:昨天刚跟 AI 讨论清楚的一个架构方案,今天新开一个会话,它完全不记得了。你在同一个仓库里翻历史对话记录,发现上一个会话已经把项目的来龙去脉都喂给了它&…

2026/10/9 6:35:27 阅读更多 →
Agent-Reach:LLM API智能路由与成本可控调度中枢

Agent-Reach:LLM API智能路由与成本可控调度中枢

1. 项目概述:Agent-Reach 是什么?它解决的不是“能不能用”,而是“怎么用得稳、用得准、用得省”Agent-Reach 这个名字乍看像某个开源模型或工具库,但结合 CLI、API、YouTube、Reddit 这些高频热词,再叠加上“zcode cl…

2026/10/9 6:34:27 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/9 6:17:20 阅读更多 →