<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>宋明河</title><link>https://s-infinite-box.github.io/</link><description>技术实践、学习记录与日常思考</description><language>zh-CN</language><generator>Hugo</generator><atom:link href="https://s-infinite-box.github.io/index.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Thu, 08 Oct 2026 02:16:02 +0800</lastBuildDate><item><title>我在内核学习方式上的探索与演进</title><link>https://s-infinite-box.github.io/posts/aa-kernel-learning-method/</link><guid>https://s-infinite-box.github.io/posts/aa-kernel-learning-method/</guid><pubDate>Tue, 06 Oct 2026 00:00:00 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux_hu_23f208142d1135b9.webp" alt="封面"&gt;&lt;p&gt;我的主要经验在云原生开发运维，熟悉 Java、Go、Rust，也经常写脚本、排查系统问题。但开始这次学习时，对汇编、GDB 和 CPU 指令基本是空白。分布式技术已经接触了不少，我希望再往内核这一侧深入，理解上层软件依赖的运行机制。&lt;/p&gt;&#10;&lt;p&gt;有了 AI 的辅助，这个原本门槛很高的方向变得可以尝试。不过，学习并不是从一开始就顺利的。这篇先不展开技术细节，主要记录四次学习方式的调整：读书、选择性阅读、仿写内核，以及逐步完善仿写的方法。&lt;/p&gt;&#10;&lt;h2 id="第一阶段纯看书用-ai-帮助理解"&gt;第一阶段：纯看书，用 AI 帮助理解&lt;/h2&gt;&#10;&lt;p&gt;最初选择赵炯老师的《Linux 内核完全注释》，是因为 Linux 0.11 的源码规模相对小，适合认识内核的基本组成。这个阶段大约持续了一到两个月，主要按书的顺序阅读；遇到不懂的内容，就用豆包拍照，让 AI 解读，再围绕解释反复追问。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/aa-kernel-learning-method/book-cover.jpg" alt="最初用来入门的《Linux 内核完全注释》"&gt;&lt;/p&gt;&#10;&lt;p&gt;这段时间补了很多基础概念，也让我能够继续读下去。但回顾时发现，主要收获还是理论知识：看懂书上的解释，并不意味着知道怎样动手实现，需要调整学习方式。&lt;/p&gt;&#10;&lt;h2 id="第二阶段结合-ai有选择地阅读"&gt;第二阶段：结合 AI，有选择地阅读&lt;/h2&gt;&#10;&lt;p&gt;接下来，我结合书的目录与 AI（当时主要使用 Claude Code，后续转向 Codex）讨论学习范围，不再要求每一章、每一节都按顺序读完，而是先分清哪些内容值得深入，哪些可以暂缓。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/aa-kernel-learning-method/book-contents.jpg" alt="结合 AI 讨论取舍、做过学习标记的目录"&gt;&lt;/p&gt;&#10;&lt;p&gt;当时暂缓的内容包括旧内核的引导过程、构建编译过程，以及块设备、字符设备等章节。前两类与今天的开发环境差异较大；设备部分则先放到后面。&lt;/p&gt;&#10;&lt;p&gt;保留的学习主线，是内核初始化、中断与异常、内存管理、进程调度与上下文切换、系统调用，以及文件系统的基本组织。重点开始从“读完整本书”转向“理解一个内核由哪些机制组成”。&lt;/p&gt;&#10;&lt;p&gt;有选择地阅读后，范围更清楚了。但又坚持了几周，仍然感觉理论输入多、实践少，进度也比较慢。第一阶段解决了能不能读懂的问题，第二阶段解决了先读什么的问题，还缺少一个能把知识真正用起来的任务。&lt;/p&gt;&#10;&lt;h2 id="第三阶段用-rust-仿写内核转向实践"&gt;第三阶段：用 Rust 仿写内核，转向实践&lt;/h2&gt;&#10;&lt;p&gt;这是整个过程中最重要的一次转折。我决定参考 Linux 0.11 的基本组成，用 Rust 编写一个简单内核，取名 aa，中文叫“一一”。Rust 是我学习了很久、也很喜欢的语言，只是在实际生产中一直没有太多使用机会；这个项目也能让我进一步练习 Rust。&lt;/p&gt;&#10;&lt;p&gt;前两个阶段留下的基础和笔记，这时开始有了用途。以前读进程切换、栈和特权级时，是逐个理解概念；现在有了自己的项目，就会带着“接下来要实现什么”的问题回到书里。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/aa-kernel-learning-method/notes-process-switch.jpg" alt="进程切换与 TSS 的手写学习笔记"&gt; &lt;img src="https://s-infinite-box.github.io/posts/aa-kernel-learning-method/notes-stack.jpg" alt="栈结构与特权级变化的学习批注"&gt;&lt;/p&gt;&#10;&lt;p&gt;刚开始，汇编、GRUB、内核启动环境都超出了我的经验范围，所以主要由 AI 编码并帮助测试。我做的事情是逐行看代码，理解为什么要这样写：这一段解决了什么问题？依赖哪些前提？如果省略它，会发生什么？不懂的地方再回到书、源码和 AI 的解释中补齐。&lt;/p&gt;&#10;&lt;p&gt;有了实践对象，知识之间的联系也更容易建立。比如“启动需要一个栈”，以前只是书上的一句话；现在要在自己的项目中找到预留栈空间的位置、设置栈指针的代码，并观察它是否真的生效。学习不再停在概念解释上，而是围绕一个具体问题，把理解、实现和验证连起来。&lt;/p&gt;&#10;&lt;p&gt;这个阶段并不快。到现在，aa 还没有真正进入 Rust 内核主函数，启动前要补的知识比预想的多。不过，通过旧内核源码阅读和 aa 的启动实验，前面零散的知识已经串联起来，收获还是很多。&lt;/p&gt;&#10;&lt;p&gt;对我来说，转折不是代码写得更多了，而是学习有了一个持续推进的对象。读书、问 AI、看源码，都开始服务于眼前的小任务；完成一个能运行、能观察的步骤，再继续下一个。&lt;/p&gt;&#10;&lt;h2 id="第四阶段完善仿写方法加入现代源码对照"&gt;第四阶段：完善仿写方法，加入现代源码对照&lt;/h2&gt;&#10;&lt;p&gt;仿写过程中又遇到了新的问题：Linux 0.11 的启动方式与 aa 面向的现代环境差异很大。准备自己编写启动检查、GDT、页表等功能时，仅仅觉得 AI 给出的代码逻辑上说得通还不够，我希望有真实源码作为参照。&lt;/p&gt;&#10;&lt;p&gt;因此，我把 Linux 6.18 也引入了学习项目：用 Linux 0.11 认识内核的基本组成和机制，用现代 Linux 对照实现条件的变化，再在 aa 中完成一个尽量小的实现。不是同时通读两套源码，而是围绕当前问题，查找各自对应的部分。&lt;/p&gt;&#10;&lt;p&gt;目前项目中的主要目录如下。自己的实现、新旧源码和学习记录放在一起，方便在同一个问题下切换查看；这里只列学习相关的部分。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;_aa_kernel/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── aa/ # 自己编写的 Rust 内核&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── .cargo/config.toml # 裸机目标与链接配置&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Cargo.toml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── build.rs&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Makefile # 构建、启动与调试入口&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── boot/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ ├── entry.S # 汇编启动代码&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ └── linker.ld # 内核内存布局&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── debug/entry.gdb # GDB 检查脚本&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── grub/grub.cfg&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── src/main.rs # 尚未实际进入的 Rust 入口&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── linux-0.11-note-songwz/ # 旧内核：基础组成与机制&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── boot/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── kernel/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── mm/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── fs/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── new-linux-6.18/ # 现代内核：实现差异对照&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── arch/x86/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── init/main.c&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── _aa_reference/ # 独立的现代内核实验&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── _docs/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── Study-Roadmap.md # 学习路线与验收标准&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── AA-Study-Progress.md # 当前检查点与下一步&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── AA-Assembly-and-GDB.md # 汇编和调试笔记&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Linux-Modern-Reference.md # 现代源码对照基线&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;AI 的角色也在调整。最初主要由它搭建和测试，我阅读理解；现在开始把小步骤的实现与调试接回来，让 AI 帮助解释背景、定位参照和检查思路。每次先明确要解决的问题，再查源码、写代码、用实验验证，最后记录结果，给下一次学习留下明确的继续位置。&lt;/p&gt;&#10;&lt;p&gt;这也让我重新理解第二阶段的取舍：暂缓旧版本的某种实现，并不等于绕过它背后的知识。需要实现的机制，仍要在合适的时机补回来，只是用当前项目需要的方式学习。&lt;/p&gt;&#10;&lt;h2 id="目前的进度与后续计划"&gt;目前的进度与后续计划&lt;/h2&gt;&#10;&lt;p&gt;目前已经梳理过 Linux 0.11 的启动链路，也搭好了 aa 的基础工程：裸机 Rust 构建、内核内存布局、GRUB/Multiboot2 加载，以及 QEMU/GDB 调试。32 位入口中的参数保存和启动栈已有动态验证；我也已经亲自连接 GDB，命中汇编入口断点。&lt;/p&gt;&#10;&lt;p&gt;启动 magic 的比较代码已经写入，接下来先完成正常、错误分支的验证，再准备 64 位运行环境，真正进入 Rust 内核主函数。之后补上串口与 panic 输出，让实验结果更容易观察。&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/aa-kernel-learning-method/aa-learning-progress.svg" alt="aa 学习进度与后续计划：已验证、当前待验证、计划"&gt;&lt;/p&gt;&#10;&lt;p&gt;图中箭头表示学习推进顺序，虚线部分是尚未实现的后续计划。这里只列涉及的技术，具体实现留到后面的系列文章。&lt;/p&gt;&#10;&lt;p&gt;等进度走到开始编写 Rust 内核主函数时，我准备更新这个系列的下一篇，集中回顾此前完成的启动与调试内容。之后再随着实践推进，逐步展开异常、内存、调度、用户态和文件系统等专题。&lt;/p&gt;&#10;&lt;p&gt;这几次调整给我最大的启发，是让学习围绕一个可以推进、可以验证的小项目展开。书提供基础，源码提供参照，AI 帮助跨过陌生知识的门槛，自己的实现和实验则帮助判断是否真正理解。对于同样有开发运维经验、但缺少底层基础的人，这条路径也许值得参考。&lt;/p&gt;&#10;</description></item><item><title>用 RTX 4090 散热器改装 Tesla T10 计算卡</title><link>https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/</link><guid>https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/nvidia_hu_fd085186b83f052a.jpg" alt="封面"&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;之前搞了一张特斯拉的T10计算卡，跑跑AI模型，使用起来强度也不是很大，散热就简单在屁股上加了个涡轮扇，用硬纸壳壳密封一下；后面在拼DD闲逛的时候发现有4090被挖核心的显卡，而且恰巧技嘉4090风魔也是后接电的，跟T10很相像，就花了80大洋买了一个被掏了核心和显存的4090回来自己搞了下散热，简单记录下分享给大家参考&lt;/p&gt;&#10;&lt;h2 id="装配与背板固定"&gt;装配与背板固定&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/14d4f39cc1ba4f6683ff500dd59a584b.png" alt="在这里插入图片描述"&gt;&#10;左边是买回来的4090风魔，可以看到在屁股上切了一刀用于后插电；&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;两个显卡的模型不是很匹配，背板只能上我标红的3个螺丝&#10;如果核心周围4个螺丝都想加上的话需要自己在散热板上攻丝加螺柱，背板打孔；&#10;核心周围我只上了1个螺丝+尾部2个，但是已经可以稳稳压住T10，就没再折腾；&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="散热片与导热处理"&gt;散热片与导热处理&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/776e7af7650d439abb101f494fe86071.png" alt="在这里插入图片描述"&gt;&#10;拆下散热的4090，注意红框处的散热片需要拆几片下来，因为T10比4090还是要长一点，这个地方会抬高一点显卡的PCB板&#10;我一开始没拆，显卡有点弯，开机识别不到显卡，差点以为给显卡搞坏了&#10;散热铜片上的导热片我基本没动，跟T10基本是一致的，可以直接扣上&#10;显卡核心相对4090稍稍往下了一点，下面的白色标签也覆盖了一点，标签的胶很粘，我就犯懒没撕，想着反正一个300W的散热来压我这150W不随便搞，结果后面烤鸡的时候hotspot有85，核心温度才58，&#10;&lt;img src="https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/4b19a230899a49bea7e8234e15b83668.png" alt="在这里插入图片描述"&gt;&#10;4090显卡背板这几个螺柱要拆掉，不然会压低显卡，一样会遇到显卡不识别的问题&lt;/p&gt;&#10;&lt;h2 id="安装效果与风扇接线"&gt;安装效果与风扇接线&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/tesla-t10-rtx4090-cooler/ea6529510b244f2a92085941ef8eb49c.jpeg" alt="在这里插入图片描述"&gt;&#10;装好以后差不多就是这样，当时还是用的T10的背板，4090的我拿回家拆螺柱了；&#10;还得注意下需要买显卡风扇ph2.0母口转主板pwm公口&lt;/p&gt;&#10;</description></item><item><title>用 ClipCascade 同步 Windows 与 Linux Wayland 的剪贴板</title><link>https://s-infinite-box.github.io/posts/clipcascade-clipboard-sharing/</link><guid>https://s-infinite-box.github.io/posts/clipcascade-clipboard-sharing/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/linux_windows_hu_ce1abbfd74ad14d4.jpg" alt="封面"&gt;&lt;p&gt;“win”和“linux-wayland”通过deskflow共享键鼠，解决剪切板不能共享的问题&lt;/p&gt;&#10;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;先说背景，不想听故事可跳过😀&lt;/p&gt;&#10;&lt;p&gt;之前装的E5主机一直将linux作为工作主力机，开发体验非常好；但是公司这边需要各种会议、办公和安全的软件，在linux上就有很多兼任性问题，靠win虚拟机、wine等各种方案适配了很多，后来又装了一台9950X的台式机，系统是windows，开发和办公也都用回windows，之前E5的linux主机就当服务器用了；&lt;/p&gt;&#10;&lt;p&gt;这几天比较心痒，想换回linux开发（就相当于把显示器鼠标从windows的台式机再插回E5主机），然后保留windows主机跑一些需要win的办公软件，一共三台显示器，两台开发用的插在linux上，一台办公用的显示器插在windows上；&lt;/p&gt;&#10;&lt;p&gt;然后就是搞键鼠和剪切板共享，一套键鼠操作多台主机。如果linux是x11的，那这一步非常简单，之前一直用的&lt;a class="link" href="https://github.com/deskflow/deskflow" target="_blank" rel="noopener"&#10; &gt;deskflow&lt;/a&gt;，两台主机装好服务，通过局域网连接上基本就搞定了；&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;而这次想尝试下wayland遇到一个问题，键鼠可以共享，剪切板不能共享了&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;然后先到github的issues上查了下，果然有人提了相关问题，&lt;a class="link" href="https://" target="_blank" rel="noopener"&#10; &gt;官方给出的恢复&lt;/a&gt;：这就是wayland的已知BUG，需要依赖上游解决；问题到这好像是只能等了，但这个官方回复下面有个人说了一嘴可以用kde-connect来共享剪切板，这不正好我用的kubuntu，然后我兴致勃勃给两台主机装上各自OS版本的kde-connect后，发现这玩意虽然可以快速找到局域网内的主机，但是过几秒就会断连，甚至连上就秒断，这个方案也不行；但是这个过程给我打开了新思路，于是我google必应查半天，最终锁定了&lt;a class="link" href="https://github.com/Sathvik-Rao/ClipCascade" target="_blank" rel="noopener"&#10; &gt;ClipCascade&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="clipcascade-安装"&gt;ClipCascade 安装&lt;/h2&gt;&#10;&lt;p&gt;ClipCascade需要部署一个server记录剪切板内容，然后所有的client通过websocket连接到server来同步剪切板内容&lt;/p&gt;&#10;&lt;p&gt;server是一个jar包，可以docker启动，也可以直接java -jar启动&lt;/p&gt;&#10;&lt;p&gt;client支持的设备看下面的表（来自官方README）&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Type&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Windows&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;MacOS&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Linux GUI&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Linux CLI&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Android&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Text&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Image&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Files&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;✔&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="服务端部署"&gt;服务端部署&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-d &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--name clipcascade &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-p 33381:8080 &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-e &lt;span class="nv"&gt;CC_MAX_MESSAGE_SIZE_IN_MiB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-v /root/p/linux-app/data/cc_users:/database &lt;span class="se"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sathvikrao/clipcascade&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;支持的ENV可以看&lt;a class="link" href="https://github.com/Sathvik-Rao/ClipCascade?tab=readme-ov-file#environment-variables" target="_blank" rel="noopener"&#10; &gt;官方配置文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;部署好后可以打开http://localhost:33381/&lt;/p&gt;&#10;&lt;p&gt;默认管理员凭据：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;用户名：&lt;/strong&gt; &lt;code&gt;admin&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;密码：&lt;/strong&gt; &lt;code&gt;admin123&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/clipcascade-clipboard-sharing/d6eca7c4-daf7-4c07-9753-d4ee2051dc27.png" alt="Snipaste_2025-07-12_19-12-38.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;点击&lt;code&gt;connect&lt;/code&gt;表示作为client连接到server，然后可以在右侧输入框输入文本，send就会同步到所有client，在下面channel可以看到刚才send的内容，每次有两条猜测分别是发送和接受的&lt;/p&gt;&#10;&lt;h3 id="客户端下载"&gt;客户端下载&lt;/h3&gt;&#10;&lt;p&gt;根据操作系统和架构到&lt;a class="link" href="https://github.com/Sathvik-Rao/ClipCascade/releases" target="_blank" rel="noopener"&#10; &gt;官方release&lt;/a&gt;下载对应包&lt;/p&gt;&#10;&lt;h3 id="windows-客户端"&gt;Windows 客户端&lt;/h3&gt;&#10;&lt;p&gt;windows就是一个单一exe文件，依赖都在里面，双击直接启动，然后输入server的地址，用户名密码就可以&lt;/p&gt;&#10;&lt;h3 id="linux-客户端与依赖处理"&gt;Linux 客户端与依赖处理&lt;/h3&gt;&#10;&lt;p&gt;linux下载好解压开需要通过main.py脚本启动，官方没有打包，需要手动安装各种依赖，这里重点讲一下&lt;a class="link" href="https://github.com/Sathvik-Rao/ClipCascade?tab=readme-ov-file#%EF%B8%8F-linux-desktop-application-gui--%EF%B8%8F-linux-terminal-based-application-cli" target="_blank" rel="noopener"&#10; &gt;官方依赖安装流程&lt;/a&gt;以外的处理&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# gi安装包处理&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt install -y python3-gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 如果是自己虚拟的python环境，比如我用的conda，gi这个包直接pip3 install gi找不到，需要再手动处理下&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ubuntu&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s /usr/lib/python3/dist-packages/gi &amp;lt;my-python-path&amp;gt;/site-packages/gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# fedora&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s /usr/lib/python3/site-packages/gi &amp;lt;my-python-path&amp;gt;/site-packages/gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 卸载旧的websocket包，重新安装&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip3 uninstall websocket websockets websocket-client&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip3 install websocket-client&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="验证剪贴板同步"&gt;验证剪贴板同步&lt;/h2&gt;&#10;&lt;p&gt;可以在各个客户段随便复制点内容，然后在server的web页面上可以看到channel有同步到数据&lt;/p&gt;&#10;</description></item><item><title>分享一个 WSL 的 IP 总是变化的解决办法</title><link>https://s-infinite-box.github.io/posts/wsl-ip-windows-hosts/</link><guid>https://s-infinite-box.github.io/posts/wsl-ip-windows-hosts/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux-or-Windows_hu_334ee4f8cd6e3a15.jpg" alt="封面"&gt;&lt;h2 id="思路"&gt;思路&lt;/h2&gt;&#10;&lt;p&gt;之前尝试过几次其他办法，可能操作有误都没正常生效&#10;后来修改了思路，每次wsl启动的时候执行一个脚本，直接将wsl当前的ip写进windows宿主机的hosts里&lt;/p&gt;&#10;&lt;h2 id="bash-代码实现"&gt;Bash 代码实现&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 主机HOST增加WSL_IP&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;HS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/mnt/c/Windows/System32/drivers/etc/hosts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;function&lt;/span&gt; replace_host&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; ! &lt;span class="o"&gt;[&lt;/span&gt; -x &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;which ip&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;fi&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 获取当前wsl的ip&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;wsl_ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ip -br a &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;/eth0/ {print $3}&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -o &lt;span class="s1"&gt;&amp;#39;^[0-9./]*$&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s@/.*@@g&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -z &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;wsl_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;wsl_ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fi&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 获取win主机host中的wsl_ip&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;current_host_wsl_ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;grep &lt;span class="s1"&gt;&amp;#39;^.* wsl$&amp;#39;&lt;/span&gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$current_host_wsl_ip&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$wsl_ip&lt;/span&gt;&lt;span class="s2"&gt; wsl&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 若本来相同则不做处理&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fi&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;replace wsl ip in hosts file&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;remove hosts: &lt;/span&gt;&lt;span class="nv"&gt;$current_host_wsl_ip&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 先删后加 分开处理，若直接替换则需考虑首次添加问题更麻烦&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sed -i &lt;span class="s1"&gt;&amp;#39;/^.* wsl/d&amp;#39;&lt;/span&gt; &lt;span class="nv"&gt;$HS&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;add wsl current ip: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;wsl_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;wsl_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; wsl&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt;&lt;span class="nv"&gt;$HS&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;可以写到.bashrc，profile里，也可以复制一个单独的脚本，通过配置/etc/wsl.conf添加wsl的启动命令实现&#10;下面是一个demo&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;win_hosts_proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sh&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;a class="link" href="https://learn.microsoft.com/zh-cn/windows/wsl/wsl-config#boot-settings" target="_blank" rel="noopener"&#10; &gt;微软关于wsl.conf的官方文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="远程访问-wsl"&gt;远程访问 WSL&lt;/h2&gt;&#10;&lt;p&gt;看一些场景是需要远程访问wsl中的docker\k3s等容器的端口，这些场景使用加hosts的方法可能不太灵活，需要搭建代理处理&lt;/p&gt;&#10;&lt;p&gt;如果只是需要ssh访问的话，那大可以直接开启windows的ssh服务，然后ssh链接windows后再输入wsl，嫌麻烦可以直接修改下ssh的默认终端程序&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 OpenSSH 客户端&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;OpenSSH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;~~~~&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 OpenSSH 服务器&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;OpenSSH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;~~~~&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 修改默认终端&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;New-ItemProperty&lt;/span&gt; &lt;span class="n"&gt;-Path&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HKLM:\SOFTWARE\OpenSSH&amp;#34;&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;DefaultShell&lt;/span&gt; &lt;span class="n"&gt;-Value&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;C:\Windows\System32\wsl.exe&amp;#34;&lt;/span&gt; &lt;span class="n"&gt;-PropertyType&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;-Force&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>WSL 相关命令的一些分享</title><link>https://s-infinite-box.github.io/posts/wsl-command-notes/</link><guid>https://s-infinite-box.github.io/posts/wsl-command-notes/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux-or-Windows_hu_334ee4f8cd6e3a15.jpg" alt="封面"&gt;&lt;h2 id="发行版安装与管理"&gt;发行版安装与管理&lt;/h2&gt;&#10;&lt;h3 id="设置默认-wsl-版本"&gt;设置默认 WSL 版本&lt;/h3&gt;&#10;&lt;p&gt;设置wsl2为默认内核版本：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-set-default-version&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="安装发行版"&gt;安装发行版&lt;/h3&gt;&#10;&lt;p&gt;curl安装wsl发行版：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;exe&lt;/span&gt; &lt;span class="n"&gt;-L&lt;/span&gt; &lt;span class="n"&gt;-o&lt;/span&gt; &lt;span class="n"&gt;ubuntu&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2004&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;appx&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;aka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;wsl-ubuntu&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2004&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;下载了发行版后，导航到包含下载内容的文件夹，并在该目录中运行以下命令，其中app-name是 Linux 发行版 .appx 文件的名称。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-AppxPackage&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;appx&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="终止所有发行版"&gt;终止所有发行版&lt;/h3&gt;&#10;&lt;p&gt;立即终止所有正在运行的发行版和 WSL 2 轻量级实用工具虚拟机。 在需要重启 WSL 2 虚拟机环境的情形下，例如更改内存使用限制或更改 .wslconfig 文件，可能必须使用此命令。&lt;/p&gt;&#10;&lt;p&gt;根据我的理解，如果有多个wsl的分发版（场景情况是一个自己用的分发+docker-desktop的情况），wsl &amp;ndash;shutdown会关闭所有分发，也就是wsl内核其实是所有分发公用的，各个分发版实质只是一个用户态的文件系统&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-shutdown&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="卸载发行版"&gt;卸载发行版&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-unregister&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="指定默认发行版"&gt;指定默认发行版&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="n"&gt;-s&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="导入导出与备份"&gt;导入导出与备份&lt;/h2&gt;&#10;&lt;h3 id="导入发行版"&gt;导入发行版&lt;/h3&gt;&#10;&lt;p&gt;导入wsl：&lt;code&gt;wsl --import &amp;lt;名称&amp;gt; &amp;lt;wsl虚拟磁盘位置&amp;gt; &amp;lt;导入源文件&amp;gt; [Options]&lt;/code&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-import&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt; &lt;span class="n"&gt;P:&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ubd&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt; &lt;span class="n"&gt;P:&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;tar&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-version&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;导入这个命令也支持tar.gz格式，根据分发版只是一个用户态文件系统的理解，依据这个命令可以玩一个比较骚的操作：直接下载一个&lt;a class="link" href="https://cdimage.ubuntu.com/ubuntu-base/releases/25.04/release/ubuntu-base-25.04-base-amd64.tar.gz" target="_blank" rel="noopener"&#10; &gt;ubuntu25.04&lt;/a&gt;的rootfs，然后直接使用wsl &amp;ndash;import这个文件，那就可以得到一个干干净净，几乎没有任何附加的wsl分发，然后再自己装一装库包&lt;/p&gt;&#10;&lt;h3 id="导出发行版"&gt;导出发行版&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-export&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt; &lt;span class="n"&gt;P:&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ub20&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;231009&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;tar&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="从-vhdx-还原发行版"&gt;从 VHDX 还原发行版&lt;/h3&gt;&#10;&lt;p&gt;将指定的 .vhdx 文件作为新分发版导入。 必须使用 ext4 文件系统类型设置此虚拟硬盘的格式。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-import-in-place&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Distro&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FileName&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;其实WSL安装好都是一个ext4.vhdx的虚拟磁盘，如果重装电脑啥的要还原之前的WSL只需将这个文件备份；&lt;/p&gt;&#10;&lt;h2 id="时间同步与-systemd"&gt;时间同步与 systemd&lt;/h2&gt;&#10;&lt;h3 id="同步宿主机时间"&gt;同步宿主机时间&lt;/h3&gt;&#10;&lt;p&gt;同步宿主机时间，解决有时候时间不一致的问题：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hwclock -s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="启用-systemd"&gt;启用 systemd&lt;/h3&gt;&#10;&lt;p&gt;wsl systemd，这个现在应该用不上了，wsl-config默认有相关配置，&lt;a class="link" href="https://learn.microsoft.com/zh-cn/windows/wsl/systemd#how-to-enable-systemd" target="_blank" rel="noopener"&#10; &gt;官方文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-update&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Bash" data-lang="Bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -L -O &lt;span class="s2"&gt;&amp;#34;https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x install.sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./install.sh install&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/opt/distrod/bin/distrod &lt;span class="nb"&gt;enable&lt;/span&gt; --start-on-windows-boot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="图形应用与字体"&gt;图形应用与字体&lt;/h2&gt;&#10;&lt;h3 id="应用缩放"&gt;应用缩放&lt;/h3&gt;&#10;&lt;p&gt;wslg 应用缩放调整：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;export GDK_DPI_SCALE=1.5&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果使用wsl中的vscode或其他图形化应用字体显示过小可以用这个；wsl打开linux图形化这个功能主要问题是输入中文需要在linux上安装中文输入法，用起来真一言难尽&lt;/p&gt;&#10;&lt;h3 id="中文字体"&gt;中文字体&lt;/h3&gt;&#10;&lt;p&gt;中文安装好依赖后方框，给windows的字体加个软连接连到wsl里，需不需要重启有点忘了，这个大家实际操作视具体情况&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p /usr/share/fonts/win11 &lt;span class="c1"&gt;# to differentiate self-built font links from system font files&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ln -s /mnt/c/Windows/Fonts/* /usr/share/fonts/win11&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;重启wsl&lt;/p&gt;&#10;&lt;h2 id="卸载-wsl"&gt;卸载 WSL&lt;/h2&gt;&#10;&lt;p&gt;wsl 卸载，winserver上只关闭wsl功能不会卸载wsl组件，需要执行下面命令&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wsl&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-uninstall&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Rust 过程宏中获取结构体 field 类型的字符串</title><link>https://s-infinite-box.github.io/posts/rust-proc-macro-field-type/</link><guid>https://s-infinite-box.github.io/posts/rust-proc-macro-field-type/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/rust_hu_c61618c0ab0d7707.jpg" alt="封面"&gt;&lt;p&gt;搜了下中文社区的资料,没找到相关的内容，自己探索了几次找到了方法，贴出来大家参考&lt;/p&gt;&#10;&lt;h2 id="获取字段类型"&gt;获取字段类型&lt;/h2&gt;&#10;&lt;p&gt;直接贴代码：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;proc_macro2&lt;/span&gt;::&lt;span class="n"&gt;Ident&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;::&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;format_ident&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quote_spanned&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;syn&lt;/span&gt;::&lt;span class="n"&gt;punctuated&lt;/span&gt;::&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;IntoIter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Punctuated&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;syn&lt;/span&gt;::&lt;span class="n"&gt;token&lt;/span&gt;::&lt;span class="n"&gt;Comma&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;syn&lt;/span&gt;::&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DataStruct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LitStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_ield_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;: &lt;span class="nc"&gt;IntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&amp;gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;::&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;punctuated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p_segment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;punctuated&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 此处获取的是首个类型，类似Option&amp;lt;String&amp;gt;，0 是Option，1是String&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;first path segment must be a raw identifier&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;p_segment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ident&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 实际是一个ident&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 其他类型，Type本身是个枚举，类型很多我基本一个没看懂，也没找到比较好的资料，如果大家有的话分享一下&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这个mod里还有其他逻辑，use引入明显有冗余，这个我就不做处理了，可以不用我这个use，create引入过程宏三件套直接来自己引入&lt;/p&gt;&#10;&lt;h3 id="示例结构体与返回结果"&gt;示例结构体与返回结果&lt;/h3&gt;&#10;&lt;p&gt;我这里是derive宏标记了下面这个结构体&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pub struct Model {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub name: Option&amp;lt;String&amp;gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub id: Uuid,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub created_date: DateTime,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub created_by: String,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub updated_date: DateTime,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub updated_by: String,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pub is_delete: i32,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;函数返回会得到类似这样的vec:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[&amp;#34;Option&amp;#34;, &amp;#34;Uuid&amp;#34;, &amp;#34;DateTime&amp;#34;, &amp;#34;String&amp;#34;, &amp;#34;DateTime&amp;#34;, &amp;#34;String&amp;#34;, &amp;#34;i32&amp;#34;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="过程宏调试"&gt;过程宏调试&lt;/h2&gt;&#10;&lt;p&gt;之前调试的时候基本只是看编译报错，但是这次找类型就想找一个能断电DEBUG或者打印信息的方式，最终尝试了两个方式可以&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;直接 println!() 宏，这个方式可以在编译的时候打印内容到控制台&lt;/li&gt;&#10;&lt;li&gt;另一种是直接 panic!()，这个方式明显也可以&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;目前我是打印或者panic，然后写一个test标记的fn，然后cargo test 对应的方法&lt;/p&gt;&#10;&lt;p&gt;应该还有更优雅，甚至可以直接DEBUG的方法，期待大佬们的分享，我也相当于抛砖引玉了&lt;/p&gt;&#10;&lt;h2 id="解析-synpath-与泛型参数"&gt;解析 syn::Path 与泛型参数&lt;/h2&gt;&#10;&lt;p&gt;再补充一个Option&lt;String&gt;对应println! 出来syn::Path的类型格式给大家参考&lt;/p&gt;&#10;&lt;p&gt;我手动缩进了一下，两个::的前后表示枚举及对应类型&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;span class="lnt"&gt;27&#10;&lt;/span&gt;&lt;span class="lnt"&gt;28&#10;&lt;/span&gt;&lt;span class="lnt"&gt;29&#10;&lt;/span&gt;&lt;span class="lnt"&gt;30&#10;&lt;/span&gt;&lt;span class="lnt"&gt;31&#10;&lt;/span&gt;&lt;span class="lnt"&gt;32&#10;&lt;/span&gt;&lt;span class="lnt"&gt;33&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;syn::Path {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; leading_colon: None,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; segments: [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; PathSegment {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ident: Ident {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ident: &amp;#34;Option&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; span: #0 bytes(763..769)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; arguments: PathArguments::AngleBracketed {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; colon2_token: None,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; lt_token: Lt,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; args: [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; GenericArgument::Type(Type::Path {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; qself: None,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; path: Path {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; leading_colon: None,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; segments: [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; PathSegment {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ident: Ident {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ident: &amp;#34;String&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; span: #0 bytes(770..776)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; arguments: PathArguments::None&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; })&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gt_token: Gt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="类型解析路径"&gt;类型解析路径&lt;/h3&gt;&#10;&lt;p&gt;这个是clion中的代码截图，IDE中可以直接看到field中每解析一步，对应的类型&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/rust-proc-macro-field-type/685ba6a7040a45db849ea087c66640b3.png" alt="在这里插入图片描述"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;Field ==&amp;gt; Type::Path(TypePath) ==&amp;gt; Path ==&amp;gt; Punctuated&amp;lt;PathSegment, PathSep&amp;gt; ==&amp;gt; PathSegment ==&amp;gt; ident&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;其中 Punctuated本质是一个vec&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Punctuated&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;inner&lt;/span&gt;: &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;: &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="泛型参数与类型嵌套"&gt;泛型参数与类型嵌套&lt;/h3&gt;&#10;&lt;p&gt;PathSegment除了ident作为当前的类型名以外，还有一个arguments字段，类型是PathArguments枚举，&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;span class="lnt"&gt;27&#10;&lt;/span&gt;&lt;span class="lnt"&gt;28&#10;&lt;/span&gt;&lt;span class="lnt"&gt;29&#10;&lt;/span&gt;&lt;span class="lnt"&gt;30&#10;&lt;/span&gt;&lt;span class="lnt"&gt;31&#10;&lt;/span&gt;&lt;span class="lnt"&gt;32&#10;&lt;/span&gt;&lt;span class="lnt"&gt;33&#10;&lt;/span&gt;&lt;span class="lnt"&gt;34&#10;&lt;/span&gt;&lt;span class="lnt"&gt;35&#10;&lt;/span&gt;&lt;span class="lnt"&gt;36&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[cfg_attr(docsrs, doc(cfg(any(feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;full&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;, feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;derive&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;))))]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;PathArguments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The `&amp;lt;&amp;#39;a, T&amp;gt;` in `std::slice::iter&amp;lt;&amp;#39;a, T&amp;gt;`.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AngleBracketed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AngleBracketedGenericArguments&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The `(A, B) -&amp;gt; C` in `Fn(A, B) -&amp;gt; C`.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Parenthesized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParenthesizedGenericArguments&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[cfg_attr(docsrs, doc(cfg(any(feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;full&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;, feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;derive&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;))))]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;AngleBracketedGenericArguments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;colon2_token&lt;/span&gt;: &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="fm"&gt;Token!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;::&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lt_token&lt;/span&gt;: &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;: &lt;span class="nc"&gt;Punctuated&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GenericArgument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;Token!&lt;/span&gt;&lt;span class="p"&gt;[,]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gt_token&lt;/span&gt;: &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[cfg_attr(docsrs, doc(cfg(any(feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;full&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;, feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;derive&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;))))]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[non_exhaustive]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;GenericArgument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// A lifetime argument.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Lifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lifetime&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// A type argument.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ### 这里再次出现Type类型，实现了类型嵌套&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// A const expression. Must be inside of a block.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;///&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// NOTE: Identity expressions are represented as Type arguments, as&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// they are indistinguishable syntactically.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Const&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// A binding (equality constraint) on an associated type: the `Item =&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// u8` in `Iterator&amp;lt;Item = u8&amp;gt;`.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AssocType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AssocType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// An equality constraint on an associated constant: the `PANIC =&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// false` in `Trait&amp;lt;PANIC = false&amp;gt;`.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AssocConst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AssocConst&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// An associated type bound: `Iterator&amp;lt;Item: Display&amp;gt;`.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;而AngleBracketedGenericArguments类型再进去还会出现Type类型，实现类型的嵌套&lt;/p&gt;&#10;&lt;h2 id="待验证的问题"&gt;待验证的问题&lt;/h2&gt;&#10;&lt;p&gt;TODO，每搞清楚为啥segments本身是一个数组，猜测是处理泛型用的，必须rust可以像python的union一样给泛型加多个特征实现，比如&lt;code&gt;T: Send + Sync&lt;/code&gt;，待后续验证一下&lt;/p&gt;&#10;</description></item><item><title>Kubernetes 1.19 升级到 1.32：常用资源 YAML 字段变动整理</title><link>https://s-infinite-box.github.io/posts/kubernetes-1-19-to-1-32-api-changes/</link><guid>https://s-infinite-box.github.io/posts/kubernetes-1-19-to-1-32-api-changes/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/k8s-flower.svg" alt="封面"&gt;&lt;h2 id="对比范围"&gt;对比范围&lt;/h2&gt;&#10;&lt;p&gt;对比了下面这些资源，基本是一些常用的：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;configmap&lt;/li&gt;&#10;&lt;li&gt;cronjob&lt;/li&gt;&#10;&lt;li&gt;daemonset&lt;/li&gt;&#10;&lt;li&gt;deployment&lt;/li&gt;&#10;&lt;li&gt;hpa&lt;/li&gt;&#10;&lt;li&gt;ingress&lt;/li&gt;&#10;&lt;li&gt;job&lt;/li&gt;&#10;&lt;li&gt;namespace&lt;/li&gt;&#10;&lt;li&gt;persistentvolume&lt;/li&gt;&#10;&lt;li&gt;persistentvolumeclaim&lt;/li&gt;&#10;&lt;li&gt;secret&lt;/li&gt;&#10;&lt;li&gt;service&lt;/li&gt;&#10;&lt;li&gt;statefulset&lt;/li&gt;&#10;&lt;li&gt;storageclass&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="资源变化情况"&gt;资源变化情况&lt;/h2&gt;&#10;&lt;h3 id="普遍修改"&gt;普遍修改&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;删除：metadata.clusterName&amp;lt;string&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：metadata.managedFields.subresource&amp;lt;string&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="pod"&gt;Pod&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;删除：spec.ephemeralContainers.volumes.ephemeral.readOnly&amp;lt;boolean&amp;gt;&lt;/code&gt;在1.31版本中删除，&lt;code&gt;ephemeralContainers&lt;/code&gt;卷的只读挂载，卷本身依旧有只读选项&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：&lt;/code&gt;亲和性和反亲和性的软硬匹配&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.podAffinityTerm.matchLabelKeys&lt;/code&gt;matchLabelKeys 是一组 Pod 标签键，用于通过计算 Pod 分布方式来选择 Pod；这是一个 Beta 字段，需要启用 MatchLabelKeysInPodTopologySpread 特性门控（默认启用）&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.namespaceSelector&lt;/code&gt;对条件所适用的名字空间集合的标签查询。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/blockquote&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：lifecycle&lt;/code&gt;：&lt;code&gt;postStart&lt;/code&gt;和&lt;code&gt;preStop&lt;/code&gt;增加字段&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;FIELDS.spec.template.spec.containers.lifecycle.postStart.sleep 睡眠表示容器在终止之前应该睡眠的持续时间&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/blockquote&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：readinessProbe/livenessProbe&lt;/code&gt;/startupProbe增加字段&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.template.spec.containers.livenessProbe.grpc&lt;/code&gt; 指定涉及 GRPC 端口的操作。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.template.spec.containers.livenessProbe.terminationGracePeriodSeconds&lt;/code&gt;表示 Pod 需要体面终止的所需的时长（以秒为单位）。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/blockquote&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.initContainers.restartPolicy&lt;/code&gt;restartPolicy 定义 Pod 中各个容器的重新启动行为。 该字段仅适用于 Init 容器，唯一允许的值是 &amp;ldquo;Always&amp;rdquo;。 将 restartPolicy 设置为 &amp;ldquo;Always&amp;rdquo; 会产生以下效果：该 Init 容器将在退出后持续重新启动，直到所有常规容器终止。 一旦所有常规容器已完成，所有具有 restartPolicy 为 &amp;ldquo;Always&amp;rdquo; 的 Init 容器将被关闭。 这种生命期与正常的 Init 容器不同，通常被称为 &amp;ldquo;sidecar&amp;rdquo; 容器。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.containers.resizePolicy&lt;/code&gt;容器的资源调整策略。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.containers.resources.claims&lt;/code&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;claims 列出了此容器/POD使用的资源名称，资源名称在 spec.resourceClaims 中定义。 这是一个 Alpha 特性字段，需要启用 DynamicResourceAllocation 功能门控开启此特性。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.ephemeralContainers.securityContext.appArmorProfile&lt;/code&gt;AppArmorProfile 定义了一个POD或容器的 Appdeck 设置。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.ephemeralContainers.securityContext.windowsOptions.hostProcess&lt;/code&gt;HostProcess 确定容器是否应作为 “Host Process” 容器运行。Pod 的所有容器必须具有相同的有效 HostProcess 值 (不允许将 HostProcess 容器和非 HostProcess 容器混合)。此外，如果 HostProcess 为 true，那么 HostNetwork 也必须设置为 true。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.containers.volumeMounts.recursiveReadOnly&lt;/code&gt;指定是否应递归处理只读挂载&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.hostUsers&lt;/code&gt;使用主机的用户名称空间&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.template.spec.os&lt;/code&gt;指定POD中容器的操作系统。如果设置了该操作系统，一些POD和容器字段将受到限制。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="daemonset"&gt;DaemonSet&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.updateStrategy.rollingUpdate.maxSurge&lt;/code&gt;对于拥有可用 DaemonSet Pod 的节点而言，在更新期间可以拥有更新后的 DaemonSet Pod 的最大节点数&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="job"&gt;Job&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.completionMode&lt;/code&gt; 增加一个JOB完成的判断&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：&lt;/code&gt;三类执行策略&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.podReplacementPolicy&lt;/code&gt; 指定何时创建替代的 Pod。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.podFailurePolicy&lt;/code&gt; 指定处理失效 Pod 的策略。特别是，它允许指定采取关联操作需要满足的一组操作和状况。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;FIELDS.spec.successPolicy&lt;/code&gt; 描述何时可以根据某些索引的成功将任务声明为成功&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="cronjob"&gt;CronJob&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;修改：Version: &lt;code&gt;batch/v1beta1&lt;/code&gt;==&amp;gt;&lt;code&gt;batch/v1&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.timeZone&lt;/code&gt;给定时间表的时区名称&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.lastSuccessfulTime&lt;/code&gt;上次成功完成作业的时间信息。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="horizontalpodautoscalerv2修改较大"&gt;HorizontalPodAutoscaler（V2修改较大）&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;修改：Version: &lt;code&gt;autoscaling/v1&lt;/code&gt;==&amp;gt;&lt;code&gt;autoscaling/v2&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;删除：spec.targetCPUUtilizationPercentage&lt;/code&gt;字段删除，V2提供了更丰富的指标选项，不仅仅局限于 CPU 利用率&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.behavior&lt;/code&gt;基于策略来扩缩POD：指定扩缩策略来限制扩缩速度。可以通过指定稳定窗口来防止抖动，可以制定绝对数量/相对数量等&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.metrics&lt;/code&gt;基于指标的扩缩：Kubernetes 的container指标，不与任何 Kubernetes 对象关联、基于来自集群外部运行组件的指标，单个 Kubernetes 对象的指标，当前扩缩目标中每个 Pod 的指标， Kubernetes 已知的resource资源指标&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.conditions&lt;/code&gt;conditions 是此自动扩缩器扩缩其目标所需的一组条件，并指示是否满足这些条件。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.currentMetrics&lt;/code&gt; 是此自动扩缩器使用的指标的最后读取状态。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="ingress"&gt;Ingress&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;修改：Version: &lt;code&gt;autoscaling/v1&lt;/code&gt;==&amp;gt;&lt;code&gt;autoscaling/v2&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;删除：spec.targetCPUUtilizationPercentage&lt;/code&gt;字段删除，V2提供了更丰富的指标选项，不仅仅局限于 CPU 利用率&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.behavior&lt;/code&gt;基于策略来扩缩POD：指定扩缩策略来限制扩缩速度。可以通过指定稳定窗口来防止抖动，可以制定绝对数量/相对数量等&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.metrics&lt;/code&gt;基于指标的扩缩：Kubernetes 的container指标，不与任何 Kubernetes 对象关联、基于来自集群外部运行组件的指标，单个 Kubernetes 对象的指标，当前扩缩目标中每个 Pod 的指标， Kubernetes 已知的resource资源指标&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.conditions&lt;/code&gt;conditions 是此自动扩缩器扩缩其目标所需的一组条件，并指示是否满足这些条件。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.currentMetrics&lt;/code&gt; 是此自动扩缩器使用的指标的最后读取状态。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="service"&gt;Service&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;修改：spec.ipFamily&amp;lt;string&amp;gt;&lt;/code&gt;==&amp;gt;&lt;code&gt;spec.ipFamilies&amp;lt;[]string&amp;gt;&lt;/code&gt; 有效值为 “IPv4” 和 “IPv6”。通常根据集群配置和 ipFamilyPolicy 字段自动设置&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;删除：spec.topologyKeys&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.internalTrafficPolicy &lt;/code&gt;描述节点如何分发它们在 ClusterIP 上接收到的服务流量。 如果设置为 “Local”，代理将假定 Pod 只想与在同一节点上的服务端点通信，如果没有本地端点，它将丢弃流量。 “Cluster” 默认将流量路由到所有端点（可能会根据拓扑和其他特性进行修改）。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.loadBalancerClass&lt;/code&gt; 是此 Service 所属的负载均衡器实现的类&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.ipFamilyPolicy&lt;/code&gt; 表示此服务请求或要求的双栈特性&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.trafficDistribution&lt;/code&gt; 提供了一种流量如何被分配到 Service 端点的偏好表达方式&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.status.conditions&lt;/code&gt;当前状态&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="persistentvolume"&gt;PersistentVolume&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;添加：&lt;code&gt;FIELDS.spec.csi.nodeExpandSecretRef&lt;/code&gt; 是对包含敏感信息的 Secret 对象的引用， 从而传递到 CSI 驱动以完成 CSI NodeExpandVolume 调用。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="persistentvolumeclaim"&gt;PersistentVolumeClaim&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;删除：spec.volumeName&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;添加：&lt;code&gt;FIELDS.spec.volumes.image&lt;/code&gt;镜像作为卷挂载到POD&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.dataSourceRef&lt;/code&gt; 允许任意名字空间中的任何非核心对象作为数据源&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="statefulset"&gt;StatefulSet&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.minReadySeconds&lt;/code&gt;新创建的 Pod 应准备就绪（其任何容器都未崩溃）的最小秒数，以使其被视为可用&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.ordinals&lt;/code&gt;ordinals 控制 StatefulSet 中副本索引的编号。 默认序数行为是将索引 &amp;ldquo;0&amp;rdquo; 设置给第一个副本，对于每个额外请求的副本，该索引加一。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加：FIELDS.spec.persistentVolumeClaimRetentionPolicy&lt;/code&gt; 描述从 VolumeClaimTemplates 创建的持久卷申领的生命周期。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;添加FIELDS.spec.updateStrategy.rollingUpdate.maxUnavailable&lt;/code&gt; 更新期间不可用的 Pod 个数上限。取值可以是绝对数量（例如：5）或所需 Pod 的百分比（例如：10%）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item><item><title>K8s 网络插件 Cilium 相关技术调研总结</title><link>https://s-infinite-box.github.io/posts/cilium-research-notes/</link><guid>https://s-infinite-box.github.io/posts/cilium-research-notes/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/cilium_hu_dbdbd5836166c7c.jpg" alt="封面"&gt;&lt;p&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="590" height="210" fill="none" viewBox="0 0 118 42" class="col-span-1 lg:col-span-1"&gt;&lt;path fill="#141A1F" d="M23.79 14.344h-7.604l-3.818 6.725 3.8 6.656h7.62l3.8-6.656zM22.775 25.9H17.18l-2.786-4.849 2.789-4.9h5.596l2.788 4.9z"&gt;&lt;/path&gt;&lt;path fill="#E83030" d="M14.392 21.068 17.18 25.9h5.596l2.806-4.832-2.806-4.968H17.18z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M23.79 28.637h-7.604l-3.818 6.707 3.8 6.656h7.62l3.8-6.656zm-1.015 11.607H17.18l-2.786-4.849 2.789-4.9h5.596l2.788 4.9z"&gt;&lt;/path&gt;&lt;path fill="#6B91C7" d="m14.392 35.344 2.788 4.9h5.596l2.806-4.9-2.806-4.9H17.18z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M23.79 0h-7.604l-3.818 6.725 3.818 6.656h7.62l3.8-6.656zm-1.015 11.556H17.18l-2.786-4.849 2.789-4.95h5.596l2.788 4.9z"&gt;&lt;/path&gt;&lt;path fill="#F9C31F" d="m14.392 6.723 2.788 4.833h5.596l2.806-4.833-2.806-4.967H17.18z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M36.159 21.541h-7.543l-3.8 6.725 3.8 6.656h7.62l3.8-6.656zm-1.015 11.585H29.55l-2.789-4.85 2.789-4.9h5.595l2.789 4.9z"&gt;&lt;/path&gt;&lt;path fill="#795AA5" d="m26.747 28.29 2.829 4.85h5.58l2.856-4.85-2.856-4.967h-5.58z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M36.159 7.197h-7.543l-3.8 6.656 3.8 6.656h7.62l3.8-6.656zM35.144 18.77H29.55l-2.789-4.85 2.789-4.9h5.595l2.789 4.9z"&gt;&lt;/path&gt;&lt;path fill="#F17423" d="m26.747 13.924 2.784 4.914h5.625l2.856-4.849-2.856-4.968h-5.625z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M11.355 21.541H3.8L0 28.266l3.8 6.656h7.62l3.8-6.656zM10.34 33.115H4.812l-2.788-4.85 2.788-4.9h5.596l2.789 4.9z"&gt;&lt;/path&gt;&lt;path fill="#97C639" d="m2.023 28.265 2.789 4.849h5.528l2.856-4.85-2.856-4.967H4.812z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M11.355 7.197H3.8L0 13.853l3.8 6.656h7.62l3.8-6.656zM10.34 18.771H4.812l-2.788-4.85 2.788-4.9h5.596l2.789 4.9z"&gt;&lt;/path&gt;&lt;path fill="#C9DB70" d="m2.023 13.92 2.789 4.85h5.528l2.856-4.85-2.856-4.967H4.812z"&gt;&lt;/path&gt;&lt;path fill="#141A1F" d="M57.088 14.074c.62.004 1.239.075 1.844.213.574.124 1.06.35 1.53.587v1.838a16 16 0 0 0-1.6-.498c-.538-.125-1.024-.214-1.564-.214s-1.06.089-1.6.25c-.54.16-.99.462-1.443.888-.417.427-.748.961-1.025 1.637-.243.676-.364 1.512-.364 2.525 0 .7.086 1.398.296 2.027.187.585.482 1.129.869 1.6.383.463.869.801 1.391 1.05q.861.372 1.982.372c.538 0 1.059-.035 1.651-.16q.815-.2 1.6-.498v1.85c-.156.088-.364.213-.608.302-.244.09-.539.16-.869.25-.296.088-.608.124-.99.16l-1.026.088a7.3 7.3 0 0 1-2.556-.427 6.9 6.9 0 0 1-2.105-1.262 6.15 6.15 0 0 1-1.391-2.188c-.342-.889-.539-1.887-.539-3.112 0-.89.087-1.69.296-2.4a6.2 6.2 0 0 1 .749-1.887c.33-.536.683-1.014 1.112-1.398a6.4 6.4 0 0 1 1.355-.925c.486-.249.991-.426 1.478-.55l1.53-.143zm6.904-2.775v-2.49h2.163v2.49zM64.026 28V14.447h2.163v13.564zm6.625.011V7.35h2.164v20.661zM77.23 11.3v-2.49h2.163v2.49zM77.264 28V14.447h2.164v13.564zm11.784.349a8 8 0 0 1-1.844-.213 6.4 6.4 0 0 1-1.443-.622c-.416-.303-.782-.587-1.059-1.014a3.9 3.9 0 0 1-.683-1.262 8 8 0 0 1-.296-1.138l-.087-1.352v-8.287H85.8v8.287c0 .766.087 1.398.296 1.888.209.587.574 1.013 1.06 1.35.484.339 1.147.5 1.894.5.818 0 1.478-.16 1.981-.552.488-.372.87-.836 1.06-1.476.156-.462.243-1.048.243-1.724v-8.293h2.164v8.324q0 .634-.087 1.262a4.3 4.3 0 0 1-.243 1.085c-.156.462-.417.889-.684 1.299-.296.373-.66.699-1.059 1.013-.416.303-.904.499-1.478.676a7.1 7.1 0 0 1-1.895.249zm20.31-.35h-2.164v-8.725a5.4 5.4 0 0 0-.208-1.512c-.122-.427-.296-.766-.539-1.014a2.4 2.4 0 0 0-.869-.587c-.342-.124-.683-.16-1.112-.16a3.76 3.76 0 0 0-2.105.623 6.4 6.4 0 0 0-1.685 1.76v9.641H98.52V14.448h1.685l.417 1.887h.034l.783-.89c.296-.248.608-.498.939-.698a3.7 3.7 0 0 1 1.148-.463c.417-.124.869-.16 1.367-.16.99 0 1.808.25 2.468.7.661.498 1.148 1.138 1.531 1.974h.034c.574-.836 1.27-1.512 2.016-1.974.746-.463 1.651-.7 2.626-.7.452 0 .939.09 1.478.214.538.125.991.373 1.443.699s.782.836 1.059 1.476c.296.622.452 1.423.452 2.437v9.089h-2.086v-8.733a5.5 5.5 0 0 0-.209-1.512c-.122-.426-.296-.765-.539-1.013a2.44 2.44 0 0 0-.868-.587c-.342-.125-.684-.16-1.113-.16-.782 0-1.478.213-2.104.622a7.1 7.1 0 0 0-1.722 1.761z"&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;br&gt;&#10;&lt;h2 id="安装参考"&gt;安装参考&lt;/h2&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/v1.12/gettingstarted/k8s-install-advanced/" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="cli-命令行安装"&gt;CLI 命令行安装&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 获取最新CLI文件&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CILIUM_CLI_VERSION&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;qO&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://api.github.com/repos/cilium/cilium-cli/releases/latest&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;jq&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.tag_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;$CILIUM_CLI_VERSION&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CILIUM_CLI_VERSION&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;qO&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://api.github.com/repos/cilium/cilium-cli/releases/latest&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;jq&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.tag_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;done&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CLI_ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amd64&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;fail&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;releases&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;/$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CILIUM_CLI_VERSION&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;-$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CLI_ARCH&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tar&lt;/span&gt; &lt;span class="n"&gt;xzvfC&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;-$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CLI_ARCH&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rf&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;-$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CLI_ARCH&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用内网镜像则在这里参考使用内网镜像处理&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cilium&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;kubeProxyReplacement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;false&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;hubble&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relay&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;hubble&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 参数说明：&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# kubeProxyReplacement=false 关闭替换kubeProxy，二进制安装kubeproxy不能被检测到，cilium会默认开启替换kube-proxy模式&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# hubble.relay.enabled=true 开启hubble，用于流量监控&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# hubble.ui.enabled=true 开启hubble的web服务&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看安装状态&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cilium&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;po&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Aw&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="helm-安装-cilium"&gt;Helm 安装 Cilium&lt;/h3&gt;&#10;&lt;p&gt;&lt;strong&gt;安装 Helm：&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;latest_release_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://get.helm.sh/helm-latest-version&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;latest_release_response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;latest_release_response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;--silent --show-error --fail &amp;#34;$latest_release_url&amp;#34; 2&amp;gt;&amp;amp;1 || true )&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$latest_release_response&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^v[0-9]&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="o"&gt;`|&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[:upper:]&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;[:lower:]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;HELM_DIST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;helm-$TAG-$OS-$ARCH.tar.gz&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DOWNLOAD_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://get.helm.sh/$HELM_DIST&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;DOWNLOAD_URL&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;添加 Helm 仓库：&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm repo add cilium https://helm.cilium.io/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;安装 Cilium：&lt;/strong&gt; 参数配置及格式同 CLI 模式。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm install cilium cilium/cilium --namespace kube-system --set kubeProxyReplacement=false --set hubble.relay.enabled=true --set hubble.ui.enabled=true&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="内网离线安装镜像处理"&gt;内网离线安装镜像处理&lt;/h3&gt;&#10;&lt;p&gt;目前cilium的CLI工具没有提供统一的离线安装参数，但是可以在安装时指定组件镜像&#10;默认镜像源：quay.io，目前在国内可以正常下载，无需梯子&lt;/p&gt;&#10;&lt;h4 id="cri-镜像仓库代理"&gt;CRI 镜像仓库代理&lt;/h4&gt;&#10;&lt;p&gt;在CRI（containerd/docker）替换镜像仓库代理：quay.io/cilium ==》 harbor.my.cn/devops(替换为自己的内网镜像仓库地址)&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;containerd，参考文档：&lt;a class="link" href="https://github.com/containerd/containerd/blob/main/docs/hosts.md#cri" target="_blank" rel="noopener"&#10; &gt;https://github.com/containerd/containerd/blob/main/docs/hosts.md#cri&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;查看版本：ctr -v&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;如果是1.x版本可以使用方式一配置较简单，但是会有waring报警&lt;/li&gt;&#10;&lt;li&gt;方式二是官方建议配置方式，稍微麻烦一点&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;方式一，适用1.x版本：&lt;/p&gt;&#10;&lt;p&gt;配置文件 /etc/containerd/config.toml 添加，&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.grpc.v1.cri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mirrors&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.grpc.v1.cri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mirrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;quay.io/cilium&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# 代理仓库配置&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;endpoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;https://harbor.my.cn/devops&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.grpc.v1.cri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# 可选：关闭tls校验，可以使用http，便于本地测试&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.grpc.v1.cri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#39;harbor.my.cn/devops&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;insecure_skip_verify&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;方式二，适用2.x版本：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;/etc/containerd/config.toml 添加&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;io.containerd.cri.v1.images&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;config_path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/etc/containerd/certs.d&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;config_path内具体路径，registry_host_name为代理的repo地址：域名或端口号，hosts为具体配置内容&#10;&lt;code&gt;/etc/containerd/certs.d/[registry_host_name|IP address][:port]/hosts.toml&lt;/code&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;hosts.toml配置&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# server指定此 Registry Host 命名空间的默认服务器。&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;#指定 （s） 后，将按列出的顺序首先尝试主机。 如果 （s） 都已尝试，则 将用作回退。hosthostserver&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;#如果未指定，则将自动使用映像的注册表主机命名空间。server&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://registry-1.docker.io&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://mirror.registry&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 是用于指定主机操作的可选设置 能够执行。仅包含适用的值。&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;capabilities&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pull&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;resolve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;push&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ca（证书颁发机构认证）可以设置为路径或 paths 每个路径都指向一个 CA 文件，用于对 Registry 进行身份验证 Namespace。&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ca&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/etc/certs/mirror.pem&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# skip_verify跳过对注册表证书链的验证，并且 host name （设置为 .这应该仅用于测试或 与其他验证连接的方法结合使用。（默认为true)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;skip_verify&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://mirror.registry&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x-custom-2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;value2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://non-compliant-mirror.registry/v2/upstream&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;capabilities&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pull&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# override_path用于指示已定义主机的 API 根端点 在 URL 路径中，而不是按 API 规范。这可以与 缺少前缀的不合规 OCI 注册表。 （默认为/false)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;override_path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 id="通过-helm-指定组件镜像"&gt;通过 Helm 指定组件镜像&lt;/h4&gt;&#10;&lt;p&gt;helm/cilium 创建时通过参数指定组件的镜像，&lt;a class="link" href="https://docs.cilium.io/en/stable/helm-reference/#id1" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;基本使用镜像 注意修改镜像版本信息，可以直接helm拉chart下来，然后自己看value.yaml&lt;/p&gt;&#10;&lt;p&gt;image: &lt;a class="link" href="http://quay.io/cilium/cilium:v1.16.4@sha256:d55ec38938854133e06739b1af237932b9c4dd4e75e9b7b2ca3acc72540a44bf" target="_blank" rel="noopener"&#10; &gt;quay.io/cilium/cilium:v1.16.4@sha256:d55ec38938854133e06739b1af237932b9c4dd4e75e9b7b2ca3acc72540a44bf&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;envoy.image: &lt;a class="link" href="http://quay.io/cilium/cilium-envoy:v1.30.7-1731393961-97edc2815e2c6a174d3d12e71731d54f5d32ea16@sha256:0287b36f70cfbdf54f894160082f4f94d1ee1fb10389f3a95baa6c8e448586ed" target="_blank" rel="noopener"&#10; &gt;quay.io/cilium/cilium-envoy:v1.30.7-1731393961-97edc2815e2c6a174d3d12e71731d54f5d32ea16@sha256:0287b36f70cfbdf54f894160082f4f94d1ee1fb10389f3a95baa6c8e448586ed&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;operator.image: &lt;a class="link" href="http://quay.io/cilium/operator-generic:v1.16.4@sha256:c55a7cbe19fe0b6b28903a085334edb586a3201add9db56d2122c8485f7a51c5" target="_blank" rel="noopener"&#10; &gt;quay.io/cilium/operator-generic:v1.16.4@sha256:c55a7cbe19fe0b6b28903a085334edb586a3201add9db56d2122c8485f7a51c5&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;hubble.relay.image: &lt;a class="link" href="http://quay.io/cilium/hubble-relay:v1.16.4@sha256:fb2c7d127a1c809f6ba23c05973f3dd00f6b6a48e4aee2da95db925a4f0351d2" target="_blank" rel="noopener"&#10; &gt;quay.io/cilium/hubble-relay:v1.16.4@sha256:fb2c7d127a1c809f6ba23c05973f3dd00f6b6a48e4aee2da95db925a4f0351d2&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;hubble.ui.frontend.image: &lt;a class="link" href="http://quay.io/cilium/hubble-ui-backend:v0.13.1@sha256:0e0eed917653441fded4e7cdb096b7be6a3bddded5a2dd10812a27b1fc6ed95b" target="_blank" rel="noopener"&#10; &gt;quay.io/cilium/hubble-ui-backend:v0.13.1@sha256:0e0eed917653441fded4e7cdb096b7be6a3bddded5a2dd10812a27b1fc6ed95b&lt;/a&gt;&lt;/p&gt;&#10;&lt;h4 id="镜像参数参考列表"&gt;镜像参数参考列表&lt;/h4&gt;&#10;&lt;p&gt;helm/cilium 安装设计镜像参数参考列表：&lt;/p&gt;&#10;&lt;table class="relative-table wrapped confluenceTable" style="width: 190.636%;"&gt;&lt;colgroup&gt;&lt;col style="width: 9.01714%;"&gt;&lt;col style="width: 12.669%;"&gt;&lt;col style="width: 2.75023%;"&gt;&lt;col style="width: 75.5186%;"&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Agent container image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/cilium","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;imagePullSecrets&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Configure image pull secrets for pulling container images&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;preflight.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Cilium pre-flight image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/cilium","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;certgen&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Configure certificate generation for Hubble integration. If hubble.tls.auto.method=cronJob, these values are used for the Kubernetes CronJob which will be scheduled regularly to (re)generate any certificates not provided manually.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"affinity":{},"annotations":{"cronJob":{},"job":{}},"extraVolumeMounts":[],"extraVolumes":[],"image":{"digest":"sha256:169d93fd8f2f9009db3b9d5ccd37c2b753d0989e1e7cd8fe79f9160c459eef4f","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/certgen","tag":"v0.2.0","useDigest":true},"podLabels":{},"tolerations":[],"ttlSecondsAfterFinished":1800}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;clustermesh.apiserver.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Clustermesh API server image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/clustermesh-apiserver","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;envoy.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Envoy container image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"sha256:709c08ade3d17d52da4ca2af33f431360ec26268d288d9a6cd1d98acc9a1dced","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/cilium-envoy","tag":"v1.30.8-1733837904-eaae5aca0fb988583e5617170a65ac5aa51c0aa8","useDigest":true}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;hubble.relay.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Hubble-relay container image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/hubble-relay","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;hubble.ui.backend.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Hubble-ui backend image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"sha256:0e0eed917653441fded4e7cdb096b7be6a3bddded5a2dd10812a27b1fc6ed95b","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/hubble-ui-backend","tag":"v0.13.1","useDigest":true}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;hubble.ui.frontend.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Hubble-ui frontend image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"sha256:e2e9313eb7caf64b0061d9da0efbdad59c6c461f6ca1752768942bfeda0796c6","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/hubble-ui","tag":"v0.13.1","useDigest":true}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;nodeinit.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;node-init image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"sha256:8d7b41c4ca45860254b3c19e20210462ef89479bb6331d6760c4e609d651b29c","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/startup-script","tag":"c54c7edeab7fde4da68e59acd319ab24af242c3f","useDigest":true}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;operator.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;cilium-operator image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"alibabacloudDigest":"","awsDigest":"","azureDigest":"","genericDigest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/operator","suffix":"","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;preflight.image&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;Cilium pre-flight image.&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;object&lt;/p&gt;&lt;/td&gt;&lt;td colspan="1" rowspan="1" style="vertical-align: top;" class="confluenceTd"&gt;&lt;p&gt;&lt;code&gt;{"digest":"","override":null,"pullPolicy":"IfNotPresent","repository":"quay.io/cilium/cilium","tag":"v1.16.5","useDigest":false}&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#10;&lt;h2 id="cilium-与-kata-配合使用"&gt;Cilium 与 Kata 配合使用&lt;/h2&gt;&#10;&lt;p&gt;暂未详细调研。&lt;/p&gt;&#10;&lt;p&gt;参考文档：&lt;a class="link" href="https://docs.cilium.io/en/stable/network/kubernetes/kata/#kata-containers-with-cilium" target="_blank" rel="noopener"&#10; &gt;https://docs.cilium.io/en/stable/network/kubernetes/kata/#kata-containers-with-cilium&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="使用外部-etcd-存储-cilium-元数据"&gt;使用外部 etcd 存储 Cilium 元数据&lt;/h2&gt;&#10;&lt;h3 id="指定外部-etcd-端点"&gt;指定外部 etcd 端点&lt;/h3&gt;&#10;&lt;p&gt;helm install cilium cilium/cilium --version 1.14.4&#10;--namespace kube-system&#10;--set etcd.enabled=true&#10;--set &amp;ldquo;etcd.endpoints[0]=&lt;a class="link" href="http://etcd-endpoint1:2379/" target="_blank" rel="noopener"&#10; &gt;http://etcd-endpoint1:2379&lt;/a&gt;&amp;rdquo;&#10;--set &amp;ldquo;etcd.endpoints[1]=&lt;a class="link" href="http://etcd-endpoint2:2379/" target="_blank" rel="noopener"&#10; &gt;http://etcd-endpoint2:2379&lt;/a&gt;&amp;rdquo;&#10;--set &amp;ldquo;etcd.endpoints[2]=&lt;a class="link" href="http://etcd-endpoint3:2379/" target="_blank" rel="noopener"&#10; &gt;http://etcd-endpoint3:2379&lt;/a&gt;&amp;rdquo;&#10;--set identityAllocationMode=kvstore&lt;/p&gt;&#10;&lt;h3 id="创建-tls-证书-secret"&gt;创建 TLS 证书 Secret&lt;/h3&gt;&#10;&lt;p&gt;使用根证书权限、客户端密钥和 etcd 证书创建一个secret&lt;/p&gt;&#10;&lt;p&gt;kubectl create secret generic -n kube-system cilium-etcd-secrets&#10;--from-file=etcd-client-ca.crt=ca.crt&#10;--from-file=etcd-client.key=client.key&#10;--from-file=etcd-client.crt=client.crt&lt;/p&gt;&#10;&lt;h3 id="启用-ssl"&gt;启用 SSL&lt;/h3&gt;&#10;&lt;p&gt;为 etcd 启用 SSL， etcd 端点 URL 修改为 https&lt;/p&gt;&#10;&lt;p&gt;helm install cilium cilium/cilium --version 1.14.4&#10;--namespace kube-system&#10;--set etcd.enabled=true&#10;--set etcd.ssl=true&#10;--set &amp;ldquo;etcd.endpoints[0]=&lt;a class="link" href="https://etcd-endpoint1:2379/" target="_blank" rel="noopener"&#10; &gt;https://etcd-endpoint1:2379&lt;/a&gt;&amp;rdquo;&#10;--set &amp;ldquo;etcd.endpoints[1]=&lt;a class="link" href="https://etcd-endpoint2:2379/" target="_blank" rel="noopener"&#10; &gt;https://etcd-endpoint2:2379&lt;/a&gt;&amp;rdquo;&#10;--set &amp;ldquo;etcd.endpoints[2]=&lt;a class="link" href="https://etcd-endpoint3:2379/" target="_blank" rel="noopener"&#10; &gt;https://etcd-endpoint3:2379&lt;/a&gt;&amp;rdquo;&lt;/p&gt;&#10;&lt;h2 id="与-istio-共同使用"&gt;与 Istio 共同使用&lt;/h2&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/network/servicemesh/istio/#gsg-istio" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="cilium-适配配置"&gt;Cilium 适配配置&lt;/h3&gt;&#10;&lt;p&gt;istio会将POD的流量通过iptable代理到边车容器或者节点代理cilium在开启kubeProxyReplacement时，可能会中断相关代理流量&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm upgrade cilium cilium/cilium --version 1.16.4 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --namespace kube-system \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --reuse-values \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --set socketLB.hostNamespaceOnly true \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --set cni.exclusive false&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="istio-相关配置"&gt;Istio 相关配置&lt;/h3&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/network/servicemesh/istio/#istio-configuration" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Sidecar: 通过在 Istio 的 PeerAuthentication 下配置 mTLS.mode = DISABLE，为希望用 Cilium L7 策略管理的工作负载禁用 Istio mTLS，Istio &lt;a class="link" href="https://istio.io/latest/docs/reference/config/security/peer_authentication/#PeerAuthentication" target="_blank" rel="noopener"&#10; &gt;PeerAuthentication&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Ambient: 通过从名称空间中移除 Istio.io/dataplane-mode 标签，或者在你希望用 Cilium l7 管理的 pods 上标注 “禁用”，从而从 Istio 环境中移除你希望用 Cilium l7 管理的工作负载 ambient.Istio.io/redirection&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="替换-kube-proxy"&gt;替换 kube-proxy&lt;/h2&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/#kube-proxy-hybrid-modes" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="安装与状态检查"&gt;安装与状态检查&lt;/h3&gt;&#10;&lt;p&gt;安装cilium 开启替换kube-proxy特性：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;helm install cilium cilium/cilium --set &lt;span class="nv"&gt;kubeProxyReplacement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; --namespace kube-system cilium install --set &lt;span class="nv"&gt;kubeProxyReplacement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; --set&lt;span class="o"&gt;=&lt;/span&gt;ipam.operator.clusterPoolIPv4PodCIDRList&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;10.244.0.0/16&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;查看cilium状态 KubeProxyReplacement: Strict：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl -n kube-system &lt;span class="nb"&gt;exec&lt;/span&gt; ds/cilium -- cilium status &lt;span class="p"&gt;|&lt;/span&gt; grep KubeProxyReplacement&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;状态详情：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl -n kube-system &lt;span class="nb"&gt;exec&lt;/span&gt; ds/cilium -- cilium status --verbose&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="查看转发规则"&gt;查看转发规则&lt;/h3&gt;&#10;&lt;p&gt;idtable查看是否有kube-proxy转发的service：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables-save &lt;span class="p"&gt;|&lt;/span&gt; grep KUBE-SVC&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;bpf转发的service 列表：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl -n kube-system &lt;span class="nb"&gt;exec&lt;/span&gt; ds/cilium -- cilium service list&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="cilium-ingress"&gt;Cilium Ingress&lt;/h2&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/v1.14/network/servicemesh/ingress/" target="_blank" rel="noopener"&#10; &gt;参考文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;前置条件：需开启kube-proxy替换&lt;/p&gt;&#10;&lt;h3 id="helm-安装参数"&gt;Helm 安装参数&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cilium&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="mf"&gt;1.16&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;kube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;reuse&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ingressController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ingressController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loadbalancerMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dedicated&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt; &lt;span class="n"&gt;cilium&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cilium&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;kube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;reuse&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ingressController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ingressController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loadbalancerMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h3 id="升级与配置"&gt;升级与配置&lt;/h3&gt;&#10;&lt;p&gt;cilium upgrade 会覆盖之前的参数 注意保存之前的安装命令&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;cilium upgrade --version 1.14.17 \ --set kubeProxyReplacement=true \ --set ingressController.enabled=true \ --set ingressController.loadbalancerMode=dedicated&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;通过 &lt;code&gt;kube-system / cilium-config&lt;/code&gt;（configmap），配置ingressclass的Name，tls开启等&lt;/p&gt;&#10;&lt;h2 id="故障排查"&gt;故障排查&lt;/h2&gt;&#10;&lt;p&gt;注意看agent启动日志，可以看到agent的所有参数&lt;/p&gt;&#10;&lt;h3 id="无法识别路由设备"&gt;无法识别路由设备&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;failed to start: daemon creation failed: failed to detect devices: unable to determine direct routing device. Use --direct-routing-device to specify it\\nfailed to stop: unable to find controller ipcache-inject-labels&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;在 kube-system / cilium-config （configmap）指定主网卡&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;direct-routing-device: &amp;#34;eth0&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;devices: &amp;#34;eth0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="其他参考文档"&gt;其他参考文档&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/cmdref/cilium-agent/#cilium-agent" target="_blank" rel="noopener"&#10; &gt;agent启动参数参考&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/helm-reference/" target="_blank" rel="noopener"&#10; &gt;helm安装参数参考&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://docs.cilium.io/en/stable/kvstore/" target="_blank" rel="noopener"&#10; &gt;元数据KV存储参考&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="内核情况整理"&gt;内核情况整理&lt;/h2&gt;&#10;&lt;h3 id="centos-内核升级"&gt;CentOS 内核升级&lt;/h3&gt;&#10;&lt;p&gt;主要考虑centos内核升级&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="http://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/" target="_blank" rel="noopener"&#10; &gt;el官方内核库&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;kernel-ml 中的ml是英文【 mainline stable 】的缩写，是最新的稳定主线版本。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;目前较新的版本：5.4.278&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;kernel-lt 中的lt是英文【 long term support 】的缩写，是长期支持版本。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;6.1.12&lt;/li&gt;&#10;&lt;li&gt;6.6.9&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="cilium-功能对应内核版本"&gt;Cilium 功能对应内核版本&lt;/h3&gt;&#10;&lt;table class="wrapped confluenceTable"&gt;&lt;colgroup&gt;&lt;col style="width: 54.0pt;"&gt; &lt;col style="width: 145.5pt;"&gt; &lt;col style="width: 100.25pt;"&gt; &lt;col style="width: 296.25pt;"&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;功能&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;说明&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;建议内核版本&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;cilium&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;基础ebpf功能&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;4.15&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;replace kube-proxy&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;替换kube-proxy&lt;/td&gt;&lt;td class="confluenceTd"&gt;v4.19.57&lt;br&gt;v5.1.16&lt;br&gt;v5.2.0&lt;br&gt;以上版本&lt;br&gt;---&lt;br&gt;v5.3&lt;br&gt;v5.8&lt;br&gt;以上性能更好&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;a class="external-link" href="https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/#kubernetes-without-kube-proxy" rel="nofollow"&gt;Kubernetes Without kube-proxy&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;ingress&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;需开启kube-proxy替换&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;a class="external-link" href="https://docs.cilium.io/en/stable/network/servicemesh/ingress/" rel="nofollow"&gt;Kubernetes Ingress Support&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;Gateway API&lt;/td&gt;&lt;td class="confluenceTd"&gt;需开启kube-proxy替换&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;a class="external-link" href="https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/" rel="nofollow"&gt;Gateway API Support&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;7层流量处理&lt;/td&gt;&lt;td class="confluenceTd"&gt;需开启kube-proxy替换&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;a class="external-link" href="https://docs.cilium.io/en/stable/network/servicemesh/envoy-circuit-breaker/#l7-circuit-breaking" rel="nofollow"&gt;熔断&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;&lt;span class="font0"&gt;IP透传&lt;/span&gt;&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;node-ipam&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="confluenceTd"&gt;整合istio&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;br&gt;&lt;/td&gt;&lt;td style="text-align: center;" class="confluenceTd"&gt;-&lt;/td&gt;&lt;td class="confluenceTd"&gt;&lt;a class="external-link" href="https://docs.cilium.io/en/stable/network/servicemesh/istio/" rel="nofollow"&gt;Integration with Istio&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#10;</description></item><item><title>Go 脚本批量给飞书任务添加负责人</title><link>https://s-infinite-box.github.io/posts/feishu-task-assignees-go/</link><guid>https://s-infinite-box.github.io/posts/feishu-task-assignees-go/</guid><pubDate>Tue, 14 Apr 2026 15:18:15 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/go_hu_9edf62dc708fba5e.png" alt="封面"&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;目前在用飞书的任务功能来记录一些代办，安排生活、工作上的一些计划；&#10;之前是这个&lt;code&gt;我负责的&lt;/code&gt;里面来添加任务，后来在下面建了一个任务清单，然后在清单内维护代办事项&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/feishu-task-assignees-go/2b9484e187ae441cbd59363107d27c19.png" alt="在这里插入图片描述"&gt;&#10;然后问题就来了：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;在&lt;code&gt;我负责的&lt;/code&gt;创建的任务，默认我就是负责人，在日历中是直接可以看到的，而任务清单需要每次都要手动添加负责人；&lt;/li&gt;&#10;&lt;li&gt;而任务清单可以将一个清单内的任务直接作为页面分享，而在&lt;code&gt;我负责的&lt;/code&gt;创建的任务默认没有任务清单&#10;后面准备调整一下生活工作的节奏，记录下每天的运动打卡任务，如果在日历里直接可以看到那还是很有成就感的，于是就看了下飞书的SDK，准备手写脚本给任务清单批量加一下负责人；本来以为很简单，但最终还是花了几个小时，在这里把过程和遇到的问题记录一下，分享给大家；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="前置条件"&gt;前置条件&lt;/h2&gt;&#10;&lt;p&gt;需要一个飞书账号，我是用的飞书企业账号，没有企业认证，实际里面就我和我对象俩人&lt;/p&gt;&#10;&lt;h2 id="应用与权限配置"&gt;应用与权限配置&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;a class="link" href="https://open.feishu.cn/app" target="_blank" rel="noopener"&#10; &gt;创建应用&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;给应用开通接口权限，应用权限和用户权限都加上&#10;没有这一步调接口会返回unauthorized&#10;&lt;img src="https://s-infinite-box.github.io/posts/feishu-task-assignees-go/3015a85efc4e422aba681e78ec1bac72.png" alt="在这里插入图片描述"&gt;3. &lt;a class="link" href="https://open.feishu.cn/document/task-v2/tasklist/list" target="_blank" rel="noopener"&#10; &gt;查看任务清单列表&lt;/a&gt;&#9;找到要处理的任务清单id；这个时候应用还没权限，可以先用user_access_token；&#10;&lt;strong&gt;简要说明下用户token和租户token：&lt;/strong&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;用户token：需要走飞书登录流程，登录成功后获取的token&lt;/li&gt;&#10;&lt;li&gt;租户token：可以简单理解为应用的ak、sk，无需每次登录&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="link" href="https://open.feishu.cn/document/task-v2/tasklist/add_members" target="_blank" rel="noopener"&#10; &gt;添加清单成员&lt;/a&gt;&#10;这一步类似于加数据权限，不然每次用租户token查询的数据都是空&#10;页面貌似只能加人，不能加应用，接口是可以把应用加到清单的协作人里&#10;我卡了很久，最后问了下平台的AI才找到原因；&#10;加成功在任务清单可以看到应用&#10;&lt;img src="https://s-infinite-box.github.io/posts/feishu-task-assignees-go/fce505fda1d44eb6ae597bc2d006f418.png" alt="在这里插入图片描述"&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="批量处理脚本"&gt;批量处理脚本&lt;/h2&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://gitcode.com/2501_90571811/blog_note/tree/main/feishu-gosdk" target="_blank" rel="noopener"&#10; &gt;源码仓库&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;先装一下sdk&#10;&lt;ul&gt;&#10;&lt;li&gt;go get -u github.com/larksuite/oapi-sdk-go/v3@latest&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;main.go代码：&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 10&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 11&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 12&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 13&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 14&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 15&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 16&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 17&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 18&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 19&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 20&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 21&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 22&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 23&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 24&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 25&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 26&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 27&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 28&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 29&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 30&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 31&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 32&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 33&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 34&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 35&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 36&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 37&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 38&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 39&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 40&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 41&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 42&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 43&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 44&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 45&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 46&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 47&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 48&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 49&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 50&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 51&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 52&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 53&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 54&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 55&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 56&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 57&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 58&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 59&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 60&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 61&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 62&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 63&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 64&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 65&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 66&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 67&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 68&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 69&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 70&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 71&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 72&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 73&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 74&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 75&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 76&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 77&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 78&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 79&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 80&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 81&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 82&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 83&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 84&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 85&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 86&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 87&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 88&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 89&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 90&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 91&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 92&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 93&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 94&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 95&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 96&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 97&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 98&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 99&#10;&lt;/span&gt;&lt;span class="lnt"&gt;100&#10;&lt;/span&gt;&lt;span class="lnt"&gt;101&#10;&lt;/span&gt;&lt;span class="lnt"&gt;102&#10;&lt;/span&gt;&lt;span class="lnt"&gt;103&#10;&lt;/span&gt;&lt;span class="lnt"&gt;104&#10;&lt;/span&gt;&lt;span class="lnt"&gt;105&#10;&lt;/span&gt;&lt;span class="lnt"&gt;106&#10;&lt;/span&gt;&lt;span class="lnt"&gt;107&#10;&lt;/span&gt;&lt;span class="lnt"&gt;108&#10;&lt;/span&gt;&lt;span class="lnt"&gt;109&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/larksuite/oapi-sdk-go/v3&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/larksuite/oapi-sdk-go/v3/core&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/larksuite/oapi-sdk-go/v3/service/task/v2&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 用户id，第三步查任务清单的时候，看清单的members可以直接看到&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;`xxx`&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 创建好应用，应用的首页默认就是基础信息与凭证&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;appId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;`xxx`&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;appSecret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;`xxx`&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 清单id，第三步的时候看name找id&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tasklistGuid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;`xxx`&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 创建 Client&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;appSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reqCount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;tasksTasklistReq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewTasksTasklistReqBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;TasklistGuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tasklistGuid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;UserIdType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`open_id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;tasksTasklistReq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PageToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 获取清单下的任务&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;V2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tasklist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Tasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;tasksTasklistReq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 处理错误&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 服务端错误处理&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;logId: %s, error response: \n%s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RequestId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;larkcore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Prettify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CodeError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 循环处理任务&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HasMore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;no more task&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PageToken&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;任务总数：%d，处理：%d &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reqCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TaskSummary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Members&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assignee&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;%s,already in task\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 接口频率限制 100次/一分钟，可以根据网速自己缩小一下时间&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reqCount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reqCount&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;sleep 10s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 给任务添加 成员&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;V2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMembers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewAddMembersTaskReqBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;TaskGuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;UserIdType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`open_id`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewAddMembersTaskReqBodyBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Members&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Member&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;larktask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewMemberBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`user`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`assignee`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;reqCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 处理错误&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 服务端错误处理&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;logId: %s, error response: \n%s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RequestId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;larkcore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Prettify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CodeError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;// 业务处理&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;larkcore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Prettify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>windows与ubuntu双系统主机下ubuntu访问windows磁盘是只读</title><link>https://s-infinite-box.github.io/posts/ubuntu-windows-ntfs-readonly/</link><guid>https://s-infinite-box.github.io/posts/ubuntu-windows-ntfs-readonly/</guid><pubDate>Thu, 21 Nov 2024 16:10:00 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux-or-Windows_hu_334ee4f8cd6e3a15.jpg" alt="封面"&gt;&lt;h2 id="尝试关闭-windows-快速启动"&gt;尝试关闭 Windows 快速启动&lt;/h2&gt;&#10;&lt;p&gt;看一些博客写的切换windows关闭快速启动，结果到windows系统以后，电源选项里就没有快速启动，这个地方还是跑了一下关闭快速启动的命令，&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;powercfg&lt;/span&gt; &lt;span class="n"&gt;-h&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt; &lt;span class="c"&gt;# 就是禁用休眠模式 同时会删除C盘的hiberfil.sys&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="尝试直接运行-ntfsfix"&gt;尝试直接运行 ntfsfix&lt;/h2&gt;&#10;&lt;p&gt;切换ubuntu，还是一样，这个时候尝试第二个方法&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ntfsfix /dev/xxx&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 并无X用&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="卸载磁盘后修复并重新挂载"&gt;卸载磁盘后修复并重新挂载&lt;/h2&gt;&#10;&lt;p&gt;先卸载磁盘，运行：“ntfsfix /dev/xxx” 再挂载，问题解决&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 卸载已挂载的设备&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo umount /dev/nvme1n1p3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ntfsfix /dev/nvme1n1p3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mount -t ntfs -w /dev/nvme1n1p3 /root/win_p&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>ubuntu20误操作导致开机到logo页面后直接关机</title><link>https://s-infinite-box.github.io/posts/ubuntu20-poweroff-on-boot/</link><guid>https://s-infinite-box.github.io/posts/ubuntu20-poweroff-on-boot/</guid><pubDate>Thu, 21 Nov 2024 12:22:00 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux_hu_23f208142d1135b9.webp" alt="封面"&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;最近一段时间一直使用ubuntu20作为日常的开发环境，因为运行着各种虚拟机和容器环境且有回家操作电脑的需要，故而几天未关机； 后来想通过启动脚本初始化虚拟机和开发环境，再加上在家操作电脑的需求并不是很高，故而想关机； 本来有一个每天下午6点半自动提交代码的cron任务，就像在里面添加一个poweroff，让他提交完代码后再关机就好，刚改好脚本的当天下班走的晚了一点，在6点半的时候看电脑未关机，就直接在终端输入了poweroff；然后第二天早上到公司每次开机都无法正常启动了，一看到ubuntu的logo，几秒就断电关机；&lt;/p&gt;&#10;&lt;h2 id="排查问题"&gt;排查问题&lt;/h2&gt;&#10;&lt;p&gt;定时任务的提交代码脚本在关机时也同时会触发，关机脚本执行逻辑定义在systemd的service，而脚本的执行逻辑存在问题，导致每次一开机就触发；&lt;/p&gt;&#10;&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;&#10;&lt;pre&gt;&lt;code&gt;在启动时进入recover模式，注释脚本中的关机命令&#10;在revocer的命令行下init 5 发现可以进入图形化界面&#10;在图形化窗口的终端输入reboot命令，走一遍正常关机重启流程，顺利重新进入系统&#10;&lt;/code&gt;&lt;/pre&gt;&#10;</description></item><item><title>编程语言学习思考</title><link>https://s-infinite-box.github.io/posts/programming-language-learning/</link><guid>https://s-infinite-box.github.io/posts/programming-language-learning/</guid><pubDate>Mon, 21 Oct 2024 12:05:00 +0800</pubDate><description>&lt;h2 id="学习成本开发效率与运行效率"&gt;学习成本、开发效率与运行效率&lt;/h2&gt;&#10;&lt;p&gt;最近学习了几个月的rust，加上前两年学习的go和python语言，本身已经掌握了比较多的编程语言了；&#10;最近总是在思考对比这些语言的特性和学习的过程，我发现像微服务设计领域的CAP理论一样，在编程语言的学习中也有这么一个定理：&#10;编程语言上手速度，开发效率和代码运行效率也是不可皆得，很多时候只能取其两项；&#10;比如快速学习语言的语法，特性以及相关库/包的使用，且要满足较高的开发效率，那运行效率必然要有牺牲，最典型的当数python了&#10;而如果想快速学习，且运行效率较高，那就会面临较低的开发效率，此处可以举例Go和C语言，两者的学习上手都不是很难，运行效率也相对较高，但是要开发复杂的业务时，语言特性的简单在这时候就面临需要编写更多代码的情况，且C语言还要面临内存溢出或误操作内存等情况&#10;对于较高的开发效率和运行效率，能够满足这两种特性的语言目前我所了解的就是rust了，rust的宏、面向表达式的设计等特性使熟练的rust开发者可以实现一些在Java/Python等语言中才能实现的逻辑，但是前提是需要熟悉rust本身诸多的语言特性，面临较复杂的学习曲线&lt;/p&gt;&#10;</description></item><item><title>云原生应用的12要素</title><link>https://s-infinite-box.github.io/posts/12-factor-app/</link><guid>https://s-infinite-box.github.io/posts/12-factor-app/</guid><pubDate>Wed, 09 Oct 2024 00:00:00 +0800</pubDate><description>&lt;h2 id="适用范围"&gt;适用范围&lt;/h2&gt;&#10;&lt;p&gt;如今，软件通常会作为一种服务来交付，它们被称为网络应用程序，或软件即服务（SaaS）。12-Factor 为构建如下的 SaaS 应用提供了方法论：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;使用标准化流程自动配置，从而使新的开发者花费最少的学习成本加入这个项目。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;和操作系统之间尽可能的划清界限，在各个系统中提供最大的可移植性。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;适合部署在现代的云计算平台，从而在服务器和系统管理方面节省资源。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将开发环境和生产环境的差异降至最低，并使用持续交付实施敏捷开发。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;这套理论适用于任意语言和后端服务（数据库、消息队列、缓存等）开发的应用程序。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;&#10;&lt;p&gt;本文的贡献者者参与过数以百计的应用程序的开发和部署，并通过 Heroku 平台间接见证了数十万应用程序的开发，运作以及扩展的过程。 本文综合了我们关于 SaaS 应用几乎所有的经验和智慧，是开发此类应用的理想实践标准，并特别关注于应用程序如何保持良性成长，开发者之间如何进行有效的代码协作，以及如何 避免软件污染 。 我们的初衷是分享在现代软件开发过程中发现的一些系统性问题，并加深对这些问题的认识。我们提供了讨论这些问题时所需的共享词汇，同时使用相关术语给出一套针对这些问题的广义解决方案。 本文格式的灵感来自于 Martin Fowler 的书籍： Patterns of Enterprise Application Architecture ， Refactoring 。&lt;/p&gt;&#10;&lt;h2 id="云原生应用的12要素"&gt;云原生应用的12要素&lt;/h2&gt;&#10;&lt;h3 id="i-基准代码"&gt;I. 基准代码&lt;/h3&gt;&#10;&lt;p&gt;一份基准代码（Codebase），多份部署（deploy） 12-Factor应用(译者注：应该是说一个使用本文概念来设计的应用，下同)通常会使用版本控制系统加以管理，如Git, Mercurial, Subversion。一份用来跟踪代码所有修订版本的数据库被称作 代码库（code repository, code repo, repo）。 在类似 SVN 这样的集中式版本控制系统中，基准代码 就是指控制系统中的这一份代码库；而在 Git 那样的分布式版本控制系统中，基准代码 则是指最上游的那份代码库。&lt;/p&gt;&#10;&lt;p&gt;一份代码库对应多份部署&lt;/p&gt;&#10;&lt;p&gt;基准代码和应用之间总是保持一一对应的关系：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;一旦有多个基准代码，就不能称为一个应用，而是一个分布式系统。分布式系统中的每一个组件都是一个应用，每一个应用可以分别使用 12-Factor 进行开发。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;多个应用共享一份基准代码是有悖于 12-Factor 原则的。解决方案是将共享的代码拆分为独立的类库，然后使用 依赖管理 策略去加载它们。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;尽管每个应用只对应一份基准代码，但可以同时存在多份部署。每份 部署 相当于运行了一个应用的实例。通常会有一个生产环境，一个或多个预发布环境。此外，每个开发人员都会在自己本地环境运行一个应用实例，这些都相当于一份部署。 所有部署的基准代码相同，但每份部署可以使用其不同的版本。比如，开发人员可能有一些提交还没有同步至预发布环境；预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码，我们就认为它们只是相同应用的不同部署而已。&lt;/p&gt;&#10;&lt;h3 id="ii-依赖"&gt;II. 依赖&lt;/h3&gt;&#10;&lt;p&gt;显式声明依赖关系（ dependency ） 大多数编程语言都会提供一个打包系统，用来为各个类库提供打包服务，就像 Perl 的 CPAN 或是 Ruby 的 Rubygems 。通过打包系统安装的类库可以是系统级的（称之为 “site packages”），或仅供某个应用程序使用，部署在相应的目录中（称之为 “vendoring” 或 “bunding”）。 12-Factor规则下的应用程序不会隐式依赖系统级的类库。 它一定通过 依赖清单 ，确切地声明所有依赖项。此外，在运行过程中通过 依赖隔离 工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。例如， Ruby 的 Bundler 使用 Gemfile 作为依赖项声明清单，使用 bundle exec 来进行依赖隔离。Python 中则可分别使用两种工具 – Pip 用作依赖声明， Virtualenv 用作依赖隔离。甚至 C 语言也有类似工具， Autoconf 用作依赖声明，静态链接库用作依赖隔离。无论用什么工具，依赖声明和依赖隔离必须一起使用，否则无法满足 12-Factor 规范。显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码，安装编程语言环境和它对应的依赖管理工具，只需通过一个 构建命令 来安装所有的依赖项，即可开始工作。例如，Ruby/Bundler 下使用 bundle install，而 Clojure/Leiningen 则是 lein deps。12-Factor 应用同样不会隐式依赖某些系统工具，如 ImageMagick 或是 curl。即使这些工具存在于几乎所有系统，但终究无法保证所有未来的系统都能支持应用顺利运行，或是能够和应用兼容。如果应用必须使用到某些系统工具，那么这些工具应该被包含在应用之中。&lt;/p&gt;&#10;&lt;h3 id="iii-配置"&gt;III. 配置&lt;/h3&gt;&#10;&lt;p&gt;在环境中存储配置 通常，应用的 配置 在不同 部署 (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;数据库，Memcached，以及其他 后端服务 的配置&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;第三方服务的证书，如 Amazon S3、Twitter 等&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;每份部署特有的配置，如域名等&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;有些应用在代码中使用常量保存配置，这与 12-Factor 所要求的代码和配置严格分离显然大相径庭。配置文件在各部署间存在大幅差异，代码却完全一致。 判断一个应用是否正确地将配置排除在代码之外，一个简单的方法是看该应用的基准代码是否可以立刻开源，而不用担心会暴露任何敏感的信息。需要指出的是，这里定义的“配置”并不包括应用的内部配置，比如 Rails 的 config/routes.rb，或是使用 Spring 时 代码模块间的依赖注入关系 。这类配置在不同部署间不存在差异，所以应该写入代码。另外一个解决方法是使用配置文件，但不把它们纳入版本控制系统，就像 Rails 的 config/database.yml 。这相对于在代码中使用常量已经是长足进步，但仍然有缺点：总是会不小心将配置文件签入了代码库；配置文件的可能会分散在不同的目录，并有着不同的格式，这让找出一个地方来统一管理所有配置变的不太现实。更糟的是，这些格式通常是语言或框架特定的。 12-Factor推荐将应用的配置存储于 环境变量 中（ env vars, env ）。环境变量可以非常方便地在不同的部署间做修改，却不动一行代码；与配置文件不同，不小心把它们签入代码库的概率微乎其微；与一些传统的解决配置问题的机制（比如 Java 的属性配置文件）相比，环境变量与语言和系统无关。配置管理的另一个方面是分组。有时应用会将配置按照特定部署进行分组（或叫做“环境”），例如Rails中的 development, test, 和 production 环境。这种方法无法轻易扩展：更多部署意味着更多新的环境，例如 staging 或 qa。随着项目的不断深入，开发人员可能还会添加他们自己的环境，比如 joes-staging，这将导致各种配置组合的激增，从而给管理部署增加了很多不确定因素。 12-Factor 应用中，环境变量的粒度要足够小，且相对独立。它们永远也不会组合成一个所谓的“环境”，而是独立存在于每个部署之中。当应用程序不断扩展，需要更多种类的部署时，这种配置管理方式能够做到平滑过渡。&lt;/p&gt;&#10;&lt;h3 id="iv-后端服务"&gt;IV. 后端服务&lt;/h3&gt;&#10;&lt;p&gt;把后端服务(backing services)当作附加资源 后端服务是指程序运行所需要的通过网络调用的各种服务，如数据库（MySQL，CouchDB），消息/队列系统（RabbitMQ，Beanstalkd），SMTP 邮件发送服务（Postfix），以及缓存系统（Memcached）。 类似数据库的后端服务，通常由部署应用程序的系统管理员一起管理。除了本地服务之外，应用程序有可能使用了第三方发布和管理的服务。示例包括 SMTP（例如 Postmark），数据收集服务（例如 New Relic 或 Loggly），数据存储服务（如 Amazon S3），以及使用 API 访问的服务（例如 Twitter, Google Maps, Last.fm）。 12-Factor 应用不会区别对待本地或第三方服务。 对应用程序而言，两种都是附加资源，通过一个 url 或是其他存储在 配置中的服务定位/服务证书来获取数据。12-Factor 应用的任意 部署 ，都应该可以在不进行任何代码改动的情况下，将本地 MySQL 数据库换成第三方服务（例如 Amazon RDS）。类似的，本地 SMTP 服务应该也可以和第三方 SMTP 服务（例如 Postmark ）互换。上述 2 个例子中，仅需修改配置中的资源地址。 每个不同的后端服务是一份 资源 。例如，一个 MySQL 数据库是一个资源，两个 MySQL 数据库（用来数据分区）就被当作是 2 个不同的资源。12-Factor 应用将这些数据库都视作 附加资源 ，这些资源和它们附属的部署保持松耦合。&lt;/p&gt;&#10;&lt;p&gt;一种部署附加4个后端服务 部署可以按需加载或卸载资源。例如，如果应用的数据库服务由于硬件问题出现异常，管理员可以从最近的备份中恢复一个数据库，卸载当前的数据库，然后加载新的数据库 – 整个过程都不需要修改代码。&lt;/p&gt;&#10;&lt;h3 id="v-构建发布运行"&gt;V. 构建，发布，运行&lt;/h3&gt;&#10;&lt;p&gt;严格分离构建和运行 基准代码 转化为一份部署(非开发环境)需要以下三个阶段：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;构建阶段 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码，获取和打包 依赖项，编译成二进制文件和资源文件。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;发布阶段 会将构建的结果和当前部署所需 配置 相结合，并能够立刻在运行环境中投入使用。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;运行阶段 （或者说“运行时”）是指针对选定的发布版本，在执行环境中启动一系列应用程序 进程。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;代码被构建，然后和配置结合成为发布版本&lt;/p&gt;&#10;&lt;p&gt;12-facfor 应用严格区分构建，发布，运行这三个步骤。 举例来说，直接修改处于运行状态的代码是非常不可取的做法，因为这些修改很难再同步回构建步骤。部署工具通常都提供了发布管理工具，最引人注目的功能是退回至较旧的发布版本。比如， Capistrano 将所有发布版本都存储在一个叫 releases 的子目录中，当前的在线版本只需映射至对应的目录即可。该工具的 rollback 命令可以很容易地实现回退版本的功能。每一个发布版本必须对应一个唯一的发布 ID，例如可以使用发布时的时间戳（ 2011-04-06-20:32:17），亦或是一个增长的数字（ v100）。发布的版本就像一本只能追加的账本，一旦发布就不可修改，任何的变动都应该产生一个新的发布版本。 新的代码在部署之前，需要开发人员触发构建操作。但是，运行阶段不一定需要人为触发，而是可以自动进行。如服务器重启，或是进程管理器重启了一个崩溃的进程。因此，运行阶段应该保持尽可能少的模块，这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题。构建阶段是可以相对复杂一些的，因为错误信息能够立刻展示在开发人员面前，从而得到妥善处理。&lt;/p&gt;&#10;&lt;h3 id="vi-进程"&gt;VI. 进程&lt;/h3&gt;&#10;&lt;p&gt;以一个或多个无状态进程运行应用 运行环境中，应用程序通常是以一个和多个 进程 运行的。 最简单的场景中，代码是一个独立的脚本，运行环境是开发人员自己的笔记本电脑，进程由一条命令行（例如python my_script.py）。另外一个极端情况是，复杂的应用可能会使用很多 进程类型 ，也就是零个或多个进程实例。 12-Factor 应用的进程必须无状态且 无共享 。 任何需要持久化的数据都要存储在 后端服务 内，比如数据库。 内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存，例如下载一个很大的文件，对其操作并将结果写入数据库的过程。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用，这是因为应用启动了多种类型的进程，将来的请求多半会由其他进程来服务。即使在只有一个进程的情形下，先前保存的数据（内存或文件系统中）也会因为重启（如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行）而丢失。 源文件打包工具（Jammit, django-compressor） 使用文件系统来缓存编译过的源文件。12-Factor 应用更倾向于在 构建步骤做此动作——正如 Rails资源管道 ，而不是在运行阶段。 一些互联网系统依赖于 “粘性 session”， 这是指将用户 session 中的数据缓存至某进程的内存中，并将同一用户的后续请求路由到同一个进程。粘性 session 是 12-Factor 极力反对的。Session 中的数据应该保存在诸如 Memcached 或 Redis 这样的带有过期时间的缓存中。&lt;/p&gt;&#10;&lt;h3 id="vii-端口绑定"&gt;VII. 端口绑定&lt;/h3&gt;&#10;&lt;p&gt;通过端口绑定(Port binding)来提供服务 互联网应用有时会运行于服务器的容器之中。例如 PHP 经常作为 Apache HTTPD 的一个模块来运行，正如 Java 运行于 Tomcat 。 12-Factor 应用完全自我加载 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 通过端口绑定来提供服务 ，并监听发送至该端口的请求。本地环境中，开发人员通过类似 &lt;a class="link" href="http://localhost:5000/%E7%9A%84%E5%9C%B0%E5%9D%80%E6%9D%A5%E8%AE%BF%E9%97%AE%E6%9C%8D%E5%8A%A1%E3%80%82%E5%9C%A8%E7%BA%BF%E4%B8%8A%E7%8E%AF%E5%A2%83%E4%B8%AD%EF%BC%8C%E8%AF%B7%E6%B1%82%E7%BB%9F%E4%B8%80%E5%8F%91%E9%80%81%E8%87%B3%E5%85%AC%E5%85%B1%E5%9F%9F%E5%90%8D%E8%80%8C%E5%90%8E%E8%B7%AF%E7%94%B1%E8%87%B3%E7%BB%91%E5%AE%9A%E4%BA%86%E7%AB%AF%E5%8F%A3%E7%9A%84%E7%BD%91%E7%BB%9C%E8%BF%9B%E7%A8%8B%E3%80%82" target="_blank" rel="noopener"&#10; &gt;http://localhost:5000/的地址来访问服务。在线上环境中，请求统一发送至公共域名而后路由至绑定了端口的网络进程。&lt;/a&gt; 通常的实现思路是，将网络服务器类库通过 依赖声明 载入应用。例如，Python 的 Tornado, Ruby 的Thin , Java 以及其他基于 JVM 语言的 Jetty。完全由 用户端 ，确切的说应该是应用的代码，发起请求。和运行环境约定好绑定的端口即可处理这些请求。 HTTP 并不是唯一一个可以由端口绑定提供的服务。其实几乎所有服务器软件都可以通过进程绑定端口来等待请求。例如，使用 XMPP 的 ejabberd ， 以及使用 Redis 协议 的 Redis 。 还要指出的是，端口绑定这种方式也意味着一个应用可以成为另外一个应用的 后端服务 ，调用方将服务方提供的相应 URL 当作资源存入 配置 以备将来调用。&lt;/p&gt;&#10;&lt;h3 id="viii-并发"&gt;VIII. 并发&lt;/h3&gt;&#10;&lt;p&gt;通过进程模型进行扩展 任何计算机程序，一旦启动，就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如，PHP 进程作为 Apache 的子进程存在，随请求按需启动。Java 进程则采取了相反的方式，在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源(CPU 和内存)，并通过多线程实现内部的并发管理。上述 2 个例子中，进程是开发人员可以操作的最小单位。&lt;/p&gt;&#10;&lt;p&gt;扩展表现为运行中的进程，工作多样性表现为进程类型。&lt;/p&gt;&#10;&lt;p&gt;在 12-factor 应用中，进程是一等公民。12-Factor 应用的进程主要借鉴于 unix 守护进程模型 。开发人员可以运用这个模型去设计应用架构，将不同的工作分配给不同的 进程类型 。例如，HTTP 请求可以交给 web 进程来处理，而常驻的后台工作则交由 worker 进程负责。 这并不包括个别较为特殊的进程，例如通过虚拟机的线程处理并发的内部运算，或是使用诸如 EventMachine, Twisted, Node.js 的异步/事件触发模型。但一台独立的虚拟机的扩展有瓶颈（垂直扩展），所以应用程序必须可以在多台物理机器间跨进程工作。 上述进程模型会在系统急需扩展时大放异彩。12-Factor 应用的进程所具备的无共享，水平分区的特性 意味着添加并发会变得简单而稳妥。这些进程的类型以及每个类型中进程的数量就被称作 进程构成 。 12-Factor 应用的进程 不需要守护进程 或是写入 PID 文件。相反的，应该借助操作系统的进程管理器(例如 Upstart ，分布式的进程管理云平台，或是类似 Foreman 的工具)，来管理 输出流 ，响应崩溃的进程，以及处理用户触发的重启和关闭超级进程的请求。&lt;/p&gt;&#10;&lt;h3 id="ix-易处理"&gt;IX. 易处理&lt;/h3&gt;&#10;&lt;p&gt;快速启动和优雅终止可最大化健壮性 12-Factor 应用的 进程 是 易处理（disposable）的，意思是说它们可以瞬间开启或停止。 这有利于快速、弹性的伸缩应用，迅速部署变化的 代码 或 配置 ，稳健的部署应用。 进程应当追求 最小启动时间 。理想状态下，进程从敲下命令到真正启动并等待请求的时间应该只需很短的时间。更少的启动时间提供了更敏捷的 发布 以及扩展过程，此外还增加了健壮性，因为进程管理器可以在授权情形下容易的将进程搬到新的物理机器上。 进程 一旦接收 终止信号（SIGTERM） 就会优雅的终止 。就网络进程而言，优雅终止是指停止监听服务的端口，即拒绝所有新的请求，并继续执行当前已接收的请求，然后退出。此类型的进程所隐含的要求是HTTP请求大多都很短(不会超过几秒钟)，而在长时间轮询中，客户端在丢失连接后应该马上尝试重连。对于 worker 进程来说，优雅终止是指将当前任务退回队列。例如，RabbitMQ 中，worker 可以发送一个 NACK信号。Beanstalkd 中，任务终止并退回队列会在worker断开时自动触发。有锁机制的系统诸如 Delayed Job 则需要确定释放了系统资源。此类型的进程所隐含的要求是，任务都应该 可重复执行 ， 这主要由将结果包装进事务或是使重复操作 幂等 来实现。 进程还应当在面对突然死亡时保持健壮，例如底层硬件故障。虽然这种情况比起优雅终止来说少之又少，但终究有可能发生。一种推荐的方式是使用一个健壮的后端队列，例如 Beanstalkd ，它可以在客户端断开或超时后自动退回任务。无论如何，12-Factor 应用都应该可以设计能够应对意外的、不优雅的终结。Crash-only design 将这种概念转化为 合乎逻辑的理论。&lt;/p&gt;&#10;&lt;h3 id="x-开发环境与线上环境等价"&gt;X. 开发环境与线上环境等价&lt;/h3&gt;&#10;&lt;p&gt;尽可能的保持开发，预发布，线上环境相同 从以往经验来看，开发环境（即开发人员的本地 部署）和线上环境（外部用户访问的真实部署）之间存在着很多差异。这些差异表现在以下三个方面：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;时间差异： 开发人员正在编写的代码可能需要几天，几周，甚至几个月才会上线。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;人员差异： 开发人员编写代码，运维人员部署代码。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;工具差异： 开发人员或许使用 Nginx，SQLite，OS X，而线上环境使用 Apache，MySQL 以及 Linux。 12-Factor 应用想要做到 持续部署 就必须缩小本地与线上差异。 再回头看上面所描述的三个差异:&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;缩小时间差异：开发人员可以几小时，甚至几分钟就部署代码。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;缩小人员差异：开发人员不只要编写代码，更应该密切参与部署过程以及代码在线上的表现。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;缩小工具差异：尽量保证开发环境以及线上环境的一致性。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;将上述总结变为一个表格如下： 传统应用12-Factor 应用每次部署间隔数周几小时开发人员 vs 运维人员不同的人相同的人开发环境 vs 线上环境不同尽量接近 后端服务 是保持开发与线上等价的重要部分，例如数据库，队列系统，以及缓存。许多语言都提供了简化获取后端服务的类库，例如不同类型服务的 适配器 。下列表格提供了一些例子。 类型语言类库适配器数据库Ruby/RailsActiveRecordMySQL, PostgreSQL, SQLite队列Python/DjangoCeleryRabbitMQ, Beanstalkd, Redis缓存Ruby/RailsActiveSupport::CacheMemory, filesystem, Memcached 开发人员有时会觉得在本地环境中使用轻量的后端服务具有很强的吸引力，而那些更重量级的健壮的后端服务应该使用在生产环境。例如，本地使用 SQLite 线上使用 PostgreSQL；又如本地缓存在进程内存中而线上存入 Memcached。 12-Factor 应用的开发人员应该反对在不同环境间使用不同的后端服务 ，即使适配器已经可以几乎消除使用上的差异。这是因为，不同的后端服务意味着会突然出现的不兼容，从而导致测试、预发布都正常的代码在线上出现问题。这些错误会给持续部署带来阻力。从应用程序的生命周期来看，消除这种阻力需要花费很大的代价。 与此同时，轻量的本地服务也不像以前那样引人注目。借助于Homebrew，apt-get等现代的打包系统，诸如Memcached、PostgreSQL、RabbitMQ 等后端服务的安装与运行也并不复杂。此外，使用类似 Chef 和 Puppet 的声明式配置工具，结合像 Vagrant 这样轻量的虚拟环境就可以使得开发人员的本地环境与线上环境无限接近。与同步环境和持续部署所带来的益处相比，安装这些系统显然是值得的。 不同后端服务的适配器仍然是有用的，因为它们可以使移植后端服务变得简单。但应用的所有部署，这其中包括开发、预发布以及线上环境，都应该使用同一个后端服务的相同版本。&lt;/p&gt;&#10;&lt;h3 id="xi-日志"&gt;XI. 日志&lt;/h3&gt;&#10;&lt;p&gt;把日志当作事件流 日志 使得应用程序运行的动作变得透明。在基于服务器的环境中，日志通常被写在硬盘的一个文件里，但这只是一种输出格式。 日志应该是 事件流 的汇总，将所有运行中进程和后端服务的输出流按照时间顺序收集起来。尽管在回溯问题时可能需要看很多行，日志最原始的格式确实是一个事件一行。日志没有确定开始和结束，但随着应用在运行会持续的增加。12-factor应用本身从不考虑存储自己的输出流。 不应该试图去写或者管理日志文件。相反，每一个运行的进程都会直接的标准输出（ stdout）事件流。开发环境中，开发人员可以通过这些数据流，实时在终端看到应用的活动。 在预发布或线上部署中，每个进程的输出流由运行环境截获，并将其他输出流整理在一起，然后一并发送给一个或多个最终的处理程序，用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置，而是完全交给程序的运行环境管理。类似 Logplex 和 Fluent 的开源工具可以达到这个目的。 这些事件流可以输出至文件，或者在终端实时观察。最重要的，输出流可以发送到 Splunk 这样的日志索引及分析系统，或 Hadoop/Hive 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能，包括：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;找出过去一段时间特殊的事件。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;图形化一个大规模的趋势，比如每分钟的请求量。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;根据用户定义的条件实时触发警报，比如每分钟的报错超过某个警戒线。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="xii-管理进程"&gt;XII. 管理进程&lt;/h3&gt;&#10;&lt;p&gt;后台管理任务当作一次性进程运行 进程构成（process formation）是指用来处理应用的常规业务（比如处理 web 请求）的一组进程。与此不同，开发人员经常希望执行一些管理或维护应用的一次性任务，例如：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;运行数据移植（Django 中的 manage.py migrate, Rails 中的 rake db:migrate）。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;运行一个控制台（也被称为 REPL shell），来执行一些代码或是针对线上数据库做一些检查。大多数语言都通过解释器提供了一个 REPL 工具（ python 或 perl） ，或是其他命令（Ruby 使用 irb, Rails 使用 rails console）。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;运行一些提交到代码仓库的一次性脚本。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;一次性管理进程应该和正常的 常驻进程 使用同样的环境。这些管理进程和任何其他的进程一样使用相同的 代码 和 配置 ，基于某个 发布版本 运行。后台管理代码应该随其他应用程序代码一起发布，从而避免同步问题。 所有进程类型应该使用同样的 依赖隔离 技术。例如，如果Ruby的web进程使用了命令 bundle exec thin start ，那么数据库移植应使用 bundle exec rake db:migrate 。同样的，如果一个 Python 程序使用了 Virtualenv，则需要在运行 Tornado Web 服务器和任何 manage.py 管理进程时引入 bin/python 。 12-factor 尤其青睐那些提供了 REPL shell 的语言，因为那会让运行一次性脚本变得简单。在本地部署中，开发人员直接在命令行使用 shell 命令调用一次性管理进程。在线上部署中，开发人员依旧可以使用ssh或是运行环境提供的其他机制来运行这样的进程。&lt;/p&gt;&#10;</description></item><item><title>系统架构设计</title><link>https://s-infinite-box.github.io/posts/system-architecture-design/</link><guid>https://s-infinite-box.github.io/posts/system-architecture-design/</guid><pubDate>Wed, 09 Oct 2024 00:00:00 +0800</pubDate><description>&lt;h2 id="分布式架构的设计"&gt;分布式架构的设计&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;业务流程，功能模块的划分&lt;/li&gt;&#10;&lt;li&gt;分布式事务、一致性处理、锁&lt;/li&gt;&#10;&lt;li&gt;分支、依赖管理&lt;/li&gt;&#10;&lt;li&gt;分库、缓存设计&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="大教堂与集市的启发"&gt;《大教堂与集市》的启发&lt;/h2&gt;&#10;&lt;p&gt;Eric Raymond 在《大教堂与集市》中总结了 Linux 的成功之道：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;好软件都源自解决开发者的切身之痛。&lt;/li&gt;&#10;&lt;li&gt;把用户当作开发伙伴，是快速改进代码和有效调试的不二法门。&lt;/li&gt;&#10;&lt;li&gt;早发布，常发布。并听取用户意见。&lt;/li&gt;&#10;&lt;li&gt;有这么多双眼睛看着，Bug无处可藏。&lt;/li&gt;&#10;&lt;li&gt;精巧的数据结构即使搭配笨拙的程序代码，也比精巧代码加笨拙结构的组合要强得多&lt;/li&gt;&#10;&lt;li&gt;保持项目的简单性。设计达到完美的时候，不是无法再增加东西了，而是无法再减少东西了。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;</description></item><item><title>开发工作流程思考</title><link>https://s-infinite-box.github.io/posts/dev-workflow-thoughts/</link><guid>https://s-infinite-box.github.io/posts/dev-workflow-thoughts/</guid><pubDate>Wed, 09 Oct 2024 00:00:00 +0800</pubDate><description>&lt;h2 id="上线生产整体流程"&gt;上线生产整体流程&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;信息同步&lt;/li&gt;&#10;&lt;li&gt;分支管理，提交审核、代码review、环境发布&lt;/li&gt;&#10;&lt;li&gt;自动化测试，测试用例分层，功能测试，基础测试&lt;/li&gt;&#10;&lt;li&gt;生产发布行事历，SQL、配置、镜像更新步骤&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="后端研发避坑指南"&gt;后端研发避坑指南&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;通用流程&#10;&lt;ul&gt;&#10;&lt;li&gt;需求沟通&lt;/li&gt;&#10;&lt;li&gt;接口文档设计&lt;/li&gt;&#10;&lt;li&gt;开发&amp;amp;自测&amp;amp;联调&lt;/li&gt;&#10;&lt;li&gt;测试&amp;amp;修复bug&lt;/li&gt;&#10;&lt;li&gt;上线&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;技术思考点&#10;&lt;ul&gt;&#10;&lt;li&gt;对于重要业务(如订购、退订、支付等核心业务)，是否需要保存上下文信息，异常监控通知；保存上下文信息：打印日志、存入mysql、redis等存储中间件, 邮件报警等&lt;/li&gt;&#10;&lt;li&gt;对于高频、分布式场景，是否需要引入限流、分布式锁、幂等、保障业务安全&lt;/li&gt;&#10;&lt;li&gt;限流，建议使用分布式限流，如springcloud-alibaba的Sentinel、redis+lua、nginx的rate-limiting&lt;/li&gt;&#10;&lt;li&gt;分布式锁：锁的粒度是否经过评估，精确到资源、租户、行为？锁的实现&lt;/li&gt;&#10;&lt;li&gt;幂等：针对MQ消息监听、订购、退订等场景，需要保证幂&lt;/li&gt;&#10;&lt;li&gt;对外接口是否需要鉴权，鉴权逻辑是否经过有效评估&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;</description></item><item><title>IO模型</title><link>https://s-infinite-box.github.io/posts/io-models/</link><guid>https://s-infinite-box.github.io/posts/io-models/</guid><pubDate>Sun, 06 Oct 2024 13:01:00 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux_hu_23f208142d1135b9.webp" alt="封面"&gt;&lt;h2 id="1-阻塞io模型"&gt;1. 阻塞IO模型&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-29-41-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;进程发起IO系统调用后，进程被阻塞，转到内核空间处理，整个IO处理完毕后返回进程。操作成功则进程获取到数据。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;1、典型应用：阻塞socket、Java BIO；&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;2、特点：&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;进程阻塞挂起不消耗CPU资源，及时响应每个操作；&lt;/li&gt;&#10;&lt;li&gt;实现难度低、开发应用较容易；&lt;/li&gt;&#10;&lt;li&gt;适用并发量小的网络应用开发；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;不适用并发量大的应用：因为一个请求IO会阻塞进程，所以，得为每请求分配一个处理进程（线程）以及时响应，系统开销大。&lt;/p&gt;&#10;&lt;h2 id="2-非阻塞io模型"&gt;2. 非阻塞IO模型&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-29-47-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;进程发起IO系统调用后，如果内核缓冲区没有数据，需要到IO设备中读取，进程返回一个错误而不会被阻塞；进程发起IO系统调用后，如果内核缓冲区有数据，内核就会把数据返回进程。&lt;/p&gt;&#10;&lt;p&gt;对于上面的阻塞IO模型来说，内核数据没准备好需要进程阻塞的时候，就返回一个错误，以使得进程不被阻塞。&lt;/p&gt;&#10;&lt;p&gt;1、典型应用：socket是非阻塞的方式（设置为NONBLOCK）&lt;/p&gt;&#10;&lt;p&gt;2、特点：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;进程轮询（重复）调用，消耗CPU的资源；&lt;/li&gt;&#10;&lt;li&gt;实现难度低、开发应用相对阻塞IO模式较难；&lt;/li&gt;&#10;&lt;li&gt;适用并发量较小、且不需要及时响应的网络应用开发；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="3-io复用模型"&gt;3. IO复用模型&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-29-56-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;多个的进程的IO可以注册到一个复用器（select）上，然后用一个进程调用该select， select会监听所有注册进来的IO；&lt;/p&gt;&#10;&lt;p&gt;如果select没有监听的IO在内核缓冲区都没有可读数据，select调用进程会被阻塞；而当任一IO在内核缓冲区中有可数据时，select调用就会返回；&lt;/p&gt;&#10;&lt;p&gt;而后select调用进程可以自己或通知另外的进程（注册进程）来再次发起读取IO，读取内核中准备好的数据。&lt;/p&gt;&#10;&lt;p&gt;可以看到，多个进程注册IO后，只有另一个select调用进程被阻塞。&lt;/p&gt;&#10;&lt;p&gt;1、典型应用：select、poll、epoll三种方案，nginx都可以选择使用这三个方案;Java NIO;&lt;/p&gt;&#10;&lt;p&gt;2、特点：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;专一进程解决多个进程IO的阻塞问题，性能好；Reactor模式;&lt;/li&gt;&#10;&lt;li&gt;实现、开发应用难度较大；&lt;/li&gt;&#10;&lt;li&gt;适用高并发服务应用开发：一个进程（线程）响应多个请求；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;3、select、poll、epoll&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Linux中IO复用的实现方式主要有select、poll和epoll：&lt;/li&gt;&#10;&lt;li&gt;Select：注册IO、阻塞扫描，监听的IO最大连接数不能多于FD_SIZE；&lt;/li&gt;&#10;&lt;li&gt;Poll：原理和Select相似，没有数量限制，但IO数量大扫描线性性能下降；&lt;/li&gt;&#10;&lt;li&gt;Epoll ：事件驱动不阻塞，mmap实现内核与用户空间的消息传递，数量很大，Linux2.6后内核支持；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="4-信号驱动io模型"&gt;4. 信号驱动IO模型&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-53-52-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;当进程发起一个IO操作，会向内核注册一个信号处理函数，然后进程返回不阻塞；当内核数据就绪时会发送一个信号给进程，进程便在信号处理函数中调用IO读取数据。&lt;/p&gt;&#10;&lt;p&gt;特点：回调机制，实现、开发应用难度大；&lt;/p&gt;&#10;&lt;h2 id="5-异步io模型"&gt;5. 异步IO模型&lt;/h2&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-30-06-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;当进程发起一个IO操作，进程返回（不阻塞），但也不能返回果结；内核把整个IO处理完后，会通知进程结果。如果IO操作成功则进程直接获取到数据。&lt;/p&gt;&#10;&lt;p&gt;1、典型应用：JAVA7 AIO、高性能&lt;a class="link" href="https://cloud.tencent.com/act/pro/promotion-cvm?from_column=20065&amp;amp;from=20065" target="_blank" rel="noopener"&#10; &gt;服务器&lt;/a&gt;应用&lt;/p&gt;&#10;&lt;p&gt;2、特点：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;不阻塞，数据一步到位；Proactor模式；&lt;/li&gt;&#10;&lt;li&gt;需要操作系统的底层支持，LINUX 2.5 版本内核首现，2.6 版本产品的内核标准特性；&lt;/li&gt;&#10;&lt;li&gt;实现、开发应用难度大；&lt;/li&gt;&#10;&lt;li&gt;非常适合高性能高并发应用；&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-56-27-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-17-31-21-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-08-18-09-13-image.png" alt=""&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://s-infinite-box.github.io/posts/io-models/2024-07-09-09-23-09-image.png" alt=""&gt;&lt;/p&gt;&#10;</description></item><item><title>进程、线程、协程</title><link>https://s-infinite-box.github.io/posts/process-thread-coroutine/</link><guid>https://s-infinite-box.github.io/posts/process-thread-coroutine/</guid><pubDate>Sun, 06 Oct 2024 00:00:00 +0800</pubDate><description>&lt;img src="https://s-infinite-box.github.io/img/covers/Linux_hu_23f208142d1135b9.webp" alt="封面"&gt;&lt;h2 id="进程切换开销"&gt;进程切换开销&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;直接开销•&#10;&lt;ul&gt;&#10;&lt;li&gt;切换页表全局目录（PGD）&lt;/li&gt;&#10;&lt;li&gt;切换内核态堆栈&lt;/li&gt;&#10;&lt;li&gt;切换硬件上下文（进程恢复前，必须装入寄存器的数据统称为硬件上下文）&lt;/li&gt;&#10;&lt;li&gt;刷新TLB&lt;/li&gt;&#10;&lt;li&gt;系统调度器的代码执行&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;间接开销&#10;&lt;ul&gt;&#10;&lt;li&gt;CPU 缓存失效导致的进程需要到内存直接访问的IO 操作变多&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="线程切换开销"&gt;线程切换开销&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;线程本质上只是一批共享资源的进程，线程切换本质上依然需要内核进行进程切换&lt;/li&gt;&#10;&lt;li&gt;一组线程因为共享内存资源，因此一个进程的所有线程共享虚拟地址空间&lt;/li&gt;&#10;&lt;li&gt;线程切换相比进程切换，主要节省了虚拟地址空间的切换&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="协程切换开销"&gt;协程切换开销&lt;/h2&gt;&#10;&lt;p&gt;用户线程无需内核帮助，应用程序在用户空间创建的可执行单元，创建销毁完全在用户态完成&lt;/p&gt;&#10;</description></item></channel></rss>