{
    "version": "https://jsonfeed.org/version/1",
    "title": "阿男说",
    "home_page_url": "https://real-tech.online/blog",
    "description": "阿男说 Blog",
    "items": [
        {
            "id": "https://real-tech.online/blog/l40s-model-quality-eval",
            "content_html": "<p>跑得最快的模型，长文本全部超时。参数最多的模型，总分垫底。最终胜出的是参数最少的那个——76.6% vs 69.7% vs 69.1%。这篇记录 160 道题、6 个维度的完整评测过程，以及为什么\"参数大 ≠ 质量好\"。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"评测设计\">评测设计<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E8%AF%84%E6%B5%8B%E8%AE%BE%E8%AE%A1\" class=\"hash-link\" aria-label=\"评测设计的直接链接\" title=\"评测设计的直接链接\">​</a></h2>\n<p>参考了 Artificial Analysis 和主流 benchmark 的方法论，设计了 6 个维度、160 道题的评测集：</p>\n<table><thead><tr><th>维度</th><th style=\"text-align:center\">题数</th><th>数据来源</th><th>考察能力</th></tr></thead><tbody><tr><td>通识基础</td><td style=\"text-align:center\">50</td><td>MMLU-Pro</td><td>多领域知识</td></tr><tr><td>高级推理</td><td style=\"text-align:center\">30</td><td>GSM8K + ARC-Challenge</td><td>数学 + 逻辑</td></tr><tr><td>指令跟随</td><td style=\"text-align:center\">30</td><td>IFEval</td><td>格式约束遵循</td></tr><tr><td>模型幻觉</td><td style=\"text-align:center\">25</td><td>TruthfulQA + SQuAD v2</td><td>拒答 + 事实性</td></tr><tr><td>工具调用</td><td style=\"text-align:center\">10</td><td>BFCL v3</td><td>Function Calling</td></tr><tr><td>长文本</td><td style=\"text-align:center\">15</td><td>K8s 文档</td><td>8K-32K 上下文理解</td></tr></tbody></table>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"为什么不直接用公开-benchmark\">为什么不直接用公开 benchmark<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E7%9B%B4%E6%8E%A5%E7%94%A8%E5%85%AC%E5%BC%80-benchmark\" class=\"hash-link\" aria-label=\"为什么不直接用公开 benchmark的直接链接\" title=\"为什么不直接用公开 benchmark的直接链接\">​</a></h3>\n<p>公开 benchmark 的问题：</p>\n<ol>\n<li><strong>数据污染</strong>——模型训练数据可能包含测试题</li>\n<li><strong>场景不匹配</strong>——我们需要的是工具调用、长文本理解，不是做高考题</li>\n<li><strong>量化影响</strong>——FP8 量化后的表现和原始精度不同，需要实测</li>\n</ol>\n<p>所以我从公开数据集中<strong>抽样</strong>，加上自己构造的工具调用和长文本题目，确保评测贴近实际使用场景。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"评测流程\">评测流程<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E8%AF%84%E6%B5%8B%E6%B5%81%E7%A8%8B\" class=\"hash-link\" aria-label=\"评测流程的直接链接\" title=\"评测流程的直接链接\">​</a></h2>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1.</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Collect：向每个模型发送</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">160</span><span class=\"token plain\"> 道题，收集原始回复</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2.</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Auto</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token maybe-class-name\">Score：规则引擎自动评分（</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">MCQ</span><span class=\"token plain\"> 精确匹配、数学答案提取、格式检查）</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3.</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Manual</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Review：人工审核自动评分结果，修正误判</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>关键配置：</p>\n<ul>\n<li><code>temperature=0.6</code>，开启 thinking mode（Qwen3.5/3.6 支持）</li>\n<li><code>max_tokens=4096</code></li>\n<li>超时 300 秒/题</li>\n</ul>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"自动评分规则\">自动评分规则<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E8%87%AA%E5%8A%A8%E8%AF%84%E5%88%86%E8%A7%84%E5%88%99\" class=\"hash-link\" aria-label=\"自动评分规则的直接链接\" title=\"自动评分规则的直接链接\">​</a></h3>\n<p>不同题型用不同评分逻辑：</p>\n<ul>\n<li><strong>MCQ</strong>：精确匹配选项字母（A/B/C/D）</li>\n<li><strong>数学</strong>：从回复中提取 <code>\\boxed{}</code> 或加粗数字，和标准答案比较</li>\n<li><strong>指令跟随</strong>：逐条检查约束（JSON 格式、字数限制、语言要求、关键词包含等）</li>\n<li><strong>幻觉/可回答</strong>：语义匹配预期答案</li>\n<li><strong>幻觉/不可回答</strong>：检测拒答模式（\"I don't know\"、\"无法确定\"等）</li>\n<li><strong>工具调用</strong>：解析模型输出的 tool call 格式，匹配函数名和参数</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"评测结果\">评测结果<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E8%AF%84%E6%B5%8B%E7%BB%93%E6%9E%9C\" class=\"hash-link\" aria-label=\"评测结果的直接链接\" title=\"评测结果的直接链接\">​</a></h2>\n<table><thead><tr><th>维度</th><th style=\"text-align:center\">Qwen3.5-27B</th><th style=\"text-align:center\">Qwen3.6-35B</th><th style=\"text-align:center\">Gemma4-31B</th></tr></thead><tbody><tr><td>通识基础 (50)</td><td style=\"text-align:center\">52.0%</td><td style=\"text-align:center\">50.0%</td><td style=\"text-align:center\"><strong>60.0%</strong></td></tr><tr><td>高级推理 (30)</td><td style=\"text-align:center\"><strong>93.3%</strong></td><td style=\"text-align:center\">86.7%</td><td style=\"text-align:center\">86.7%</td></tr><tr><td>指令跟随 (30)</td><td style=\"text-align:center\"><strong>71.7%</strong></td><td style=\"text-align:center\">61.7%</td><td style=\"text-align:center\">68.3%</td></tr><tr><td>模型幻觉 (25)</td><td style=\"text-align:center\"><strong>100%</strong></td><td style=\"text-align:center\"><strong>100%</strong></td><td style=\"text-align:center\"><strong>100%</strong></td></tr><tr><td>工具调用 (10)</td><td style=\"text-align:center\"><strong>100%</strong></td><td style=\"text-align:center\">80.0%</td><td style=\"text-align:center\">90.0%</td></tr><tr><td>长文本 (15)</td><td style=\"text-align:center\"><strong>80.0%</strong></td><td style=\"text-align:center\">60.0%</td><td style=\"text-align:center\">0.0% ⚠️</td></tr><tr><td><strong>总分 (160)</strong></td><td style=\"text-align:center\"><strong>76.6%</strong></td><td style=\"text-align:center\">69.7%</td><td style=\"text-align:center\">69.1%</td></tr></tbody></table>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"逐维度分析\">逐维度分析<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E9%80%90%E7%BB%B4%E5%BA%A6%E5%88%86%E6%9E%90\" class=\"hash-link\" aria-label=\"逐维度分析的直接链接\" title=\"逐维度分析的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"通识基础gemma4-领先\">通识基础：Gemma4 领先<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E9%80%9A%E8%AF%86%E5%9F%BA%E7%A1%80gemma4-%E9%A2%86%E5%85%88\" class=\"hash-link\" aria-label=\"通识基础：Gemma4 领先的直接链接\" title=\"通识基础：Gemma4 领先的直接链接\">​</a></h3>\n<p>Gemma4 在 MMLU-Pro 多选题上表现最好（60%），可能因为 Google 的训练数据在百科知识方面更全面。Qwen3.5 和 3.6 都在 50% 左右，说明 FP8 量化对知识类任务有一定影响。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"高级推理qwen35-碾压\">高级推理：Qwen3.5 碾压<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E9%AB%98%E7%BA%A7%E6%8E%A8%E7%90%86qwen35-%E7%A2%BE%E5%8E%8B\" class=\"hash-link\" aria-label=\"高级推理：Qwen3.5 碾压的直接链接\" title=\"高级推理：Qwen3.5 碾压的直接链接\">​</a></h3>\n<p>Qwen3.5 在数学推理上达到 93.3%，远超其他两个模型。Qwen3.6 虽然有 thinking mode，但<strong>倾向于过度推理</strong>——在复杂数学题上写了很长的推导过程，结果被 <code>max_tokens</code> 截断，最终答案没输出完。</p>\n<p>这是 MoE 架构的一个隐性问题：Expert 路由增加了推理路径的不确定性，模型更容易\"跑偏\"。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"指令跟随所有模型都不够好\">指令跟随：所有模型都不够好<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E6%8C%87%E4%BB%A4%E8%B7%9F%E9%9A%8F%E6%89%80%E6%9C%89%E6%A8%A1%E5%9E%8B%E9%83%BD%E4%B8%8D%E5%A4%9F%E5%A5%BD\" class=\"hash-link\" aria-label=\"指令跟随：所有模型都不够好的直接链接\" title=\"指令跟随：所有模型都不够好的直接链接\">​</a></h3>\n<p>IFEval 的约束非常严格（\"用 JSON 格式回答\"、\"不超过 50 个词\"、\"必须包含关键词 X\"），三个模型都只有 62-72%。这是当前开源模型的普遍短板。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"模型幻觉全部满分\">模型幻觉：全部满分<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E6%A8%A1%E5%9E%8B%E5%B9%BB%E8%A7%89%E5%85%A8%E9%83%A8%E6%BB%A1%E5%88%86\" class=\"hash-link\" aria-label=\"模型幻觉：全部满分的直接链接\" title=\"模型幻觉：全部满分的直接链接\">​</a></h3>\n<p>三个模型在幻觉测试上都是 100%——该拒答的拒答，该引用的引用。FP8 量化没有影响模型的事实性判断能力。这是个好消息。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"工具调用格式差异\">工具调用：格式差异<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E5%B7%A5%E5%85%B7%E8%B0%83%E7%94%A8%E6%A0%BC%E5%BC%8F%E5%B7%AE%E5%BC%82\" class=\"hash-link\" aria-label=\"工具调用：格式差异的直接链接\" title=\"工具调用：格式差异的直接链接\">​</a></h3>\n<p>Qwen3.5 满分，Gemma4 90%，Qwen3.6 只有 80%。</p>\n<p>问题出在<strong>格式</strong>：</p>\n<ul>\n<li>Qwen3.5/3.6 用 <code>&lt;function=name&gt;</code> XML 格式</li>\n<li>Gemma4 用 <code>&lt;|tool_call&gt;call:name{...}</code> 格式</li>\n</ul>\n<p>Qwen3.6 的 2 道错题是参数格式不对（JSON 里多了引号转义），不是逻辑错误。这种问题在实际使用中可以通过 prompt 工程缓解。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"长文本gemma4-全军覆没\">长文本：Gemma4 全军覆没<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E9%95%BF%E6%96%87%E6%9C%ACgemma4-%E5%85%A8%E5%86%9B%E8%A6%86%E6%B2%A1\" class=\"hash-link\" aria-label=\"长文本：Gemma4 全军覆没的直接链接\" title=\"长文本：Gemma4 全军覆没的直接链接\">​</a></h3>\n<p>Gemma4 的 15 道长文本题<strong>全部超时</strong>（300 秒）。原因：Dense 31B 模型在单卡 L40S 上处理 8K-32K 的 prefill 太慢，TTFT 超过 300 秒。</p>\n<p>这不是模型能力问题，是<strong>硬件限制</strong>。如果给 Gemma4 双卡 TP=2，长文本性能会好很多。但在单卡方案里，它不适合长文本场景。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"最终选型\">最终选型<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E6%9C%80%E7%BB%88%E9%80%89%E5%9E%8B\" class=\"hash-link\" aria-label=\"最终选型的直接链接\" title=\"最终选型的直接链接\">​</a></h2>\n<p>综合性能和质量：</p>\n<table><thead><tr><th>指标</th><th style=\"text-align:center\">Qwen3.5-27B</th><th style=\"text-align:center\">Qwen3.6-35B</th><th style=\"text-align:center\">Gemma4-31B</th></tr></thead><tbody><tr><td>质量总分</td><td style=\"text-align:center\"><strong>76.6%</strong></td><td style=\"text-align:center\">69.7%</td><td style=\"text-align:center\">69.1%</td></tr><tr><td>单请求速度</td><td style=\"text-align:center\"><strong>18.1</strong> tok/s</td><td style=\"text-align:center\">11.0 tok/s</td><td style=\"text-align:center\">17.4 tok/s</td></tr><tr><td>并发吞吐</td><td style=\"text-align:center\">130.3 tok/s</td><td style=\"text-align:center\">83.6 tok/s</td><td style=\"text-align:center\"><strong>132.0</strong> tok/s</td></tr><tr><td>长文本支持</td><td style=\"text-align:center\">✅ 128K</td><td style=\"text-align:center\">⚠️ 64K</td><td style=\"text-align:center\">❌ 32K OOM</td></tr><tr><td>工具调用</td><td style=\"text-align:center\"><strong>100%</strong></td><td style=\"text-align:center\">80%</td><td style=\"text-align:center\">90%</td></tr></tbody></table>\n<p><strong>结论：Qwen3.5-27B-FP8 是单卡 L40S 上的最佳选择。</strong></p>\n<p>它在质量、速度、长文本、工具调用四个维度上都是最优或接近最优。唯一的短板是通识知识（52% vs Gemma4 的 60%），但这对我们的业务场景（代码生成、文档问答、工具调用）影响不大。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"复盘\">复盘<a href=\"https://real-tech.online/blog/l40s-model-quality-eval#%E5%A4%8D%E7%9B%98\" class=\"hash-link\" aria-label=\"复盘的直接链接\" title=\"复盘的直接链接\">​</a></h2>\n<p>整个评测过程中学到的几点：</p>\n<ol>\n<li><strong>不要同时跑 throughput 和 eval</strong>——我犯过这个错误，两个测试互相干扰，数据全废了</li>\n<li><strong>MoE 模型的\"活跃参数\"是个陷阱</strong>——3B 活跃参数不代表 3B 的速度，Expert 路由有开销</li>\n<li><strong>量化对不同能力的影响不同</strong>——FP8 对推理能力影响小，对知识记忆影响大</li>\n<li><strong>硬件限制比模型能力更重要</strong>——Gemma4 的长文本能力不差，是单卡显存不够</li>\n</ol>\n<p>这个系列到此结束。从基础设施搭建、显存优化、性能测试到质量评测，完整记录了在单卡 L40S 上部署大模型推理服务的全过程。希望对同样在做企业内部大模型部署的同学有帮助。</p>",
            "url": "https://real-tech.online/blog/l40s-model-quality-eval",
            "title": "L40S 大模型部署实录④：160 道题考三个大模型，赢家出乎意料",
            "summary": "跑得最快的模型，长文本全部超时。参数最多的模型，总分垫底。最终胜出的是参数最少的那个——76.6% vs 69.7% vs 69.1%。这篇记录 160 道题、6 个维度的完整评测过程，以及为什么\"参数大 ≠ 质量好\"。",
            "date_modified": "2026-05-02T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：L40S大模型部署",
                "LLM",
                "模型评测",
                "vLLM",
                "AI"
            ]
        },
        {
            "id": "https://real-tech.online/blog/l40s-model-benchmark",
            "content_html": "<p>Qwen3.5-27B：18 tok/s。Qwen3.6-35B：11 tok/s。gemma-4-26B 双卡：93 tok/s。同样是 L40S，模型选错速度差 8 倍。这篇用真实测试数据告诉你，哪个模型值得你的 GPU 时间。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"测试方法\">测试方法<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E6%B5%8B%E8%AF%95%E6%96%B9%E6%B3%95\" class=\"hash-link\" aria-label=\"测试方法的直接链接\" title=\"测试方法的直接链接\">​</a></h2>\n<p>自己写了一个 benchmark 脚本（<code>bench_model.py</code>），核心逻辑：</p>\n<ul>\n<li><strong>Warm-up</strong>：每个场景先跑 2 次预热，不计入统计</li>\n<li><strong>多次运行</strong>：每个场景跑 3 次，取中位数</li>\n<li><strong>测试矩阵</strong>：4 种输入长度（512/2K/8K/32K）× 4 种并发度（1/2/4/8）</li>\n<li><strong>输出固定 512 tokens</strong></li>\n<li><strong>指标</strong>：TPS（tokens/s）、TTFT（首 token 延迟）、TPOT（每 token 延迟）</li>\n</ul>\n<p>所有测试在同一节点上完成，3 张卡各跑一个模型并行测试。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"测试环境\">测试环境<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83\" class=\"hash-link\" aria-label=\"测试环境的直接链接\" title=\"测试环境的直接链接\">​</a></h2>\n<table><thead><tr><th>项目</th><th>配置</th></tr></thead><tbody><tr><td>GPU</td><td>单卡 NVIDIA L40S 48GB</td></tr><tr><td>vLLM</td><td>v0.19.1（Qwen3.5/Gemma4），latest（Qwen3.6）</td></tr><tr><td>优化</td><td><code>--kv-cache-dtype=fp8 --enable-prefix-caching --enable-chunked-prefill</code></td></tr></tbody></table>\n<p>三个模型的关键差异：</p>\n<table><thead><tr><th>模型</th><th>架构</th><th>精度</th><th style=\"text-align:center\">权重大小</th><th style=\"text-align:center\">max-model-len</th><th style=\"text-align:center\">CUDA Graph</th></tr></thead><tbody><tr><td>Qwen3.5-27B-FP8</td><td>Dense</td><td>FP8</td><td style=\"text-align:center\">~28GB</td><td style=\"text-align:center\">128K</td><td style=\"text-align:center\">✅</td></tr><tr><td>Qwen3.6-35B-A3B-FP8</td><td>MoE 128E/8A</td><td>FP8</td><td style=\"text-align:center\">~34GB</td><td style=\"text-align:center\">64K</td><td style=\"text-align:center\">❌ enforce-eager</td></tr><tr><td>Gemma4-31B-FP8</td><td>Dense</td><td>FP8</td><td style=\"text-align:center\">~31GB</td><td style=\"text-align:center\">128K</td><td style=\"text-align:center\">✅</td></tr></tbody></table>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"单请求吞吐c1\">单请求吞吐（c=1）<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E5%8D%95%E8%AF%B7%E6%B1%82%E5%90%9E%E5%90%90c1\" class=\"hash-link\" aria-label=\"单请求吞吐（c=1）的直接链接\" title=\"单请求吞吐（c=1）的直接链接\">​</a></h2>\n<p>最基础的指标——一个请求，模型能跑多快：</p>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">512 输入</th><th style=\"text-align:center\">2K 输入</th><th style=\"text-align:center\">8K 输入</th><th style=\"text-align:center\">32K 输入</th></tr></thead><tbody><tr><td>Qwen3.5-27B</td><td style=\"text-align:center\"><strong>18.1</strong> tok/s</td><td style=\"text-align:center\"><strong>18.5</strong> tok/s</td><td style=\"text-align:center\"><strong>18.3</strong> tok/s</td><td style=\"text-align:center\"><strong>16.2</strong> tok/s</td></tr><tr><td>Qwen3.6-35B</td><td style=\"text-align:center\">11.0 tok/s</td><td style=\"text-align:center\">11.1 tok/s</td><td style=\"text-align:center\">10.9 tok/s</td><td style=\"text-align:center\">❌ OOM</td></tr><tr><td>Gemma4-31B</td><td style=\"text-align:center\">17.4 tok/s</td><td style=\"text-align:center\">17.2 tok/s</td><td style=\"text-align:center\">16.7 tok/s</td><td style=\"text-align:center\">❌ OOM</td></tr></tbody></table>\n<p><strong>关键发现</strong>：</p>\n<ol>\n<li><strong>Qwen3.5 最快</strong>，18 tok/s 稳定输出，32K 长文本也只降到 16.2</li>\n<li><strong>Gemma4 接近 Qwen3.5</strong>，但 32K 输入 OOM（31B 权重占了太多显存，KV Cache 不够）</li>\n<li><strong>Qwen3.6 最慢</strong>，只有 11 tok/s。原因是 <code>enforce-eager</code>（没有 CUDA Graph 加速）+ MoE 架构的 Expert 路由开销</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"并发吞吐c8\">并发吞吐（c=8）<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E5%B9%B6%E5%8F%91%E5%90%9E%E5%90%90c8\" class=\"hash-link\" aria-label=\"并发吞吐（c=8）的直接链接\" title=\"并发吞吐（c=8）的直接链接\">​</a></h2>\n<p>8 个并发请求同时打：</p>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">512 输入</th><th style=\"text-align:center\">2K 输入</th><th style=\"text-align:center\">8K 输入</th></tr></thead><tbody><tr><td>Qwen3.5-27B</td><td style=\"text-align:center\">130.3 tok/s</td><td style=\"text-align:center\">130.1 tok/s</td><td style=\"text-align:center\">100.8 tok/s</td></tr><tr><td>Qwen3.6-35B</td><td style=\"text-align:center\">83.6 tok/s</td><td style=\"text-align:center\">82.0 tok/s</td><td style=\"text-align:center\">80.9 tok/s</td></tr><tr><td>Gemma4-31B</td><td style=\"text-align:center\"><strong>132.0</strong> tok/s</td><td style=\"text-align:center\"><strong>129.5</strong> tok/s</td><td style=\"text-align:center\"><strong>126.2</strong> tok/s</td></tr></tbody></table>\n<p><strong>Gemma4 在高并发下反超 Qwen3.5</strong>！原因是 Gemma4 的 KV Cache 更大（7GB vs Qwen3.5 的 10GB），在 8K 输入时 Qwen3.5 开始受 KV Cache 容量限制，吞吐下降到 100.8。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"延迟指标\">延迟指标<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E5%BB%B6%E8%BF%9F%E6%8C%87%E6%A0%87\" class=\"hash-link\" aria-label=\"延迟指标的直接链接\" title=\"延迟指标的直接链接\">​</a></h2>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">TTFT (512in, c=1)</th><th style=\"text-align:center\">TTFT (8Kin, c=1)</th><th style=\"text-align:center\">TPOT (c=1)</th><th style=\"text-align:center\">TPOT (c=8)</th></tr></thead><tbody><tr><td>Qwen3.5</td><td style=\"text-align:center\">1,224 ms</td><td style=\"text-align:center\">1,599 ms</td><td style=\"text-align:center\"><strong>53.0 ms</strong></td><td style=\"text-align:center\">57.3 ms</td></tr><tr><td>Qwen3.6</td><td style=\"text-align:center\">1,148 ms</td><td style=\"text-align:center\">1,839 ms</td><td style=\"text-align:center\">88.3 ms</td><td style=\"text-align:center\">92.3 ms</td></tr><tr><td>Gemma4</td><td style=\"text-align:center\"><strong>1,025 ms</strong></td><td style=\"text-align:center\">1,675 ms</td><td style=\"text-align:center\">55.4 ms</td><td style=\"text-align:center\">57.8 ms</td></tr></tbody></table>\n<ul>\n<li><strong>TTFT</strong>（首 token 延迟）：Gemma4 最快，因为 prefill 阶段 Dense 架构比 MoE 高效</li>\n<li><strong>TPOT</strong>（每 token 延迟）：Qwen3.5 最低 53ms，Qwen3.6 因为 enforce-eager 高达 88ms</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"并发扩展性\">并发扩展性<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E5%B9%B6%E5%8F%91%E6%89%A9%E5%B1%95%E6%80%A7\" class=\"hash-link\" aria-label=\"并发扩展性的直接链接\" title=\"并发扩展性的直接链接\">​</a></h2>\n<p>所有模型都展现了近线性的并发扩展：</p>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">c=1</th><th style=\"text-align:center\">c=2</th><th style=\"text-align:center\">c=4</th><th style=\"text-align:center\">c=8</th><th style=\"text-align:center\">扩展比</th></tr></thead><tbody><tr><td>Qwen3.5</td><td style=\"text-align:center\">18.1</td><td style=\"text-align:center\">36.9</td><td style=\"text-align:center\">73.1</td><td style=\"text-align:center\">130.3</td><td style=\"text-align:center\">7.2× ✅</td></tr><tr><td>Qwen3.6</td><td style=\"text-align:center\">11.0</td><td style=\"text-align:center\">21.3</td><td style=\"text-align:center\">42.1</td><td style=\"text-align:center\">83.6</td><td style=\"text-align:center\">7.6× ✅</td></tr><tr><td>Gemma4</td><td style=\"text-align:center\">17.4</td><td style=\"text-align:center\">34.3</td><td style=\"text-align:center\">67.9</td><td style=\"text-align:center\">132.0</td><td style=\"text-align:center\">7.6× ✅</td></tr></tbody></table>\n<p>8 并发达到 7.2-7.6× 的扩展，说明 vLLM 的 continuous batching 在 L40S 上工作良好。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"历史对比单卡-vs-双卡\">历史对比：单卡 vs 双卡<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E5%8E%86%E5%8F%B2%E5%AF%B9%E6%AF%94%E5%8D%95%E5%8D%A1-vs-%E5%8F%8C%E5%8D%A1\" class=\"hash-link\" aria-label=\"历史对比：单卡 vs 双卡的直接链接\" title=\"历史对比：单卡 vs 双卡的直接链接\">​</a></h2>\n<p>之前还测过 TP=2（双卡）的配置：</p>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">卡数</th><th style=\"text-align:center\">c=1</th><th style=\"text-align:center\">c=8</th><th style=\"text-align:center\">TPOT</th></tr></thead><tbody><tr><td>gemma-4-26B-A4B BF16</td><td style=\"text-align:center\">2</td><td style=\"text-align:center\"><strong>93.0</strong></td><td style=\"text-align:center\"><strong>536.9</strong></td><td style=\"text-align:center\"><strong>9.1 ms</strong></td></tr><tr><td>Qwen3.5-27B-Int4</td><td style=\"text-align:center\">1</td><td style=\"text-align:center\">24.5</td><td style=\"text-align:center\">167.3</td><td style=\"text-align:center\">39.0 ms</td></tr><tr><td>Qwen3.5-27B-FP8</td><td style=\"text-align:center\">1</td><td style=\"text-align:center\">18.1</td><td style=\"text-align:center\">130.3</td><td style=\"text-align:center\">53.0 ms</td></tr></tbody></table>\n<p><strong>gemma-4-26B-A4B 双卡 BF16 是性能怪兽</strong>：93 tok/s 单请求，537 tok/s 并发。MoE 架构（4B 活跃参数）+ 双卡 + BF16 精度 = 极致速度。但它占两张卡，在\"一卡一模型\"的方案里用不了。</p>\n<p>另一个有趣的发现：<strong>Int4 比 FP8 快</strong>（24.5 vs 18.1 tok/s）。Int4 权重更小（~15GB vs ~28GB），更多显存给 KV Cache，decode 阶段的显存带宽压力更小。代价是精度损失，需要评测验证。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"结论\">结论<a href=\"https://real-tech.online/blog/l40s-model-benchmark#%E7%BB%93%E8%AE%BA\" class=\"hash-link\" aria-label=\"结论的直接链接\" title=\"结论的直接链接\">​</a></h2>\n<p>在单卡 L40S 48GB 上：</p>\n<ul>\n<li><strong>追求质量+速度平衡</strong>：Qwen3.5-27B-FP8（18 tok/s，76.6% 质量）</li>\n<li><strong>追求极致吞吐</strong>：Gemma4-31B-FP8（132 tok/s @c=8，但长文本 OOM）</li>\n<li><strong>不推荐</strong>：Qwen3.6-35B-A3B-FP8（enforce-eager 拖累太大，11 tok/s）</li>\n</ul>\n<p>下一篇讲质量评测——速度快不代表回答好，160 道题 6 个维度的评测结果。</p>",
            "url": "https://real-tech.online/blog/l40s-model-benchmark",
            "title": "L40S 大模型部署实录③：同一张卡跑三个模型，速度差了 8 倍",
            "summary": "Qwen3.5-27B：18 tok/s。Qwen3.6-35B：11 tok/s。gemma-4-26B 双卡：93 tok/s。同样是 L40S，模型选错速度差 8 倍。这篇用真实测试数据告诉你，哪个模型值得你的 GPU 时间。",
            "date_modified": "2026-05-01T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：L40S大模型部署",
                "GPU",
                "vLLM",
                "性能测试",
                "LLM"
            ]
        },
        {
            "id": "https://real-tech.online/blog/l40s-gpu-memory-optimization",
            "content_html": "<p><code>Free memory: 0.41 GiB</code>。这是我第一次尝试在一张卡上跑两个模型时，vLLM 启动日志里的数字。然后它 crash 了。从第一次 OOM 到三组模型稳定运行，中间经历了 7 种不同的失败姿势。这篇是完整的踩坑记录。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"目标一卡双模型\">目标：一卡双模型<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E7%9B%AE%E6%A0%87%E4%B8%80%E5%8D%A1%E5%8F%8C%E6%A8%A1%E5%9E%8B\" class=\"hash-link\" aria-label=\"目标：一卡双模型的直接链接\" title=\"目标：一卡双模型的直接链接\">​</a></h2>\n<p>需求很明确：每张 L40S 上跑一个 LLM（用于对话/推理）+ 一个 Embedding 模型（用于 RAG 检索）。三张卡，三组模型。</p>\n<p>看起来显存够用：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">LLM</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">27B </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">FP8</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">     </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token plain\">28GB 权重 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token plain\">10GB </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">KV</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Cache</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token plain\">38GB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token function maybe-class-name\" style=\"color:hsl(221, 87%, 60%)\">Embedding</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6B</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">2GB 权重 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">3GB </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">KV</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Cache</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">5GB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">总计</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">              </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">~</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">39</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">5GB </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> 48GB，还剩 </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">8</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">5GB</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>实际情况远没这么简单。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-1k8s-gpu-隔离两个容器不能各声明一张卡\">坑 1：K8s GPU 隔离——两个容器不能各声明一张卡<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-1k8s-gpu-%E9%9A%94%E7%A6%BB%E4%B8%A4%E4%B8%AA%E5%AE%B9%E5%99%A8%E4%B8%8D%E8%83%BD%E5%90%84%E5%A3%B0%E6%98%8E%E4%B8%80%E5%BC%A0%E5%8D%A1\" class=\"hash-link\" aria-label=\"坑 1：K8s GPU 隔离——两个容器不能各声明一张卡的直接链接\" title=\"坑 1：K8s GPU 隔离——两个容器不能各声明一张卡的直接链接\">​</a></h2>\n<p>最初的想法：Pod 里两个容器，各声明 <code>nvidia.com/gpu: 1</code>。</p>\n<p><strong>错了。</strong> K8s NVIDIA Device Plugin 按容器分配 GPU，不是按 Pod。两个容器各声明 1 张 GPU = Pod 需要 2 张 GPU。</p>\n<p>正确做法：只有 Embedding 容器声明 <code>nvidia.com/gpu: 1</code>，LLM 容器不声明 GPU，通过 <code>NVIDIA_VISIBLE_DEVICES=all</code> 访问所有 GPU。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-2nvidia_visible_devicesall-看到的是所有卡\">坑 2：NVIDIA_VISIBLE_DEVICES=all 看到的是所有卡<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-2nvidia_visible_devicesall-%E7%9C%8B%E5%88%B0%E7%9A%84%E6%98%AF%E6%89%80%E6%9C%89%E5%8D%A1\" class=\"hash-link\" aria-label=\"坑 2：NVIDIA_VISIBLE_DEVICES=all 看到的是所有卡的直接链接\" title=\"坑 2：NVIDIA_VISIBLE_DEVICES=all 看到的是所有卡的直接链接\">​</a></h2>\n<p>LLM 容器设了 <code>NVIDIA_VISIBLE_DEVICES=all</code> 后，它能看到节点上<strong>所有 GPU</strong>，不只是 Embedding 拿到的那张。vLLM 默认用 <code>cuda:0</code>，但 <code>cuda:0</code> 可能是别的 Pod 正在用的卡。</p>\n<p>结果：vLLM 启动时发现 <code>cuda:0</code> 只剩 0.41GB 可用显存，直接 crash。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token known-class-name class-name\" style=\"color:hsl(35, 99%, 36%)\">ValueError</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Free</span><span class=\"token plain\"> memory on device cuda</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.41</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">44.39</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">GiB</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">is less than desired </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">GPU</span><span class=\"token plain\"> memory </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">utilization</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.55</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">24.42</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">GiB</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p><strong>解决方案：GPU UUID 文件协调</strong></p>\n<p>Embedding 容器启动后，把自己拿到的 GPU UUID 写到共享 Volume：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\"># Embedding 启动脚本</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">GPU_UUID</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$(</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">nvidia-smi --query-gpu</span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">gpu_uuid </span><span class=\"token variable parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--format</span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">csv,noheader</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token builtin class-name\" style=\"color:hsl(35, 99%, 36%)\">echo</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"</span><span class=\"token string variable\" style=\"color:hsl(221, 87%, 60%)\">$GPU_UUID</span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> /mnt/models/.gpu-uuid-</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$MODEL_NAME</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>LLM 容器读取 UUID，转换成物理索引：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\"># LLM 启动脚本</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">GPU_UUID</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$(</span><span class=\"token variable function\" style=\"color:hsl(221, 87%, 60%)\">cat</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> /mnt/models/.gpu-uuid-$MODEL_NAME</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">GPU_INDEX</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$(</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">nvidia-smi --query-gpu</span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">index,gpu_uuid </span><span class=\"token variable parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--format</span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">csv,noheader </span><span class=\"token variable punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">  </span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> </span><span class=\"token variable function\" style=\"color:hsl(221, 87%, 60%)\">grep</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> </span><span class=\"token variable string\" style=\"color:hsl(119, 34%, 47%)\">\"</span><span class=\"token variable string variable\" style=\"color:hsl(221, 87%, 60%)\">$GPU_UUID</span><span class=\"token variable string\" style=\"color:hsl(119, 34%, 47%)\">\"</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> </span><span class=\"token variable operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> </span><span class=\"token variable function\" style=\"color:hsl(221, 87%, 60%)\">cut</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> -d</span><span class=\"token variable string\" style=\"color:hsl(119, 34%, 47%)\">','</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\"> </span><span class=\"token variable parameter variable\" style=\"color:hsl(221, 87%, 60%)\">-f1</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token builtin class-name\" style=\"color:hsl(35, 99%, 36%)\">export</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">CUDA_VISIBLE_DEVICES</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$GPU_INDEX</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-3cuda_visible_devices-不接受-uuid\">坑 3：CUDA_VISIBLE_DEVICES 不接受 UUID<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-3cuda_visible_devices-%E4%B8%8D%E6%8E%A5%E5%8F%97-uuid\" class=\"hash-link\" aria-label=\"坑 3：CUDA_VISIBLE_DEVICES 不接受 UUID的直接链接\" title=\"坑 3：CUDA_VISIBLE_DEVICES 不接受 UUID的直接链接\">​</a></h2>\n<p>一开始我直接把 UUID 传给 <code>CUDA_VISIBLE_DEVICES</code>：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token builtin class-name\" style=\"color:hsl(35, 99%, 36%)\">export</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">CUDA_VISIBLE_DEVICES</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">GPU-47ecdc0c-acfd-cb3a-2768-b3da530ff5c1</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>vLLM 报错：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token known-class-name class-name\" style=\"color:hsl(35, 99%, 36%)\">ValueError</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> invalid literal </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">int</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">with</span><span class=\"token plain\"> base </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">10</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'GPU-47ecdc...'</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>必须转成整数索引（0/1/2/3）。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-4gpu-memory-utilization-是各算各的\">坑 4：gpu-memory-utilization 是各算各的<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-4gpu-memory-utilization-%E6%98%AF%E5%90%84%E7%AE%97%E5%90%84%E7%9A%84\" class=\"hash-link\" aria-label=\"坑 4：gpu-memory-utilization 是各算各的的直接链接\" title=\"坑 4：gpu-memory-utilization 是各算各的的直接链接\">​</a></h2>\n<p>两个 vLLM 进程各自独立计算 <code>gpu-memory-utilization</code>，都是基于<strong>整卡 48GB</strong> 算的。</p>\n<p>如果 Embedding 设 0.08（3.8GB），LLM 设 0.92（43.2GB），加起来 47GB，看起来刚好。但每个进程还有 ~0.5GB 的 CUDA context 开销，实际总需求超过 48GB → OOM。</p>\n<p><strong>最终配置</strong>：Embedding 0.08 + LLM 0.87 = 0.95，留 5% 给双 CUDA context。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-5moe-模型加载全部参数\">坑 5：MoE 模型加载全部参数<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-5moe-%E6%A8%A1%E5%9E%8B%E5%8A%A0%E8%BD%BD%E5%85%A8%E9%83%A8%E5%8F%82%E6%95%B0\" class=\"hash-link\" aria-label=\"坑 5：MoE 模型加载全部参数的直接链接\" title=\"坑 5：MoE 模型加载全部参数的直接链接\">​</a></h2>\n<p>Qwen3.6-35B-A3B-FP8 标称\"3B 活跃参数\"，但它有 128 个 Expert，总参数 35B。vLLM 加载时把<strong>全部 35B 权重</strong>（~34GB）都放到 GPU 上，不是只放 3B。</p>\n<p>这意味着 35B MoE 在单卡 48GB 上非常紧张：34GB 权重 + CUDA context + KV Cache，几乎没有余量。最终只分配到 2.3GB KV Cache（约 53K tokens），勉强能用。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-6qwen36-的-torchcompile-吃显存\">坑 6：Qwen3.6 的 torch.compile 吃显存<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-6qwen36-%E7%9A%84-torchcompile-%E5%90%83%E6%98%BE%E5%AD%98\" class=\"hash-link\" aria-label=\"坑 6：Qwen3.6 的 torch.compile 吃显存的直接链接\" title=\"坑 6：Qwen3.6 的 torch.compile 吃显存的直接链接\">​</a></h2>\n<p>Qwen3.6 加载完 34GB 权重后，torch.compile 阶段会额外占用显存做 CUDA Graph capture。在 48GB 卡上，这个阶段直接 OOM。</p>\n<p>尝试过的方案：</p>\n<ol>\n<li><code>--compilation-config '{\"cudagraph_capture_sizes\": [1,2,4,8]}'</code> — 减少 capture 数量，从 51 个降到 4 个。但 Helm YAML 转义 JSON 时出错，没生效。</li>\n<li><code>--enforce-eager</code> — 完全跳过 torch.compile 和 CUDA Graph。<strong>这个有效。</strong></li>\n</ol>\n<p>代价是推理速度下降：TPOT 从理论的 ~55ms 涨到 88ms。但至少能跑起来。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"坑-7probe-超时\">坑 7：Probe 超时<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E5%9D%91-7probe-%E8%B6%85%E6%97%B6\" class=\"hash-link\" aria-label=\"坑 7：Probe 超时的直接链接\" title=\"坑 7：Probe 超时的直接链接\">​</a></h2>\n<p>多容器 Pod 的 LLM 容器有 90 秒启动延迟（等 Embedding 先启动），加上模型加载时间，总启动时间可能超过 5 分钟。</p>\n<p>Kubernetes 的 liveness probe 默认 <code>initialDelaySeconds</code> 太短，模型还没加载完就被 kill 了，进入 CrashLoopBackOff。</p>\n<p>最终配置：</p>\n<table><thead><tr><th>模型</th><th style=\"text-align:center\">initialDelaySeconds</th></tr></thead><tbody><tr><td>27B Dense</td><td style=\"text-align:center\">180s</td></tr><tr><td>35B MoE + MTP</td><td style=\"text-align:center\">600s</td></tr><tr><td>31B Dense</td><td style=\"text-align:center\">360s</td></tr></tbody></table>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"最终显存分布\">最终显存分布<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E6%9C%80%E7%BB%88%E6%98%BE%E5%AD%98%E5%88%86%E5%B8%83\" class=\"hash-link\" aria-label=\"最终显存分布的直接链接\" title=\"最终显存分布的直接链接\">​</a></h2>\n<p>三组模型全部 2/2 Running，0 restarts 后的 <code>nvidia-smi</code>：</p>\n<table><thead><tr><th>GPU</th><th>已用</th><th>剩余</th><th>Pod</th></tr></thead><tbody><tr><td>0</td><td>44,600 MiB (96.8%)</td><td>859 MiB</td><td>Qwen3.6-27B + Embedding</td></tr><tr><td>1</td><td>44,322 MiB (96.2%)</td><td>1,136 MiB</td><td>Qwen3.6-35B + Embedding</td></tr><tr><td>2</td><td>44,398 MiB (96.5%)</td><td>1,060 MiB</td><td>Gemma4-31B + Embedding</td></tr></tbody></table>\n<p>三张卡都用到了 96% 以上。这就是为什么调参过程如此痛苦——每一个百分点的显存分配都可能决定模型能不能启动。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"经验总结\">经验总结<a href=\"https://real-tech.online/blog/l40s-gpu-memory-optimization#%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93\" class=\"hash-link\" aria-label=\"经验总结的直接链接\" title=\"经验总结的直接链接\">​</a></h2>\n<ol>\n<li><strong>K8s 里多容器共享 GPU，只能一个容器声明 GPU 资源</strong>，另一个用 <code>NVIDIA_VISIBLE_DEVICES=all</code> + UUID 文件协调</li>\n<li><strong>gpu-memory-utilization 是各算各的</strong>，两个进程加起来不能超过 0.95</li>\n<li><strong>MoE 模型按总参数算显存</strong>，不是活跃参数</li>\n<li><strong>enforce-eager 是最后的救命稻草</strong>，牺牲速度换稳定性</li>\n<li><strong>Probe 超时要按最慢的模型配置</strong>，35B MoE 需要 10 分钟</li>\n</ol>\n<p>下一篇讲性能基准测试——同样的硬件，不同模型的吞吐差异有多大。</p>",
            "url": "https://real-tech.online/blog/l40s-gpu-memory-optimization",
            "title": "L40S 大模型部署实录②：48GB 显存塞两个模型——7 个让我崩溃的坑",
            "summary": "Free memory: 0.41 GiB。这是我第一次尝试在一张卡上跑两个模型时，vLLM 启动日志里的数字。然后它 crash 了。从第一次 OOM 到三组模型稳定运行，中间经历了 7 种不同的失败姿势。这篇是完整的踩坑记录。",
            "date_modified": "2026-04-30T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：L40S大模型部署",
                "GPU",
                "vLLM",
                "显存优化",
                "Kubernetes"
            ]
        },
        {
            "id": "https://real-tech.online/blog/l40s-llm-infra-setup",
            "content_html": "<p>单卡 L40S，48GB 显存。公司给了一台 EKS GPU 节点，有 3 张 L40S 可用，每张卡独立部署一个模型做横向对比。目标：找出单卡 L40S 上跑 27B-35B 大模型的最优方案。最终结论——Qwen3.5-27B-FP8 单卡 18 tok/s，96% 显存利用率。这篇记录从零搭建的完整过程。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"为什么是-l40s\">为什么是 L40S<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%98%AF-l40s\" class=\"hash-link\" aria-label=\"为什么是 L40S的直接链接\" title=\"为什么是 L40S的直接链接\">​</a></h2>\n<p>选 GPU 之前先明确需求：我们要在一个 EKS 集群上同时跑多个 20B-35B 参数的大模型，提供 OpenAI 兼容 API，给内部多个业务系统调用。</p>\n<p>L40S 的定位是\"推理专用卡\"，和 A100 的区别（数据来自 NVIDIA 官方 spec sheet）：</p>\n<table><thead><tr><th>对比项</th><th>L40S</th><th>A100 80GB</th></tr></thead><tbody><tr><td>显存</td><td>48GB GDDR6</td><td>80GB HBM2e</td></tr><tr><td>FP8 算力</td><td>733 TFLOPS</td><td>不支持原生 FP8</td></tr><tr><td>BF16 算力</td><td>366 TFLOPS</td><td>312 TFLOPS</td></tr><tr><td>显存带宽</td><td>864 GB/s</td><td>2,039 GB/s</td></tr><tr><td>每卡每小时</td><td>~$2.62 (g6e)</td><td>~$2.74 (p4d)</td></tr></tbody></table>\n<p>L40S 的优势是 <strong>FP8 原生支持</strong>：同样跑 FP8 量化模型，L40S 的算力是 A100 的两倍多。劣势是显存带宽低（864 vs 2039 GB/s），大模型推理的 decode 阶段（memory-bound）会比 A100 慢。但我们的核心目标是<strong>在有限的 GPU 性能下找出效果最好的模型</strong>，不追求极致速度。</p>\n<p>最终用的是 <code>g6e.12xlarge</code>：3×L40S 可用 + 48 vCPU + 384GB 内存 + 2×1.8TB NVMe SSD。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"eks-gpu-环境搭建\">EKS GPU 环境搭建<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#eks-gpu-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA\" class=\"hash-link\" aria-label=\"EKS GPU 环境搭建的直接链接\" title=\"EKS GPU 环境搭建的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"nvidia-gpu-operator\">NVIDIA GPU Operator<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#nvidia-gpu-operator\" class=\"hash-link\" aria-label=\"NVIDIA GPU Operator的直接链接\" title=\"NVIDIA GPU Operator的直接链接\">​</a></h3>\n<p>不要手动装驱动。用 NVIDIA GPU Operator 一键搞定：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">helm </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">install</span><span class=\"token plain\"> gpu-operator nvidia/gpu-operator </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--namespace</span><span class=\"token plain\"> gpu-operator --create-namespace </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--set</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">driver.enabled</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">true </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--set</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">toolkit.enabled</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">true </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--set</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">devicePlugin.enabled</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">true </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--set</span><span class=\"token plain\"> </span><span class=\"token assign-left variable\" style=\"color:hsl(221, 87%, 60%)\">dcgmExporter.enabled</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">true</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>它会自动安装：驱动、Container Toolkit、Device Plugin（让 K8s 识别 GPU 资源）、DCGM Exporter（GPU 监控指标）。</p>\n<p>验证：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">kubectl get pods </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">-n</span><span class=\"token plain\"> gpu-operator</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">nvidia-smi  </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\"># 应该看到 3×L40S</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"nvme-存储别忘了挂载\">NVMe 存储——别忘了挂载<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#nvme-%E5%AD%98%E5%82%A8%E5%88%AB%E5%BF%98%E4%BA%86%E6%8C%82%E8%BD%BD\" class=\"hash-link\" aria-label=\"NVMe 存储——别忘了挂载的直接链接\" title=\"NVMe 存储——别忘了挂载的直接链接\">​</a></h3>\n<p>g6e.12xlarge 自带 2×1.8TB NVMe SSD，但<strong>默认不挂载</strong>。模型文件动辄 20-30GB，必须用本地 NVMe 而不是 EBS。</p>\n<p>我写了一个 DaemonSet 自动格式化和挂载：</p>\n<div class=\"language-yaml codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-yaml codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\"># nvme-auto-mount DaemonSet 核心逻辑</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">mkfs.xfs /dev/nvme1n1 </span><span class=\"token important\" style=\"color:hsl(230, 8%, 24%);font-weight:bold\">&amp;&amp;</span><span class=\"token plain\"> mount /dev/nvme1n1 /data1</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">mkfs.xfs /dev/nvme2n1 </span><span class=\"token important\" style=\"color:hsl(230, 8%, 24%);font-weight:bold\">&amp;&amp;</span><span class=\"token plain\"> mount /dev/nvme2n1 /data2</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p><strong>坑</strong>：EKS 节点扩缩容后，新节点的 NVMe 没有挂载，模型 Pod 会卡在 <code>PodInitializing</code>，hostPath PV 挂载失败但不报错。必须确保 DaemonSet 先于模型 Pod 运行。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"模型下载策略\">模型下载策略<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#%E6%A8%A1%E5%9E%8B%E4%B8%8B%E8%BD%BD%E7%AD%96%E7%95%A5\" class=\"hash-link\" aria-label=\"模型下载策略的直接链接\" title=\"模型下载策略的直接链接\">​</a></h3>\n<p>模型存在 NVMe 上，用 Init Container 从 HuggingFace 镜像站下载：</p>\n<div class=\"language-yaml codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-yaml codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token key atrule\" style=\"color:hsl(35, 99%, 36%)\">initContainers</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\" style=\"color:hsl(35, 99%, 36%)\">name</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> model</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\">downloader</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token key atrule\" style=\"color:hsl(35, 99%, 36%)\">command</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\"> sh</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\">c</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">-</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">|</span><span class=\"token scalar string\" style=\"color:hsl(119, 34%, 47%)\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token scalar string\" style=\"color:hsl(119, 34%, 47%)\">        if [ -z \"$(ls -A $MODEL_DIR)\" ]; then</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token scalar string\" style=\"color:hsl(119, 34%, 47%)\">          huggingface-cli download $MODEL_NAME --local-dir $MODEL_DIR</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token scalar string\" style=\"color:hsl(119, 34%, 47%)\">        fi</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p><strong>坑</strong>：<code>ls -A</code> 检查目录非空就跳过下载。如果上次下载中断，目录存在但文件不完整，vLLM 启动时报 \"Cannot find model weights\"。解决方案：加一个完整性校验，或者在下载完成后写一个 <code>.done</code> 标记文件。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"vllm-关键配置\">vLLM 关键配置<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#vllm-%E5%85%B3%E9%94%AE%E9%85%8D%E7%BD%AE\" class=\"hash-link\" aria-label=\"vLLM 关键配置的直接链接\" title=\"vLLM 关键配置的直接链接\">​</a></h2>\n<p>vLLM 是目前最成熟的开源推理框架。核心配置：</p>\n<div class=\"language-bash codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-bash codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">python </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">-m</span><span class=\"token plain\"> vllm.entrypoints.openai.api_server </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token parameter variable\" style=\"color:hsl(221, 87%, 60%)\">--model</span><span class=\"token plain\"> </span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$MODEL_PATH</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --served-model-name </span><span class=\"token variable\" style=\"color:hsl(221, 87%, 60%)\">$MODEL_NAME</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --max-model-len </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">128000</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --gpu-memory-utilization </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.92</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --kv-cache-dtype fp8 </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --enable-prefix-caching </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --enable-chunked-prefill </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">\\</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  --tensor-parallel-size </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>逐个解释：</p>\n<ul>\n<li><code>--kv-cache-dtype fp8</code>：KV Cache 用 FP8 存储，显存占用减半，质量几乎无损。这是 L40S 上的必选项。</li>\n<li><code>--gpu-memory-utilization 0.92</code>：vLLM 预分配 92% 显存给模型+KV Cache。留 8% 给 CUDA context。</li>\n<li><code>--enable-prefix-caching</code>：相同前缀的请求共享 KV Cache，多轮对话场景提升明显。</li>\n<li><code>--enable-chunked-prefill</code>：长文本分块预填充，避免单个长请求阻塞其他请求。</li>\n<li><code>--max-model-len</code>：最大上下文长度。这个值直接影响 KV Cache 大小，设太大会 OOM。</li>\n</ul>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"enforce-eager什么时候需要\">enforce-eager：什么时候需要<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#enforce-eager%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E9%9C%80%E8%A6%81\" class=\"hash-link\" aria-label=\"enforce-eager：什么时候需要的直接链接\" title=\"enforce-eager：什么时候需要的直接链接\">​</a></h3>\n<p>默认情况下 vLLM 会用 CUDA Graph 加速推理。但有些模型架构不兼容：</p>\n<ul>\n<li><strong>Qwen3.6 的 Mamba/DeltaNet 混合架构</strong>：Mamba cache 和 CUDA Graph 不兼容，必须 <code>--enforce-eager</code></li>\n<li><strong>MoE + BF16 + Tensor Parallel</strong>：某些组合下 CUDA Graph capture 会 OOM</li>\n</ul>\n<p><code>--enforce-eager</code> 的代价是 TPOT 增加约 40%（Qwen3.6: 88ms vs Qwen3.5: 53ms）。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"部署架构\">部署架构<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#%E9%83%A8%E7%BD%B2%E6%9E%B6%E6%9E%84\" class=\"hash-link\" aria-label=\"部署架构的直接链接\" title=\"部署架构的直接链接\">​</a></h2>\n<p>3 张 L40S，每张卡独立部署一个模型，做横向对比：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">EKS</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">GPU</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:hsl(221, 87%, 60%)\">Node</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3</span><span class=\"token plain\">×</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">L40S</span><span class=\"token plain\"> 48GB</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">GPU</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Qwen3</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">6</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">27B</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">FP8</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Embedding</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6B</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">GPU</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Qwen3</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">6</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">35B</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">A3B</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">FP8</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Embedding</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6B</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">GPU</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Gemma4</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">31B</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">FP8</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Embedding</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6B</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">└── </span><span class=\"token maybe-class-name\">LiteLLM</span><span class=\"token plain\"> → 统一 </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">API</span><span class=\"token plain\"> 网关，路由到各模型</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>核心思路是<strong>单卡部署</strong>：每张卡跑一个 LLM + 一个 Embedding 模型，通过 LiteLLM 做统一路由。3 张卡 3 个模型并行跑，方便做性能和质量的横向对比。这个\"一卡双模型\"的方案踩了非常多坑，下一篇详细讲。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"小结\">小结<a href=\"https://real-tech.online/blog/l40s-llm-infra-setup#%E5%B0%8F%E7%BB%93\" class=\"hash-link\" aria-label=\"小结的直接链接\" title=\"小结的直接链接\">​</a></h2>\n<p>搭建 GPU 推理基础设施，核心是三件事：</p>\n<ol>\n<li><strong>GPU Operator 自动化</strong>——不要手动装驱动</li>\n<li><strong>NVMe 存储</strong>——模型文件必须在本地盘，EBS 太慢</li>\n<li><strong>vLLM 配置调优</strong>——<code>kv-cache-dtype=fp8</code> 是 L40S 上的必选项</li>\n</ol>\n<p>下一篇讲多模型 GPU 共享的显存优化，那才是真正的地狱。</p>",
            "url": "https://real-tech.online/blog/l40s-llm-infra-setup",
            "title": "L40S 大模型部署实录①：单卡 48GB，能跑多大的模型？",
            "summary": "单卡 L40S，48GB 显存。公司给了一台 EKS GPU 节点，有 3 张 L40S 可用，每张卡独立部署一个模型做横向对比。目标：找出单卡 L40S 上跑 27B-35B 大模型的最优方案。最终结论——Qwen3.5-27B-FP8 单卡 18 tok/s，96% 显存利用率。这篇记录从零搭建的完整过程。",
            "date_modified": "2026-04-29T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：L40S大模型部署",
                "GPU",
                "vLLM",
                "EKS",
                "DevOps"
            ]
        },
        {
            "id": "https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice",
            "content_html": "<p>日均的技术栈很简单：SwiftUI + SwiftData，纯 iOS 原生开发。没有后端，没有第三方依赖，数据通过 iCloud 同步。</p>\n<p>这篇记录一些技术选型的思考和实际开发中的经验。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"为什么选-swiftui--swiftdata\">为什么选 SwiftUI + SwiftData<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89-swiftui--swiftdata\" class=\"hash-link\" aria-label=\"为什么选 SwiftUI + SwiftData的直接链接\" title=\"为什么选 SwiftUI + SwiftData的直接链接\">​</a></h2>\n<p>2026 年做一个新的 iOS App，SwiftUI 已经是默认选择。但 SwiftData 的选择需要多想一步。</p>\n<p><strong>选 SwiftData 的理由：</strong></p>\n<ul>\n<li>与 SwiftUI 深度集成，<code>@Query</code> 宏让数据绑定极其简洁</li>\n<li>内置 iCloud 同步（CloudKit），零配置</li>\n<li>不需要写 migration 代码（对于 v1.x 阶段的快速迭代很重要）</li>\n<li>一个人开发，学习成本要低</li>\n</ul>\n<p><strong>放弃 Core Data 的理由：</strong></p>\n<ul>\n<li>样板代码太多</li>\n<li>NSManagedObject 和 SwiftUI 的配合不够自然</li>\n<li>2026 年了，没必要背历史包袱</li>\n</ul>\n<p><strong>没考虑 Realm / SQLite 的理由：</strong></p>\n<ul>\n<li>引入第三方依赖 = 引入维护风险</li>\n<li>日均的数据模型很简单，不需要复杂查询</li>\n<li>iCloud 同步是刚需，SwiftData 原生支持</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"数据模型设计\">数据模型设计<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%E8%AE%BE%E8%AE%A1\" class=\"hash-link\" aria-label=\"数据模型设计的直接链接\" title=\"数据模型设计的直接链接\">​</a></h2>\n<p>日均的核心模型只有两个：</p>\n<div class=\"language-swift codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-swift codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token attribute atrule\" style=\"color:hsl(35, 99%, 36%)\">@Model</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">TrackedItem</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> name</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">String</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> emoji</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">String</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> price</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Double</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> trackingType</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">TrackingType</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// byTime or byCount</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> purchaseDate</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Date</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> expectedUsageDays</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Int</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">?</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> usageRecords</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">UsageRecord</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> isTracked</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Bool</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// prevent duplicate tracking from calm list</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// computed: dailyCost, costPerUse, totalUses...</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token attribute atrule\" style=\"color:hsl(35, 99%, 36%)\">@Model</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">CalmItem</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> name</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">String</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> emoji</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">String</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> price</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Double</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> calmDays</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Int</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// 3, 5, 7, or 14</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> addedDate</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Date</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> isTracked</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Bool</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// computed: expiryDate, daysRemaining...</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>设计原则：<strong>模型尽量扁平，计算属性代替冗余字段</strong>。</p>\n<p>比如 <code>dailyCost</code> 不存储在数据库里，而是每次从 <code>price</code>、<code>purchaseDate</code>、<code>usageRecords</code> 实时计算。好处是数据永远一致，坏处是列表多的时候可能有性能问题——但日均的数据量级（几十到几百个物品）完全不是问题。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"icloud-同步零配置的代价\">iCloud 同步：零配置的代价<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#icloud-%E5%90%8C%E6%AD%A5%E9%9B%B6%E9%85%8D%E7%BD%AE%E7%9A%84%E4%BB%A3%E4%BB%B7\" class=\"hash-link\" aria-label=\"iCloud 同步：零配置的代价的直接链接\" title=\"iCloud 同步：零配置的代价的直接链接\">​</a></h2>\n<p>SwiftData + CloudKit 的 iCloud 同步确实是\"零配置\"——在 Xcode 里勾选 iCloud 能力，选择 CloudKit 容器，就完了。</p>\n<p>但\"零配置\"不等于\"零问题\"：</p>\n<ol>\n<li><strong>同步延迟不可控</strong> — 有时候几秒，有时候几分钟。用户换设备后可能看不到最新数据。</li>\n<li><strong>冲突解决是黑盒</strong> — CloudKit 的 last-write-wins 策略，你无法自定义。</li>\n<li><strong>调试困难</strong> — 同步出问题时，几乎没有日志可看。</li>\n</ol>\n<p>对日均来说，这些问题可以接受。用户不会在两台设备上同时编辑同一个物品，同步延迟几分钟也不影响使用。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"widget-开发app-group-是关键\">Widget 开发：App Group 是关键<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#widget-%E5%BC%80%E5%8F%91app-group-%E6%98%AF%E5%85%B3%E9%94%AE\" class=\"hash-link\" aria-label=\"Widget 开发：App Group 是关键的直接链接\" title=\"Widget 开发：App Group 是关键的直接链接\">​</a></h2>\n<p>v1.5 加入了桌面小组件。Widget Extension 是独立进程，不能直接访问主 App 的 SwiftData 数据库。</p>\n<p>解决方案：<strong>App Group + UserDefaults 缓存</strong>。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">主 </span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> 数据变更 → 写入 </span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Group</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">UserDefaults</span><span class=\"token plain\"> → </span><span class=\"token maybe-class-name\">Widget</span><span class=\"token plain\"> 读取缓存</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>为什么不让 Widget 直接访问 SwiftData？</p>\n<ul>\n<li>Widget 的内存限制很严格</li>\n<li>SwiftData 的初始化开销不小</li>\n<li>Widget 只需要展示数据，不需要写入</li>\n</ul>\n<p>实际做法：主 App 在每次数据变更时，把 Widget 需要的数据（日均成本最低的物品、冷静清单倒计时）序列化写入 UserDefaults。Widget 只读这个缓存。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"storekit-2-付费写好但不上线\">StoreKit 2 付费：写好但不上线<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#storekit-2-%E4%BB%98%E8%B4%B9%E5%86%99%E5%A5%BD%E4%BD%86%E4%B8%8D%E4%B8%8A%E7%BA%BF\" class=\"hash-link\" aria-label=\"StoreKit 2 付费：写好但不上线的直接链接\" title=\"StoreKit 2 付费：写好但不上线的直接链接\">​</a></h2>\n<p>日均的付费逻辑已经写好了：</p>\n<div class=\"language-swift codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-swift codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">PurchaseManager</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// 月付 ¥3 / 年付 ¥18 / 永久买断 ¥38</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">func</span><span class=\"token plain\"> </span><span class=\"token function-definition function\" style=\"color:hsl(221, 87%, 60%)\">purchase</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token omit keyword\" style=\"color:hsl(301, 63%, 40%)\">_</span><span class=\"token plain\"> product</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Product</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">throws</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-&gt;</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Transaction</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">func</span><span class=\"token plain\"> </span><span class=\"token function-definition function\" style=\"color:hsl(221, 87%, 60%)\">restorePurchases</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">async</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token plain\"> isPro</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">Bool</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">get</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>StoreKit 2 比 StoreKit 1 好用太多——纯 Swift async/await API，不需要处理 SKPaymentQueue 的回调地狱。</p>\n<p>但这些代码目前处于\"写好不上线\"状态。PaywallView 写好了，产品 ID 定义好了，但 App Store Connect 里没有配置产品。原因在留存那篇文章里说过：留存没达标之前，上付费没有意义。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"通知系统一个低级-bug-的教训\">通知系统：一个低级 Bug 的教训<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#%E9%80%9A%E7%9F%A5%E7%B3%BB%E7%BB%9F%E4%B8%80%E4%B8%AA%E4%BD%8E%E7%BA%A7-bug-%E7%9A%84%E6%95%99%E8%AE%AD\" class=\"hash-link\" aria-label=\"通知系统：一个低级 Bug 的教训的直接链接\" title=\"通知系统：一个低级 Bug 的教训的直接链接\">​</a></h2>\n<p>v1.2 的冷静清单有一个严重 bug：到期通知从未触发。</p>\n<p>原因很简单：<code>scheduleCalmExpiry</code> 函数写好了，但在添加冷静物品的流程里<strong>忘了调用</strong>。</p>\n<div class=\"language-swift codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-swift codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// v1.2 的代码（有 bug）</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">func</span><span class=\"token plain\"> </span><span class=\"token function-definition function\" style=\"color:hsl(221, 87%, 60%)\">addCalmItem</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token omit keyword\" style=\"color:hsl(301, 63%, 40%)\">_</span><span class=\"token plain\"> item</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">CalmItem</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    modelContext</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">insert</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">item</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// scheduleCalmExpiry(item)  ← 这行不存在</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// v1.3.1 修复后</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">func</span><span class=\"token plain\"> </span><span class=\"token function-definition function\" style=\"color:hsl(221, 87%, 60%)\">addCalmItem</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token omit keyword\" style=\"color:hsl(301, 63%, 40%)\">_</span><span class=\"token plain\"> item</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:hsl(35, 99%, 36%)\">CalmItem</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    modelContext</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">insert</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">item</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">scheduleCalmExpiry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">item</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">requestNotificationPermission</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">// 同时请求权限</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>教训：<strong>写完功能要走一遍完整的用户流程</strong>。不是测试单个函数，而是从\"用户点击添加\"到\"7 天后收到通知\"的完整链路。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"html-原型先行\">HTML 原型先行<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#html-%E5%8E%9F%E5%9E%8B%E5%85%88%E8%A1%8C\" class=\"hash-link\" aria-label=\"HTML 原型先行的直接链接\" title=\"HTML 原型先行的直接链接\">​</a></h2>\n<p>日均的开发流程有一个不太常见的做法：<strong>先用 HTML 做原型，再写 SwiftUI</strong>。</p>\n<p><code>ui/</code> 目录下有完整的 HTML 原型：</p>\n<ul>\n<li><code>page1_home.html</code> — 首页列表</li>\n<li><code>page2_add.html</code> — 添加物品</li>\n<li><code>page3_detail.html</code> — 物品详情</li>\n<li><code>page4_calm_list.html</code> — 冷静清单</li>\n<li><code>page5_calm_detail.html</code> — 冷静详情</li>\n<li><code>page6_insight.html</code> — 洞察页</li>\n</ul>\n<p>为什么用 HTML 而不是 Figma？</p>\n<ol>\n<li><strong>我更熟悉 CSS</strong> — 写 HTML 比拖 Figma 快</li>\n<li><strong>可以精确定义数值</strong> — 颜色、间距、圆角都是代码，直接复制到 SwiftUI</li>\n<li><strong>可以在浏览器里交互</strong> — 比静态设计稿更接近真实体验</li>\n<li><strong>零成本</strong> — 不需要 Figma 订阅</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"项目结构\">项目结构<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84\" class=\"hash-link\" aria-label=\"项目结构的直接链接\" title=\"项目结构的直接链接\">​</a></h2>\n<p>日均的代码组织很简单：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token maybe-class-name\">ZhiValue</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token maybe-class-name\">Sources</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token maybe-class-name\">ZhiValue</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token maybe-class-name\">Models</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">          # </span><span class=\"token maybe-class-name\">SwiftData</span><span class=\"token plain\"> 模型</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token maybe-class-name\">Views</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">           # </span><span class=\"token maybe-class-name\">SwiftUI</span><span class=\"token plain\"> 视图</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">│   ├── </span><span class=\"token maybe-class-name\">Calculator</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">  # 算一算</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">│   ├── </span><span class=\"token maybe-class-name\">Items</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">       # 物品列表和详情</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">│   ├── </span><span class=\"token maybe-class-name\">Calm</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">        # 冷静清单</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">│   ├── </span><span class=\"token maybe-class-name\">Insight</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">     # 洞察</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">│   └── </span><span class=\"token maybe-class-name\">Settings</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">    # 设置</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">├── </span><span class=\"token maybe-class-name\">Services</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">        # 通知、购买等服务</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">└── </span><span class=\"token maybe-class-name\">Theme</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">           # </span><span class=\"token maybe-class-name\">AppTheme（颜色、字体、间距）</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>没有用 MVVM、没有用 Coordinator、没有用 Clean Architecture。对于一个人开发的小 App，<strong>View 直接操作 Model</strong> 是最简单高效的方式。</p>\n<p>等 App 复杂到需要架构的时候再重构，不要提前过度设计。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"给独立开发者的技术建议\">给独立开发者的技术建议<a href=\"https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice#%E7%BB%99%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E6%8A%80%E6%9C%AF%E5%BB%BA%E8%AE%AE\" class=\"hash-link\" aria-label=\"给独立开发者的技术建议的直接链接\" title=\"给独立开发者的技术建议的直接链接\">​</a></h2>\n<ol>\n<li><strong>SwiftData 够用就用</strong> — 除非你需要复杂查询或自定义同步逻辑</li>\n<li><strong>不要引入不必要的依赖</strong> — 每个依赖都是维护负担</li>\n<li><strong>HTML 原型比 Figma 更适合开发者</strong> — 如果你会写 CSS 的话</li>\n<li><strong>先跑通完整流程，再优化细节</strong> — 通知 bug 就是反面教材</li>\n<li><strong>代码写好不等于要上线</strong> — 付费逻辑可以提前写，但上线时机要看数据</li>\n<li><strong>计算属性优于冗余字段</strong> — 数据一致性比性能更重要（在小数据量下）</li>\n</ol>\n<hr>\n<p>这是日均系列的最后一篇。五篇文章覆盖了产品定位、设计系统、留存优化、获客漏斗和技术实践——一个独立开发者从 0 到 1 的完整记录。</p>\n<p>日均还在继续迭代。如果你也在做独立开发，欢迎在 App Store 搜索「日均」体验，或者在小红书找到我聊聊。</p>",
            "url": "https://real-tech.online/blog/zhi-value-swiftui-swiftdata-practice",
            "title": "日均开发实录⑤：SwiftUI + SwiftData 实践笔记",
            "summary": "日均的技术栈很简单：SwiftUI + SwiftData，纯 iOS 原生开发。没有后端，没有第三方依赖，数据通过 iCloud 同步。",
            "date_modified": "2026-04-28T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：日均开发实录",
                "独立开发",
                "iOS",
                "日均"
            ]
        },
        {
            "id": "https://real-tech.online/blog/zhi-value-acquisition-funnel",
            "content_html": "<p>日均上线后的前两周，我没花一分钱投广告，累计获得了 211 次下载。</p>\n<p>这个数字不大，但背后的获客路径很有意思：<strong>不是 App Store 搜索带来的自然流量，而是小红书内容间接驱动的</strong>。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"数据时间线\">数据时间线<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E6%95%B0%E6%8D%AE%E6%97%B6%E9%97%B4%E7%BA%BF\" class=\"hash-link\" aria-label=\"数据时间线的直接链接\" title=\"数据时间线的直接链接\">​</a></h2>\n<table><thead><tr><th>日期</th><th>累计下载</th><th>单日新增</th><th>发生了什么</th></tr></thead><tbody><tr><td>~04-04</td><td>8</td><td>—</td><td>上线一周，几乎没有下载</td></tr><tr><td>04-05</td><td>44</td><td>+36</td><td>爆发式增长</td></tr><tr><td>04-13</td><td>211</td><td>—</td><td>9 天新增 167 次</td></tr></tbody></table>\n<p>关键转折点在 04-05。单日 +36 次下载，之前一周总共才 8 次。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"发生了什么\">发生了什么？<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88\" class=\"hash-link\" aria-label=\"发生了什么？的直接链接\" title=\"发生了什么？的直接链接\">​</a></h2>\n<p>03-30 开始在小红书发布日均相关的内容。发帖后约一周，下载量爆发。</p>\n<p>时间线高度吻合：</p>\n<ul>\n<li>03-30 之前：累计 8 次下载</li>\n<li>03-30 开始发帖</li>\n<li>04-05 开始爆发</li>\n<li>04-13 累计 211 次</li>\n</ul>\n<p><strong>小红书内容是触发器，App Store 搜索是下载渠道。</strong></p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"获客漏斗的真实结构\">获客漏斗的真实结构<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E8%8E%B7%E5%AE%A2%E6%BC%8F%E6%96%97%E7%9A%84%E7%9C%9F%E5%AE%9E%E7%BB%93%E6%9E%84\" class=\"hash-link\" aria-label=\"获客漏斗的真实结构的直接链接\" title=\"获客漏斗的真实结构的直接链接\">​</a></h2>\n<p>一开始我以为获客漏斗是这样的：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Store</span><span class=\"token plain\"> 搜索 → 看到日均 → 下载</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>实际上是这样的：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">小红书笔记 → 用户产生兴趣 → 去 </span><span class=\"token maybe-class-name\">App</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Store</span><span class=\"token plain\"> 搜索</span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"日均\"</span><span class=\"token plain\"> → 下载</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>这个认知修正很重要。它意味着：</p>\n<ol>\n<li><strong>App Store 搜索词优化（ASO）仍然重要</strong> — 用户搜\"日均\"必须能找到</li>\n<li><strong>但流量源头是小红书</strong> — 没有内容触达，就没有搜索行为</li>\n<li><strong>小红书涨粉和 App 获客是同一条漏斗</strong> — 不是两件事</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"小红书内容策略\">小红书内容策略<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E5%B0%8F%E7%BA%A2%E4%B9%A6%E5%86%85%E5%AE%B9%E7%AD%96%E7%95%A5\" class=\"hash-link\" aria-label=\"小红书内容策略的直接链接\" title=\"小红书内容策略的直接链接\">​</a></h2>\n<p>什么样的内容能驱动下载？不是直接说\"下载我的 App\"，而是<strong>先提供价值，再自然引导</strong>。</p>\n<p>有效的内容类型：</p>\n<ul>\n<li><strong>消费观点类</strong> — \"你的 AirPods 每天花你多少钱？\"引发思考</li>\n<li><strong>自嘲式故事</strong> — \"买了 ¥800 的跑鞋，穿了 3 次，每次 ¥267\"引发共鸣</li>\n<li><strong>数据可视化</strong> — 把日均成本做成直观的对比图</li>\n</ul>\n<p>核心原则：<strong>内容本身有价值，App 是解决方案的自然延伸</strong>。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"aso让搜索能找到你\">ASO：让搜索能找到你<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#aso%E8%AE%A9%E6%90%9C%E7%B4%A2%E8%83%BD%E6%89%BE%E5%88%B0%E4%BD%A0\" class=\"hash-link\" aria-label=\"ASO：让搜索能找到你的直接链接\" title=\"ASO：让搜索能找到你的直接链接\">​</a></h2>\n<p>v1.2 提交时做了一轮 ASO 优化：</p>\n<ul>\n<li><strong>副标题：</strong> 每笔消费值不值？算一下就知道</li>\n<li><strong>关键词：</strong> 日均成本、值不值、性价比、理性消费、冲动消费、省钱、消费管理、购物决策、冷静期……</li>\n</ul>\n<p>关键词策略的思路：</p>\n<ol>\n<li><strong>品牌词</strong> — \"日均\"、\"日均成本\"（搜索意图最强）</li>\n<li><strong>场景词</strong> — \"值不值\"、\"冲动消费\"、\"购物决策\"（用户痛点）</li>\n<li><strong>竞品词</strong> — \"记账\"、\"省钱\"（蹭流量，但转化率低）</li>\n</ol>\n<p>目前样本量太小，App Store Connect 还没显示关键词数据。但从下载时间线看，品牌词\"日均\"应该是主要搜索词。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"一个反直觉的发现\">一个反直觉的发现<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E4%B8%80%E4%B8%AA%E5%8F%8D%E7%9B%B4%E8%A7%89%E7%9A%84%E5%8F%91%E7%8E%B0\" class=\"hash-link\" aria-label=\"一个反直觉的发现的直接链接\" title=\"一个反直觉的发现的直接链接\">​</a></h2>\n<p><strong>App Store 的\"搜索\"下载量，不等于自然搜索流量。</strong></p>\n<p>App Store Connect 显示的\"搜索\"来源，包括了用户主动搜索品牌词的行为。当用户在小红书看到\"日均\"这个名字，去 App Store 搜索下载，这在数据上显示为\"搜索\"来源——但实际触发点是小红书内容。</p>\n<p>这意味着：如果你只看 App Store 数据，会误以为是 ASO 在起作用。实际上是内容营销在起作用。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"活跃设备-vs-下载量\">活跃设备 vs 下载量<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E6%B4%BB%E8%B7%83%E8%AE%BE%E5%A4%87-vs-%E4%B8%8B%E8%BD%BD%E9%87%8F\" class=\"hash-link\" aria-label=\"活跃设备 vs 下载量的直接链接\" title=\"活跃设备 vs 下载量的直接链接\">​</a></h2>\n<p>211 次下载，峰值活跃设备 18 个。</p>\n<p>这个比例（~8.5%）说明了什么？</p>\n<ol>\n<li><strong>大量用户下载后很快卸载</strong> — 首次体验没有留住他们（这就是上一篇聊的留存问题）</li>\n<li><strong>获客不是瓶颈</strong> — 小红书能持续带来新用户</li>\n<li><strong>留存才是瓶颈</strong> — 留不住人，获客再多也是漏水的桶</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"成本分析\">成本分析<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E6%88%90%E6%9C%AC%E5%88%86%E6%9E%90\" class=\"hash-link\" aria-label=\"成本分析的直接链接\" title=\"成本分析的直接链接\">​</a></h2>\n<p>这 211 次下载的获客成本：</p>\n<ul>\n<li>广告费：¥0</li>\n<li>小红书内容制作：个人时间（每篇约 1-2 小时）</li>\n<li>ASO 优化：个人时间（一次性）</li>\n</ul>\n<p>纯时间成本，零现金投入。对独立开发者来说，这是最可持续的获客方式。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"给独立开发者的获客建议\">给独立开发者的获客建议<a href=\"https://real-tech.online/blog/zhi-value-acquisition-funnel#%E7%BB%99%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E8%8E%B7%E5%AE%A2%E5%BB%BA%E8%AE%AE\" class=\"hash-link\" aria-label=\"给独立开发者的获客建议的直接链接\" title=\"给独立开发者的获客建议的直接链接\">​</a></h2>\n<p><strong>1. 内容先行，App 后置</strong></p>\n<p>不要一上来就推 App。先在目标用户聚集的平台（小红书、即刻、Twitter）提供有价值的内容，让用户自然产生兴趣。</p>\n<p><strong>2. 品牌词要好搜</strong></p>\n<p>App 名字要简短、好记、好搜。\"日均\"两个字，用户在小红书看到后能直接去 App Store 搜索。如果名字是\"SmartCostTracker\"，这个漏斗就断了。</p>\n<p><strong>3. 小红书的内容半衰期比你想象的长</strong></p>\n<p>不像微博或朋友圈，小红书的笔记有搜索流量。一篇好的笔记可以持续几周甚至几个月带来曝光。</p>\n<p><strong>4. 先跑通漏斗，再优化每一步</strong></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">内容触达 → 产生兴趣 → 搜索下载 → 首次体验 → 留存</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>先确认整条漏斗是通的，再逐步优化每个环节的转化率。</p>\n<p><strong>5. 数据小的时候，看趋势不看绝对值</strong></p>\n<p>211 次下载的统计意义有限。但\"发帖后下载量爆发\"这个趋势是确定的。在早期，定性判断比定量分析更有用。</p>\n<hr>\n<p>下一篇是这个系列的最后一篇，聊技术——SwiftUI + SwiftData 的独立开发实践，包括架构选择、iCloud 同步、Widget 开发的踩坑记录。</p>",
            "url": "https://real-tech.online/blog/zhi-value-acquisition-funnel",
            "title": "日均开发实录④：小红书 + App Store 的获客漏斗——211 次下载背后的故事",
            "summary": "日均上线后的前两周，我没花一分钱投广告，累计获得了 211 次下载。",
            "date_modified": "2026-04-27T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：日均开发实录",
                "独立开发",
                "iOS",
                "日均"
            ]
        },
        {
            "id": "https://real-tech.online/blog/zhi-value-retention-struggle",
            "content_html": "<p>D1 留存 12%，D7 留存 4%。</p>\n<p>这两个数字，是日均上线两周后 App Store Connect 给我的现实。100 个人下载了 App，一周后只有 4 个人还在用。</p>\n<p>这篇文章记录我怎么诊断问题、做出决策、以及为什么\"砍功能\"有时候比\"加功能\"更重要。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"数据现实\">数据现实<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E6%95%B0%E6%8D%AE%E7%8E%B0%E5%AE%9E\" class=\"hash-link\" aria-label=\"数据现实的直接链接\" title=\"数据现实的直接链接\">​</a></h2>\n<p>先看时间线：</p>\n<table><thead><tr><th>日期</th><th>累计下载</th><th>活跃设备</th><th>备注</th></tr></thead><tbody><tr><td>~04-04</td><td>8</td><td>—</td><td>v1.2.2 发布前</td></tr><tr><td>04-05</td><td>44</td><td>—</td><td>单日 +36，小红书内容开始驱动</td></tr><tr><td>04-13</td><td>211</td><td>峰值 18</td><td>D1 留存 12%，D7 留存 4%</td></tr></tbody></table>\n<p>211 次下载，峰值活跃 18 个设备。这意味着绝大多数用户下载后很快就流失了。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"诊断新用户的前-30-秒\">诊断：新用户的前 30 秒<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E8%AF%8A%E6%96%AD%E6%96%B0%E7%94%A8%E6%88%B7%E7%9A%84%E5%89%8D-30-%E7%A7%92\" class=\"hash-link\" aria-label=\"诊断：新用户的前 30 秒的直接链接\" title=\"诊断：新用户的前 30 秒的直接链接\">​</a></h2>\n<p>留存问题的根源通常在<strong>新用户的首次体验</strong>。我回头审视了 v1.2 的 Tab 结构：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">v1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Tab</span><span class=\"token plain\"> 结构：</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">我的物品（列表）</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 冷静 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 洞察 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 设置</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">算一算被隐藏在二级入口</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>问题出在哪？</p>\n<p>新用户打开 App，看到的是一个<strong>空列表</strong>。没有物品、没有数据、没有即时价值。要体验核心功能\"算一算\"，需要找到入口、输入数据、等待结果。</p>\n<p><strong>新用户在获得价值之前就离开了。</strong></p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"关键决策恢复算一算为首-tab\">关键决策：恢复算一算为首 Tab<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E5%85%B3%E9%94%AE%E5%86%B3%E7%AD%96%E6%81%A2%E5%A4%8D%E7%AE%97%E4%B8%80%E7%AE%97%E4%B8%BA%E9%A6%96-tab\" class=\"hash-link\" aria-label=\"关键决策：恢复算一算为首 Tab的直接链接\" title=\"关键决策：恢复算一算为首 Tab的直接链接\">​</a></h2>\n<p>v1.3.1 的核心改动只有一个：<strong>把算一算恢复为第一个 Tab</strong>。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">v1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3.1</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Tab</span><span class=\"token plain\"> 结构：</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">算一算（默认）</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 我的物品 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 冷静 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> 洞察</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>这个决策的逻辑：</p>\n<ol>\n<li><strong>即时价值</strong> — 新用户打开 App，立刻看到一个计算器。输入价格和使用频率，10 秒内得到结果。</li>\n<li><strong>零门槛</strong> — 不需要先添加物品，不需要理解\"追踪\"概念。</li>\n<li><strong>转化漏斗</strong> — 算完之后自然引导到\"开始追踪\"或\"加入冷静清单\"。</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"同时修复的-bug\">同时修复的 Bug<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E5%90%8C%E6%97%B6%E4%BF%AE%E5%A4%8D%E7%9A%84-bug\" class=\"hash-link\" aria-label=\"同时修复的 Bug的直接链接\" title=\"同时修复的 Bug的直接链接\">​</a></h2>\n<p>诊断过程中还发现了一个严重 bug：<strong>冷静清单到期通知从未触发</strong>。</p>\n<p>原因：<code>scheduleCalmExpiry</code> 函数写好了，但从未被调用。用户添加了冷静物品，设了 7 天冷静期，但 7 天后什么都没发生。</p>\n<p>这意味着冷静清单的核心价值——\"到期提醒你做决定\"——完全失效了。</p>\n<p>修复清单：</p>\n<ul>\n<li>修复 <code>scheduleCalmExpiry</code> 调用时机</li>\n<li>修复通知权限请求时机（添加冷静物品时请求，而非只在记录使用时）</li>\n<li>算一算新增物品名输入框，预填到追踪/冷静清单</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"为什么不加更多功能\">为什么不加更多功能<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%8A%A0%E6%9B%B4%E5%A4%9A%E5%8A%9F%E8%83%BD\" class=\"hash-link\" aria-label=\"为什么不加更多功能的直接链接\" title=\"为什么不加更多功能的直接链接\">​</a></h2>\n<p>面对 4% 的留存，直觉反应是\"加功能\"——加社交、加成就系统、加每日签到。</p>\n<p>但我选择了相反的方向：<strong>不加功能，调整结构</strong>。</p>\n<p>理由：</p>\n<ol>\n<li>用户不是因为功能不够而离开，是因为<strong>没感受到核心价值</strong>就离开了</li>\n<li>加功能 = 加复杂度 = 新用户更难理解产品</li>\n<li>一个人的开发资源有限，每加一个功能就是一个维护负担</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"付费功能的克制\">付费功能的克制<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E4%BB%98%E8%B4%B9%E5%8A%9F%E8%83%BD%E7%9A%84%E5%85%8B%E5%88%B6\" class=\"hash-link\" aria-label=\"付费功能的克制的直接链接\" title=\"付费功能的克制的直接链接\">​</a></h2>\n<p>v1.3.1 还做了一个决定：<strong>隐藏 Pro 升级入口</strong>。</p>\n<p>已经写好了 StoreKit 2 的付费逻辑、PaywallView、产品配置。但数据告诉我：</p>\n<ul>\n<li>活跃用户十几个</li>\n<li>D7 留存 4%</li>\n<li>瓶颈是留存，不是变现</li>\n</ul>\n<p>在这个阶段上付费，不仅赚不到钱，还会让新用户觉得\"又一个想收费的 App\"。</p>\n<p>付费上线的前提条件我定得很明确：</p>\n<ul>\n<li>D7 留存 &gt; 25%</li>\n<li>周活跃用户 &gt; 500</li>\n<li>用户平均追踪物品数 &gt; 3</li>\n</ul>\n<p>三个条件缺一不可。在此之前，所有功能免费。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"验证指标\">验证指标<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E9%AA%8C%E8%AF%81%E6%8C%87%E6%A0%87\" class=\"hash-link\" aria-label=\"验证指标的直接链接\" title=\"验证指标的直接链接\">​</a></h2>\n<p>v1.3.1 发版后需要观察一周的指标：</p>\n<ol>\n<li><strong>D1 留存是否从 12% 提升到 20%+</strong> — 算一算作为首 Tab 是否让新用户更快获得价值</li>\n<li><strong>Sessions/用户是否提升</strong> — 用户是否更频繁地打开 App</li>\n<li><strong>算一算 → 开始追踪的转化率</strong> — 计算完之后有多少人真的开始追踪</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"独立开发者的留存思维\">独立开发者的留存思维<a href=\"https://real-tech.online/blog/zhi-value-retention-struggle#%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E7%95%99%E5%AD%98%E6%80%9D%E7%BB%B4\" class=\"hash-link\" aria-label=\"独立开发者的留存思维的直接链接\" title=\"独立开发者的留存思维的直接链接\">​</a></h2>\n<p>几个从这次经历中学到的东西：</p>\n<p><strong>1. 新用户的前 30 秒决定一切</strong></p>\n<p>不是你的功能不好，是用户没机会体验到。首屏必须提供即时价值。</p>\n<p><strong>2. 空状态是杀手</strong></p>\n<p>新用户看到空列表 = 看到一个没用的 App。要么预填示例数据，要么把不需要数据的功能放在前面。</p>\n<p><strong>3. 留存问题先看结构，再看功能</strong></p>\n<p>Tab 顺序、默认页面、首次引导——这些\"结构性\"改动的效果往往比新功能大得多。</p>\n<p><strong>4. 数据小的时候，定性比定量重要</strong></p>\n<p>18 个活跃用户的留存率统计意义有限。但\"新用户打开看到空列表\"这个问题，不需要统计就能判断。</p>\n<p><strong>5. 克制是一种能力</strong></p>\n<p>不上付费、不加功能、不做社交——在 4% 留存面前，这些决定比\"做什么\"更难。</p>\n<hr>\n<p>留存的故事还在继续。下一篇聊获客——小红书内容是怎么驱动 App Store 下载的，211 次下载背后的完整漏斗。</p>",
            "url": "https://real-tech.online/blog/zhi-value-retention-struggle",
            "title": "日均开发实录③：独立开发者的留存困局——从 4% 到破局之路",
            "summary": "D1 留存 12%，D7 留存 4%。",
            "date_modified": "2026-04-26T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：日均开发实录",
                "独立开发",
                "iOS",
                "日均"
            ]
        },
        {
            "id": "https://real-tech.online/blog/zhi-value-design-system",
            "content_html": "<p>独立开发者最容易忽略的事情之一：设计系统。不是说要做一套 Material Design 那样的巨型规范，而是——你的 App 看起来像是同一个人做的吗？</p>\n<p>日均的设计关键词是四个字：<strong>温暖极简</strong>。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"为什么需要设计系统\">为什么需要设计系统<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%E8%AE%BE%E8%AE%A1%E7%B3%BB%E7%BB%9F\" class=\"hash-link\" aria-label=\"为什么需要设计系统的直接链接\" title=\"为什么需要设计系统的直接链接\">​</a></h2>\n<p>一个人做 App，最常见的状态是：这个页面用了蓝色，那个页面用了绿色，按钮有的圆角 8px 有的 16px，字号从 12 到 18 随机分布。</p>\n<p>不是审美问题，是效率问题。每次写新页面都要重新决定颜色、间距、字号，这些决策消耗的心智资源比你想象的多。</p>\n<p>所以在写第一行 SwiftUI 代码之前，我先做了一件事：<strong>用 HTML 原型定义设计语言</strong>。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"设计理念温暖极简\">设计理念：温暖极简<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E8%AE%BE%E8%AE%A1%E7%90%86%E5%BF%B5%E6%B8%A9%E6%9A%96%E6%9E%81%E7%AE%80\" class=\"hash-link\" aria-label=\"设计理念：温暖极简的直接链接\" title=\"设计理念：温暖极简的直接链接\">​</a></h2>\n<blockquote>\n<p>干净但不冷漠。App 应该像一个值得信赖的朋友帮你思考，而不是一张电子表格。</p>\n</blockquote>\n<p>参考对象：</p>\n<ul>\n<li><strong>Apple Notes</strong> 的简洁</li>\n<li><strong>Notion</strong> 的卡片布局</li>\n<li><strong>温暖色调</strong>（不是纯白纯黑）</li>\n</ul>\n<p>关键决策：背景色不用 <code>#FFFFFF</code>，用暖米色 <code>#F7F5F2</code>。这一个决定就让整个 App 的感觉从\"工具\"变成了\"生活\"。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"色彩系统四种情绪\">色彩系统：四种情绪<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E8%89%B2%E5%BD%A9%E7%B3%BB%E7%BB%9F%E5%9B%9B%E7%A7%8D%E6%83%85%E7%BB%AA\" class=\"hash-link\" aria-label=\"色彩系统：四种情绪的直接链接\" title=\"色彩系统：四种情绪的直接链接\">​</a></h2>\n<p>日均的色彩不是随便选的，每种颜色对应一种情绪状态：</p>\n<table><thead><tr><th>颜色</th><th>色值</th><th>情绪</th><th>使用场景</th></tr></thead><tbody><tr><td>薄荷绿</td><td><code>#3D9E7E</code></td><td>正向 / 值得</td><td>品牌主色、CTA、成本下降</td></tr><tr><td>蓝色</td><td><code>#3A78B5</code></td><td>中性 / 追踪中</td><td>冷静清单、按时间追踪</td></tr><tr><td>橙色</td><td><code>#E8A87C</code></td><td>警告 / 偏贵</td><td>高成本提醒、紧急冷静</td></tr><tr><td>紫色</td><td><code>#7952D4</code></td><td>决策 / 反思</td><td>冷静详情、倒计时</td></tr></tbody></table>\n<p>这套颜色系统的好处是：用户不需要读文字，看颜色就知道这个物品的状态。绿色 = 值，橙色 = 贵，紫色 = 再想想。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"卡片设计克制的阴影\">卡片设计：克制的阴影<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E5%8D%A1%E7%89%87%E8%AE%BE%E8%AE%A1%E5%85%8B%E5%88%B6%E7%9A%84%E9%98%B4%E5%BD%B1\" class=\"hash-link\" aria-label=\"卡片设计：克制的阴影的直接链接\" title=\"卡片设计：克制的阴影的直接链接\">​</a></h2>\n<p>日均的卡片设计有一个原则：<strong>阴影极其克制</strong>。</p>\n<div class=\"language-css codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-css codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token property\" style=\"color:hsl(5, 74%, 59%)\">box-shadow</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token unit\">px</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">12</span><span class=\"token unit\">px</span><span class=\"token plain\"> </span><span class=\"token color function\" style=\"color:hsl(221, 87%, 60%)\">rgba</span><span class=\"token color punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token color number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token color punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token color number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token color punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token color number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token color punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token color number\" style=\"color:hsl(35, 99%, 36%)\">0.06</span><span class=\"token color punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>0.06 的透明度。大多数 App 用 0.1 到 0.2，日均刻意压低。原因是：暖米色背景 + 重阴影 = 脏。轻阴影让卡片\"浮\"起来，但不会抢视线。</p>\n<p>卡片的其他规范：</p>\n<ul>\n<li>圆角 20px（大卡片）、16px（小元素）</li>\n<li>内边距 16–18px</li>\n<li>背景纯白 <code>#FFFFFF</code></li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"数字的温度生活类比\">数字的温度：生活类比<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E6%95%B0%E5%AD%97%E7%9A%84%E6%B8%A9%E5%BA%A6%E7%94%9F%E6%B4%BB%E7%B1%BB%E6%AF%94\" class=\"hash-link\" aria-label=\"数字的温度：生活类比的直接链接\" title=\"数字的温度：生活类比的直接链接\">​</a></h2>\n<p>设计系统不只是视觉，还包括文案。日均最重要的设计决策之一是<strong>生活类比</strong>。</p>\n<p>\"日均 ¥16\" 是冰冷的数字。但 \"≈ 一杯咖啡\" 立刻有了温度。</p>\n<p>这个设计贯穿整个 App：</p>\n<ul>\n<li>算一算结果页：大数字 + 判断标签 + 生活类比，三层信息交错动画展示</li>\n<li>物品卡片：右上角用颜色色块暗示价值判断</li>\n<li>进度条：渐变填充，用得越多颜色越\"满\"</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"动画原则冷静克制\">动画原则：冷静克制<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E5%8A%A8%E7%94%BB%E5%8E%9F%E5%88%99%E5%86%B7%E9%9D%99%E5%85%8B%E5%88%B6\" class=\"hash-link\" aria-label=\"动画原则：冷静克制的直接链接\" title=\"动画原则：冷静克制的直接链接\">​</a></h2>\n<p>日均的动画有一条红线：<strong>不用弹性/弹跳动画</strong>。</p>\n<div class=\"language-swift codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-swift codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">animation</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">easeInOut</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">duration</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.25</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> value</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">:</span><span class=\"token plain\"> someState</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>原因很简单：日均帮用户做理性决策，弹跳动画传递的是\"活泼\"和\"兴奋\"，跟产品气质不符。</p>\n<p>动画规范：</p>\n<ul>\n<li>过渡动画 0.25s</li>\n<li>展示动画 0.3s</li>\n<li>交错展示：元素间 0.3s 延迟</li>\n<li>缓动函数统一 <code>.easeInOut</code></li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"emoji-作为视觉标识\">Emoji 作为视觉标识<a href=\"https://real-tech.online/blog/zhi-value-design-system#emoji-%E4%BD%9C%E4%B8%BA%E8%A7%86%E8%A7%89%E6%A0%87%E8%AF%86\" class=\"hash-link\" aria-label=\"Emoji 作为视觉标识的直接链接\" title=\"Emoji 作为视觉标识的直接链接\">​</a></h2>\n<p>一个省钱的设计决策：用 Emoji 代替自定义图标作为物品的主要视觉标识。</p>\n<p>好处：</p>\n<ol>\n<li>零设计成本</li>\n<li>用户自选，有归属感</li>\n<li>跨平台一致</li>\n<li>放在 42px 圆角色块中，配合主题色，效果不输自定义图标</li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"营销视觉一致性\">营销视觉一致性<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E8%90%A5%E9%94%80%E8%A7%86%E8%A7%89%E4%B8%80%E8%87%B4%E6%80%A7\" class=\"hash-link\" aria-label=\"营销视觉一致性的直接链接\" title=\"营销视觉一致性的直接链接\">​</a></h2>\n<p>设计系统不止于 App 内部。小红书封面、App Store 截图都遵循同一套规范：</p>\n<ul>\n<li>薄荷绿主色</li>\n<li>暖米色背景（不用纯白纯黑）</li>\n<li>大数字用粗体</li>\n<li>Emoji 作为视觉锚点</li>\n<li>温暖感，不要企业感</li>\n</ul>\n<p>这让用户从小红书看到封面，到 App Store 看到截图，到打开 App，视觉体验是连贯的。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"给独立开发者的建议\">给独立开发者的建议<a href=\"https://real-tech.online/blog/zhi-value-design-system#%E7%BB%99%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E5%BB%BA%E8%AE%AE\" class=\"hash-link\" aria-label=\"给独立开发者的建议的直接链接\" title=\"给独立开发者的建议的直接链接\">​</a></h2>\n<ol>\n<li><strong>先定颜色，再写代码</strong> — 3-4 个主色 + 背景色 + 文字色，够了</li>\n<li><strong>背景色别用纯白</strong> — 加一点暖色（米色、浅灰），质感立刻不同</li>\n<li><strong>阴影要克制</strong> — 透明度 0.06-0.08，不要超过 0.1</li>\n<li><strong>统一圆角</strong> — 选 2-3 个值（比如 12/16/20），全局复用</li>\n<li><strong>文案也是设计</strong> — \"计算\"不如\"看看值不值\"，\"确认\"不如\"开始追踪\"</li>\n</ol>\n<p>设计系统不需要完美，需要<strong>一致</strong>。一致性本身就是专业感。</p>\n<p>下一篇聊留存——D7 留存 4%，我是怎么诊断问题并尝试破局的。</p>",
            "url": "https://real-tech.online/blog/zhi-value-design-system",
            "title": "日均开发实录②：一个人做 iOS App 的设计系统——日均的温暖极简风格",
            "summary": "独立开发者最容易忽略的事情之一：设计系统。不是说要做一套 Material Design 那样的巨型规范，而是——你的 App 看起来像是同一个人做的吗？",
            "date_modified": "2026-04-25T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：日均开发实录",
                "独立开发",
                "iOS",
                "日均"
            ]
        },
        {
            "id": "https://real-tech.online/blog/zhi-value-product-positioning",
            "content_html": "<p>做「日均」之前，我问自己一个问题：市面上记账 App 已经几百个了，我为什么还要做一个跟钱有关的工具？</p>\n<p>答案是——我不做记账。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"一个消费者的真实困惑\">一个消费者的真实困惑<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E4%B8%80%E4%B8%AA%E6%B6%88%E8%B4%B9%E8%80%85%E7%9A%84%E7%9C%9F%E5%AE%9E%E5%9B%B0%E6%83%91\" class=\"hash-link\" aria-label=\"一个消费者的真实困惑的直接链接\" title=\"一个消费者的真实困惑的直接链接\">​</a></h2>\n<p>买了一台 ¥2,980 的投影仪。买的时候觉得贵，用了半年后觉得——其实每天才 ¥16，比去电影院便宜多了。</p>\n<p>但买了一双 ¥800 的跑鞋，穿了三次就扔在鞋柜里。每次 ¥267。</p>\n<p><strong>问题不是\"花了多少钱\"，而是\"这钱花得值不值\"。</strong></p>\n<p>这个视角转换，就是日均的全部。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"不做什么比做什么更重要\">不做什么，比做什么更重要<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E4%B8%8D%E5%81%9A%E4%BB%80%E4%B9%88%E6%AF%94%E5%81%9A%E4%BB%80%E4%B9%88%E6%9B%B4%E9%87%8D%E8%A6%81\" class=\"hash-link\" aria-label=\"不做什么，比做什么更重要的直接链接\" title=\"不做什么，比做什么更重要的直接链接\">​</a></h2>\n<p>在定位日均的时候，我花了很多时间想清楚<strong>不做什么</strong>：</p>\n<ul>\n<li>❌ 不做记账 — 不追踪收入，不做分类，不做预算</li>\n<li>❌ 不做购物助手 — 不比价，不找优惠券</li>\n<li>❌ 不做理财顾问 — 不提供投资建议</li>\n<li>❌ 不做极简主义 App — 不评判你买什么</li>\n</ul>\n<p>日均只回答一个问题：<strong>这笔钱，值不值？</strong></p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"竞品分析找到空白地带\">竞品分析：找到空白地带<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E7%AB%9E%E5%93%81%E5%88%86%E6%9E%90%E6%89%BE%E5%88%B0%E7%A9%BA%E7%99%BD%E5%9C%B0%E5%B8%A6\" class=\"hash-link\" aria-label=\"竞品分析：找到空白地带的直接链接\" title=\"竞品分析：找到空白地带的直接链接\">​</a></h2>\n<table><thead><tr><th>竞品类型</th><th>它们做什么</th><th>日均的差异</th></tr></thead><tbody><tr><td>鲨鱼记账 / 随手记</td><td>完整记账——收入、支出、分类、预算</td><td>日均不做记账，只做判断</td></tr><tr><td>钱迹</td><td>轻量记账</td><td>仍以追踪为核心，日均以判断为核心</td></tr><tr><td>各种\"日均计算器\"小程序</td><td>一次性计算，不追踪</td><td>日均长期追踪——用得越多，数字越好看</td></tr></tbody></table>\n<p>空白地带在哪？<strong>即时计算 + 长期追踪 + 行为干预</strong>，三者结合在一个轻量的包里。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"核心价值我们真正在卖什么\">核心价值：我们真正在卖什么<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E6%A0%B8%E5%BF%83%E4%BB%B7%E5%80%BC%E6%88%91%E4%BB%AC%E7%9C%9F%E6%AD%A3%E5%9C%A8%E5%8D%96%E4%BB%80%E4%B9%88\" class=\"hash-link\" aria-label=\"核心价值：我们真正在卖什么的直接链接\" title=\"核心价值：我们真正在卖什么的直接链接\">​</a></h2>\n<p>不是功能，是三种感受：</p>\n<ol>\n<li><strong>减少后悔</strong> — \"还好我想了想\"（冷静清单）</li>\n<li><strong>验证消费</strong> — \"这个其实挺值的\"（日均成本追踪）</li>\n<li><strong>新视角</strong> — \"我从来没这么想过\"（从总价到日均/次均）</li>\n</ol>\n<p>这不是功能堆砌，是一次消费认知的升级。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"判断算法把感觉变成数字\">判断算法：把感觉变成数字<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E5%88%A4%E6%96%AD%E7%AE%97%E6%B3%95%E6%8A%8A%E6%84%9F%E8%A7%89%E5%8F%98%E6%88%90%E6%95%B0%E5%AD%97\" class=\"hash-link\" aria-label=\"判断算法：把感觉变成数字的直接链接\" title=\"判断算法：把感觉变成数字的直接链接\">​</a></h2>\n<p>v1.2 加入了\"算一算\"功能，核心是一套判断算法：</p>\n<table><thead><tr><th>日均成本</th><th>判断</th><th>生活类比</th></tr></thead><tbody><tr><td>&lt; ¥3</td><td>👍 非常值得</td><td>≈ 一瓶水</td></tr><tr><td>¥3–10</td><td>👍 值得</td><td>≈ 一杯咖啡</td></tr><tr><td>¥10–30</td><td>🤔 还行</td><td>≈ 一顿早餐</td></tr><tr><td>¥30–60</td><td>⚠️ 偏高</td><td>≈ 一顿外卖</td></tr><tr><td>¥60–100</td><td>⚠️ 需要想想</td><td>≈ 一顿正餐</td></tr><tr><td>&gt; ¥100</td><td>❌ 冲动风险</td><td>≈ 一天生活费</td></tr></tbody></table>\n<p><strong>生活类比</strong>是关键设计决策。\"日均 ¥16\" 是个抽象数字，但\"每天一杯咖啡的钱\"立刻有了体感。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"目标用户谁会用这个\">目标用户：谁会用这个？<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E7%9B%AE%E6%A0%87%E7%94%A8%E6%88%B7%E8%B0%81%E4%BC%9A%E7%94%A8%E8%BF%99%E4%B8%AA\" class=\"hash-link\" aria-label=\"目标用户：谁会用这个？的直接链接\" title=\"目标用户：谁会用这个？的直接链接\">​</a></h2>\n<p>我定义了三类用户画像，但营销主攻第二类：</p>\n<ol>\n<li><strong>理性优化型</strong> — 买前做功课，想量化\"值不值\"</li>\n<li><strong>冲动消费型</strong> — 频繁网购，事后愧疚（小红书受众最大）</li>\n<li><strong>自我提升型</strong> — 想养成更好的消费习惯</li>\n</ol>\n<p>为什么主攻冲动消费型？因为他们的痛点最强烈，小红书传播潜力最大，而且产品的\"冷静清单\"功能直接解决他们的问题。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"变现策略先留存后收费\">变现策略：先留存，后收费<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E5%8F%98%E7%8E%B0%E7%AD%96%E7%95%A5%E5%85%88%E7%95%99%E5%AD%98%E5%90%8E%E6%94%B6%E8%B4%B9\" class=\"hash-link\" aria-label=\"变现策略：先留存，后收费的直接链接\" title=\"变现策略：先留存，后收费的直接链接\">​</a></h2>\n<p>一个反直觉的决定：<strong>v1.0 到 v1.3 全部功能免费</strong>。</p>\n<p>不是因为不想赚钱，而是数据告诉我时机不对：</p>\n<ul>\n<li>D1 留存 12%，D7 留存 4%</li>\n<li>活跃用户十几个</li>\n<li>瓶颈是留存，不是变现</li>\n</ul>\n<p>付费上线的前提条件（缺一不可）：</p>\n<ul>\n<li>D7 留存 &gt; 25%</li>\n<li>周活跃用户 &gt; 500</li>\n<li>用户平均追踪物品数 &gt; 3</li>\n</ul>\n<p>在这之前，把最强留存工具（小组件、通知）锁在付费后面 = 自断留存。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"北极星指标\">北极星指标<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E5%8C%97%E6%9E%81%E6%98%9F%E6%8C%87%E6%A0%87\" class=\"hash-link\" aria-label=\"北极星指标的直接链接\" title=\"北极星指标的直接链接\">​</a></h2>\n<p>最终选定：<strong>每周活跃追踪物品数</strong>。</p>\n<p>这个指标同时衡量了获客（新增物品）和留存（用户回来记录使用），比 DAU 更能反映产品的真实健康度。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"回头看\">回头看<a href=\"https://real-tech.online/blog/zhi-value-product-positioning#%E5%9B%9E%E5%A4%B4%E7%9C%8B\" class=\"hash-link\" aria-label=\"回头看的直接链接\" title=\"回头看的直接链接\">​</a></h2>\n<p>做日均最大的收获不是技术，是学会了<strong>克制</strong>。</p>\n<p>一个人做产品，最大的诱惑是什么都想加。但日均的核心竞争力恰恰是它<strong>不做什么</strong>——不做记账、不做预算、不做比价。只做一件事：帮你看清每一笔消费的真实成本。</p>\n<p>下一篇聊聊设计——一个人怎么从零建立一套完整的设计系统。</p>",
            "url": "https://real-tech.online/blog/zhi-value-product-positioning",
            "title": "日均开发实录①：从想法到上架——日均 App 的产品定位思考",
            "summary": "做「日均」之前，我问自己一个问题：市面上记账 App 已经几百个了，我为什么还要做一个跟钱有关的工具？",
            "date_modified": "2026-04-24T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：日均开发实录",
                "独立开发",
                "iOS",
                "日均"
            ]
        },
        {
            "id": "https://real-tech.online/blog/refactor-with-kiro-cli",
            "content_html": "<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"problem-context\">Problem Context<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#problem-context\" class=\"hash-link\" aria-label=\"Problem Context的直接链接\" title=\"Problem Context的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"问题背景\">问题背景<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E9%97%AE%E9%A2%98%E8%83%8C%E6%99%AF\" class=\"hash-link\" aria-label=\"问题背景的直接链接\" title=\"问题背景的直接链接\">​</a></h3>\n<p><strong>原有架构问题：</strong></p>\n<ul>\n<li>使用 Docusaurus 文档站，但内容既不是产品文档也不是系统教程</li>\n<li>零散技术笔记用文档形式组织，维护成本高</li>\n<li>无法展示实际项目（如 Peer Drop）</li>\n<li>每次添加内容需要思考目录结构，心理负担大</li>\n</ul>\n<p><strong>为什么需要解决：</strong></p>\n<ul>\n<li>网站定位与实际内容不匹配，影响访问者理解</li>\n<li>缺少产品展示，无法体现实际项目进展</li>\n<li>维护成本高导致更新频率低</li>\n</ul>\n<p><strong>常见替代方案：</strong></p>\n<ul>\n<li>继续使用文档站，逐步调整结构（耗时且效果有限）</li>\n<li>完全重写网站（投入过大，容易放弃）</li>\n<li>迁移到其他平台（如 WordPress，失去技术控制力）</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"practice-record\">Practice Record<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#practice-record\" class=\"hash-link\" aria-label=\"Practice Record的直接链接\" title=\"Practice Record的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"采用的方案\">采用的方案<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E9%87%87%E7%94%A8%E7%9A%84%E6%96%B9%E6%A1%88\" class=\"hash-link\" aria-label=\"采用的方案的直接链接\" title=\"采用的方案的直接链接\">​</a></h3>\n<p>使用 kiro-cli（AI 编程助手）辅助重构，人工负责战略决策，AI 负责执行层工作。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"实施步骤\">实施步骤<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E5%AE%9E%E6%96%BD%E6%AD%A5%E9%AA%A4\" class=\"hash-link\" aria-label=\"实施步骤的直接链接\" title=\"实施步骤的直接链接\">​</a></h3>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"1-禁用文档系统\">1. 禁用文档系统<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#1-%E7%A6%81%E7%94%A8%E6%96%87%E6%A1%A3%E7%B3%BB%E7%BB%9F\" class=\"hash-link\" aria-label=\"1. 禁用文档系统的直接链接\" title=\"1. 禁用文档系统的直接链接\">​</a></h4>\n<p>修改 Docusaurus 配置文件，禁用 docs 插件，只保留博客插件。这样原有的文档结构会被转换为按时间线组织的博客文章。</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"2-转换现有文档为博客\">2. 转换现有文档为博客<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#2-%E8%BD%AC%E6%8D%A2%E7%8E%B0%E6%9C%89%E6%96%87%E6%A1%A3%E4%B8%BA%E5%8D%9A%E5%AE%A2\" class=\"hash-link\" aria-label=\"2. 转换现有文档为博客的直接链接\" title=\"2. 转换现有文档为博客的直接链接\">​</a></h4>\n<p>将文档目录下的文件迁移到博客目录，并为每篇文章添加博客必需的 front matter（包括标题、标签、发布日期等元数据）。AI 批量处理了 9 篇文档的转换工作。</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"3-创建产品展示系统\">3. 创建产品展示系统<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#3-%E5%88%9B%E5%BB%BA%E4%BA%A7%E5%93%81%E5%B1%95%E7%A4%BA%E7%B3%BB%E7%BB%9F\" class=\"hash-link\" aria-label=\"3. 创建产品展示系统的直接链接\" title=\"3. 创建产品展示系统的直接链接\">​</a></h4>\n<p>创建产品数据文件，定义产品的基本信息（名称、描述、链接、标签等）。然后创建产品卡片组件，用于在页面上展示产品，包含标题、描述、访问链接和 hover 动画效果。</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"4-配置多语言支持\">4. 配置多语言支持<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#4-%E9%85%8D%E7%BD%AE%E5%A4%9A%E8%AF%AD%E8%A8%80%E6%94%AF%E6%8C%81\" class=\"hash-link\" aria-label=\"4. 配置多语言支持的直接链接\" title=\"4. 配置多语言支持的直接链接\">​</a></h4>\n<p>配置 Docusaurus 的 i18n 插件，添加中文和英文两种语言支持。配置完成后，网站右上角会显示语言切换按钮，URL 会自动根据语言分开。</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"5-样式重构深色主题\">5. 样式重构（深色主题）<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#5-%E6%A0%B7%E5%BC%8F%E9%87%8D%E6%9E%84%E6%B7%B1%E8%89%B2%E4%B8%BB%E9%A2%98\" class=\"hash-link\" aria-label=\"5. 样式重构（深色主题）的直接链接\" title=\"5. 样式重构（深色主题）的直接链接\">​</a></h4>\n<p>自定义 CSS 变量和组件样式，采用深色背景配合绿色主题色，类似 Supabase 的设计风格。产品卡片使用毛玻璃效果和 hover 动画，提升视觉质感。</p>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"results\">Results<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#results\" class=\"hash-link\" aria-label=\"Results的直接链接\" title=\"Results的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"量化结果\">量化结果<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E9%87%8F%E5%8C%96%E7%BB%93%E6%9E%9C\" class=\"hash-link\" aria-label=\"量化结果的直接链接\" title=\"量化结果的直接链接\">​</a></h3>\n<table><thead><tr><th>指标</th><th>数值</th></tr></thead><tbody><tr><td>总耗时</td><td>3 小时</td></tr><tr><td>修改文件数</td><td>49 个</td></tr><tr><td>新增代码</td><td>12,517 行</td></tr><tr><td>删除代码</td><td>6,690 行</td></tr><tr><td>转换文档</td><td>9 篇</td></tr><tr><td>创建产品页</td><td>1 个（Peer Drop）</td></tr></tbody></table>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"功能成果\">功能成果<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E5%8A%9F%E8%83%BD%E6%88%90%E6%9E%9C\" class=\"hash-link\" aria-label=\"功能成果的直接链接\" title=\"功能成果的直接链接\">​</a></h3>\n<p><strong>重构前：</strong></p>\n<ul>\n<li>❌ 文档站结构，定位模糊</li>\n<li>❌ 无产品展示</li>\n<li>❌ 单语言（中文）</li>\n<li>❌ 朴素设计</li>\n</ul>\n<p><strong>重构后：</strong></p>\n<ul>\n<li>✅ 博客架构，清晰的时间线</li>\n<li>✅ 产品展示页面（What I Build）</li>\n<li>✅ 中英文双语切换</li>\n<li>✅ 现代化深色设计（Supabase 风格）</li>\n</ul>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"意外发现\">意外发现<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E6%84%8F%E5%A4%96%E5%8F%91%E7%8E%B0\" class=\"hash-link\" aria-label=\"意外发现的直接链接\" title=\"意外发现的直接链接\">​</a></h3>\n<ul>\n<li>Docusaurus 的文档转博客比预期简单（只需调整 front matter）</li>\n<li>AI 在处理重复性工作时效率极高（如批量添加 front matter）</li>\n<li>多语言配置的复杂度被高估了（Docusaurus 内置支持完善）</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"limitations--trade-offs\">Limitations &amp; Trade-offs<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#limitations--trade-offs\" class=\"hash-link\" aria-label=\"Limitations &amp; Trade-offs的直接链接\" title=\"Limitations &amp; Trade-offs的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"局限性\">局限性<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E5%B1%80%E9%99%90%E6%80%A7\" class=\"hash-link\" aria-label=\"局限性的直接链接\" title=\"局限性的直接链接\">​</a></h3>\n<p><strong>AI 辅助的边界：</strong></p>\n<ul>\n<li>AI 无法决定网站应该展示什么内容（战略决策）</li>\n<li>AI 无法判断设计风格是否符合个人品牌（审美决策）</li>\n<li>AI 无法保证技术选型的长期适用性（架构决策）</li>\n</ul>\n<p><strong>技术权衡：</strong></p>\n<ul>\n<li>从文档站改博客后，失去了文档的层级导航（但获得了时间线浏览）</li>\n<li>产品展示页面需要手动维护（但比集成 CMS 更轻量）</li>\n<li>多语言需要双倍翻译工作（但 Docusaurus 的 i18n 简化了流程）</li>\n</ul>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"不适用场景\">不适用场景<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E4%B8%8D%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF\" class=\"hash-link\" aria-label=\"不适用场景的直接链接\" title=\"不适用场景的直接链接\">​</a></h3>\n<ul>\n<li>需要复杂权限系统的内容管理</li>\n<li>需要实时协作的文档平台</li>\n<li>需要高度定制化设计的项目（AI 只能提供通用方案）</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"reusable-pattern\">Reusable Pattern<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#reusable-pattern\" class=\"hash-link\" aria-label=\"Reusable Pattern的直接链接\" title=\"Reusable Pattern的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"核心原则\">核心原则<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E6%A0%B8%E5%BF%83%E5%8E%9F%E5%88%99\" class=\"hash-link\" aria-label=\"核心原则的直接链接\" title=\"核心原则的直接链接\">​</a></h3>\n<p><strong>AI 辅助执行层工作模式：</strong></p>\n<blockquote>\n<p>人工负责战略决策（做什么、为什么做），AI 负责执行层工作（怎么做、具体代码）</p>\n</blockquote>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"操作指南\">操作指南<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97\" class=\"hash-link\" aria-label=\"操作指南的直接链接\" title=\"操作指南的直接链接\">​</a></h3>\n<p><strong>适用场景判断：</strong></p>\n<ol>\n<li>目标清晰，但执行步骤繁琐</li>\n<li>知道怎么做，但不想写重复代码</li>\n<li>需要快速验证想法，而非追求完美</li>\n</ol>\n<p><strong>工作流程：</strong></p>\n<ol>\n<li><strong>明确目标</strong> - 用自然语言描述想要什么</li>\n<li><strong>确认边界</strong> - 说明哪些需要人工决策</li>\n<li><strong>分步执行</strong> - 让 AI 按步骤输出，逐步验证</li>\n<li><strong>人工审查</strong> - 关键决策点暂停，人工确认</li>\n</ol>\n<p><strong>投入产出比计算：</strong></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">传统方式：需求分析</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">2h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">编码</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">8h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">调试</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">4h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> 14h</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">AI</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">辅助：需求分析</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">2h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">AI</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">执行</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">1h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">审查</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">1h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> 4h</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">节省时间：10h</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">71</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"相关实践\">相关实践<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E7%9B%B8%E5%85%B3%E5%AE%9E%E8%B7%B5\" class=\"hash-link\" aria-label=\"相关实践的直接链接\" title=\"相关实践的直接链接\">​</a></h3>\n<ul>\n<li>AI Agent 系统配置</li>\n<li>自动化工作流设计</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"citations--references\">Citations &amp; References<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#citations--references\" class=\"hash-link\" aria-label=\"Citations &amp; References的直接链接\" title=\"Citations &amp; References的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"工具使用\">工具使用<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8\" class=\"hash-link\" aria-label=\"工具使用的直接链接\" title=\"工具使用的直接链接\">​</a></h3>\n<ul>\n<li><a href=\"https://github.com/kiro-cli/kiro\" target=\"_blank\" rel=\"noopener noreferrer\">kiro-cli</a> - AI 编程助手，用于代码生成和重构</li>\n<li><a href=\"https://docusaurus.io/\" target=\"_blank\" rel=\"noopener noreferrer\">Docusaurus</a> - 静态网站生成器，支持博客和多语言</li>\n<li><a href=\"https://peer-drop.real-tech.online/\" target=\"_blank\" rel=\"noopener noreferrer\">Peer Drop</a> - P2P 文件传输工具（本项目产出）</li>\n</ul>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"进一步阅读\">进一步阅读<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#%E8%BF%9B%E4%B8%80%E6%AD%A5%E9%98%85%E8%AF%BB\" class=\"hash-link\" aria-label=\"进一步阅读的直接链接\" title=\"进一步阅读的直接链接\">​</a></h3>\n<ul>\n<li><a href=\"https://docusaurus.io/docs/blog\" target=\"_blank\" rel=\"noopener noreferrer\">Docusaurus 博客迁移指南</a></li>\n<li><a href=\"https://docusaurus.io/docs/i18n/introduction\" target=\"_blank\" rel=\"noopener noreferrer\">Docusaurus 国际化</a></li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"ai-extraction-hints\">AI Extraction Hints<a href=\"https://real-tech.online/blog/refactor-with-kiro-cli#ai-extraction-hints\" class=\"hash-link\" aria-label=\"AI Extraction Hints的直接链接\" title=\"AI Extraction Hints的直接链接\">​</a></h2>\n<hr>\n<p><strong>重构时间：</strong> 2026 年 1 月 22 日下午<br>\n<strong>总耗时：</strong> 3 小时<br>\n<strong>核心工具：</strong> AI 编程助手<br>\n<strong>关键收获：</strong> 不用自己写代码的感觉，真好</p>",
            "url": "https://real-tech.online/blog/refactor-with-kiro-cli",
            "title": "3 小时重构个人网站：AI 辅助执行层工作的实践记录",
            "summary": "记录使用 kiro-cli 在 3 小时内完成 Docusaurus 网站从文档站到博客 + 产品展示的重构过程，包含具体操作步骤、代码变更数据和 AI 协作边界反思",
            "date_modified": "2026-01-22T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "ai-tools",
                "docusaurus",
                "refactoring",
                "web-development",
                "automation"
            ]
        },
        {
            "id": "https://real-tech.online/blog/gitlab-gitlab-pipeline",
            "content_html": "<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"配置使用-gitlab-runner\">配置使用 Gitlab runner<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E9%85%8D%E7%BD%AE%E4%BD%BF%E7%94%A8-gitlab-runner\" class=\"hash-link\" aria-label=\"配置使用 Gitlab runner的直接链接\" title=\"配置使用 Gitlab runner的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"gitlab-runner-介绍\">Gitlab runner 介绍<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#gitlab-runner-%E4%BB%8B%E7%BB%8D\" class=\"hash-link\" aria-label=\"Gitlab runner 介绍的直接链接\" title=\"Gitlab runner 介绍的直接链接\">​</a></h3>\n<p>GitLab Runner是GitLab CI/CD系统中的一个组件，它负责执行构建和部署任务。<br>\n<!-- -->主要功能包括：</p>\n<ol>\n<li>执行构建任务： 当开发者提交代码时，GitLab Runner负责执行CI/CD流水线中定义的构建任务，例如编译代码、运行测试等。</li>\n<li>并行执行： GitLab Runner支持并行执行多个任务，这有助于提高构建和测试的效率。</li>\n<li>多平台支持： 它可以在不同的操作系统和环境中运行，例如Linux、macOS、Windows等，从而满足不同项目的需求。</li>\n<li>Docker支持： GitLab Runner可以与Docker集成，使构建和部署过程更加轻量和可移植。</li>\n<li>持续交付： GitLab Runner通过执行CI/CD流水线中的任务，支持自动化持续集成和交付流程，使团队能够更快地将软件交付到生产环境中。</li>\n</ol>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"安装-gitlab-runner-centos-79\">安装 Gitlab runner （CentOS 7.9）<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E5%AE%89%E8%A3%85-gitlab-runner-centos-79\" class=\"hash-link\" aria-label=\"安装 Gitlab runner （CentOS 7.9）的直接链接\" title=\"安装 Gitlab runner （CentOS 7.9）的直接链接\">​</a></h3>\n<p>由于 Gitlab runner 是运行在自己的服务器上，所以需要在自己的服务器上安装依赖</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">curl </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">LJO</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/rpm/gitlab-runner_amd64.rpm\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">rpm </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">i gitlab</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runner_amd64</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rpm</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">gitlab</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runner start</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<blockquote>\n<p>详细安装信息请参考 <a href=\"https://docs.gitlab.com/runner/install/\" target=\"_blank\" rel=\"noopener noreferrer\">https://docs.gitlab.com/runner/install/</a></p>\n</blockquote>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"注册-gitlab-runnercentos-79\">注册 Gitlab runner（CentOS 7.9）<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E6%B3%A8%E5%86%8C-gitlab-runnercentos-79\" class=\"hash-link\" aria-label=\"注册 Gitlab runner（CentOS 7.9）的直接链接\" title=\"注册 Gitlab runner（CentOS 7.9）的直接链接\">​</a></h3>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"获取-registration-token\">获取 registration token<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E8%8E%B7%E5%8F%96-registration-token\" class=\"hash-link\" aria-label=\"获取 registration token的直接链接\" title=\"获取 registration token的直接链接\">​</a></h4>\n<p>在项目页面中，选择 <code>Settings -&gt; CI/CD -&gt; Runners</code>, 在这里获取 URL 和 token</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"执行注册指令\">执行注册指令<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E6%89%A7%E8%A1%8C%E6%B3%A8%E5%86%8C%E6%8C%87%E4%BB%A4\" class=\"hash-link\" aria-label=\"执行注册指令的直接链接\" title=\"执行注册指令的直接链接\">​</a></h4>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">gitlab</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runner register \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">non</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">interactive \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">url </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"$GITLAB_URL\"</span><span class=\"token plain\"> \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">token </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"$RUNNER_TOKEN\"</span><span class=\"token plain\"> \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">executor </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"docker\"</span><span class=\"token plain\"> \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">image alpine</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest \\</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">description </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"docker-runner\"</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>成功以后可以在项目 Runners 页面看到刚注册的 Gitlab runner</p>\n<h4 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"异常情况\">异常情况<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E5%BC%82%E5%B8%B8%E6%83%85%E5%86%B5\" class=\"hash-link\" aria-label=\"异常情况的直接链接\" title=\"异常情况的直接链接\">​</a></h4>\n<ol>\n<li>在 Gitlab runner 运行时出现 no permitted 权限问题<br>\n<!-- -->找到 gitlab-runner的配置文件，一般在 <code>/etc/gitlab-runner/config.toml</code>, 找到对应的 gitlab runner 配置， 将 <code>privileged = false</code> 修改 <code>privileged = true</code>, 重新启动。</li>\n</ol>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">gitlab</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runner restart</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"编写-gitlab-ciyml\">编写 <code>.gitlab-ci.yml</code><a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E7%BC%96%E5%86%99-gitlab-ciyml\" class=\"hash-link\" aria-label=\"编写-gitlab-ciyml的直接链接\" title=\"编写-gitlab-ciyml的直接链接\">​</a></h2>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"gitlab-ciyml-介绍\"><code>.gitlab-ci.yml</code> 介绍<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#gitlab-ciyml-%E4%BB%8B%E7%BB%8D\" class=\"hash-link\" aria-label=\"gitlab-ciyml-介绍的直接链接\" title=\"gitlab-ciyml-介绍的直接链接\">​</a></h3>\n<p><code>.gitlab-ci.yml</code> 是GitLab CI/CD的配置文件，用于定义项目的持续集成和持续交付（CI/CD）流水线。这个文件采用YAML（YAML Ain't Markup Language）格式，以清晰且易读的方式描述了构建、测试、部署等任务的执行步骤和规则。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"基本结构和内容\">基本结构和内容<a href=\"https://real-tech.online/blog/gitlab-gitlab-pipeline#%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84%E5%92%8C%E5%86%85%E5%AE%B9\" class=\"hash-link\" aria-label=\"基本结构和内容的直接链接\" title=\"基本结构和内容的直接链接\">​</a></h3>\n<p>一个简单的<code>.gitlab-ci.yml</code>文件可能包含以下部分：</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">stages</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> build</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> test</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> deploy</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">variables</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">APP_NAME</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"my-app\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">before_script</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> echo </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"Setting up environment...\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">build</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">stage</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> build</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">script</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> echo </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"Building the application...\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">test</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">stage</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> test</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">script</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> echo </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"Running tests...\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">deploy</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">stage</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> deploy</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">script</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> echo </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"Deploying to production...\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">only</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> master</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<ul>\n<li><code>stages</code> 部分定义了流水线的阶段，每个阶段包含一个或多个任务。</li>\n<li><code>variables</code> 部分用于定义全局变量，可以在整个流水线中使用。</li>\n<li><code>before_script</code> 部分包含在每个任务执行之前运行的脚本。</li>\n<li><code>build</code>, <code>test</code>, 和 <code>deploy</code> 是具体的任务，每个任务包含一个或多个脚本命令。</li>\n</ul>",
            "url": "https://real-tech.online/blog/gitlab-gitlab-pipeline",
            "title": "GitLab CICD",
            "summary": "配置使用 Gitlab runner",
            "date_modified": "2026-01-08T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "cicd",
                "gitlab",
                "pipeline"
            ]
        },
        {
            "id": "https://real-tech.online/blog/offline-install-mysql-8",
            "content_html": "<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"本文内容\">本文内容<a href=\"https://real-tech.online/blog/offline-install-mysql-8#%E6%9C%AC%E6%96%87%E5%86%85%E5%AE%B9\" class=\"hash-link\" aria-label=\"本文内容的直接链接\" title=\"本文内容的直接链接\">​</a></h2>\n<ul>\n<li>通过 binary 方式部署 MySQL8</li>\n<li>为 MySQL8 配置 Service 并设置开机启动</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"背景描述\">背景描述<a href=\"https://real-tech.online/blog/offline-install-mysql-8#%E8%83%8C%E6%99%AF%E6%8F%8F%E8%BF%B0\" class=\"hash-link\" aria-label=\"背景描述的直接链接\" title=\"背景描述的直接链接\">​</a></h2>\n<ul>\n<li>服务器访问不到内网，软件只能离线部署</li>\n<li>服务器的 OS 版本为 CentOS 7.9</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"安装包准备\">安装包准备<a href=\"https://real-tech.online/blog/offline-install-mysql-8#%E5%AE%89%E8%A3%85%E5%8C%85%E5%87%86%E5%A4%87\" class=\"hash-link\" aria-label=\"安装包准备的直接链接\" title=\"安装包准备的直接链接\">​</a></h2>\n<p>点击进入 <a href=\"https://downloads.mysql.com/archives/community/\" target=\"_blank\" rel=\"noopener noreferrer\">MySQL 安装包官方下载地址</a>，选择我们服务器对应的安装包。在这里我选择的是</p>\n<ul>\n<li>Product Version: 8.0.33</li>\n<li>Operating System: Red Hat Enterprise Linux / Oracle Linux</li>\n<li>OS Version: Red Hat Enterprise Linux 7 / Oracle Linux 7 (x86, 64-bit)</li>\n</ul>\n<p>版本选择后可以看到最下方有 <strong>Compress TAR Archive</strong>, 点击右边的 <strong>Download</strong> 按钮下载。<br>\n<!-- -->如果你的OS版本和笔者一样，也直接点击  <a href=\"https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-el7-x86_64.tar.gz\" target=\"_blank\" rel=\"noopener noreferrer\">这里</a>  下载。<br>\n<!-- -->下载完毕后，我们得到安装包 <code>mysql-8.0.33-el7-x86_64.tar.gz</code></p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"mysql8安装\">MySQL8安装<a href=\"https://real-tech.online/blog/offline-install-mysql-8#mysql8%E5%AE%89%E8%A3%85\" class=\"hash-link\" aria-label=\"MySQL8安装的直接链接\" title=\"MySQL8安装的直接链接\">​</a></h2>\n<p>上传 MySQL8 安装包到服务器，解压并将解压后的目录移动到 <code>/usr/local/mysql</code></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ tar zxf mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">8.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.33</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">el7</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">x86_64</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">gz</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo mv mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">8.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.33</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">el7</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">x86_64 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>权限配置 (我打算将<code>/data/mysql</code>作为MySQL8的数据目录，所以在这里一并创建)</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo groupadd mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo useradd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">g mysql mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chown </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">R</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chmod </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">R</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">755</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo mkdir </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chown </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">R</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>编辑 MySQL 8 配置文件 <code>/etc/my.cnf</code></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo vi </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">my</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cnf</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token plain\">mysqld</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">log</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">error</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysqld</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">log</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">pid</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">file</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">pid</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">datadir</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">socket</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">lower_case_table_names</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token plain\">mysqld_safe</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">log</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">error</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysqld</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">log</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">pid</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">file</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">pid</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">datadir</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">socket</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">socket</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token plain\">mysqldump</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">socket</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<blockquote>\n<p>这里需要注意一点，MySQL8 只有在初始化的时候，才能修改 <code>lower_case_table_names</code>这个配置，所以大家一开始就需要根据实际场景，来配置 <code>lower_case_table_names</code>，避免后面出现不兼容的情况。<code>lower_case_table_names</code> 默认为0.</p>\n</blockquote>\n<p>初始化 MySQL8</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysqld </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">initialize </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">user</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">lower</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">case</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">table</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">names</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">datadir</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">basedir</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo grep </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">i password </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysqld</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">log</span><span class=\"token plain\"> </span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<blockquote>\n<p>最后一步执行完，可得到 MySQL8 的root临时密码，需要记录下来。比如这里我输出的是<br>\n<code>A temporary password is generated for root@localhost: XXXXXXX</code></p>\n</blockquote>\n<p>到这里 MySQL8 已经安装好了，接下来我们为 MySQL8 配置服务</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"配置-mysql8-service\">配置 MySQL8 Service<a href=\"https://real-tech.online/blog/offline-install-mysql-8#%E9%85%8D%E7%BD%AE-mysql8-service\" class=\"hash-link\" aria-label=\"配置 MySQL8 Service的直接链接\" title=\"配置 MySQL8 Service的直接链接\">​</a></h2>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo ln </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">s </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">support</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">files</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">server</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">init</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo ln </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">s </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo ln </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">s </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo vi </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">lib</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Unit</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Description</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token maybe-class-name\">MySQL</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Server</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">After</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">network</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">After</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">syslog</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">User</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Group</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Type</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">forking</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">PermissionsStartOnly</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token boolean\" style=\"color:hsl(35, 99%, 36%)\">true</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ExecStart</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">init</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql start</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ExecStop</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">init</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql stop</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ExecReload</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">init</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">mysql restart</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">LimitNOFILE</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">LimitNPROC</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Install</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">WantedBy</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">multi</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl daemon</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">reload</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl stop mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl restart mysql</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chkconfig mysql on</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>到这里 MySQL 8的服务已经正常配置且启动了，接下来我们用上面获取到的临时密码登录进去，并修改密码</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ mysql </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">uroot </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Enter</span><span class=\"token plain\"> password</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Welcome</span><span class=\"token plain\"> to the </span><span class=\"token maybe-class-name\">MySQL</span><span class=\"token plain\"> monitor</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">  </span><span class=\"token property-access maybe-class-name\">Commands</span><span class=\"token plain\"> end </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">with</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> or \\g</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access maybe-class-name\">Your</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MySQL</span><span class=\"token plain\"> connection id is </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">8</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Server</span><span class=\"token plain\"> version</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">8.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.33</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token function maybe-class-name\" style=\"color:hsl(221, 87%, 60%)\">Copyright</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">c</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2000</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2023</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Oracle</span><span class=\"token plain\"> and</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">or its affiliates</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access maybe-class-name\">Oracle</span><span class=\"token plain\"> is a registered trademark </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">of</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Oracle</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Corporation</span><span class=\"token plain\"> and</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">or its</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">affiliates</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token property-access maybe-class-name\">Other</span><span class=\"token plain\"> names may be trademarks </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">of</span><span class=\"token plain\"> their respective</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">owners</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access maybe-class-name\">Type</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'help;'</span><span class=\"token plain\"> or </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'\\h'</span><span class=\"token plain\"> </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> help</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token property-access maybe-class-name\">Type</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'\\c'</span><span class=\"token plain\"> to clear the current input statement</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> alter user </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'root'</span><span class=\"token plain\">@</span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'localhost'</span><span class=\"token plain\"> identified by </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">'123456'</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Query</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">OK</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> rows </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">affected</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.02</span><span class=\"token plain\"> sec</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> flush privileges</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Query</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">OK</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> rows </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">affected</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.01</span><span class=\"token plain\"> sec</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">mysql</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> exit</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Bye</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>自此 MySQL8 已经成功部署。</p>",
            "url": "https://real-tech.online/blog/offline-install-mysql-8",
            "title": "离线安装 - MySQL 8",
            "summary": "本文内容",
            "date_modified": "2026-01-07T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：离线部署",
                "devops",
                "docker",
                "kubernetes"
            ]
        },
        {
            "id": "https://real-tech.online/blog/offline-install-k3s",
            "content_html": "<ul>\n<li>通过binary方式部署轻量级kubernertes(K3S)</li>\n<li>配置K3S使用私有镜像仓库</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"部署背景\">部署背景<a href=\"https://real-tech.online/blog/offline-install-k3s#%E9%83%A8%E7%BD%B2%E8%83%8C%E6%99%AF\" class=\"hash-link\" aria-label=\"部署背景的直接链接\" title=\"部署背景的直接链接\">​</a></h2>\n<ul>\n<li>所在服务器访问不到外网，只能离线部署</li>\n<li>服务器OS版本为CentOS 7.9</li>\n<li>已经搭建好私有docker镜像仓库。（如没有可移步 <a href=\"https://real-tech.online/blog/offline-install-docker\">离线环境部署docker及私有镜像仓库</a>）</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"什么是k3s\">什么是K3S<a href=\"https://real-tech.online/blog/offline-install-k3s#%E4%BB%80%E4%B9%88%E6%98%AFk3s\" class=\"hash-link\" aria-label=\"什么是K3S的直接链接\" title=\"什么是K3S的直接链接\">​</a></h2>\n<blockquote>\n<p>K3s 是轻量级的 Kubernetes。K3s 易于安装，而且仅需要 Kubernetes 内存的一半，所有组件都在一个小于 100 MB 的二进制文件中。</p>\n</blockquote>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"安装包准备\">安装包准备<a href=\"https://real-tech.online/blog/offline-install-k3s#%E5%AE%89%E8%A3%85%E5%8C%85%E5%87%86%E5%A4%87\" class=\"hash-link\" aria-label=\"安装包准备的直接链接\" title=\"安装包准备的直接链接\">​</a></h2>\n<ol>\n<li><code>k3s-airgap-images-amd64.tar.gz</code>. K3S镜像包，下载地址 <a href=\"https://github.com/k3s-io/k3s/releases\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/k3s-io/k3s/releases</a> . 由于服务器的CPU是X86_64架构，所以选择 <code>amd64</code>版本.</li>\n<li><code>k3s</code>.K3S 可执行文件. 下载地址 <a href=\"https://github.com/k3s-io/k3s/releases\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/k3s-io/k3s/releases</a></li>\n<li><code>install.sh</code>. K3S安装脚本.下载地址 <a href=\"https://get.k3s.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://get.k3s.io</a></li>\n<li><code>k3s-selinux-1.4-1.el7.noarch.rpm</code>. 非必须，只有当你的服务器需要SELinux时才需要安装。下载地址<a href=\"https://github.com/k3s-io/k3s-selinux/releases/tag/v1.4.stable.1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/k3s-io/k3s-selinux/releases/tag/v1.4.stable.1</a></li>\n</ol>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"k3s安装\">K3S安装<a href=\"https://real-tech.online/blog/offline-install-k3s#k3s%E5%AE%89%E8%A3%85\" class=\"hash-link\" aria-label=\"K3S安装的直接链接\" title=\"K3S安装的直接链接\">​</a></h2>\n<p>将安装包上传到目标服务器,并放在同一个目录<br>\n<!-- -->安装SELinux支持（如不需要可跳过此步骤）<br>\n<!-- -->假如出现缺少container-selinux 依赖的报错，下载安装 <a href=\"http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.107-3.el7.noarch.rpm\" target=\"_blank\" rel=\"noopener noreferrer\">container-selinux-2.107-3.el7.noarch.rpm</a></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo rpm </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ivh container</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">selinux</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2.107</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">el7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">noarch</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rpm</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo rpm </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ivh k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">selinux</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1.4</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">el7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">noarch</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rpm</span><span class=\"token plain\"> </span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>关闭firewalld</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl disable firewalld </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">now</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>如果你希望保持firewalld的开启状态，那需要为K3S加几条规则</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ firewall</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">cmd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">permanent </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">add</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">port</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">6443</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">tcp #apiserver</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ firewall</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">cmd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">permanent </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">zone</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">trusted </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">add</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">source</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">10.42</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> #pods</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ firewall</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">cmd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">permanent </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">zone</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">trusted </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">add</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">source</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">10.43</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> #services</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ firewall</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">cmd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">reload</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>安装K3S</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo mkdir </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">lib</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">rancher</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">agent</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">images</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo cp </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">airgap</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">images</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">amd64</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">gz</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">lib</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">rancher</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">agent</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">images</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo cp </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chmod </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\">x </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INSTALL_K3S_SELINUX_WARN</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token boolean\" style=\"color:hsl(35, 99%, 36%)\">true</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INSTALL_K3S_SKIP_DOWNLOAD</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token boolean\" style=\"color:hsl(35, 99%, 36%)\">true</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">install</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sh</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">write</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">kubeconfig</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">mode</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">644</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Skipping</span><span class=\"token plain\"> k3s download and verify</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Skipping</span><span class=\"token plain\"> installation </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">of</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">SELinux</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">RPM</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">WARN</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Failed</span><span class=\"token plain\"> to find the k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">selinux policy</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> please install</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    yum install </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">y container</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">selinux</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    yum install </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">y https</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">rpm</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rancher</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">io</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">stable</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">common</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">centos</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">7</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">noarch</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">kubectl symlink to k3s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">crictl symlink to k3s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Skipping</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">ctr symlink to k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> command exists </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">in</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PATH</span><span class=\"token plain\"> at </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">ctr</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> killall script </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">killall</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sh</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> uninstall script </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">uninstall</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sh</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  env</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> environment file </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">env</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Creating</span><span class=\"token plain\"> service file </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Enabling</span><span class=\"token plain\"> k3s unit</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Created</span><span class=\"token plain\"> symlink </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">from</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">multi</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">wants</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"> to </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">INFO</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Starting</span><span class=\"token plain\"> k3s</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>参数说明:</p>\n<blockquote>\n<p>INSTALL_K3S_SELINUX_WARN=true: 当缺少<code>k3s-selinux</code>依赖时，也会继续安装<br>\n<!-- -->INSTALL_K3S_SKIP_DOWNLOAD=true: 跳过下载k3s安装包<br>\n<!-- -->--write-kubeconfig-mode=644: 修改k3s配置文件的权限，避免普通用户无法使用kubectl的情况</p>\n</blockquote>\n<p>验证</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ systemctl status k3s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">● k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Lightweight</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Kubernetes</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Loaded</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">loaded</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> enabled</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> vendor preset</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> disabled</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Active</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">active</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">running</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> since </span><span class=\"token maybe-class-name\">Sun</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2023</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">12</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">24</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">09</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">52</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">44</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">EST</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> 1min 4s ago</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">     </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Docs</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> https</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">io</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Process</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11405</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">ExecStartPre</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">sbin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">modprobe </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">overlay</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">code</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">exited</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> status</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">SUCCESS</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Process</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11402</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">ExecStartPre</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">sbin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">modprobe </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">br_netfilter</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">code</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">exited</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> status</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">SUCCESS</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Process</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11399</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">ExecStartPre</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">sh </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">xc </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">!</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemctl is</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">enabled </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">quiet nm</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">cloud</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">setup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token method function property-access\" style=\"color:hsl(221, 87%, 60%)\">service</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">code</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">exited</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> status</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">SUCCESS</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Main</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11408</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">server</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Tasks</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">59</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Memory</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">486</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">0M</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">CGroup</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">slice</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">           ├─</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11408</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s server</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">           └─</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11462</span><span class=\"token plain\"> containerd </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ kubectl </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">get</span><span class=\"token plain\"> pod </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">A</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NAMESPACE</span><span class=\"token plain\">     </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NAME</span><span class=\"token plain\">                                      </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">READY</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">STATUS</span><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">RESTARTS</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">AGE</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">kube</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">system   local</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">path</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">provisioner</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">84db5d44d9</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ws8wq   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">     </span><span class=\"token maybe-class-name\">Running</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">          19s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">kube</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">system   metrics</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">server</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">67c658944b</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">xj6mr           </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">     </span><span class=\"token maybe-class-name\">Running</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">          19s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">kube</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">system   coredns</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">6799fbcd5</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">6k2ff                   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">     </span><span class=\"token maybe-class-name\">Running</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">          19s</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>如果pod/coredns出现报错<code>plugin/forward: no nameservers found</code>,编辑configmap <code>kubectl edit cm coredns -n kube-system</code>, 将 <code>forward . /etc/resolv.conf</code>这一行注释。保存退出后，删除pod/coredns</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"私有镜像仓库配置\">私有镜像仓库配置<a href=\"https://real-tech.online/blog/offline-install-k3s#%E7%A7%81%E6%9C%89%E9%95%9C%E5%83%8F%E4%BB%93%E5%BA%93%E9%85%8D%E7%BD%AE\" class=\"hash-link\" aria-label=\"私有镜像仓库配置的直接链接\" title=\"私有镜像仓库配置的直接链接\">​</a></h2>\n<p>我们可以将容器配置为连接到私有镜像仓库，并在节点上使用私有镜像仓库拉取私有镜像。K3s在启动时会检查<code>/etc/rancher/k3s/</code>中是否存在<code>registries.yaml</code>文件，存在的话在启动容器的时候会使用该文件中定义的镜像仓库。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo vi </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">rancher</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">k3s</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registries</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">yaml</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">mirrors</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">  docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">io</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">endpoint</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">      </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"http://127.0.0.1:5000\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl restart k3s</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>比如上面的配置，当我们容器需要的镜像仓库是docker.io时，k3s会从127.0.0.1:5000仓库来拉取镜像。</p>",
            "url": "https://real-tech.online/blog/offline-install-k3s",
            "title": "离线安装 - K3S",
            "summary": "- 通过binary方式部署轻量级kubernertes(K3S)",
            "date_modified": "2026-01-06T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：离线部署",
                "devops",
                "docker",
                "kubernetes"
            ]
        },
        {
            "id": "https://real-tech.online/blog/offline-install-docker",
            "content_html": "<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"本文内容\">本文内容<a href=\"https://real-tech.online/blog/offline-install-docker#%E6%9C%AC%E6%96%87%E5%86%85%E5%AE%B9\" class=\"hash-link\" aria-label=\"本文内容的直接链接\" title=\"本文内容的直接链接\">​</a></h2>\n<ul>\n<li>通过binary方式安装docker，并注册成服务</li>\n<li>搭建docker私有镜像仓库</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"背景描述\">背景描述<a href=\"https://real-tech.online/blog/offline-install-docker#%E8%83%8C%E6%99%AF%E6%8F%8F%E8%BF%B0\" class=\"hash-link\" aria-label=\"背景描述的直接链接\" title=\"背景描述的直接链接\">​</a></h2>\n<ul>\n<li>所在的服务器是一个内网，无法访问到外网环境。</li>\n<li>服务器OS版本是 CentOS 7.9</li>\n</ul>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"安装docker\">安装docker<a href=\"https://real-tech.online/blog/offline-install-docker#%E5%AE%89%E8%A3%85docker\" class=\"hash-link\" aria-label=\"安装docker的直接链接\" title=\"安装docker的直接链接\">​</a></h2>\n<p>获取所需版本的docker binary包，官方链接在 <a href=\"https://download.docker.com/linux/static/stable/x86_64/\" target=\"_blank\" rel=\"noopener noreferrer\">https://download.docker.com/linux/static/stable/x86_64/</a>. 在这里我选择了最新版本的<code> docker-24.0.7.tgz</code></p>\n<p>将压缩包上传到目标服务器。</p>\n<p>解压压缩包，并把文件放在<code>/usr/bin/</code></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ tar zxvf docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">24.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tgz</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">init</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">dockerd</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">runc</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">ctr</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">shim</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">v2</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">proxy</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo cp docker</span><span class=\"token comment\" style=\"color:hsl(230, 4%, 64%)\">/* /usr/bin/</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>编写service文件</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ vim </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Unit</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Description</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token maybe-class-name\">Docker</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Application</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Container</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Engine</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Documentation</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">https</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docs</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">com</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">After</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">network</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">online</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token plain\"> firewalld</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Wants</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">network</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">online</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Type</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">notify</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## the </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">default</span><span class=\"token plain\"> is not to use systemd </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> cgroups because the delegate issues still</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## exists and systemd currently does not support the cgroup feature </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">set</span><span class=\"token plain\"> required</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> containers run by docker</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ExecStart</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">dockerd</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ExecReload</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">kill </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">s </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">HUP</span><span class=\"token plain\"> $</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">MAINPID</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token maybe-class-name\">Having</span><span class=\"token plain\"> non</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">zero </span><span class=\"token maybe-class-name\">Limit</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">*</span><span class=\"token plain\">s causes </span><span class=\"token dom variable\" style=\"color:hsl(221, 87%, 60%)\">performance</span><span class=\"token plain\"> problems due to accounting overhead</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">in</span><span class=\"token plain\"> the kernel</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token property-access maybe-class-name\">We</span><span class=\"token plain\"> recommend using cgroups to </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">do</span><span class=\"token plain\"> container</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">local accounting</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access maybe-class-name\">LimitNOFILE</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">infinity</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">LimitNPROC</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">infinity</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">LimitCORE</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">infinity</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token maybe-class-name\">Uncomment</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">TasksMax</span><span class=\"token plain\"> </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">if</span><span class=\"token plain\"> your systemd version supports it</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token maybe-class-name\">Only</span><span class=\"token plain\"> systemd </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">226</span><span class=\"token plain\"> and above support </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">this</span><span class=\"token plain\"> version</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token property-access\">#TasksMax</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">infinity</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">TimeoutStartSec</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">set</span><span class=\"token plain\"> delegate yes so that systemd does not reset the cgroups </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">of</span><span class=\"token plain\"> docker containers</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Delegate</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">yes</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## kill only the docker process</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> not all processes </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">in</span><span class=\"token plain\"> the cgroup</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">KillMode</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">process</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">## restart the docker process </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">if</span><span class=\"token plain\"> it exits prematurely</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Restart</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">on</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">failure</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">StartLimitBurst</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">StartLimitInterval</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">60s</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token maybe-class-name\">Install</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">WantedBy</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">multi</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">target</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>新增用户组 docker。其他用户需要有docker的执行权限，只需将用户加入docker用户组即可</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo groupadd docker</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo usermod </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">aG docker $</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">USER</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>启动docker service,并设置开机自启动</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo chmod </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\">x </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl daemon</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">reload</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl start docker</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo systemctl enable docker</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>验证</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ systemctl status docker                                                         </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">● docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Docker</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Application</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Container</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Engine</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Loaded</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">loaded</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">systemd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> enabled</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> vendor preset</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> disabled</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Active</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">active</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">running</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"> since </span><span class=\"token maybe-class-name\">Sun</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2023</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">12</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">24</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">02</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">13</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">06</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">EST</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> 1min 1s ago</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">     </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Docs</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> https</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docs</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">com</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Main</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1764</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">dockerd</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">CGroup</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">system</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">slice</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">service</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">           ├─</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1764</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">dockerd</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">           └─</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1771</span><span class=\"token plain\"> containerd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">config </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">run</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">toml</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">v</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Docker</span><span class=\"token plain\"> version </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">24.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> build afdd53b</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"搭建docker私有镜像仓库\">搭建docker私有镜像仓库<a href=\"https://real-tech.online/blog/offline-install-docker#%E6%90%AD%E5%BB%BAdocker%E7%A7%81%E6%9C%89%E9%95%9C%E5%83%8F%E4%BB%93%E5%BA%93\" class=\"hash-link\" aria-label=\"搭建docker私有镜像仓库的直接链接\" title=\"搭建docker私有镜像仓库的直接链接\">​</a></h2>\n<p>在一台可以访问到外网的服务器上面准备registry镜像包</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker pull registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Using</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">default</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">tag</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">latest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pulling</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">from</span><span class=\"token plain\"> library</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">c926b61bad3b</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pull</span><span class=\"token plain\"> complete </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">5501dced60f8</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pull</span><span class=\"token plain\"> complete </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">e875fe5e6b9c</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pull</span><span class=\"token plain\"> complete </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">21f4bf2f86f9</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pull</span><span class=\"token plain\"> complete </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">98513cca25bb</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pull</span><span class=\"token plain\"> complete </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Digest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> sha256</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">0a182cb82c93939407967d6d71d6caf11dcef0e5689c6afe2d60518e3b34ab86</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Status</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Downloaded</span><span class=\"token plain\"> newer image </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">docker</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">io</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">library</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker save </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">o registry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><span class=\"token plain\"> registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ gzip registry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>上传镜像包<code>registry.tar.gz</code>到目标服务器</p>\n<p>解压加载镜像</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ gunzip registry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">gz</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker load </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\"> registry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">tar</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">4693057ce236</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">626MB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">626MB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">f4285c491509</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">771</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">771</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">90d6ca1e837f</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">2MB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">2MB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">f79c4d8837b6</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">096kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">096kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">85f82aceeda3</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">048kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">048kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Loaded</span><span class=\"token plain\"> image</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2.8</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.2</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">9fe9a137fd00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">63MB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">63MB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">d9bce47b357e</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">771</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">771</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">6kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">afcdb1715fb3</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">17</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">55MB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">17</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">55MB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">9f383ae4f64d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">096kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">096kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">645ddea72735</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Loading</span><span class=\"token plain\"> layer </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">===</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token arrow operator\" style=\"color:hsl(221, 87%, 60%)\">=&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">048kB</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">048kB</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Loaded</span><span class=\"token plain\"> image</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>启动私有镜像仓库容器</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo mkdir </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker run </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">itd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">v </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">data</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">restart</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token plain\">always </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">name </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">private</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">registry registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">98cb5c25871b94420418094efb19f36c45c7fbe18274229e9f8c4b00328ec180</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>参数说明</p>\n<blockquote>\n<p>-itd：在容器中打开一个伪终端进行交互操作，并在后台运行<br>\n<!-- -->-v：映射目录, 将宿主机的/data/registry 映射到容器的/dcoker/registry<br>\n<!-- -->-p：映射端口, 将宿主机的5000端口映射到容器的5000端口</p>\n</blockquote>\n<p>测试上传镜像到private-registry</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker tag registry </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker push </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Using</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">default</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">tag</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">The</span><span class=\"token plain\"> push refers to repository </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">645ddea72735</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pushed</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">9f383ae4f64d</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pushed</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">afcdb1715fb3</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pushed</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">d9bce47b357e</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pushed</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">9fe9a137fd00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pushed</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">latest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> digest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> sha256</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">860f379a011eddfab604d9acfe3cf50b2d6e958026fb0f977132b0b083b1a3d7 size</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1363</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>测试下载镜像</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker rmi </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Untagged</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Untagged</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry@sha256</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">860f379a011eddfab604d9acfe3cf50b2d6e958026fb0f977132b0b083b1a3d7</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker pull </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Using</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">default</span><span class=\"token plain\"> </span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">tag</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">latest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Pulling</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">from</span><span class=\"token plain\"> registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Digest</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> sha256</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">860f379a011eddfab604d9acfe3cf50b2d6e958026fb0f977132b0b083b1a3d7</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Status</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Downloaded</span><span class=\"token plain\"> newer image </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">for</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">127.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>查看私有仓库镜像</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ curl http</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">localhost</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">v2</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">_catalog</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"repositories\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"registry\"</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>",
            "url": "https://real-tech.online/blog/offline-install-docker",
            "title": "离线安装 - Docker",
            "summary": "本文内容",
            "date_modified": "2026-01-05T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：离线部署",
                "devops",
                "docker",
                "kubernetes"
            ]
        },
        {
            "id": "https://real-tech.online/blog/docker-docker-fsroot",
            "content_html": "<p>在了解了Docker容器的2个基础技术 <a href=\"https://real-tech.online/blog/docker-docker-namespace\">Linux namespace</a> 和 <a href=\"https://real-tech.online/blog/docker-docker-cgroups\">Linux cgroup</a> 以后。我们来聊聊Docker镜像，也就是挂载在容器根分区<code>/</code>下面的文件系统，也叫做<strong>rootfs</strong>.</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"linux-rootfs\">Linux rootfs<a href=\"https://real-tech.online/blog/docker-docker-fsroot#linux-rootfs\" class=\"hash-link\" aria-label=\"Linux rootfs的直接链接\" title=\"Linux rootfs的直接链接\">​</a></h2>\n<p><strong>Linux rootfs</strong>，<strong>Linux Root File System</strong>, Linux 根文件系统，是包含在和根目录相同的分区上的文件系统，是内核启动时挂载的第一个文件系统。系统的引导启动进程，会在根文件系统挂载以后，把初始化脚本和服务等加载到内存中运行。而在Docker容器进程中，也有一个<strong>rootfs</strong>， 这个文件系统的主要功能是用来给容器进程提供隔离后的执行环境。它也有另外一个名字，叫做 <strong>Docker容器镜像</strong>。<br>\n<!-- -->有一个比较重要的点是，<strong>rootfs</strong> 只是一个操作系统所包含的文件、配置以及目录，并不包括操作系统内核。在Linux 操作系统中，<strong>文件系统和系统内核是分开存放的</strong>，操作系统只有在开机启动时，才会加载指定版本的内核。这就意味着，同一个宿主机上面的所有容器，都<strong>共享宿主机操作系统的内核</strong>。当容器进程需要配置内核参数、加载额外的内核模块和内核进行直接的交互时，实际上都是直接调用宿主机操作系统的内核。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"容器的-rootfs\">容器的 rootfs<a href=\"https://real-tech.online/blog/docker-docker-fsroot#%E5%AE%B9%E5%99%A8%E7%9A%84-rootfs\" class=\"hash-link\" aria-label=\"容器的 rootfs的直接链接\" title=\"容器的 rootfs的直接链接\">​</a></h2>\n<p>容器的 <strong>rootfs</strong> 自下而上分为三个部分，分别是，只读层（ro+wh），init层（ro+wh），读写层（rw）</p>\n<table><thead><tr><th style=\"text-align:center\">名称</th><th style=\"text-align:left\">描述</th></tr></thead><tbody><tr><td style=\"text-align:center\">只读层</td><td style=\"text-align:left\">对应 Docker 容器的镜像层，这部分不可被修改</td></tr><tr><td style=\"text-align:center\">init 层</td><td style=\"text-align:left\">夹在只读层和读写层之间，Docker 容器单独生成的一个内部层，专门用来存放 <code>/etc/hosts</code>、<code>/etc/resolv.conf</code>等信息</td></tr><tr><td style=\"text-align:center\">读写层</td><td style=\"text-align:left\">这一层的挂载方式是 <code>rw</code>，一旦在容器里做了写操作，你修改后的内容就会增量地出现在这个层中</td></tr></tbody></table>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"观察一个docker容器\">观察一个Docker容器<a href=\"https://real-tech.online/blog/docker-docker-fsroot#%E8%A7%82%E5%AF%9F%E4%B8%80%E4%B8%AAdocker%E5%AE%B9%E5%99%A8\" class=\"hash-link\" aria-label=\"观察一个Docker容器的直接链接\" title=\"观察一个Docker容器的直接链接\">​</a></h3>\n<blockquote>\n<p>在之前 <a href=\"https://real-tech.online/blog/offline-install-docker\">《离线环境部署docker环境》</a> 我们启动了一个registry容器，接下来我们来看看它的文件系统</p>\n</blockquote>\n<p>我们可以利用 <code>docker inspect</code> 指令来获取容器的详细信息</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker inspect </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">private</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">        </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"GraphDriver\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">            </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"Data\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"LowerDir\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"/var/lib/docker/overlay2/7d83a80fb09250a1ef49b37d20a0492b37b93db65e9a4b954f3c820a0f2ed106-init/diff:/var/lib/docker/overlay2/242007cc0f388dbb760a60b5e8b635a981b62b9dc170fd2c8aa02dc762426a10/diff:/var/lib/docker/overlay2/7d4c76a7d4f3cb5d5c3ebae69a45aac157060178cb29f113e1cfda1142ba9e88/diff:/var/lib/docker/overlay2/bf51aac76ea5da6532f53b5d4d833f69f479ffdc4033695ba6c9a400c3333649/diff:/var/lib/docker/overlay2/826cee954a8e9db6b13ffff58c333bc3071de9a569a0e6afd888b347c968f6db/diff:/var/lib/docker/overlay2/d4f5a3d3ae5157eb33cad7d3b24808f0420f55b61910f36c8026bfb18bd6b99b/diff\"</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"MergedDir\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"/var/lib/docker/overlay2/7d83a80fb09250a1ef49b37d20a0492b37b93db65e9a4b954f3c820a0f2ed106/merged\"</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"UpperDir\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"/var/lib/docker/overlay2/7d83a80fb09250a1ef49b37d20a0492b37b93db65e9a4b954f3c820a0f2ed106/diff\"</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"WorkDir\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"/var/lib/docker/overlay2/7d83a80fb09250a1ef49b37d20a0492b37b93db65e9a4b954f3c820a0f2ed106/work\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">            </span><span class=\"token string-property property\" style=\"color:hsl(5, 74%, 59%)\">\"Name\"</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"overlay2\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">}</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>我们可以看到，这个容器的用到的文件系统类型是 overlayfs, 这个是目前 Docker的默认类型。另外我们可以看到 <code>docker inspect</code> 的输出有4个类型的目录，镜像所挂载的目录层为 Lower 层，然后通过 Merged 展示所有的文件目录与文件。用户写入的所有文件都是在 UpperDir 目录,并且会在 UpperDir 建立于 Merged层展示的文件 目录结构, 所以用户就可以看到写入的文件。并且底层的镜像是不能被修改(如果挂载目 录为 UpperDir,则可以修改源镜像)。</p>",
            "url": "https://real-tech.online/blog/docker-docker-fsroot",
            "title": "Docker 原理：rootfs",
            "summary": "在了解了Docker容器的2个基础技术 Linux namespace 和 Linux cgroup 以后。我们来聊聊Docker镜像，也就是挂载在容器根分区/下面的文件系统，也叫做rootfs.",
            "date_modified": "2026-01-04T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：Docker原理",
                "docker",
                "linux"
            ]
        },
        {
            "id": "https://real-tech.online/blog/docker-docker-cgroups",
            "content_html": "<p>在 <a href=\"https://real-tech.online/blog/docker-docker-intro\">《5分钟Docker容器原理 | 开篇》</a> 中，我们提到，为了限制 <strong>Docker容器</strong> 运行时能够使用的最大资源，我们用到了 <strong>Linux cgroup</strong> 技术。这篇我们继续来了解下这个技术。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"linux-cgroup-介绍\">Linux cgroup 介绍<a href=\"https://real-tech.online/blog/docker-docker-cgroups#linux-cgroup-%E4%BB%8B%E7%BB%8D\" class=\"hash-link\" aria-label=\"Linux cgroup 介绍的直接链接\" title=\"Linux cgroup 介绍的直接链接\">​</a></h2>\n<p>在一个容器中，假如不对其进行资源限制，允许其使用无限大的内存和CPU资源，有时候因为一些内存泄漏，代码逻辑问题，把整个宿主机的内存资源和CPU资源全部占满，影响宿主机上其他进程的允许。为了避免这样的情况发生，我们就必须对容器进行资源限制。<br>\n<strong>Linux cgroup</strong>, 全称 <strong>Linux crontrol group</strong>, 最初是由Google的工程师提出，后被整合进Linux内核中。<strong>Linux cgroup</strong> 是一种可以限制、记录、隔离进程组（process groups）所使用的物理资源（如：内存、CPU、IO等）的机制。<br>\n<strong>Linux cgroup</strong> 的功能如下：</p>\n<table><thead><tr><th style=\"text-align:center\">功能</th><th style=\"text-align:left\">描述</th></tr></thead><tbody><tr><td style=\"text-align:center\">资源限制（Resource limitation）</td><td style=\"text-align:left\"><strong>cgroup</strong> 可以对进程组使用的<strong>资源总额</strong>进行限制。比如我们可以设置应用运行时内存上限时，一旦超过整个配额（quota）就会发出OOM（Out of Memory）</td></tr><tr><td style=\"text-align:center\">优先级分配（Prioritization）</td><td style=\"text-align:left\"><strong>cgroup</strong> 能够控制进程运行的优先级，实际上这个控制是通过限制分配的CPU时间片数量以及硬盘IO、带宽大小来实现的</td></tr><tr><td style=\"text-align:center\">资源统计（Accounting）</td><td style=\"text-align:left\"><strong>cgroup</strong> 可以统计系统的资源总使用量，比如内存用量、CPU使用时长的。</td></tr><tr><td style=\"text-align:center\">进程控制（Process Control）</td><td style=\"text-align:left\"><strong>cgroup</strong> 可以对进程组进行挂起、恢复等操作</td></tr></tbody></table>\n<blockquote>\n<p><strong>Linux cgroup</strong>的API是以一个伪文件系统的方式实现，所有资源管理的功能都以子系统（subsystem）的方式管理。比如 CPU 的 cgroup 就一般会放在 <code>/sys/fs/cgroup/cpu</code>里面，内存的 cgroup 就一般会放在 <code>/sys/fs/cgroup/memory</code>里面。</p>\n</blockquote>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"观察一个docker容器\">观察一个Docker容器<a href=\"https://real-tech.online/blog/docker-docker-cgroups#%E8%A7%82%E5%AF%9F%E4%B8%80%E4%B8%AAdocker%E5%AE%B9%E5%99%A8\" class=\"hash-link\" aria-label=\"观察一个Docker容器的直接链接\" title=\"观察一个Docker容器的直接链接\">​</a></h2>\n<p>我们首先通过<code>busybox</code>镜像<code>run</code>一个容器，指定最大CPU配额为0.2，也就是容器能够使用的最大CPU个数为0.2个。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker run </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">it </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">rm </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">cpus</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.2</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">name busybox busybox sh</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> # </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> # </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">while</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:hsl(35, 99%, 36%)\">true</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">do</span><span class=\"token plain\"> a</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> done</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>我们在里面运行了一个死循环，我们另开一个terminal，用<code>docker stats</code>指令观察容器的CPU利用率</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker stats busybox</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CONTAINER</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">ID</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NAME</span><span class=\"token plain\">      </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CPU</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token plain\">     </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">MEM</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">USAGE</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">LIMIT</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">MEM</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token plain\">     </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NET</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">I</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">O</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">BLOCK</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">I</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">O</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PIDS</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">565d245db66c   busybox   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">19.97</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token plain\">    148KiB </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">62</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\">65GiB   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token plain\">     0B </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> 0B   0B </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> 0B     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>能够看到CPU利用率一直在 20% 附近波动，证明参数是生效的。接下来我们到 <code>/sys/fs/cgroup/cpu</code>下面，找到<code>docker</code>分组下面对应<code>容器ID</code>的目录</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">sys</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">fs</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">cgroup</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">cpu</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ls</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">clone_children</span><span class=\"token plain\">  cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\">          cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\">   cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\">       notify_on_release  tasks</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">event_control</span><span class=\"token plain\">   cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage</span><span class=\"token plain\">         cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_period_us</span><span class=\"token plain\">   docker         release_agent  </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">procs</span><span class=\"token plain\">           cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage_percpu</span><span class=\"token plain\">  cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_runtime_us</span><span class=\"token plain\">  kubepods       scs</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sane_behavior</span><span class=\"token plain\">   cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_period_us</span><span class=\"token plain\">     cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">shares</span><span class=\"token plain\">         machine</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">slice</span><span class=\"token plain\">  system</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">slice</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cd docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ls</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage</span><span class=\"token plain\"> cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage_percpu</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_period_us</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_period_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_runtime_us</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">shares</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\"> cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">clone_children</span><span class=\"token plain\">  </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">565d245db66c2e3fba3d6dec90a49ee03b2c90b9e8ca5ab40fd2d20bc2059562</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">event_control</span><span class=\"token plain\">  cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">procs</span><span class=\"token plain\">  cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\"> notify_on_release</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">tasks</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cd 565d245db66c2e3fba3d6dec90a49ee03b2c90b9e8ca5ab40fd2d20bc2059562</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ls</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">clone_children</span><span class=\"token plain\">  cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">procs</span><span class=\"token plain\">  cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage</span><span class=\"token plain\">         cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_period_us</span><span class=\"token plain\">  cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_period_us</span><span class=\"token plain\">   cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">shares</span><span class=\"token plain\">  notify_on_release cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">event_control</span><span class=\"token plain\">   cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\">  cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage_percpu</span><span class=\"token plain\">  cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\">   cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_runtime_us</span><span class=\"token plain\">  cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\">    tasks</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>能够看到这里就是<strong>cgroup</strong>对我们刚刚那个容器进程的CPU限制目录。我们关注2个文件，一个是<code>tasks</code>，里面配置了资源受限的进程ID，另一个是<code>cpu.cfs_quota_us</code>，里面配置了最大CPU额度（quota）。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cat cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">20000</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ cat tasks</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">146058</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>在CPU的cgroup中，一个CPU核心被切割成了10万份，这里配置了2万，也就是0.2个CPU</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"cpu-cgroup的实践\">CPU cgroup的实践<a href=\"https://real-tech.online/blog/docker-docker-cgroups#cpu-cgroup%E7%9A%84%E5%AE%9E%E8%B7%B5\" class=\"hash-link\" aria-label=\"CPU cgroup的实践的直接链接\" title=\"CPU cgroup的实践的直接链接\">​</a></h2>\n<p>接下来我们模拟下Docker容器，创建一个CPU受限的进程。<br>\n<!-- -->首先在<code>/sys/fs/cgroup/cpu</code>目录下面创建一个目录<code>ob01</code></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># sudo su</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># cd </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">sys</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">fs</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">cgroup</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">cpu</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># mkdir ob01</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># cd ob01</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># ls </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">l</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">total </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">clone_children</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">w</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">w</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">w</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">event_control</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cgroup</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">procs</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpuacct</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">usage_percpu</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_period_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_period_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">rt_runtime_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">shares</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">stat</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> notify_on_release</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">rw</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">r</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root root </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Dec</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">29</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">42</span><span class=\"token plain\"> tasks</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>可以看到系统已经帮我们创建了一系列的配置文件了，接下来我们将把CPU配额<code>cpu.cfs_quota_us</code>修改成5万，然后把当前进程ID加入到<code>tasks</code>文件中</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># echo </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"50000\"</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">cfs_quota_us</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># echo $$</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">152314</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># echo $$ </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> tasks </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">while</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:hsl(35, 99%, 36%)\">true</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> </span><span class=\"token keyword control-flow\" style=\"color:hsl(301, 63%, 40%)\">do</span><span class=\"token plain\"> a</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"> done</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>然后打开另外一个terminal，用<code>top -p </code>指令查看CPU利用率</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ top </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">152314</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">top </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">21</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">50</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">40</span><span class=\"token plain\"> up </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">86</span><span class=\"token plain\"> days</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">36</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">2</span><span class=\"token plain\"> users</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  load average</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.90</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.61</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.60</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Tasks</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> total</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> running</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> sleeping</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> stopped</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> zombie</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token function maybe-class-name\" style=\"color:hsl(221, 87%, 60%)\">Cpu</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1.8</span><span class=\"token plain\"> us</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.2</span><span class=\"token plain\"> sy</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\"> ni</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">97.9</span><span class=\"token plain\"> id</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\"> wa</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\"> hi</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\"> si</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\"> st</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">KiB</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Mem</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">65689704</span><span class=\"token plain\"> total</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4661644</span><span class=\"token plain\"> free</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">20283872</span><span class=\"token plain\"> used</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">40744188</span><span class=\"token plain\"> buff</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">cache</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">KiB</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">Swap</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> total</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> free</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\">        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> used</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">41196384</span><span class=\"token plain\"> avail </span><span class=\"token maybe-class-name\">Mem</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">USER</span><span class=\"token plain\">      </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PR</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NI</span><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">VIRT</span><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">RES</span><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">SHR</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">S</span><span class=\"token plain\">  </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CPU</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">%</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">MEM</span><span class=\"token plain\">     </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TIME</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">+</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">COMMAND</span><span class=\"token plain\">                                                        </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">152314</span><span class=\"token plain\"> root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">20</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">116796</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3624</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1800</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">R</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">49.8</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">12.89</span><span class=\"token plain\"> bash                                                           </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>可以看到CPU利用率也是稳定在 50%, 和我们的限额是保持一致的。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"the-end\">The End<a href=\"https://real-tech.online/blog/docker-docker-cgroups#the-end\" class=\"hash-link\" aria-label=\"The End的直接链接\" title=\"The End的直接链接\">​</a></h2>\n<p>目前我们已经观察和试验过了<strong>Docker容器</strong>底层的2个重要技术，<strong>Linux namespace</strong>的隔离，还有<strong>Linux cgroup</strong>的限额（如果<strong>Linux namespace</strong>隔离部分还没看的话可以跳转<a href=\"https://real-tech.online/blog/docker-docker-namespace\">《5分钟Docker容器原理 | namespace 观察和实践篇》</a>）虽然Docker容器听起来是一个很玄的概念，但是经过我们分析，其实也是一个特殊的进程，并且在我们了解了隔离和限额2个技术以后，它神秘的面纱也被慢慢解开，原理一了解，回过头来看，其实也就这么回事。<br>\n<!-- -->接下来我还会继续更新这个系列的其他文章，希望对大家理解<strong>Docker原理</strong>带来帮助。<br>\n<!-- -->我是老骨头，下次再见。</p>",
            "url": "https://real-tech.online/blog/docker-docker-cgroups",
            "title": "Docker 原理：cgroup",
            "summary": "在 《5分钟Docker容器原理 | 开篇》 中，我们提到，为了限制 Docker容器 运行时能够使用的最大资源，我们用到了 Linux cgroup 技术。这篇我们继续来了解下这个技术。",
            "date_modified": "2026-01-03T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：Docker原理",
                "docker",
                "linux"
            ]
        },
        {
            "id": "https://real-tech.online/blog/docker-docker-namespace",
            "content_html": "<p>在 <a href=\"https://real-tech.online/blog/docker-docker-intro\">《5分钟Docker容器原理 | 开篇》</a> 提到，<strong>Docker容器</strong>的隔离性是通过 <strong>Linux namespace</strong> 技术来实现的，本篇详细介绍下这个技术，并以一个<strong>Docker容器</strong>作为切入点，验证和实践下<strong>Linux namespace</strong>的隔离性。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"linux-namespace-的类型\">Linux namespace 的类型<a href=\"https://real-tech.online/blog/docker-docker-namespace#linux-namespace-%E7%9A%84%E7%B1%BB%E5%9E%8B\" class=\"hash-link\" aria-label=\"Linux namespace 的类型的直接链接\" title=\"Linux namespace 的类型的直接链接\">​</a></h2>\n<table><thead><tr><th style=\"text-align:center\">名称</th><th style=\"text-align:left\">隔离对象</th><th style=\"text-align:left\">描述</th><th style=\"text-align:center\">内核版本</th></tr></thead><tbody><tr><td style=\"text-align:center\">MNT namespace</td><td style=\"text-align:left\">Mount points</td><td style=\"text-align:left\">提供磁盘挂载点和文件系统的隔离</td><td style=\"text-align:center\">2.4.19</td></tr><tr><td style=\"text-align:center\">IPC namespace</td><td style=\"text-align:left\">System V IPC, POSIX message queues</td><td style=\"text-align:left\">提供进程间通信的隔离</td><td style=\"text-align:center\">2.6.19</td></tr><tr><td style=\"text-align:center\">UTS namespace</td><td style=\"text-align:left\">Hostname and NIS domain name</td><td style=\"text-align:left\">提供主机名和域名的隔离</td><td style=\"text-align:center\">2.6.19</td></tr><tr><td style=\"text-align:center\">PID namespace</td><td style=\"text-align:left\">Process IDs</td><td style=\"text-align:left\">提供进程的隔离</td><td style=\"text-align:center\">2.6.24</td></tr><tr><td style=\"text-align:center\">Net namespace</td><td style=\"text-align:left\">Network devices, stacks, ports, etc.</td><td style=\"text-align:left\">提供网络的隔离</td><td style=\"text-align:center\">2.6.29</td></tr><tr><td style=\"text-align:center\">User namespace</td><td style=\"text-align:left\">User and group IDs</td><td style=\"text-align:left\">提供用户和权限的隔离</td><td style=\"text-align:center\">3.8</td></tr></tbody></table>\n<p><strong>Docker容器</strong>本质上是一个进程，为了在分布式的环境下进行通信和定位，Docker容器必须拥有自己独立的IP、端口、路由，这个时候就需要用到<strong>Net namespace</strong>提供的网络隔离能力。网络通信需要隔离，进程间通信也需要隔离，所以需要用<strong>IPC namespace</strong>。还有用户权限、用户组权限，也需要和宿主机区分开，就用到了<strong>User namespace</strong>。容器里面的进程也拥有自己的PID，这个是<strong>PID namespace</strong>起到的隔离作用......<br>\n<!-- -->所以，<strong>Docker容器</strong>本质上是一个带有不同的<strong>namespace</strong>参数的进程，正是这些<strong>namespace</strong>的存在, 容器内部就只能看到自己当前<strong>namespace</strong>限定的资源、文件、设备、状态、配置等。<br>\n<!-- -->上面这几种<strong>namespace</strong>类型，我们可以通过指令<code>unshare --help</code>来查看。</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ uname </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">3.10</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1160</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">el7</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">x86_64</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ unshare </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">help</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Usage</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> unshare </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token plain\">options</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\">program</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\">argument</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">Run</span><span class=\"token plain\"> a program </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">with</span><span class=\"token plain\"> some namespaces unshared </span><span class=\"token keyword module\" style=\"color:hsl(301, 63%, 40%)\">from</span><span class=\"token plain\"> the parent</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token literal-property property\" style=\"color:hsl(5, 74%, 59%)\">Options</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">m</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">mount               unshare mounts namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">u</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">uts                 unshare </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">UTS</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">namespace</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">hostname etc</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">i</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">ipc                 unshare </span><span class=\"token maybe-class-name\">System</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">V</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">IPC</span><span class=\"token plain\"> namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">n</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">net                 unshare network namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">p</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">pid                 unshare pid namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">U</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">user                unshare user namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">f</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">fork                fork before launching </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\">program</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">     </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">mount</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">proc</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">[</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">=</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\">dir</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">]</span><span class=\"token plain\">  mount proc filesystem </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">first</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">implies </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">mount</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">r</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">map</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">root</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">user       map current user to </span><span class=\"token function\" style=\"color:hsl(221, 87%, 60%)\">root</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">(</span><span class=\"token plain\">implies </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">     </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">propagation </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&lt;</span><span class=\"token plain\">slave</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\">shared</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">private</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\">unchanged</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">                           modify mount propagation </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">in</span><span class=\"token plain\"> mount namespace</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">s</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">setgroups allow</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\">deny  control the setgroups syscall </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">in</span><span class=\"token plain\"> user namespaces</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">h</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">help     display </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">this</span><span class=\"token plain\"> help and exit</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">V</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">version  output version information and exit</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>可以看到，当前OS的内核版本是3.10.0， 目前<code>unshare</code>支持的<strong>namespace</strong>类型是6种，跟上面的表格是一致的。<br>\n<!-- -->大家如果想看到更具体的信息，可以使用<code>man unshare</code>指令看看详细的文档。</p>\n<blockquote>\n<p>在 <a href=\"https://real-tech.online/blog/offline-install-docker\">《离线环境部署docker及私有镜像仓库》</a> 中，我们启动了一个Docker容器，接下来我们来观察下这个容器，以<strong>PID namespace</strong>为例，来进行简单的验证和实践。</p>\n</blockquote>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"pid-namespace的观察\">PID namespace的观察<a href=\"https://real-tech.online/blog/docker-docker-namespace#pid-namespace%E7%9A%84%E8%A7%82%E5%AF%9F\" class=\"hash-link\" aria-label=\"PID namespace的观察的直接链接\" title=\"PID namespace的观察的直接链接\">​</a></h2>\n<p>首先我们找到并使用<code>sh</code>进入容器</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker ps</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CONTAINER</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">ID</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">IMAGE</span><span class=\"token plain\">             </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">COMMAND</span><span class=\"token plain\">                  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CREATED</span><span class=\"token plain\">      </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">STATUS</span><span class=\"token plain\">          </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PORTS</span><span class=\"token plain\">                                       </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">NAMES</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">98cb5c25871b   registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token plain\">latest   </span><span class=\"token string\" style=\"color:hsl(119, 34%, 47%)\">\"/entrypoint.sh /etc…\"</span><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">4</span><span class=\"token plain\"> days ago   </span><span class=\"token maybe-class-name\">Up</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">39</span><span class=\"token plain\"> minutes   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">.0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">tcp</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&gt;</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">5000</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">tcp   </span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">private</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">registry</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ docker exec </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">it 98cb5c25871b sh</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> # </span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>接下来我们打印当前容器运行的所有进程。可以看到容器内主进程<code>registry</code>的PID为<code>1</code></p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\"> # ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token plain\">   </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">USER</span><span class=\"token plain\">     </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TIME</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">COMMAND</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\"> root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> registry serve </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">config</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">yml</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">11</span><span class=\"token plain\"> root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> sh</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">   </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">18</span><span class=\"token plain\"> root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>我们打开另外一个终端，在宿主机中查看<strong>docker</strong>相关进程</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> grep docker</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1917</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">07</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">26</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">?</span><span class=\"token plain\">        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">01</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">usr</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">shim</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">runc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">v2 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">namespace moby </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">id 98cb5c25871b94420418094efb19f36c45c7fbe18274229e9f8c4b00328ec180 </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">address </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token keyword\" style=\"color:hsl(301, 63%, 40%)\">var</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">run</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">containerd</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">sock</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root      </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1945</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1917</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">07</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">26</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">01</span><span class=\"token plain\"> registry serve </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">etc</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">docker</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">registry</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">config</span><span class=\"token punctuation\" style=\"color:hsl(119, 34%, 47%)\">.</span><span class=\"token property-access\">yml</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>由于显示的内容非常多，在这里我只截取了2个进程信息。可以看到<code>registry</code>进程在宿主机中的PID是<code>1945</code>,而且它的父进程ID正是容器进程的PID<code>1917</code>。这正是<strong>PID namespace</strong>的作用。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"pid-namespace的实践\">PID namespace的实践<a href=\"https://real-tech.online/blog/docker-docker-namespace#pid-namespace%E7%9A%84%E5%AE%9E%E8%B7%B5\" class=\"hash-link\" aria-label=\"PID namespace的实践的直接链接\" title=\"PID namespace的实践的直接链接\">​</a></h2>\n<p>我们可以用<code>unshare</code>指令来创建一个PID隔离的<strong>bash</strong>进程。如下</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ sudo unshare </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">pid </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">fork </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">--</span><span class=\"token plain\">mount</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">proc </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bash</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># </span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">UID</span><span class=\"token plain\">        </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PPID</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">C</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">STIME</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TTY</span><span class=\"token plain\">          </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TIME</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CMD</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root         </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bash</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">10</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># sleep </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1024</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">&amp;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"># ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">UID</span><span class=\"token plain\">        </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PID</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">PPID</span><span class=\"token plain\">  </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">C</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">STIME</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TTY</span><span class=\"token plain\">          </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">TIME</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:hsl(35, 99%, 36%)\">CMD</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root         </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bash</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">13</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">22</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> sleep </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1024</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root        </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">14</span><span class=\"token plain\">     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">22</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>可以看到，我们的<strong>bash</strong>进程，已经成为了1号进程，并且我们创建的<code>sleep</code>静默进程，此时的父进程ID为<code>1</code><br>\n<!-- -->接下来我们在宿主机打印出相关进程</p>\n<div class=\"language-javascript codeBlockContainer_APcc theme-code-block\" style=\"--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)\"><div class=\"codeBlockContent_m3Ux\"><pre class=\"prism-code language-javascript codeBlock_qGQc thin-scrollbar\" style=\"background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)\"><code class=\"codeBlockLines_p187\"><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> grep sleep</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">17301</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">15805</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">22</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> sleep </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1024</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">$ ps </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">-</span><span class=\"token plain\">ef </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">|</span><span class=\"token plain\"> grep </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">15805</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">15805</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">15803</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">16</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bin</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token plain\">bash</span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\">root     </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">17301</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">15805</span><span class=\"token plain\">  </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">08</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">22</span><span class=\"token plain\"> pts</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">/</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">0</span><span class=\"token plain\">    </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token operator\" style=\"color:hsl(221, 87%, 60%)\">:</span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">00</span><span class=\"token plain\"> sleep </span><span class=\"token number\" style=\"color:hsl(35, 99%, 36%)\">1024</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:hsl(230, 8%, 24%)\"><span class=\"token plain\"></span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><span class=\"token spread operator\" style=\"color:hsl(221, 87%, 60%)\">...</span><br></span></code></pre><div class=\"buttonGroup_6DOT\"><button type=\"button\" aria-label=\"复制代码到剪贴板\" title=\"复制\" class=\"clean-btn\"><span class=\"copyButtonIcons_FhaS\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"copyButtonIcon_phi_\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z\"></path></svg><svg viewBox=\"0 0 24 24\" class=\"copyButtonSuccessIcon_FfTR\"><path fill=\"currentColor\" d=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"></path></svg></span></button></div></div></div>\n<p>可以看到，宿主机中运行的<code>bash</code>进程PID为<code>15805</code>，而它的子进程<code>sleep</code>，在宿主机中的PID为<code>17301</code>。<br>\n<!-- -->以上就是对<strong>PID namespace</strong>的观察与实践，大家如果对其他<strong>Linux namespace</strong>也感兴趣，可以参考下<code>unshare</code>的说明文档，继续做下相关的测试和验证。</p>",
            "url": "https://real-tech.online/blog/docker-docker-namespace",
            "title": "Docker 原理：namespace",
            "summary": "在 《5分钟Docker容器原理 | 开篇》 提到，Docker容器的隔离性是通过 Linux namespace 技术来实现的，本篇详细介绍下这个技术，并以一个Docker容器作为切入点，验证和实践下Linux namespace的隔离性。",
            "date_modified": "2026-01-02T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：Docker原理",
                "docker",
                "linux"
            ]
        },
        {
            "id": "https://real-tech.online/blog/docker-docker-intro",
            "content_html": "<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"容器的本质\">容器的本质<a href=\"https://real-tech.online/blog/docker-docker-intro#%E5%AE%B9%E5%99%A8%E7%9A%84%E6%9C%AC%E8%B4%A8\" class=\"hash-link\" aria-label=\"容器的本质的直接链接\" title=\"容器的本质的直接链接\">​</a></h2>\n<p>容器技术，是一种<strong>沙盒</strong>技术， 这种技术就像<strong>集装箱</strong>一样，把你的应用装到里面去，因此应用与应用之间因为有了<strong>集装箱</strong>的存在，不会相互干扰。而且被装进<strong>集装箱</strong>的应用，也可以很方便地搬来搬去。<br>\n<!-- -->容器技术的核心功能，就是提供这么一个<strong>集装箱</strong>，一个<strong>被约束好边界和条件的进程</strong>。<br>\n<!-- -->容器，其实就是一种特殊的进程。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"虚拟机vm和容器container的区别\">虚拟机(VM)和容器(Container)的区别<a href=\"https://real-tech.online/blog/docker-docker-intro#%E8%99%9A%E6%8B%9F%E6%9C%BAvm%E5%92%8C%E5%AE%B9%E5%99%A8container%E7%9A%84%E5%8C%BA%E5%88%AB\" class=\"hash-link\" aria-label=\"虚拟机(VM)和容器(Container)的区别的直接链接\" title=\"虚拟机(VM)和容器(Container)的区别的直接链接\">​</a></h2>\n<table><thead><tr><th style=\"text-align:center\">VM</th><th style=\"text-align:center\">Container</th></tr></thead><tbody><tr><td style=\"text-align:center\"><img decoding=\"async\" loading=\"lazy\" alt=\"vm.png\" src=\"https://real-tech.online/assets/images/vm-6ad212205b90c4d1358f1b6651516ddd.png\" width=\"429\" height=\"369\" class=\"img_EnGc\"></td><td style=\"text-align:center\"><img decoding=\"async\" loading=\"lazy\" alt=\"container.png\" src=\"https://real-tech.online/assets/images/container-466b6528a0eac7c3da54fd8b8080d634.png\" width=\"428\" height=\"367\" class=\"img_EnGc\"></td></tr></tbody></table>\n<p>虚拟机的运行，需要<strong>Hypervisor</strong>为其创建虚拟硬件/固件，而且还需要搭建<strong>Guest OS</strong>才能运行用户的应用进程。这个虚拟机是真实存在的，无论用户的应用进程是否运行，都需要消耗和占用一定的资源来运行虚拟机。而且应用进程在虚拟机上面运行、调用资源的时候，无可避免地都要经过虚拟机的连接和处理，带来额外的性能损耗。<br>\n<!-- -->容器化后的用户应用，实际上还是一个进程，并不会有虚拟化带来的性能损耗。而且容器本身的<strong>隔离</strong>，是通过<code>namespace</code>技术来实现的，资源的消耗和占用可以忽略不计。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"容器的隔离和限制\">容器的隔离和限制<a href=\"https://real-tech.online/blog/docker-docker-intro#%E5%AE%B9%E5%99%A8%E7%9A%84%E9%9A%94%E7%A6%BB%E5%92%8C%E9%99%90%E5%88%B6\" class=\"hash-link\" aria-label=\"容器的隔离和限制的直接链接\" title=\"容器的隔离和限制的直接链接\">​</a></h2>\n<p>对于Docker等大多数Linux容器来说，<strong>隔离</strong>是通过<strong>namespace</strong>技术来实现，而<strong>限制</strong>是通过<strong>cgroup</strong>技术来控制。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"隔离\">隔离<a href=\"https://real-tech.online/blog/docker-docker-intro#%E9%9A%94%E7%A6%BB\" class=\"hash-link\" aria-label=\"隔离的直接链接\" title=\"隔离的直接链接\">​</a></h3>\n<p>资源隔离。通过<strong>Linux namespace</strong>技术可以对全局系统资源进行封装和隔离，让容器内的进程只能看到自己<strong>namespace</strong>的相关资源，这样就和其他<strong>namespace</strong>的进程起到了隔离的作用。改变一个<strong>namespace</strong>里面的资源，只会影响同一个<strong>namespace</strong>里的进程，对其他<strong>namespace</strong>的进程没有影响。<br>\n<!-- -->在<strong>Linux namespace</strong>中，虽然能够隔离很多资源，包括性能资源、文件、设备、状态、配置等，但也有不能隔离的对象。最典型的是时间，当你修改容器里的时间时，同时会对宿主机的时间造成修改。</p>\n<h3 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"限制\">限制<a href=\"https://real-tech.online/blog/docker-docker-intro#%E9%99%90%E5%88%B6\" class=\"hash-link\" aria-label=\"限制的直接链接\" title=\"限制的直接链接\">​</a></h3>\n<p>Docker容器中的进程，虽然在<strong>Linux namespace</strong>技术的隔离下，各自之间的运行不受影响，但是他们实际上还是宿主机上面的一个进程，消耗和占用着宿主机的资源。宿主机的资源是有限且公用的，如果不对这些进程进行资源的限制，这些进程可能会占用很多的系统资源，从而影响到其他进程的正常运行。<br>\n<strong>Linux cgroups</strong>技术是Linux内核中用来为进程限制资源调用的一个重要技术。<strong>Linux cgroups</strong>的全称是<strong>Linux Control Group</strong>, 它最主要的功能，就是限制一个进程能够使用的资源上限，包括内存、CPU、磁盘空间、网络带宽等。</p>\n<h2 class=\"anchor anchorWithHideOnScrollNavbar_Kn_G\" id=\"容器的文件系统\">容器的文件系统<a href=\"https://real-tech.online/blog/docker-docker-intro#%E5%AE%B9%E5%99%A8%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F\" class=\"hash-link\" aria-label=\"容器的文件系统的直接链接\" title=\"容器的文件系统的直接链接\">​</a></h2>\n<p>为了让容器内部<strong>更像</strong>一个独立的系统，一般我们会把一整个操作系统的文件系统，挂载到容器的根目录<code>/</code>下面，用来给容器内部的进程提供隔离后的执行环境。这个文件系统，就是<strong>容器镜像</strong>，也叫做<strong>rootfs</strong>.</p>",
            "url": "https://real-tech.online/blog/docker-docker-intro",
            "title": "Docker 原理：从虚拟机到容器",
            "summary": "容器的本质",
            "date_modified": "2026-01-01T00:00:00.000Z",
            "author": {
                "name": "阿男",
                "url": "https://real-tech.online"
            },
            "tags": [
                "系列：Docker原理",
                "docker",
                "linux"
            ]
        }
    ]
}