<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>运维 on Liangweidong's blog</title><link>https://liangweidonggood.github.io/tags/%E8%BF%90%E7%BB%B4/</link><description>Recent content in 运维 on Liangweidong's blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 15 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://liangweidonggood.github.io/tags/%E8%BF%90%E7%BB%B4/index.xml" rel="self" type="application/rss+xml"/><item><title>K8s 节点扩容：worker 加入集群一键脚本</title><link>https://liangweidonggood.github.io/p/k8s-jiedie-kuorong-worker-jiaru-jiqun-yijian-jiaoben/</link><pubDate>Sun, 15 Dec 2024 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/k8s-jiedie-kuorong-worker-jiaru-jiqun-yijian-jiaoben/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/k8s-jiedie-kuorong-worker-jiaru-jiqun-yijian-jiaoben/image/cover.jpg" alt="Featured image of post K8s 节点扩容：worker 加入集群一键脚本" /&gt;&lt;h2 id="k8s-集群扩容的场景"&gt;K8s 集群扩容的场景
&lt;/h2&gt;&lt;p&gt;集群跑了一段时间，资源不够了，要加新 worker？常见两种来源：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全新机器&lt;/strong&gt;（裸金属 + Ubuntu 22.04）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;之前装过 kubeadm&lt;/strong&gt; 跑挂了，现在想重新加入&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第二种特别棘手——kubeadm 残留的证书、配置文件、iptables 规则都会让 node join 失败。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;适用版本：K8s 1.28.5 / Ubuntu 22.04&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-全新-worker-加入推荐"&gt;1. 全新 worker 加入（推荐）
&lt;/h2&gt;&lt;h3 id="11-master1-上操作"&gt;1.1 master1 上操作
&lt;/h3&gt;&lt;h4 id="设置-hosts"&gt;设置 hosts
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;lt;&amp;lt; &lt;span class="s2"&gt;&amp;#34;EOF&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/hosts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;新 worker1 ip&amp;gt; worker1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;新 worker2 ip&amp;gt; worker2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="免密登录"&gt;免密登录
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshpass -p &amp;lt;YOUR_SSH_PASSWORD&amp;gt; ssh-copy-id -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no worker1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 如果 worker 之前有 known_hosts 冲突&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -f &lt;span class="s2"&gt;&amp;#34;/root/.ssh/known_hosts&amp;#34;&lt;/span&gt; -R &lt;span class="s2"&gt;&amp;#34;worker1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshpass -p &amp;lt;YOUR_SSH_PASSWORD&amp;gt; ssh-copy-id -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no worker1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;实际密码用占位符 &lt;code&gt;&amp;lt;YOUR_SSH_PASSWORD&amp;gt;&lt;/code&gt; 替代（执行前请把 &lt;code&gt;&amp;lt;YOUR_SSH_PASSWORD&amp;gt;&lt;/code&gt; 替换为真实 SSH 密码，或通过 &lt;code&gt;export SSHPASS=...&lt;/code&gt; 后 &lt;code&gt;sshpass -p $SSHPASS&lt;/code&gt; 注入）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h4 id="推送二进制--证书--服务配置"&gt;推送二进制 + 证书 + 服务配置
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 推送二进制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,-proxy&lt;span class="o"&gt;}&lt;/span&gt; worker1:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp /usr/local/bin/cri-dockerd worker1:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 推送证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh worker1 mkdir -p /etc/kubernetes/&lt;span class="o"&gt;{&lt;/span&gt;manifests,pki&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /etc/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem kubelet-conf.yml kube-proxy.yaml bootstrap-kubelet.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /etc/kubernetes/&lt;span class="nv"&gt;$FILE&lt;/span&gt; worker1:/etc/kubernetes/&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -r /etc/kubernetes/manifests worker1:/etc/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 推送 systemd 单元&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; FILE in /etc/systemd/system/cri-docker.service /etc/systemd/system/cri-docker.socket /etc/systemd/system/kubelet.service /etc/systemd/system/kube-proxy.service&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp &lt;span class="nv"&gt;$FILE&lt;/span&gt; worker1:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="12-一键脚本推荐"&gt;1.2 一键脚本（推荐）
&lt;/h3&gt;&lt;p&gt;把上面 3 步封装到 &lt;code&gt;join_k8s.sh&lt;/code&gt;，在 master1 上：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# join_k8s.sh &amp;lt;worker-name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;WORKER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Pushing binaries to &lt;/span&gt;&lt;span class="nv"&gt;$WORKER&lt;/span&gt;&lt;span class="s2"&gt; ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,-proxy&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;$WORKER&lt;/span&gt;:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp /usr/local/bin/cri-dockerd &lt;span class="nv"&gt;$WORKER&lt;/span&gt;:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Pushing certs ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh &lt;span class="nv"&gt;$WORKER&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mkdir -p /etc/kubernetes/{manifests,pki}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem kubelet-conf.yml kube-proxy.yaml bootstrap-kubelet.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /etc/kubernetes/&lt;span class="nv"&gt;$FILE&lt;/span&gt; &lt;span class="nv"&gt;$WORKER&lt;/span&gt;:/etc/kubernetes/&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -r /etc/kubernetes/manifests &lt;span class="nv"&gt;$WORKER&lt;/span&gt;:/etc/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Pushing systemd units ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; FILE in /etc/systemd/system/cri-docker.service /etc/systemd/system/cri-docker.socket /etc/systemd/system/kubelet.service /etc/systemd/system/kube-proxy.service&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp &lt;span class="nv"&gt;$FILE&lt;/span&gt; &lt;span class="nv"&gt;$WORKER&lt;/span&gt;:&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Done. Now SSH to &lt;/span&gt;&lt;span class="nv"&gt;$WORKER&lt;/span&gt;&lt;span class="s2"&gt; and start services ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;worker 上的 &lt;code&gt;worker.sh&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# worker.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Disable swap ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -ri &lt;span class="s1"&gt;&amp;#39;s/.*swap.*/#&amp;amp;/&amp;#39;&lt;/span&gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Set hostname ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hostnamectl set-hostname &lt;span class="k"&gt;$(&lt;/span&gt;hostname&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Install nfs-common (for nfs pv) ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y nfs-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Reload systemd ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Start services ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now cri-docker.socket
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now cri-docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Status ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status cri-docker.socket
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status cri-docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== Logs ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -f -u kubelet
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在 worker 上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash worker.sh worker1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在 master1 上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash /data/softs/join_k8s.sh worker1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="13-验证"&gt;1.3 验证
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# worker1 应该出现在列表中，STATUS 从 NotReady 变 Ready&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="2-之前装过-kubeadm-的-worker-清理"&gt;2. 之前装过 kubeadm 的 worker 清理
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;kubeadm reset&lt;/code&gt; 是最干净的清理方式（如果还装在系统里）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 如果 kubeadm 还在&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubeadm reset
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果 kubeadm 已经删了，需要手动清：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 卸载相关包&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum remove -y kubeadm kubectl kubelet kubernetes-cni kube*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum autoremove -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ubuntu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get purge kubeadm kubectl kubelet kubernetes-cni kube*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get autoremove
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 清残留&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf ~/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/kube*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 清 iptables 规则（kubeadm 会留下）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables -F
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables -t nat -F
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables -t mangle -F
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables -X
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;再走&amp;quot;全新 worker&amp;quot;流程。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-常见坑"&gt;3. 常见坑
&lt;/h2&gt;&lt;h3 id="31-日志采集不到"&gt;3.1 日志采集不到
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;failed to tail file, stat failed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stat /var/log/pods/kube-system_calico-node-95qkq_d7cbeb3d-5f17-40b9-bbb4-6e4cdb04a42e/calico-node/0.log:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;no such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：docker 改过数据目录路径（比如 &lt;code&gt;data-root&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：改回 &lt;code&gt;/var/lib/docker&lt;/code&gt; 或者把 &lt;code&gt;journalctl&lt;/code&gt; 改用 journal 模式（不依赖文件）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;临时方案&lt;/strong&gt;：删 calico-node Pod，让它自动重建：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl delete pod -n kube-system -l k8s-app&lt;span class="o"&gt;=&lt;/span&gt;calico-node
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="32-kubelet-启动报-kubeletgo2286-error-updating-node-status"&gt;3.2 kubelet 启动报 &lt;code&gt;kubelet.go:2286] &amp;quot;Error updating node status&amp;quot;&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;通常是 node IP 选错（多网卡场景）。在 &lt;code&gt;kubelet-conf.yml&lt;/code&gt; 加：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;nodeIP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;固定 IP&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="33-kubelet-failed-to-create-kubelet-cgroup-driver-cgroupfs-is-different-from-docker-systemd"&gt;3.3 &lt;code&gt;kubelet: failed to create kubelet: cgroup driver &amp;quot;cgroupfs&amp;quot; is different from docker &amp;quot;systemd&amp;quot;&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;Docker cgroupDriver 与 kubelet 不一致：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;exec-opts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;native.cgroupdriver=systemd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="34-kubelet-failed-to-start-containermanager--cgroup--not-found"&gt;3.4 &lt;code&gt;kubelet: failed to start ContainerManager ... cgroup ... not found&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;swap 没禁，或 cgroup 子系统没加载：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;swapoff -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 加载内核模块&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;modprobe br_netfilter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;modprobe ip_vs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="35-kubeletgo1380-failed-to-start-cadvisor--failed-to-get-cgroup-stats"&gt;3.5 &lt;code&gt;kubelet.go:1380] &amp;quot;Failed to start cAdvisor&amp;quot; ... Failed to get cgroup stats&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;cgroup v2 内核与 cadvisor 不兼容。&lt;strong&gt;降级到 cgroup v1&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 启动参数加 systemd.unified_cgroup_hierarchy=0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/default/grub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;GRUB_CMDLINE_LINUX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;systemd.unified_cgroup_hierarchy=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;update-grub
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="36-kubelet-node-name-not-found"&gt;3.6 &lt;code&gt;kubelet: node &amp;quot;&amp;lt;name&amp;gt;&amp;quot; not found&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;node 没注册到 apiserver。检查：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get csr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 应该有 Pending 的 CSR（worker 发出的证书请求）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl certificate approve &amp;lt;csr-name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="37-容器启动后立即退出"&gt;3.7 容器启动后立即退出
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl describe pod &amp;lt;pod&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Events 里有 &amp;#34;Back-off pulling image&amp;#34; / &amp;#34;Failed to pull image&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解决：检查 docker daemon.json 的 insecure-registries + imagePullSecrets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="38-节点-notready"&gt;3.8 节点 NotReady
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl describe node &amp;lt;name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Conditions：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ready False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# NetworkUnavailable True（calico 没装）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# MemoryPressure False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# DiskPressure False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PIDPressure False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;NetworkUnavailable = calico DaemonSet 还没起来，重启一下。&lt;/p&gt;
&lt;h3 id="39-节点-ready-但-pod-起不来"&gt;3.9 节点 Ready 但 Pod 起不来
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get events -A &lt;span class="p"&gt;|&lt;/span&gt; grep -i error
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;常见：calico-kube-controllers CrashLoopBackOff → 重新 apply calico.yaml。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-缩容"&gt;4. 缩容
&lt;/h2&gt;&lt;p&gt;如果要把 worker 退出集群：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 驱逐 Pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl drain &amp;lt;node&amp;gt; --ignore-daemonsets --delete-emptydir-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 标记不可调度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl cordon &amp;lt;node&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删除节点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl delete node &amp;lt;node&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;worker 上清理：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop kube-proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable kube-proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /usr/local/bin/kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /usr/local/bin/kube-proxy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-实战worker10-加入带坑排查"&gt;5. 实战：worker10 加入（带坑排查）
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. SSH 免密&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshpass -p &amp;lt;YOUR_SSH_PASSWORD&amp;gt; ssh-copy-id -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no worker10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 跑一键脚本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash join_k8s.sh worker10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 在 worker10 上启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash worker.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 等 30 秒&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# worker10 出现&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;日志采不到 → 删 calico-node 让它重建。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-小结"&gt;6. 小结
&lt;/h2&gt;&lt;p&gt;节点扩容 / 缩容看似简单，但隐藏的坑很多：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全新机器&lt;/strong&gt; 走 join_k8s.sh + worker.sh 一键脚本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubeadm 残留&lt;/strong&gt; 必须 &lt;code&gt;kubeadm reset&lt;/code&gt; 或手动清包 + iptables&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;calico-node CrashLoopBackOff&lt;/strong&gt; 删 Pod 重建最省事&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cgroup driver 一致&lt;/strong&gt; 是节点 Ready 的前提&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cgroup v2&lt;/strong&gt; K8s 1.24 之前需要 &lt;code&gt;systemd.unified_cgroup_hierarchy=0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下一步：[cert-manager 1.13 自动证书管理 + Ingress TLS 自动化](/p/k8s-cert-manager-zi dong-zhengshu-guanli-ingress-tls-zidonghua/)。&lt;/p&gt;</description></item><item><title>K8s 集群升级与卸载：版本升级 + finalizers 清理</title><link>https://liangweidonggood.github.io/p/k8s-jiqun-shengji-yu-xiezai-banben-shengji-finalizers-qingli/</link><pubDate>Fri, 15 Nov 2024 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/k8s-jiqun-shengji-yu-xiezai-banben-shengji-finalizers-qingli/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/k8s-jiqun-shengji-yu-xiezai-banben-shengji-finalizers-qingli/image/cover.jpg" alt="Featured image of post K8s 集群升级与卸载：版本升级 + finalizers 清理" /&gt;&lt;h2 id="升级-vs-卸载"&gt;升级 vs 卸载
&lt;/h2&gt;&lt;p&gt;K8s 集群&amp;quot;生命周期&amp;quot;两个最复杂的操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;升级&lt;/strong&gt;：小版本（1.28.5 → 1.28.8）可以&amp;quot;无脑&amp;quot;替换二进制；大版本（1.28 → 1.29）要看组件参数变化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;卸载&lt;/strong&gt;：彻底清掉所有 master / worker 上的 K8s 文件、systemd 单元、容器运行时、证书&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;适用版本：升级 1.28.5 → 1.28.8 / 卸载 K8s 1.28.5&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-升级策略"&gt;1. 升级策略
&lt;/h2&gt;&lt;h3 id="11-大版本-vs-小版本"&gt;1.1 大版本 vs 小版本
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;小版本升级&lt;/strong&gt;（patch 1.28.x → 1.28.y）：只换二进制 + 重启组件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;次版本升级&lt;/strong&gt;（1.28 → 1.29）：要关注 deprecated API（如 &lt;code&gt;policy/v1beta1&lt;/code&gt;）、CRD schema 变化、组件 flag 变化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大版本升级&lt;/strong&gt;（1.x → 2.x）：&lt;strong&gt;官方不支持&lt;/strong&gt;，必须重装&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="12-升级顺序"&gt;1.2 升级顺序
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;master1 → master2 → master3 → worker1 → worker2 → ... → workerN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;etcd 先升&lt;/strong&gt;，K8s 控制面组件（apiserver → controller-manager → scheduler）后升，最后 worker。&lt;/p&gt;
&lt;h3 id="13-当前环境"&gt;1.3 当前环境
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;组件&lt;/th&gt;
					&lt;th&gt;当前&lt;/th&gt;
					&lt;th&gt;目标&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;etcd&lt;/td&gt;
					&lt;td&gt;v3.5.11&lt;/td&gt;
					&lt;td&gt;3.5.13&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;kubernetes-server&lt;/td&gt;
					&lt;td&gt;1.28.5&lt;/td&gt;
					&lt;td&gt;1.28.8&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;coredns&lt;/td&gt;
					&lt;td&gt;1.29.0&lt;/td&gt;
					&lt;td&gt;1.29.0（不动）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-升级-etcd"&gt;2. 升级 etcd
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 备份&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /data/etcd-bak
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;etcdctl snapshot save /data/etcd-bak/etcd-snapshot-&lt;span class="k"&gt;$(&lt;/span&gt;date +%Y%m%d&lt;span class="k"&gt;)&lt;/span&gt;.db
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停 etcd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv /usr/local/bin/etcd* /data/etcd-bak/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 装新版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /data/softs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar -xf etcd-v3.5.13-linux-amd64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv etcd-v3.5.13-linux-amd64/etcd /usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv etcd-v3.5.13-linux-amd64/etcdctl /usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv etcd-v3.5.13-linux-amd64/etcdutl /usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 同步到其他 master&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in master2 master3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh &lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mv /usr/local/bin/etcd* /data/etcd-bak/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /usr/local/bin/etcd* &lt;span class="nv"&gt;$NODE&lt;/span&gt;:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;etcdctl version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# etcdctl version: 3.5.13&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-升级-k8s-控制面"&gt;3. 升级 K8s 控制面
&lt;/h2&gt;&lt;h3 id="31-升级-master1"&gt;3.1 升级 master1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 备份&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /usr/local/bin/bak
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,ctl,-apiserver,-controller-manager,-scheduler,-proxy&lt;span class="o"&gt;}&lt;/span&gt; /usr/local/bin/bak
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 装新版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /data/softs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar -xf kubernetes-server-linux-amd64.tar.gz &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --strip-components&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -C /usr/local/bin &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; kubernetes/server/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,ctl,-apiserver,-controller-manager,-scheduler,-proxy&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 重启所有 master 组件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-controller-manager.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-scheduler.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# master1 应该还是 Ready，但 VERSION 还是 1.28.5（只有 etcd 那台没升时）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="32-升级-master2--master3"&gt;3.2 升级 master2 + master3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in master2 master3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== &lt;/span&gt;&lt;span class="nv"&gt;$NODE&lt;/span&gt;&lt;span class="s2"&gt; ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mkdir -p /usr/local/bin/bak &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; mv /usr/local/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} /usr/local/bin/bak&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,ctl,-apiserver,-controller-manager,-scheduler,-proxy&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$NODE&lt;/span&gt;:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemctl restart kube-apiserver.service &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl restart kube-controller-manager.service &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl restart kube-scheduler.service &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl restart kubelet.service &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl restart kube-proxy.service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="33-升级-worker"&gt;3.3 升级 worker
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in worker1 worker2 worker3 worker4 worker5 worker6 worker7 worker8 worker9&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== &lt;/span&gt;&lt;span class="nv"&gt;$NODE&lt;/span&gt;&lt;span class="s2"&gt; ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mkdir -p /usr/local/bin/bak &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; mv /usr/local/bin/kube{let,-proxy} /usr/local/bin/bak&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,-proxy&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;$NODE&lt;/span&gt;:/usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemctl restart kubelet.service &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl restart kube-proxy.service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="34-验证"&gt;3.4 验证
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 全部 Ready，VERSION 显示 1.28.8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="4-升级时的节点隔离"&gt;4. 升级时的节点隔离
&lt;/h2&gt;&lt;p&gt;升级 master 时要先把 master 标记不可调度（避免新 Pod 调度到正在重启的 master）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 隔离&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl cordon master1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl drain master1 --delete-local-data --ignore-daemonsets --force
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 恢复&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl uncordon master1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;drain&lt;/code&gt; 驱逐所有非 DaemonSet Pod 到其他节点。&lt;code&gt;--delete-emptydir-data&lt;/code&gt; 允许删除 emptyDir 类型数据（一般安全）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-卸载-k8s-集群"&gt;5. 卸载 K8s 集群
&lt;/h2&gt;&lt;h3 id="51-停服务顺序"&gt;5.1 停服务顺序
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 停所有 K8s 服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kube-controller-manager.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kube-scheduler.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... 同上其他&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="52-删-systemd-单元"&gt;5.2 删 systemd 单元
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/multi-user.target.wants/kube-apiserver.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/kube-controller-manager.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/multi-user.target.wants/kube-controller-manager.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/kube-scheduler.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/multi-user.target.wants/kube-scheduler.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/multi-user.target.wants/kubelet.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/multi-user.target.wants/kube-proxy.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf ~/bootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="53-删目录"&gt;5.3 删目录
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /usr/local/bin/kube&lt;span class="o"&gt;{&lt;/span&gt;let,ctl,-apiserver,-controller-manager,-scheduler,-proxy&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/log/kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/cni/net.d
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /root/.kube
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf ~/bootstrap/bootstrap.secret.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="54-清环境变量"&gt;5.4 清环境变量
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 临时&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;unset&lt;/span&gt; KUBECONFIG
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 永久&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;/KUBECONFIG/d&amp;#39;&lt;/span&gt; /etc/profile ~/.bashrc ~/.profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="55-停-etcd"&gt;5.5 停 etcd
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/etcd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /usr/local/bin/etcd*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/etcd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/etcd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="56-停容器运行时"&gt;5.6 停容器运行时
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停所有 docker 相关&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop cri-docker.socket
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable cri-docker.socket
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop cri-docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable cri-docker.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop containerd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable containerd.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删 systemd 单元&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/systemd/system/&lt;span class="o"&gt;{&lt;/span&gt;docker.service,docker.socket,cri-docker.service,cri-docker.socket,containerd.service&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /etc/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /usr/local/bin/&lt;span class="o"&gt;{&lt;/span&gt;containerd*,docker*,runc,cri-dockerd,ctr&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/containerd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /run/cri-dockerd.sock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/run/docker.sock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="57-其他清理"&gt;5.7 其他清理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 网络（IPIP 模式 / CNI）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;modprobe -r ipip 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link delete tunl0 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /opt/cni/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/cni
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/calico 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bootstrap 目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf ~/bootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 历史镜像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker system prune -af 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="58-验证"&gt;5.8 验证
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 进程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ps -ef &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;kube|etcd|docker|containerd&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -v grep
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 应当空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;6443|2379|2380|10250|10251|10252|10255&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 应当空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 残留目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls /usr/local/bin &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;kube|etcd|containerd|docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 应当空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6-namespace-卡-terminating-终极清理"&gt;6. namespace 卡 Terminating 终极清理
&lt;/h2&gt;&lt;p&gt;卸载过程中如果 namespace 一直卡 Terminating（典型场景：Rook-Ceph、cert-manager）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 通用方法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;rook-ceph
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get namespace &lt;span class="nv"&gt;$ns&lt;/span&gt; -o json &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.spec = {&amp;#34;finalizers&amp;#34;:[]}&amp;#39;&lt;/span&gt; &amp;gt; temp.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -k -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; -X PUT &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/&lt;span class="nv"&gt;$ns&lt;/span&gt;/finalize
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch ns rook-ceph --type&lt;span class="o"&gt;=&lt;/span&gt;merge -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;:{&amp;#34;finalizers&amp;#34;:null}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但要先启动 kubectl proxy：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl proxy &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="61-pvc-卡-terminating"&gt;6.1 PVC 卡 Terminating
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch pvc jenkins-agent-pvc -n kube-ops --type&lt;span class="o"&gt;=&lt;/span&gt;merge -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;:{&amp;#34;finalizers&amp;#34;:null}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch pv pvc-c87554c7-6b20-42ed-8cdd-8be1d630a744 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;:{&amp;#34;finalizers&amp;#34;:null}}&amp;#39;&lt;/span&gt; --type&lt;span class="o"&gt;=&lt;/span&gt;merge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="62-pod-卡-terminating"&gt;6.2 Pod 卡 Terminating
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch pod nacos-0 -n safety-xjprod &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --type&lt;span class="o"&gt;=&lt;/span&gt;merge -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;metadata&amp;#34;:{&amp;#34;finalizers&amp;#34;:null}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl delete po &amp;lt;pod&amp;gt; -n &amp;lt;ns&amp;gt; --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; --force
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="63-后台强删-namespace"&gt;6.3 后台强删 namespace
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nohup kubectl delete ns cattle-impersonation-system --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; --force &amp;gt; /dev/null 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nohup kubectl delete ns cattle-system --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; --force &amp;gt; /dev/null 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="64-kubesphere-等第三方组件"&gt;6.4 KubeSphere 等第三方组件
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 看 CRD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get crd,clusterrole,clusterrolebinding &lt;span class="p"&gt;|&lt;/span&gt; grep kubesphere
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删 cluster CRD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl edit crd clusters.cluster.kubesphere.io
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删 metadata.finalizers 保存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 后台删 namespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nohup kubectl delete namespace kubesphere-system --force --grace-period&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &amp;gt; /dev/null 2&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="7-排错速查"&gt;7. 排错速查
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;原因&lt;/th&gt;
					&lt;th&gt;解决&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;升级后 &lt;code&gt;kubectl get node&lt;/code&gt; 仍是旧版本&lt;/td&gt;
					&lt;td&gt;部分 master 没升完&lt;/td&gt;
					&lt;td&gt;检查每台 master 的 &lt;code&gt;kubelet --version&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;etcdctl: this member is not a leader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;etcd 升级没让 leader 先升&lt;/td&gt;
					&lt;td&gt;先升 leader，重启会自动选主&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;kubectl drain&lt;/code&gt; 报 &amp;ldquo;cannot delete Pods using local storage&amp;rdquo;&lt;/td&gt;
					&lt;td&gt;用了 local PV&lt;/td&gt;
					&lt;td&gt;加 &lt;code&gt;--delete-emptydir-data --force&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;卸载后 &lt;code&gt;kubelet&lt;/code&gt; 还在&lt;/td&gt;
					&lt;td&gt;daemon-reload 没跑&lt;/td&gt;
					&lt;td&gt;跑 &lt;code&gt;systemctl daemon-reload&lt;/code&gt; 再 &lt;code&gt;systemctl reset-failed&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;节点还在 cluster 里&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;kubectl delete node&lt;/code&gt; 没跑&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;kubectl delete node &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="8-小结"&gt;8. 小结
&lt;/h2&gt;&lt;p&gt;升级 / 卸载是 K8s 集群&amp;quot;压箱底&amp;quot;操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;小版本升级&lt;/strong&gt; 只换二进制，2 分钟一台&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;卸载&lt;/strong&gt; 顺序：&lt;strong&gt;停服务 → 删单元 → 删目录 → 清环境变量&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;finalizers&lt;/strong&gt; 是 namespace 卡死的最常见原因，patch 一下就解决&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保留备份&lt;/strong&gt;（etcd snapshot、admin.kubeconfig）永远不亏&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下一步：&lt;a class="link" href="https://liangweidonggood.github.io/p/k8s-jiedie-kuorong-worker-jiaru-jiqun-yijian-jiaoben/" &gt;K8s 节点扩容：worker 加入集群一键脚本&lt;/a&gt;。&lt;/p&gt;</description></item><item><title>Watchtower 容器自动更新：守护所有容器的升级</title><link>https://liangweidonggood.github.io/p/watchtower-rongqi-zidong-gengxin/</link><pubDate>Sat, 15 Jun 2024 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/watchtower-rongqi-zidong-gengxin/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/watchtower-rongqi-zidong-gengxin/image/cover.jpg" alt="Featured image of post Watchtower 容器自动更新：守护所有容器的升级" /&gt;&lt;p&gt;Docker 镜像升级是日常运维里&lt;strong&gt;最烦又最不能不做的事&lt;/strong&gt;——CVE 漏洞、版本过期、安全审计都要求镜像保持最新。&lt;code&gt;Watchtower&lt;/code&gt; 把这件&amp;quot;每月手动 docker pull + restart&amp;quot;的事自动化：&lt;strong&gt;它会按周期拉取镜像、检查新版本、自动重启容器&lt;/strong&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：管 5+ 容器实例的运维 / DevOps
&lt;strong&gt;覆盖范围&lt;/strong&gt;：Watchtower 基础用法 + 选择性更新 + 标签筛选 + 远程仓库认证 + 远程主机升级 + 定时调度 + 监控日志&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一为什么需要-watchtower"&gt;一、为什么需要 Watchtower
&lt;/h2&gt;&lt;p&gt;手动升级 Docker 容器的痛点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CVE 爆出 → 需要紧急升级 nginx → 10 台机器挨个 pull + restart&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试环境新版本发布 → 手动改 5 个 compose 文件&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;半夜收到 Prometheus 告警 → 紧急 docker pull redis:7.2-alpine&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Watchtower 本质&lt;/strong&gt;：把&amp;quot;定期升级&amp;quot;做成可调度、可过滤、可观测的 cron 任务。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试 / 预发环境镜像更新（&lt;strong&gt;强烈推荐&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;内部工具的镜像（&lt;strong&gt;推荐&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;生产环境（&lt;strong&gt;谨慎使用，建议灰度 + 人工 confirm&lt;/strong&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;不适用&lt;/strong&gt;：需要特殊启动参数 / 一次性初始化（如数据库迁移）的镜像——升级可能丢数据。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="二最小化启动"&gt;二、最小化启动
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;参数说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-v /var/run/docker.sock&lt;/code&gt;：必须挂载，&lt;strong&gt;Watchtower 通过 Docker API 操作其他容器&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; / &lt;code&gt;--cleanup&lt;/code&gt;：升级后&lt;strong&gt;自动删除旧镜像&lt;/strong&gt;——避免磁盘满&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;启动后 Watchtower 默认 &lt;strong&gt;每 5 分钟&lt;/strong&gt;轮询一次所有运行容器的镜像，看是否有新版本。&lt;/p&gt;
&lt;h2 id="三选择性更新"&gt;三、选择性更新
&lt;/h2&gt;&lt;p&gt;只升级特定容器，避免 Watchtower 动到不该动的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; nginx redis mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;nginx redis mysql&lt;/code&gt; 是&lt;strong&gt;容器名列表&lt;/strong&gt;——只升级这几个，其他的不动。&lt;/p&gt;
&lt;h3 id="31-通过文件列表更新"&gt;3.1 通过文件列表更新
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 创建列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; ~/.watchtower.list &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;aria2-pro
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;unlockmusic
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;mtg
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /root/.watchtower.list:/root/.watchtower.list:ro &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;$(&lt;/span&gt;cat ~/.watchtower.list&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;好处&lt;/strong&gt;：增删容器名只改文件，&lt;strong&gt;不用重启 Watchtower&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="四排除特定容器"&gt;四、排除特定容器
&lt;/h2&gt;&lt;p&gt;给容器加 label &lt;code&gt;com.centurylinklabs.watchtower.enable=false&lt;/code&gt;，&lt;strong&gt;Watchtower 会自动跳过&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name openwrt-mini &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --network openwrt &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --privileged &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --label com.centurylinklabs.watchtower.enable&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; p3terx/openwrt-mini &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; /sbin/init
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;反向操作&lt;/strong&gt;：&lt;code&gt;watchtower&lt;/code&gt; 只升级&lt;strong&gt;显式标记&lt;/strong&gt;的容器，其他一律不管。&lt;/p&gt;
&lt;p&gt;启动 Watchtower 时加 &lt;code&gt;--label-enable&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart unless-stopped &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --label-enable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;启动容器时加 &lt;code&gt;--label com.centurylinklabs.watchtower.enable=true&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name my-critical-app &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --label com.centurylinklabs.watchtower.enable&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; myapp:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="五调度频率"&gt;五、调度频率
&lt;/h2&gt;&lt;h3 id="51-间隔模式"&gt;5.1 间隔模式
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 每 3600 秒（1 小时）检查一次&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart unless-stopped &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --interval &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="52-cron-模式"&gt;5.2 Cron 模式
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 每天凌晨 2 点检查&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart unless-stopped &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --schedule &lt;span class="s2"&gt;&amp;#34;0 0 2 * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：Watchtower 的 cron 是 &lt;strong&gt;6 位&lt;/strong&gt;（秒 分 时 日 月 周），比传统 cron 多 1 位秒。&lt;/p&gt;
&lt;h2 id="六私有-registry-认证"&gt;六、私有 Registry 认证
&lt;/h2&gt;&lt;p&gt;公司用 Harbor 时，Watchtower 升级私有镜像需要认证：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_PASS&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;REDACTED&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; base
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;环境变量 &lt;code&gt;REPO_USER&lt;/code&gt; / &lt;code&gt;REPO_PASS&lt;/code&gt; 会被 Watchtower 用于 &lt;code&gt;docker login&lt;/code&gt; Harbor。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;更安全的做法&lt;/strong&gt;：用 &lt;code&gt;~/.docker/config.json&lt;/code&gt; 挂载：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /root/.docker/config.json:/config.json &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;jq -r .auths.&lt;span class="s2"&gt;&amp;#34;dockerhub.example.com&amp;#34;&lt;/span&gt;.auth /config.json &lt;span class="p"&gt;|&lt;/span&gt; base64 -d &lt;span class="p"&gt;|&lt;/span&gt; cut -d: -f1&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;jq -r .auths.&lt;span class="s2"&gt;&amp;#34;dockerhub.example.com&amp;#34;&lt;/span&gt;.auth /config.json &lt;span class="p"&gt;|&lt;/span&gt; base64 -d &lt;span class="p"&gt;|&lt;/span&gt; cut -d: -f2&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="七远程主机升级"&gt;七、远程主机升级
&lt;/h2&gt;&lt;p&gt;通过 &lt;code&gt;DOCKER_HOST&lt;/code&gt; 环境变量，&lt;strong&gt;让本机 Watchtower 升级远程机器的容器&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;REPO_PASS&lt;/span&gt;&lt;span class="o"&gt;={{&lt;/span&gt;REDACTED&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tcp://203.0.113.10:2375&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; base
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;前提&lt;/strong&gt;：远程机器的 Docker daemon 监听 &lt;code&gt;0.0.0.0:2375&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生产强烈推荐 TLS&lt;/strong&gt;（&lt;code&gt;tcp://host:2376&lt;/code&gt; + CA 证书），避免 2375 明文端口被扫到。&lt;/p&gt;
&lt;h2 id="八手动触发更新"&gt;八、手动触发更新
&lt;/h2&gt;&lt;p&gt;偶尔需要&lt;strong&gt;立即升级某容器&lt;/strong&gt;（不等调度），用 &lt;code&gt;--run-once&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -cR aria2-pro
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt;：清理旧镜像&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; / &lt;code&gt;--run-once&lt;/code&gt;：跑一次就退出，&lt;strong&gt;不进入常驻守护模式&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CVE 紧急升级&lt;/li&gt;
&lt;li&gt;调试时反复升级测&lt;/li&gt;
&lt;li&gt;一次性升级指定容器&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="九监控与日志"&gt;九、监控与日志
&lt;/h2&gt;&lt;h3 id="91-看实时日志"&gt;9.1 看实时日志
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker logs -f watchtower
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;time=&amp;#34;2024-06-15T03:00:00Z&amp;#34; level=info msg=&amp;#34;Found new redis:7.2-alpine image&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;time=&amp;#34;2024-06-15T03:00:01Z&amp;#34; level=info msg=&amp;#34;Stopping /running redis (abc123)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;time=&amp;#34;2024-06-15T03:00:05Z&amp;#34; level=info msg=&amp;#34;Creating /running redis (def456)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;time=&amp;#34;2024-06-15T03:00:10Z&amp;#34; level=info msg=&amp;#34;Updated container redis&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="92-接入-loki--elk"&gt;9.2 接入 Loki / ELK
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --log-driver&lt;span class="o"&gt;=&lt;/span&gt;loki &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --log-opt loki-url&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://internal.example.com:3100/loki/api/v1/push&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --log-opt max-size&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;50m&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --log-opt max-file&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;10&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;告警规则&lt;/strong&gt;（Loki + Grafana）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 升级失败告警&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{&lt;span class="l"&gt;job=&amp;#34;watchtower&amp;#34;} |= &amp;#34;level=error&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="93-prometheus-指标通过-cadvisor"&gt;9.3 Prometheus 指标（通过 cAdvisor）
&lt;/h3&gt;&lt;p&gt;Watchtower 自身不暴露 metrics 端点，但&lt;strong&gt;它操作的容器&lt;/strong&gt;被 cAdvisor 抓取——可以看每个容器重启次数。&lt;/p&gt;
&lt;h2 id="十典型坑位"&gt;十、典型坑位
&lt;/h2&gt;&lt;h3 id="101-watchtower-自己被升级"&gt;10.1 Watchtower 自己被升级
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：Watchtower 升级自己时失败，&lt;strong&gt;陷入死循环&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：给 Watchtower 加 &lt;code&gt;disable&lt;/code&gt; label：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --label com.centurylinklabs.watchtower.enable&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者用 &lt;code&gt;--label-enable&lt;/code&gt; 模式 + 给所有其他容器显式 enable。&lt;/p&gt;
&lt;h3 id="102-升级后容器启动失败"&gt;10.2 升级后容器启动失败
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：Watchtower 升级 redis:7.2 → 7.4，但 7.4 改了配置文件路径，&lt;strong&gt;容器启动失败&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：升级前在测试环境验证；或者用 &lt;code&gt;--no-restart&lt;/code&gt; 模式只下载不重启：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --no-restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;人工&lt;/strong&gt; 确认升级后的容器能起来，再 &lt;code&gt;docker restart&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id="103-数据库容器被升级丢数据"&gt;10.3 数据库容器被升级丢数据
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：MySQL 8.0.36 → 8.4 自动升级，&lt;strong&gt;数据文件结构不兼容，启动报错&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：&lt;strong&gt;永远别让 Watchtower 自动升级数据库&lt;/strong&gt;——给 &lt;code&gt;mysql&lt;/code&gt; / &lt;code&gt;postgres&lt;/code&gt; / &lt;code&gt;mongodb&lt;/code&gt; 容器加 &lt;code&gt;disable&lt;/code&gt; label。&lt;/p&gt;
&lt;h3 id="104-大量容器同时升级"&gt;10.4 大量容器同时升级
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;症状&lt;/strong&gt;：20 个容器同时重启，&lt;strong&gt;业务抖动 30 秒&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修复&lt;/strong&gt;：分批升级——用容器名列表分多个 Watchtower：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Watchtower 1：升级 nginx / redis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d --name wt-frontend -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -c nginx redis --schedule &lt;span class="s2"&gt;&amp;#34;0 0 2 * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Watchtower 2：升级 backend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d --name wt-backend -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -c api worker scheduler --schedule &lt;span class="s2"&gt;&amp;#34;0 30 2 * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="十一生产级建议"&gt;十一、生产级建议
&lt;/h2&gt;&lt;h3 id="111-灰度升级"&gt;11.1 灰度升级
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 升级 1 台机器（canary）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tcp://host-1:2375 watchtower -cR --run-once api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 监控 5 分钟无异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 批量升级其他机器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; host in host-2 host-3 host-4&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;DOCKER_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tcp://&lt;span class="nv"&gt;$host&lt;/span&gt;:2375 watchtower -cR --run-once api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="112-升级前快照"&gt;11.2 升级前快照
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 升级前 commit 当前容器为镜像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker commit api api:pre-upgrade-backup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 触发升级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower -cR api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 监控 10 分钟&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 出问题回滚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker stop api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker rm api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d --name api api:pre-upgrade-backup
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="113-通知集成"&gt;11.3 通知集成
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Slack 通知&lt;/strong&gt;（用 &lt;code&gt;[shouts](https://github.com/containrrr/shoutrrr)&lt;/code&gt; 库，Watchtower 内置支持）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name watchtower &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;WATCHTOWER_NOTIFICATIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;shoutrrr &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;WATCHTOWER_NOTIFICATION_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;slack://token@channel &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; containrrr/watchtower
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;支持的通知方式&lt;/strong&gt;：Slack / Discord / Telegram / Email / Pushover / Gotify / Microsoft Teams / Mattermost / Smtp。&lt;/p&gt;
&lt;h2 id="十二完整生产配置示例"&gt;十二、完整生产配置示例
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3.8&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;watchtower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;containrrr/watchtower&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;watchtower&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;TZ=Asia/Shanghai&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_LABEL_ENABLE=true &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 只升级标记的容器&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_INCLUDE_STOPPED=false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_CLEANUP=true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_SCHEDULE=0 0 3 * * * &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 每天凌晨 3 点&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_TIMEOUT=60s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;REPO_USER=admin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;REPO_PASS={{REDACTED}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_NOTIFICATIONS=shoutrrr&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;WATCHTOWER_NOTIFICATION_URL=slack://{{SLACK_TOKEN}}@{{SLACK_CHANNEL}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;com.centurylinklabs.watchtower.enable=false&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 自身不升级&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;业务容器&lt;/strong&gt;（要被自动升级的）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nginx:1.25-alpine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;com.centurylinklabs.watchtower.enable=true&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="十三watchtower-替代方案"&gt;十三、Watchtower 替代方案
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;优势&lt;/th&gt;
					&lt;th&gt;劣势&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Watchtower&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;简单、单二进制&lt;/td&gt;
					&lt;td&gt;不支持 K8s&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Diun&lt;/strong&gt;（&lt;a class="link" href="https://github.com/crazy-max/diun" target="_blank" rel="noopener"
 &gt;diun&lt;/a&gt;）&lt;/td&gt;
					&lt;td&gt;只通知不升级，&lt;strong&gt;安全首选&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;不自动操作&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Renovate / Dependabot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;适合 K8s manifest 自动 PR&lt;/td&gt;
					&lt;td&gt;需要 GitOps 体系&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ArgoCD Image Updater&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;K8s 生态完整&lt;/td&gt;
					&lt;td&gt;K8s only&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;K8s 用户推荐 ArgoCD Image Updater + Renovate 组合&lt;/strong&gt;——Watchtower 在 K8s 里不是最佳实践。&lt;/p&gt;
&lt;h2 id="十四安全加固清单"&gt;十四、安全加固清单
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/var/run/docker.sock&lt;/code&gt; 权限最小化&lt;/strong&gt;：默认是 &lt;code&gt;root&lt;/code&gt; 拥有，&lt;strong&gt;容器挂载后相当于 root in container&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;加 label &lt;code&gt;disable&lt;/code&gt;&lt;/strong&gt;：防止 Watchtower 升级自己&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据库容器 disable&lt;/strong&gt;：避免自动升级导致数据丢失&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审计日志&lt;/strong&gt;：所有 Watchtower 操作都进 Loki，&lt;strong&gt;定期回看&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE 优先级&lt;/strong&gt;：用 &lt;code&gt;Diun&lt;/code&gt; + Watchtower 组合，&lt;strong&gt;先通知再决定升不升&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2024-视角补充"&gt;2024+ 视角补充
&lt;/h2&gt;&lt;p&gt;本文写于 2024-06，2024-2026 期间容器自动更新工具演进：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Watchtower 1.7+&lt;/strong&gt;（2024）：&lt;strong&gt;Podman 原生支持&lt;/strong&gt;（除 Docker 外）；&lt;strong&gt;OCI 1.1+ 镜像清单&lt;/strong&gt;；&lt;strong&gt;HTTP API&lt;/strong&gt;（查询 / 触发 / 状态）；&lt;strong&gt;Healthcheck endpoint&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diun 4.x&lt;/strong&gt;（2024-2025）：仍是 &amp;ldquo;&lt;strong&gt;只通知不升级&lt;/strong&gt;&amp;rdquo; 首选——&lt;strong&gt;配合 Watchtower&lt;/strong&gt; 是稳态组合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Renovate / Dependabot 2024+&lt;/strong&gt;：&lt;strong&gt;K8s manifest 自动 PR&lt;/strong&gt; 仍是 GitOps 体系推荐&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ArgoCD Image Updater 0.13+&lt;/strong&gt;：K8s 自动化 + GitOps 黄金组合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K8s 场景新选择&lt;/strong&gt;：&lt;strong&gt;Keel.sh&lt;/strong&gt;（轻量 Deployment 自动滚动）；&lt;strong&gt;Pulumi + Kubernetes Operator&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OrbStack / Docker Desktop 5.x&lt;/strong&gt;：本地开发环境&lt;strong&gt;已经内置&lt;/strong&gt;自动更新检测&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实战建议（2025-2026 视角）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docker 单机 / VM&lt;/strong&gt; → Watchtower + Diun 仍是首选&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K8s&lt;/strong&gt; → &lt;strong&gt;ArgoCD Image Updater + Renovate&lt;/strong&gt; 黄金组合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;企业合规&lt;/strong&gt; → Diun 通知 + 人工审核 + 灰度（不要让 Watchtower 自动升级生产数据库）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新趋势&lt;/strong&gt;：&lt;strong&gt;AI 辅助 CVE 评估&lt;/strong&gt;（如 Snyk / Aikido）——自动判断镜像升级是否引入 breaking change&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="下一步"&gt;下一步
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;想看 &lt;strong&gt;VPN 与代理自托管&lt;/strong&gt;（OpenVPN / V2Ray）→ &lt;a class="link" href="#" &gt;VPN 与代理自托管&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;想看 &lt;strong&gt;站点与博客自托管&lt;/strong&gt;（WordPress / WVP 视频监控）→ &lt;a class="link" href="#" &gt;站点与博客自托管&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;想看 &lt;strong&gt;Vaultwarden 密码管理&lt;/strong&gt;（Bitwarden 自托管）→ &lt;a class="link" href="#" &gt;Vaultwarden 密码管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;想看 &lt;strong&gt;MinIO 对象存储实战&lt;/strong&gt;（S3 兼容对象存储）→ &lt;a class="link" href="#" &gt;MinIO 对象存储实战&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Windows 系统管理员实战：远程桌面、SNMP 监控、注册服务与 winget 时代工具链</title><link>https://liangweidonggood.github.io/p/windows-system-admin-2022/</link><pubDate>Thu, 15 Dec 2022 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/windows-system-admin-2022/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/windows-system-admin-2022/image/cover.jpg" alt="Featured image of post Windows 系统管理员实战：远程桌面、SNMP 监控、注册服务与 winget 时代工具链" /&gt;&lt;h2 id="一为什么-windows-系统配置仍然是必备技能"&gt;一、为什么 Windows 系统配置仍然是&amp;quot;必备技能&amp;quot;
&lt;/h2&gt;&lt;p&gt;很多人以为 Windows &amp;ldquo;开箱即用&amp;quot;不需要管，但对真正在企业环境里维护 Windows Server 的人来说，&lt;strong&gt;&amp;ldquo;装好之后还要改的东西&amp;quot;远比装系统本身多&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;远程桌面授权到期，全员登不上；&lt;/li&gt;
&lt;li&gt;自研 exe 想常驻，注册成系统服务；&lt;/li&gt;
&lt;li&gt;SNMP 装好但&amp;quot;安全&amp;quot;标签页没出来；&lt;/li&gt;
&lt;li&gt;C 盘一年没清，几个 G 的 &lt;code&gt;Hiberfil.sys&lt;/code&gt; 默默躺在那；&lt;/li&gt;
&lt;li&gt;包管理器从零散的 &lt;code&gt;.msi&lt;/code&gt; 下载到 &lt;code&gt;winget&lt;/code&gt; 一行命令；&lt;/li&gt;
&lt;li&gt;终端代理怎么设、命令行怎么拉起 Python 解释器。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文把 6 类高频场景串成一份&lt;strong&gt;可对照操作的速查手册&lt;/strong&gt;，全部基于 PowerShell 7 + Windows 10/11/Server 2019+。&lt;/p&gt;
&lt;h2 id="二远程桌面复制失效--授权到期"&gt;二、远程桌面：复制失效 &amp;amp; 授权到期
&lt;/h2&gt;&lt;h3 id="21-远程无法互相复制文件"&gt;2.1 远程无法互相复制文件
&lt;/h3&gt;&lt;p&gt;远程桌面里&amp;quot;复制粘贴&amp;quot;突然失效，最常见的原因是 &lt;code&gt;rdpclip.exe&lt;/code&gt; 进程挂了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 在远程主机上任务管理器 → 结束 rdpclip.exe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 然后 Win+R → 运行 rdpclip.exe 重启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者一行 PowerShell：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-Process&lt;/span&gt; &lt;span class="n"&gt;rdpclip&lt;/span&gt; &lt;span class="n"&gt;-ErrorAction&lt;/span&gt; &lt;span class="n"&gt;SilentlyContinue&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Stop-Process&lt;/span&gt; &lt;span class="n"&gt;-Force&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Start-Process&lt;/span&gt; &lt;span class="n"&gt;rdpclip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="22-远程授权到期由于没有远程桌面授权服务器可以提供许可证远程会话连接已断开"&gt;2.2 远程授权到期：&amp;ldquo;由于没有远程桌面授权服务器可以提供许可证，远程会话连接已断开&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;Server 默认 120 天宽限期，过期后管理员也无法登录。&lt;strong&gt;应急办法：用 &lt;code&gt;/admin&lt;/code&gt; 模式强制登录一次&lt;/strong&gt;，然后清理注册表里的宽限期记录。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 强制登录（用 /admin 而非 /console，2012 R2 之后 console 已废弃）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mstsc /admin /v:internal.example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;注：&lt;code&gt;internal.example.com&lt;/code&gt; 在此仅作占位，请替换为实际服务器地址。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;登录后清理授权记录（可重置回 120 天）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 打开注册表 regedit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 进入 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\GracePeriod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 右键 GracePeriod → 权限 → 高级
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 所有者 → 更改 → 高级 → 立即查找 → 选择 Administrators → 确定
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. 审核 → 添加 → 主体：Administrators → 勾选安全控制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;6. 回到 GracePeriod 权限 → Administrators 勾选安全控制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;7. 删除 REG_BINARY → 重启
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;此方法可继续使用 120 天，过期后再次按此操作。&lt;strong&gt;这是临时续命方案&lt;/strong&gt;，长期请部署正式的 RD Licensing 服务器。&lt;/p&gt;
&lt;h2 id="三可执行程序注册为系统服务"&gt;三、可执行程序注册为系统服务
&lt;/h2&gt;&lt;h3 id="31-nssm最省心的方案"&gt;3.1 nssm：最省心的方案
&lt;/h3&gt;&lt;p&gt;下载 &lt;a class="link" href="https://nssm.cc/download" target="_blank" rel="noopener"
 &gt;nssm&lt;/a&gt;（建议 2.24+），把 &lt;code&gt;nssm.exe&lt;/code&gt; 加入 &lt;code&gt;PATH&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm install 服务名
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 编辑已存在服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm edit 服务名
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删除服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm remove 服务名 confirm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装 + 启动 + 设自启（一气呵成）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm install MyApp &lt;span class="s2"&gt;&amp;#34;C:\apps\myapp.exe&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--config C:\apps\config.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm &lt;span class="nb"&gt;set&lt;/span&gt; MyApp AppDirectory &lt;span class="s2"&gt;&amp;#34;C:\apps&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm &lt;span class="nb"&gt;set&lt;/span&gt; MyApp AppStdout &lt;span class="s2"&gt;&amp;#34;C:\apps\logs\stdout.log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm &lt;span class="nb"&gt;set&lt;/span&gt; MyApp AppStderr &lt;span class="s2"&gt;&amp;#34;C:\apps\logs\stderr.log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nssm &lt;span class="nb"&gt;set&lt;/span&gt; MyApp Start SERVICE_AUTO_START
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;net start MyApp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;nssm install&lt;/code&gt; 会弹出 GUI 让你填：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application 路径（你的 exe）&lt;/li&gt;
&lt;li&gt;Startup directory&lt;/li&gt;
&lt;li&gt;Arguments&lt;/li&gt;
&lt;li&gt;I/O 重定向（Logs tab 里把 stdout/stderr 重定向到文件，&lt;strong&gt;没配这个进程挂了根本查不到原因&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;Restart behavior（默认是&amp;quot;应用退出时不重启&amp;rdquo;，要改成&amp;quot;On exit&amp;quot;或&amp;quot;On failure&amp;quot;并设重试次数）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比写 &lt;code&gt;sc.exe&lt;/code&gt; 命令或 unit 文件简单一个量级，&lt;strong&gt;特别适合把 jar、bat、PowerShell 脚本注册成服务&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="32-powershell-原生方式无-gui适合脚本化"&gt;3.2 PowerShell 原生方式（无 GUI，适合脚本化）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 把可执行文件注册为服务（需要管理员）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;New-Service&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyService&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-BinaryPathName&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;C:\apps\myapp.exe --config C:\apps\config.yaml&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-DisplayName&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;My Application&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-StartupType&lt;/span&gt; &lt;span class="n"&gt;Automatic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Start-Service&lt;/span&gt; &lt;span class="n"&gt;MyService&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 设置失败时自动重启（sc.exe 的 failureflag 命令，PowerShell 里没有原生命令）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;exe&lt;/span&gt; &lt;span class="n"&gt;failure&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyService&amp;#34;&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;60&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;30000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;nssm&lt;/code&gt; 优势是&lt;strong&gt;自带&amp;quot;应用崩溃自动重启 + 日志重定向&amp;rdquo;&lt;/strong&gt;；纯 &lt;code&gt;New-Service&lt;/code&gt; 想要这些得自己写恢复脚本。&lt;/p&gt;
&lt;h2 id="四snmp-监控装配置安全选项丢失接监控平台"&gt;四、SNMP 监控：装、配置、安全选项丢失、接监控平台
&lt;/h2&gt;&lt;p&gt;SNMP 在企业网管里出场率仍然很高。Windows Server 装 SNMP 后，&lt;strong&gt;&amp;ldquo;安全&amp;quot;标签页丢失&lt;/strong&gt;是经典坑。&lt;/p&gt;
&lt;h3 id="41-完整安装流程"&gt;4.1 完整安装流程
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 查询是否已安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SNMP*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# State: NotPresent 表示未安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;WMI-SNMP-Provider.Client~~~~0.0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 SNMP 客户端&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SNMP.Client~~~~0.0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 WMI SNMP Provider&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;WMI-SNMP-Provider.Client~~~~0.0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 RSAT-SNMP（含管理工具，Server 才有这个 Feature）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Install-WindowsFeature&lt;/span&gt; &lt;span class="nb"&gt;RSAT-SNMP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="42-修复安全选项卡丢失"&gt;4.2 修复&amp;quot;安全&amp;quot;选项卡丢失
&lt;/h3&gt;&lt;p&gt;安装完成后&lt;strong&gt;刷新一下组策略&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gpupdate /force
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果还不行就重启。重启后用管理员身份打开 &lt;code&gt;services.msc&lt;/code&gt;，右键 SNMP Service → 属性，应该能看到&amp;quot;安全&amp;quot;标签页，可配置 community（v2c）或用户名（v3）。&lt;/p&gt;
&lt;h3 id="43-用-apache-hertzbeat-接入-windows-监控"&gt;4.3 用 Apache HertzBeat 接入 Windows 监控
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://hertzbeat.apache.org/" target="_blank" rel="noopener"
 &gt;HertzBeat&lt;/a&gt;（Apache 顶级项目，2022-11 毕业）是国产开源的监控告警平台，&lt;strong&gt;支持 SNMP 直接拉取 Windows 指标&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;被监控端（Windows）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;按 4.1 装好 SNMP + WMI Provider&lt;/li&gt;
&lt;li&gt;&lt;code&gt;services.msc&lt;/code&gt; → SNMP Service → 属性 → 安全&lt;/li&gt;
&lt;li&gt;添加 community：&lt;code&gt;public&lt;/code&gt;（v2c 测试用，生产请改复杂字符串）&lt;/li&gt;
&lt;li&gt;接受来自指定 NMS 服务器的 SNMP 包&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;监控端（HertzBeat）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录 HertzBeat Web 控制台&lt;/li&gt;
&lt;li&gt;监控中心 → 新增 → 操作系统 → Windows&lt;/li&gt;
&lt;li&gt;填主机名/IP、SNMP 版本（v2c）、community、采集间隔（默认 60s）&lt;/li&gt;
&lt;li&gt;启用模板：&lt;code&gt;hostName&lt;/code&gt;、&lt;code&gt;uptime&lt;/code&gt;、&lt;code&gt;cpu&lt;/code&gt;、&lt;code&gt;memory&lt;/code&gt;、&lt;code&gt;disk&lt;/code&gt;、&lt;code&gt;interface&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;提交后等 1-2 个采集周期，Dashboard 即可看到数据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HertzBeat 相比 Zabbix 的优势是&lt;strong&gt;配置都在 Web UI，agent 端零配置&lt;/strong&gt;；劣势是 SNMP 指标不如 Zabbix 默认模板细。&lt;/p&gt;
&lt;h2 id="五文件清理c-盘减肥必杀技"&gt;五、文件清理：C 盘减肥必杀技
&lt;/h2&gt;&lt;h3 id="51-关闭休眠文件"&gt;5.1 关闭休眠文件
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Hiberfil.sys&lt;/code&gt; 占用 ≈ 物理内存大小（16G 内存 = 16G 占用）。不用休眠功能可以直接关掉：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;powercfg -h off
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关掉后立刻回收几个 G。如果以后想恢复：&lt;code&gt;powercfg -h on&lt;/code&gt;。&lt;strong&gt;服务器/笔记本慎用&lt;/strong&gt;——笔记本开盖唤醒、Server 断电恢复都依赖休眠。&lt;/p&gt;
&lt;h3 id="52-虚拟内存-pagefilesys"&gt;5.2 虚拟内存 pagefile.sys
&lt;/h3&gt;&lt;p&gt;不建议直接删（删了会蓝屏），但可以把它从 C 盘挪到 D 盘：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;系统属性 → 高级 → 性能设置 → 高级 → 虚拟内存 更改
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 取消&amp;#34;自动管理&amp;#34; → 选 C 盘 → &amp;#34;无分页文件&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 选 D 盘 → &amp;#34;系统管理的大小&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 重启
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="53-磁盘可视化分析"&gt;5.3 磁盘可视化分析
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="http://www.uderzo.it/main_products/space_sniffer/" target="_blank" rel="noopener"
 &gt;SpaceSniffer&lt;/a&gt;（免安装、绿色软件）是看&amp;quot;哪个文件夹在偷空间&amp;quot;的利器。treemap 视图一眼就能找到几十 G 的&amp;quot;未知文件夹&amp;rdquo;。&lt;strong&gt;配合 WizTree&lt;/strong&gt;（NTFS MFT 直读，速度比 SpaceSniffer 快一个量级）双剑合璧。&lt;/p&gt;
&lt;h2 id="六环境变量与代理"&gt;六、环境变量与代理
&lt;/h2&gt;&lt;h3 id="61-命令行代理"&gt;6.1 命令行代理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CMD 临时设置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:1081
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:1081
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PowerShell 临时设置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;:http_proxy &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:1081&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;:https_proxy &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:1081&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PowerShell 永久设置（用户级）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;Environment&lt;span class="o"&gt;]&lt;/span&gt;::SetEnvironmentVariable&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http_proxy&amp;#34;&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:1081&amp;#34;&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;Environment&lt;span class="o"&gt;]&lt;/span&gt;::SetEnvironmentVariable&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https_proxy&amp;#34;&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:1081&amp;#34;&lt;/span&gt;, &lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;Python &lt;code&gt;pip&lt;/code&gt; &lt;strong&gt;不支持 socks5 代理&lt;/strong&gt;。要么走 HTTP 代理，要么用 &lt;code&gt;pip install --proxy=http://...&lt;/code&gt; 显式指定。Scoop/winget 同样走 HTTP_PROXY/HTTPS_PROXY 环境变量。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="62-永久环境变量"&gt;6.2 永久环境变量
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 用户级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;SetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MY_VAR&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 系统级（需要管理员）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;SetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;JAVA_HOME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;C:\Program Files\Java\jdk-17&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Machine&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 追加到现有 PATH（而不是覆盖！）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$current&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;SetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$current&lt;/span&gt;&lt;span class="s2"&gt;;C:\my\bin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="七命令行工具与软件分类2022-版"&gt;七、命令行工具与软件分类（2022 版）
&lt;/h2&gt;&lt;h3 id="71-包管理器winget--choco--scoop-三足鼎立"&gt;7.1 包管理器：winget / choco / scoop 三足鼎立
&lt;/h3&gt;&lt;p&gt;2022 年 Windows 原生包管理器终于成气候了，&lt;strong&gt;已经不用再去 Ninite 或手动下 &lt;code&gt;.msi&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;出品方&lt;/th&gt;
					&lt;th&gt;优势&lt;/th&gt;
					&lt;th&gt;适合&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;winget&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;微软官方（2020-05 起随 App Installer 内置）&lt;/td&gt;
					&lt;td&gt;系统自带、&lt;code&gt;msstore&lt;/code&gt; 源、企业可私有源&lt;/td&gt;
					&lt;td&gt;个人日常、批量脚本&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;choco&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Chocolatey 社区&lt;/td&gt;
					&lt;td&gt;仓库最大（9000+ 包）、成熟稳定&lt;/td&gt;
					&lt;td&gt;开发机、CI 服务器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;scoop&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;社区&lt;/td&gt;
					&lt;td&gt;绿色安装、装在用户目录、不污染 PATH&lt;/td&gt;
					&lt;td&gt;开发者、命令行控&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="winget-常用命令"&gt;winget 常用命令
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget search &lt;span class="s2"&gt;&amp;#34;nodejs&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装（含 msstore 源和 winget 仓库）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget install --id Microsoft.PowerShell -e
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget install --id Git.Git -e --source winget
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget install --id Microsoft.VisualStudioCode -e
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 升级全部&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget upgrade --all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 卸载&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget uninstall --id Git.Git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 导出/导入（机器间同步）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget &lt;span class="nb"&gt;export&lt;/span&gt; -o packages.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget import -i packages.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;winget 安装包走 &lt;code&gt;Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle&lt;/code&gt; 这个 App Installer 内置，&lt;strong&gt;Windows 10 1809+ / Windows 11 默认可用&lt;/strong&gt;，老系统手动装一下 App Installer 即可。&lt;/p&gt;
&lt;h4 id="choco-常用命令"&gt;choco 常用命令
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装（管理员 PowerShell）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Set-ExecutionPolicy Bypass -Scope Process -Force
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iex &lt;span class="o"&gt;((&lt;/span&gt;New-Object System.Net.WebClient&lt;span class="o"&gt;)&lt;/span&gt;.DownloadString&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://community.chocolatey.org/install.ps1&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 改安装路径（默认 C:\ProgramData\chocolatey，SSD 小的话挪去 D 盘）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;choco config &lt;span class="nb"&gt;set&lt;/span&gt; --name installLocation --value &lt;span class="s2"&gt;&amp;#34;D:\soft\choco&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 装软件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;choco install git -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;choco install vscode -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;choco install googlechrome -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 升级全部&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;choco upgrade all -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="scoop-常用命令"&gt;scoop 常用命令
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装（PowerShell，普通用户权限即可）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;irm &lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;sh&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;iex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 加常用 bucket&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;extras&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="nb"&gt;nodejs-lts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="nv"&gt;@3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 全部升级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scoop&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;三选一建议&lt;/strong&gt;：日常主力 winget（系统自带），开发环境额外装 scoop（绿色不污染系统），企业批量部署用 choco（成熟 + 私有源支持）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="72-实用工具分类速查"&gt;7.2 实用工具分类速查
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类别&lt;/th&gt;
					&lt;th&gt;推荐工具&lt;/th&gt;
					&lt;th&gt;用途&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;截屏标注&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Snipaste&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;贴图截图、像素级标注，截图工具事实标准&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;终端&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Windows Terminal&lt;/strong&gt;（微软官方 2019 开源）&lt;/td&gt;
					&lt;td&gt;多 Tab + 分屏 + GPU 加速&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SSH 客户端&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;WindTerm&lt;/strong&gt;（2019 发布，开源免费）&lt;br /&gt;&lt;strong&gt;electerm&lt;/strong&gt;（2017 起，跨平台）&lt;/td&gt;
					&lt;td&gt;终端 + SFTP + 端口转发一体&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;下载&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Motrix&lt;/strong&gt;（2019 开源，免费）&lt;br /&gt;&lt;strong&gt;IDM&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;多线程下载、BT/磁力&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;知识管理&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Obsidian&lt;/strong&gt;（2020 发布，Markdown + 双链）&lt;/td&gt;
					&lt;td&gt;本地 Markdown、插件丰富&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;API 调试&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Apifox&lt;/strong&gt;（国产，2020 至今）&lt;br /&gt;&lt;strong&gt;Postman&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;HTTP + Mock + 文档 + 团队协作&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;Docker Desktop&lt;/strong&gt;（2016 至今，WSL2 后端）&lt;/td&gt;
					&lt;td&gt;容器 + Kubernetes 本地集群&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;内网穿透&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;frp&lt;/strong&gt;（2016 起，反向代理神器）&lt;/td&gt;
					&lt;td&gt;把内网服务暴露到公网&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;压缩&lt;/td&gt;
					&lt;td&gt;7-Zip&lt;/td&gt;
					&lt;td&gt;解压各种格式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;视频&lt;/td&gt;
					&lt;td&gt;PotPlayer、OBS&lt;/td&gt;
					&lt;td&gt;播放 / 录屏&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;鼠标&lt;/td&gt;
					&lt;td&gt;YoloMouse&lt;/td&gt;
					&lt;td&gt;改光标样式 / 大小 / 颜色&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;FTP&lt;/td&gt;
					&lt;td&gt;FileZilla、WinSCP&lt;/td&gt;
					&lt;td&gt;文件传输&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;IDE&lt;/td&gt;
					&lt;td&gt;VS Code、IntelliJ IDEA&lt;/td&gt;
					&lt;td&gt;编码&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文本&lt;/td&gt;
					&lt;td&gt;Notepad++、Sublime Text&lt;/td&gt;
					&lt;td&gt;轻量编辑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;数据库&lt;/td&gt;
					&lt;td&gt;Navicat、DBeaver&lt;/td&gt;
					&lt;td&gt;多数据库 GUI&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Markdown&lt;/td&gt;
					&lt;td&gt;Typora&lt;/td&gt;
					&lt;td&gt;写作&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="73-端口与进程"&gt;7.3 端口与进程
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查 443 端口占用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat -aon &lt;span class="p"&gt;|&lt;/span&gt; findstr &lt;span class="s2"&gt;&amp;#34;443&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 最后一位是 PID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 通过 PID 找程序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tasklist &lt;span class="p"&gt;|&lt;/span&gt; findstr &lt;span class="s2"&gt;&amp;#34;1008&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 通过 PID 杀进程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;taskkill /f /pid &lt;span class="m"&gt;4620&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PowerShell 7 等价（更易解析）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Get-NetTCPConnection -LocalPort &lt;span class="m"&gt;443&lt;/span&gt; -State Established &lt;span class="p"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Select-Object OwningProcess, @&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="o"&gt;={(&lt;/span&gt;Get-Process -Id &lt;span class="nv"&gt;$_&lt;/span&gt;.OwningProcess&lt;span class="o"&gt;)&lt;/span&gt;.Path&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;code&gt;Get-NetTCPConnection&lt;/code&gt; 是 PowerShell 7+ 原生命令，输出可对象化，比 netstat 字符串解析舒服得多。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="八启用-administrator-账户"&gt;八、启用 Administrator 账户
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CMD（管理员）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;net user administrator /active:yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 设密码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;net user administrator &amp;lt;新密码&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 注销重新登录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown -l
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="九安全模式--定时关机"&gt;九、安全模式 &amp;amp; 定时关机
&lt;/h2&gt;&lt;h3 id="91-进入安全模式"&gt;9.1 进入安全模式
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown /r /o
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一分钟后弹出&amp;quot;选择一个选项&amp;quot;界面：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;疑难解答 → 高级选项 → 启动设置 → 重启
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;按 F4 进入安全模式，F5 带网络的安全模式。&lt;strong&gt;Win10/11 时代按住 F8 进安全模式的老办法已失效&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="92-定时关机"&gt;9.2 定时关机
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 300 秒后关机&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown -s -t &lt;span class="m"&gt;300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 带&amp;#34;我要加班&amp;#34;提示&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown -s -t &lt;span class="m"&gt;3600&lt;/span&gt; -c &lt;span class="s2"&gt;&amp;#34;1 小时后自动关机，请保存文件&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 取消&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 改成重启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shutdown -r -t &lt;span class="m"&gt;300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="十常见-5-个坑"&gt;十、常见 5 个坑
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;远程桌面授权过期&lt;/strong&gt;直接用 &lt;code&gt;/admin&lt;/code&gt; 强登，再清注册表，不要重装系统。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SNMP&amp;quot;安全&amp;quot;选项卡消失&lt;/strong&gt;：&lt;code&gt;gpupdate /force&lt;/code&gt; 不行就重启，不要反复重装。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;powercfg -h off&lt;/code&gt; 后启动变慢&lt;/strong&gt;：少量机器关掉休眠后冷启动更慢，是正常现象，因为 Windows 把休眠恢复的那部分代码也禁用了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;pip&lt;/code&gt; 不走 socks5 代理&lt;/strong&gt;：socks5 代理需要先转 HTTP，或用 &lt;code&gt;pip install --proxy&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mstsc&lt;/code&gt; 保存的密码丢了&lt;/strong&gt;：Win10/11 RDP 凭据默认存放在&amp;quot;凭据管理器 → Windows 凭据&amp;quot;里；遇到读取失败时，先 &lt;code&gt;cmdkey /list&lt;/code&gt; 看凭据是否还在，再用 &lt;code&gt;gpedit.msc&lt;/code&gt; → &amp;ldquo;本地计算机策略 → 计算机配置 → 管理模板 → Windows 组件 → 远程桌面服务 → 设备与资源重定向&amp;quot;检查是否被 GPO 禁用。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="十一总结"&gt;十一、总结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;远程桌面问题：&lt;strong&gt;&lt;code&gt;/admin&lt;/code&gt; + 注册表清理&lt;/strong&gt; 是双保险。&lt;/li&gt;
&lt;li&gt;注册服务：&lt;strong&gt;nssm &amp;gt; PowerShell &lt;code&gt;New-Service&lt;/code&gt;&lt;/strong&gt;，但 nssm 是 GUI，对自动化部署不友好。&lt;/li&gt;
&lt;li&gt;SNMP 装好却没&amp;quot;安全&amp;quot;选项：&lt;code&gt;gpupdate /force&lt;/code&gt; → 重启。接监控平台首选 &lt;strong&gt;HertzBeat&lt;/strong&gt;（国产、UI 友好、SNMP 直拉）。&lt;/li&gt;
&lt;li&gt;C 盘减肥：&lt;code&gt;powercfg -h off&lt;/code&gt; 收益最大。&lt;/li&gt;
&lt;li&gt;包管理：&lt;strong&gt;winget 系统自带 + scoop 绿色补充 + choco 企业批量&lt;/strong&gt;，三件套覆盖 90% 装软件场景。&lt;/li&gt;
&lt;li&gt;工具链：截屏 &lt;strong&gt;Snipaste&lt;/strong&gt;、终端 &lt;strong&gt;Windows Terminal + WindTerm&lt;/strong&gt;、下载 &lt;strong&gt;Motrix&lt;/strong&gt;、知识库 &lt;strong&gt;Obsidian&lt;/strong&gt;、API &lt;strong&gt;Apifox&lt;/strong&gt;、容器 &lt;strong&gt;Docker Desktop&lt;/strong&gt;、内网穿透 &lt;strong&gt;frp&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://nssm.cc/" target="_blank" rel="noopener"
 &gt;nssm - the Non-Sucking Service Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/powershell/module/dism/add-windowscapability" target="_blank" rel="noopener"
 &gt;Microsoft Docs - Add-WindowsCapability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://hertzbeat.apache.org/" target="_blank" rel="noopener"
 &gt;Apache HertzBeat - 实时监控告警系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/windows/package-manager/winget/" target="_blank" rel="noopener"
 &gt;winget 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.chocolatey.org/" target="_blank" rel="noopener"
 &gt;Chocolatey 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://scoop.sh/" target="_blank" rel="noopener"
 &gt;Scoop 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill" target="_blank" rel="noopener"
 &gt;Windows 命令行文档 - taskkill&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://www.uderzo.it/main_products/space_sniffer/" target="_blank" rel="noopener"
 &gt;SpaceSniffer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.snipaste.com/" target="_blank" rel="noopener"
 &gt;Snipaste 官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://obsidian.md/" target="_blank" rel="noopener"
 &gt;Obsidian 官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://hertzbeat.apache.org/docs/help/windows" target="_blank" rel="noopener"
 &gt;Apache HertzBeat 监控 Windows 文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>面试软技能 + 智力题：技术之外的硬通货</title><link>https://liangweidonggood.github.io/p/mianshi-ruanjineng-zhili-ti/</link><pubDate>Sun, 15 Dec 2019 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/mianshi-ruanjineng-zhili-ti/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/mianshi-ruanjineng-zhili-ti/image/cover.jpg" alt="Featured image of post 面试软技能 + 智力题：技术之外的硬通货" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;本文写于 2019 年 12 月&lt;/strong&gt;——经济下行期，面试软技能 + 智力题权重上升。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一面试软技能清单"&gt;一、面试软技能清单
&lt;/h2&gt;&lt;h3 id="11-沟通能力"&gt;1.1 沟通能力
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;STAR 法则&lt;/strong&gt;：Situation（情境）/ Task（任务）/ Action（行动）/ Result（结果）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用数据说话&lt;/strong&gt;：不说&amp;quot;做了高并发系统&amp;quot;，说&amp;quot;支持 10 万 QPS、可用性 99.99%&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结论先行&lt;/strong&gt;：先说结论，再说过程&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;听不懂就问&lt;/strong&gt;：面试官也欣赏&amp;quot;敢问&amp;quot;的人&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="12-抗压能力"&gt;1.2 抗压能力
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;接受挑战&lt;/strong&gt;：不回避难题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;承认边界&lt;/strong&gt;：不会就说不会，但说明学习路径&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情绪稳定&lt;/strong&gt;：不与面试官争论&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="13-学习能力"&gt;1.3 学习能力
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;学习路径&lt;/strong&gt;：展示如何学一项新技术&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;举一反三&lt;/strong&gt;：用类比说明理解深度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总结输出&lt;/strong&gt;：博客 / GitHub / 技术分享&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="14-团队协作"&gt;1.4 团队协作
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;冲突处理&lt;/strong&gt;：如何处理技术分歧&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码评审&lt;/strong&gt;：如何给别人 review&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识传递&lt;/strong&gt;：如何给团队培训&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二智力题分类"&gt;二、智力题分类
&lt;/h2&gt;&lt;h3 id="21-推理题"&gt;2.1 推理题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;蓝眼岛&lt;/strong&gt;：岛上有蓝眼/棕眼两种人，每天傍晚有人离岛。岛主说&amp;quot;你们中间有蓝眼的人&amp;quot;，第二天所有蓝眼都离岛了，为什么？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：n=1 时自己会走（如果自己是棕眼，岛主的话无意义），所以当 n 个人时，递归 n-1 后第 n 步自己走&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;疯狗&lt;/strong&gt;：村里有 50 条狗，其中若干是疯狗（不表现出任何症状），每天傍晚杀掉所有疯狗。村民不知道自己是疯狗。第几天杀完？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：第 49 天（如果有 1 条疯狗，当天就杀光；以此类推）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;耳光&lt;/strong&gt;：100 个逻辑学家围成一圈，每人头上一个数（红/蓝），能看见其他人看不见自己。每晚有人按规则打耳光。三天后耳光声响了，怎么推理？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：递归 + 公共知识&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-二进制问题"&gt;2.2 二进制问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;毒酒问题&lt;/strong&gt;：1000 桶酒，1 桶有毒，10 只小白鼠，24 小时找出毒酒。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：每桶编号二进制，每只老鼠喝对应位为 1 的酒。24h 后看哪几只死，二进制转十进制就是毒酒编号&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;砝码问题&lt;/strong&gt;：1-100 找最重 / 最轻的多少次？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：天平分组（3 进制）
&lt;ul&gt;
&lt;li&gt;找最重：1 次分 3 组&lt;/li&gt;
&lt;li&gt;找最重 + 最轻：⌈n/3⌉ 次&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="23-先手必胜"&gt;2.3 先手必胜
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;取石子&lt;/strong&gt;：100 个石子，每次取 1-3 个，先取必胜？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：必胜点为 4 的倍数（先手凑到 4 的倍数必胜）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;翻硬币&lt;/strong&gt;：N 枚硬币排成一行，每次翻一枚 + 邻接一枚，所有正面朝上为赢。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：分奇偶讨论&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="24-水桶问题"&gt;2.4 水桶问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;3 升和 5 升&lt;/strong&gt;：如何量出 4 升？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：3L 倒满 5L → 5L 倒掉 → 3L 倒进 5L → 再取 3L 倒满 → 5L 已有 3L 只能再装 2L → 3L 剩 1L → 5L 倒空 → 1L 倒入 5L → 再取 3L → 4L 搞定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;8 升和 5 升&lt;/strong&gt;：量出任意整数升&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="25-赛马问题"&gt;2.5 赛马问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：25 匹马，每次只能 5 匹比赛，最少几次找出最快的 3 匹？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;6 次&lt;/strong&gt;（无计时器）/ &lt;strong&gt;5 次&lt;/strong&gt;（有计时器）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第 1-5 轮：5 组比赛，每组 5 匹（共 25 匹）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 找出每组最快的 1 匹（A1, B1, C1, D1, E1）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第 6 轮：A1, B1, C1, D1, E1 比赛
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 排序：A1 &amp;gt; B1 &amp;gt; C1 &amp;gt; D1 &amp;gt; E1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;最快的 3 匹：A1 + A2 + A3 或 B1 或 B2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- A1：确定最快
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- A2：A 组第二
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- A3 / B1 / B2：竞争第二、第三
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A3 比 B1：需要第 6 轮 A1, B1, C1 + A2, A3, B1 比赛
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 答案 6 次
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="26-过河过桥"&gt;2.6 过河/过桥
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：4 人过桥，1/2/5/10 分钟，最少几分钟？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1+2 过，1 回 → 3 分钟&lt;/li&gt;
&lt;li&gt;5+10 过，2 回 → 12 分钟&lt;/li&gt;
&lt;li&gt;1+2 过 → 2 分钟&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总计 17 分钟&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="27-灯泡开关"&gt;2.7 灯泡开关
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：3 个开关控制 3 个灯泡（楼下看不见楼上），只能上楼 1 次，怎么确定对应关系？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开 1 号 5 分钟 → 关 1 号 → 开 2 号 → 上楼&lt;/li&gt;
&lt;li&gt;亮的是 2 号控制&lt;/li&gt;
&lt;li&gt;灭但热的是 1 号控制&lt;/li&gt;
&lt;li&gt;灭且冷的是 3 号控制&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="28-最优解问题"&gt;2.8 最优解问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;经典题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;撕书问题&lt;/strong&gt;：N 页书（双面），最少多少次撕出 100 张单页？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解法&lt;/strong&gt;：50 张 = 1 次（N/2 张）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;煎饼排序&lt;/strong&gt;：每次翻转前缀，最少几次排好序？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="三java-集合类"&gt;三、Java 集合类
&lt;/h2&gt;&lt;h3 id="31-java-基础合集"&gt;3.1 Java 基础合集
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
					&lt;th&gt;关键&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ArrayList&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;动态数组&lt;/td&gt;
					&lt;td&gt;扩容 1.5x&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;LinkedList&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;双向链表&lt;/td&gt;
					&lt;td&gt;增删快，查找慢&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HashMap&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;哈希表&lt;/td&gt;
					&lt;td&gt;JDK 8 红黑树化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ConcurrentHashMap&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;线程安全哈希表&lt;/td&gt;
					&lt;td&gt;CAS + synchronized&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;TreeMap&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;红黑树&lt;/td&gt;
					&lt;td&gt;有序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HashSet&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基于 HashMap&lt;/td&gt;
					&lt;td&gt;O(1) 查找&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="32-经典面试追问"&gt;3.2 经典面试追问
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Q1：HashMap 为什么用红黑树而不是 AVL？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AVL 严格平衡，查询快 O(log n)&lt;/li&gt;
&lt;li&gt;红黑树近似平衡，&lt;strong&gt;插入删除快&lt;/strong&gt;（旋转少）&lt;/li&gt;
&lt;li&gt;哈希冲突链表 &amp;gt; 8 时转红黑树，避免 hash 攻击退化为 O(n)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Q2：ConcurrentHashMap 1.7 vs 1.8？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1.7&lt;/strong&gt;：Segment（16 个）+ ReentrantLock&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1.8&lt;/strong&gt;：Node + CAS + synchronized（锁粒度更细）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Q3：ArrayList vs LinkedList？&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;ArrayList&lt;/th&gt;
					&lt;th&gt;LinkedList&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;随机访问&lt;/td&gt;
					&lt;td&gt;O(1)&lt;/td&gt;
					&lt;td&gt;O(n)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;头部插入&lt;/td&gt;
					&lt;td&gt;O(n)&lt;/td&gt;
					&lt;td&gt;O(1)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;内存占用&lt;/td&gt;
					&lt;td&gt;少&lt;/td&gt;
					&lt;td&gt;多（每个节点 2 个指针）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;缓存友好&lt;/td&gt;
					&lt;td&gt;友好&lt;/td&gt;
					&lt;td&gt;不友好&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="四java-io-模型"&gt;四、Java IO 模型
&lt;/h2&gt;&lt;h3 id="41-bio--nio--aio"&gt;4.1 BIO / NIO / AIO
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;全称&lt;/th&gt;
					&lt;th&gt;适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;BIO&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Blocking I/O&lt;/td&gt;
					&lt;td&gt;传统阻塞（连接数少）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;NIO&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Non-blocking I/O&lt;/td&gt;
					&lt;td&gt;高并发（Netty 底层）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;AIO&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Asynchronous I/O&lt;/td&gt;
					&lt;td&gt;异步回调（Linux 5+）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="42-nio-三大组件"&gt;4.2 NIO 三大组件
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;组件&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Channel（通道）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;双向数据通道（FileChannel / SocketChannel）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Buffer（缓冲区）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据容器（ByteBuffer / CharBuffer）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Selector（选择器）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;多路复用（一个线程管理多个 Channel）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="五mybatis-实战"&gt;五、MyBatis 实战
&lt;/h2&gt;&lt;h3 id="51-一级缓存-vs-二级缓存"&gt;5.1 一级缓存 vs 二级缓存
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;一级缓存&lt;/th&gt;
					&lt;th&gt;二级缓存&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;范围&lt;/td&gt;
					&lt;td&gt;SqlSession&lt;/td&gt;
					&lt;td&gt;Mapper（namespace）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;默认开启&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;✗（需配置）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;失效&lt;/td&gt;
					&lt;td&gt;增删改 / commit / close&lt;/td&gt;
					&lt;td&gt;同 namespace 增删改&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="52--vs-"&gt;5.2 #{} vs $
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#{}&lt;/code&gt;：预编译，&lt;code&gt;?&lt;/code&gt; 占位符（防 SQL 注入）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;${}&lt;/code&gt;：字符串拼接（有注入风险）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六设计模式高频题"&gt;六、设计模式高频题
&lt;/h2&gt;&lt;h3 id="61-单例模式-8-种实现"&gt;6.1 单例模式 8 种实现
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方式&lt;/th&gt;
					&lt;th&gt;线程安全&lt;/th&gt;
					&lt;th&gt;性能&lt;/th&gt;
					&lt;th&gt;推荐&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;饿汉&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;★★★&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;懒汉（同步方法）&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;✗&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;懒汉（DCL）&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;★★★★&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;静态内部类&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;★★★★★&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;枚举&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;★★★★★&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器式&lt;/td&gt;
					&lt;td&gt;取决于实现&lt;/td&gt;
					&lt;td&gt;-&lt;/td&gt;
					&lt;td&gt;单例池&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ThreadLocal&lt;/td&gt;
					&lt;td&gt;单线程&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;线程内单例&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CAS&lt;/td&gt;
					&lt;td&gt;✓&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;✗（代码复杂）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="62-工厂模式-vs-抽象工厂"&gt;6.2 工厂模式 vs 抽象工厂
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;工厂方法&lt;/th&gt;
					&lt;th&gt;抽象工厂&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;复杂度&lt;/td&gt;
					&lt;td&gt;单一产品&lt;/td&gt;
					&lt;td&gt;产品族&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;扩展&lt;/td&gt;
					&lt;td&gt;新增产品加新工厂&lt;/td&gt;
					&lt;td&gt;新增产品族加新工厂&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="63-代理模式"&gt;6.3 代理模式
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;静态代理&lt;/strong&gt;：手动写代理类&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JDK 动态代理&lt;/strong&gt;：基于接口（Proxy + InvocationHandler）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CGLIB 动态代理&lt;/strong&gt;：基于继承（Enhancer + MethodInterceptor）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="七netty-面试"&gt;七、Netty 面试
&lt;/h2&gt;&lt;h3 id="71-netty-三大特点"&gt;7.1 Netty 三大特点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;异步 NIO&lt;/strong&gt;：基于 Java NIO&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事件驱动&lt;/strong&gt;：ChannelPipeline + ChannelHandler&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高性能&lt;/strong&gt;：零拷贝、内存池、无锁设计&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="72-经典面试题"&gt;7.2 经典面试题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Q1：Netty 的线程模型？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reactor 单线程&lt;/strong&gt;：所有 I/O + 业务在单线程（NIO）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reactor 多线程&lt;/strong&gt;：I/O 单线程 + 业务线程池&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主从 Reactor 多线程&lt;/strong&gt;：Main Reactor + Sub Reactor + 业务线程池（Netty 推荐）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Q2：Netty 的零拷贝？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;堆外内存&lt;/strong&gt;（DirectByteBuffer）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CompositeByteBuf&lt;/strong&gt;（合并多个 buffer）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FileChannel.transferTo&lt;/strong&gt;（sendfile 系统调用）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ByteBuf 池化&lt;/strong&gt;（减少 GC）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Q3：Netty 的心跳机制？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IdleStateHandler&lt;/strong&gt;：读 / 写 / 读写空闲检测&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;服务端定期发送 Ping&lt;/strong&gt; + &lt;strong&gt;客户端响应 Pong&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;超时未响应则关闭连接&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="八写在最后"&gt;八、写在最后
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;面试软技能要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;STAR 法则&lt;/strong&gt;：讲故事用情境-任务-行动-结果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据量化&lt;/strong&gt;：用具体数字说明成就&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;诚实谦逊&lt;/strong&gt;：不懂就说不懂，承认边界&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反向提问&lt;/strong&gt;：准备 2-3 个有深度的问题&lt;/li&gt;
&lt;/ol&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://book.douban.com/subject/3004255/" target="_blank" rel="noopener"
 &gt;编程之美（智力题）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://book.douban.com/subject/25910595/" target="_blank" rel="noopener"
 &gt;剑指 Offer（编程题）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://book.douban.com/subject/26835090/" target="_blank" rel="noopener"
 &gt;软技能：代码之外的生存指南&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Docker 进阶与运维：网络模式、Volume 与镜像加速实战</title><link>https://liangweidonggood.github.io/p/docker-jin-jie-yu-yun-wei/</link><pubDate>Thu, 20 Jun 2019 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/docker-jin-jie-yu-yun-wei/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/docker-jin-jie-yu-yun-wei/image/cover.jpg" alt="Featured image of post Docker 进阶与运维：网络模式、Volume 与镜像加速实战" /&gt;&lt;p&gt;装好 Docker 引擎只是入门。&lt;strong&gt;真正决定一台主机能不能稳定跑生产容器的，是网络、存储和镜像拉取这三件事&lt;/strong&gt;。这一篇围绕&amp;quot;网络模式 + 存储卷 + 镜像代理 + 常见排障&amp;quot;四个高频主题，把零散的运维笔记整理成可复用的参考。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：已经能跑 &lt;code&gt;docker run&lt;/code&gt; 的开发者、想把 Docker 用于生产环境或本地自建集群的运维同学
&lt;strong&gt;覆盖范围&lt;/strong&gt;：bridge / host / none / container / 自定义网络 + Volume 生命周期 + Docker Hub / ghcr / GCR / k8s / Quay 代理 + 故障排查&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一为什么需要关注网络与存储"&gt;一、为什么需要关注网络与存储
&lt;/h2&gt;&lt;p&gt;跑一个 &lt;code&gt;hello-world&lt;/code&gt; 很简单，但一旦要把 Docker 真正&amp;quot;用起来&amp;quot;，就会撞到这些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容器之间怎么互访？同一个 Pod 里的两个 sidecar 容器能直接 &lt;code&gt;localhost&lt;/code&gt; 通信吗？&lt;/li&gt;
&lt;li&gt;数据库的数据在容器里，删容器数据就没了——怎么持久化？&lt;/li&gt;
&lt;li&gt;怎么让外部用户访问容器内的服务？&lt;/li&gt;
&lt;li&gt;不同机器上的容器怎么互联？&lt;/li&gt;
&lt;li&gt;国内服务器拉 Docker Hub 镜像慢到秒级超时，&lt;strong&gt;K8s 节点拉 CoreDNS 镜像也卡&lt;/strong&gt;怎么办？&lt;/li&gt;
&lt;li&gt;私有仓库（&lt;code&gt;ghcr.io&lt;/code&gt; / &lt;code&gt;gcr.io&lt;/code&gt; / &lt;code&gt;quay.io&lt;/code&gt;）在国内怎么拉？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题的答案，藏在&lt;strong&gt;网络模式、Volume、镜像代理&lt;/strong&gt;三个核心机制里。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单机多容器互访 → bridge / 自定义网络&lt;/li&gt;
&lt;li&gt;容器需要&amp;quot;绑定宿主机端口&amp;quot;的高性能场景 → host 网络&lt;/li&gt;
&lt;li&gt;强隔离、不能联网的安全沙箱 → none 网络&lt;/li&gt;
&lt;li&gt;数据库、需要长期保存的日志 → Volume（命名卷）/ bind mount&lt;/li&gt;
&lt;li&gt;跨主机容器互联（Swarm / k8s）→ overlay 网络（本文不展开）&lt;/li&gt;
&lt;li&gt;国内服务器拉镜像 → 镜像代理（&lt;code&gt;dockerproxy&lt;/code&gt; / &lt;code&gt;ghcr.nju.edu.cn&lt;/code&gt; 等）&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;h2 id="二容器网络基础docker0-网桥与-veth-pair"&gt;二、容器网络基础：docker0 网桥与 veth pair
&lt;/h2&gt;&lt;p&gt;Docker 启动时会在宿主机上创建一个叫 &lt;code&gt;docker0&lt;/code&gt; 的&lt;strong&gt;虚拟网桥&lt;/strong&gt;（默认子网 &lt;code&gt;172.17.0.0/16&lt;/code&gt;）。所有以 bridge 模式启动的容器都会接到这张网桥上，&lt;strong&gt;通过这张网桥 + iptables NAT 表与宿主机通信&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;可以用 &lt;code&gt;ifconfig&lt;/code&gt;（或 &lt;code&gt;ip a&lt;/code&gt;）看到 &lt;code&gt;docker0&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ifconfig
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker0 Link encap:Ethernet HWaddr 02:42:xx:xx:xx:xx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心机制（veth pair）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容器内看到的 &lt;code&gt;eth0&lt;/code&gt; 并不是真正的网卡，而是一对 &lt;strong&gt;veth pair 设备&lt;/strong&gt;的一端&lt;/li&gt;
&lt;li&gt;另一端放在宿主机，挂到 &lt;code&gt;docker0&lt;/code&gt; 网桥上&lt;/li&gt;
&lt;li&gt;数据从一端进，另一端出，&lt;strong&gt;等同于一根虚拟网线&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以用 &lt;code&gt;brctl show&lt;/code&gt;（来自 &lt;code&gt;bridge-utils&lt;/code&gt; 包）查看网桥上挂了哪些 veth：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ brctl show docker0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bridge name bridge id STP enabled interfaces
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker0 8000.0242xxxxxx no vethxxxxxx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;重要结论&lt;/strong&gt;：&lt;code&gt;docker0&lt;/code&gt; 网桥对外是不可见的，外部网络无法通过 Container-IP 直接访问容器。要让外部访问，&lt;strong&gt;必须做端口映射&lt;/strong&gt;（&lt;code&gt;-p&lt;/code&gt; 参数）。&lt;/p&gt;
&lt;h2 id="三四种网络模式详解"&gt;三、四种网络模式详解
&lt;/h2&gt;&lt;p&gt;Docker 在安装时会自动创建三个网络：&lt;code&gt;bridge&lt;/code&gt;（默认）、&lt;code&gt;none&lt;/code&gt;、&lt;code&gt;host&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker network ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;NETWORK ID NAME DRIVER SCOPE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xxxxx bridge bridge &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xxxxx host host &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xxxxx none null &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;创建容器时通过 &lt;code&gt;--net&lt;/code&gt; / &lt;code&gt;--network&lt;/code&gt; 指定：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模式&lt;/th&gt;
					&lt;th&gt;指定方式&lt;/th&gt;
					&lt;th&gt;核心特点&lt;/th&gt;
					&lt;th&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;bridge&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--net=bridge&lt;/code&gt;（默认）&lt;/td&gt;
					&lt;td&gt;独立 netns，分配 IP，通过 docker0 + NAT 通信&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;90% 场景&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;host&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--net=host&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;共享宿主机 netns，无独立 IP&lt;/td&gt;
					&lt;td&gt;高性能网络服务、监控 agent&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;none&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--net=none&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;仅有 lo 回环，无任何网络&lt;/td&gt;
					&lt;td&gt;强隔离、离线批处理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;container&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--net=container:NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;共享另一个容器的 netns&lt;/td&gt;
					&lt;td&gt;sidecar 模式紧密协作&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="31-bridge-模式默认"&gt;3.1 bridge 模式（默认）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 随机端口映射（大写 P）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -itd --name test1 -P nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 指定端口映射（小写 p）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -itd --name test2 -p 44541:80 nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;访问路径&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;外部网络 → 宿主机 IP:宿主机端口 → iptables DNAT → 容器 IP:容器端口
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;可以用 &lt;code&gt;iptables -t nat -vnL&lt;/code&gt; 看到 Docker 自动添加的 DNAT 规则：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ iptables -t nat -vnL
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Chain DOCKER &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; references&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pkts bytes target prot opt in out &lt;span class="nb"&gt;source&lt;/span&gt; destination
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:44541 to:172.17.0.2:80
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;等价类比&lt;/strong&gt;：bridge 模式 ≈ VMware 里的 NAT 模式——容器有独立 IP、能上网，但需要端口映射才能被外部访问。&lt;/p&gt;
&lt;h3 id="32-host-模式"&gt;3.2 host 模式
&lt;/h3&gt;&lt;p&gt;容器&lt;strong&gt;不创建自己的网卡&lt;/strong&gt;，直接使用宿主机的 IP 和端口。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -itd --name test-host --net&lt;span class="o"&gt;=&lt;/span&gt;host nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优势&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有 NAT 转换，性能最佳&lt;/li&gt;
&lt;li&gt;适合需要&amp;quot;处理大量端口&amp;quot;的服务（如 nginx 反代、Kafka、Prometheus exporter）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;代价&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容器与宿主机共用网络栈，&lt;strong&gt;端口冲突&lt;/strong&gt;会直接报错&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; / &lt;code&gt;--publish&lt;/code&gt; 参数被忽略，会出现 &lt;code&gt;WARNING: Published ports are discarded when using host network mode&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：host 网络驱动&lt;strong&gt;只支持 Linux 宿主机&lt;/strong&gt;。Docker Desktop for Mac / Windows / Windows Server 上的 Docker 不支持 host 模式。&lt;/p&gt;
&lt;p&gt;在 Swarm 集群里也可以使用 host 网络：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker service create --network host nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;控制流量（swarm manager 相关）仍走 overlay 网络，&lt;strong&gt;但 swarm 服务容器本身使用 Docker 守护进程的主机网络和端口发送数据&lt;/strong&gt;——这意味着如果一个服务容器绑定到 80 端口，那么在给定的集群节点上只能运行一个该服务容器。&lt;/p&gt;
&lt;h3 id="33-none-模式"&gt;3.3 none 模式
&lt;/h3&gt;&lt;p&gt;容器有独立的 Network Namespace，&lt;strong&gt;但 Docker 不会给它配置任何网络&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有 eth0、没有 IP、没有路由&lt;/li&gt;
&lt;li&gt;只有 &lt;code&gt;lo&lt;/code&gt; 回环网卡&lt;/li&gt;
&lt;li&gt;完全不能上网&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型场景：&lt;strong&gt;安全沙箱&lt;/strong&gt;、&lt;strong&gt;离线批处理任务&lt;/strong&gt;（如敏感数据脱敏、纯计算作业）。&lt;/p&gt;
&lt;h3 id="34-container-模式"&gt;3.4 container 模式
&lt;/h3&gt;&lt;p&gt;新创建的容器&lt;strong&gt;共享指定容器的 netns&lt;/strong&gt;，而不是和宿主机共享。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看已有容器的 PID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker inspect -f &lt;span class="s1"&gt;&amp;#39;{{.State.Pid}}&amp;#39;&lt;/span&gt; 5ace523962fc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;14685&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证 net namespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ls -l /proc/14685/ns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;... net -&amp;gt; net:&lt;span class="o"&gt;[&lt;/span&gt;4026532649&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 就是这个 net namespace ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建新容器并共享&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker run -itd --name test3 --net&lt;span class="o"&gt;=&lt;/span&gt;container:5ace523962fc centos bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证新容器的 net namespace 一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker inspect -f &lt;span class="s1"&gt;&amp;#39;{{.State.Pid}}&amp;#39;&lt;/span&gt; 2b7af7c8842d
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;15832&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ls -l /proc/15832/ns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;... net -&amp;gt; net:&lt;span class="o"&gt;[&lt;/span&gt;4026532649&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 跟前面一样&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;特性&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;两个容器共享 IP、端口范围&lt;/li&gt;
&lt;li&gt;网络之外（文件系统、进程、用户）仍然隔离&lt;/li&gt;
&lt;li&gt;两个容器的进程可以通过 &lt;code&gt;lo&lt;/code&gt; 通信&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型场景：&lt;strong&gt;sidecar 模式&lt;/strong&gt;——主容器和 sidecar 容器（如日志收集器、监控 agent、Service Mesh proxy）共用 netns，方便在 &lt;code&gt;localhost&lt;/code&gt; 上互调。&lt;/p&gt;
&lt;h2 id="四自定义网络指定-ip--子网"&gt;四、自定义网络：指定 IP / 子网
&lt;/h2&gt;&lt;p&gt;直接用默认 bridge 模式，&lt;strong&gt;不能给容器指定固定 IP&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 报错：只能在自定义网络指定 IP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker run -itd --name test4 --network bridge --ip 172.17.0.5 centos:7 /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error response from daemon: User specified IP address is supported only when connecting to networks with user configured subnets.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：先自定义网络，再指定 IP 启动。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 创建自定义网络（指定子网 + 网卡名）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker network create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --subnet&lt;span class="o"&gt;=&lt;/span&gt;172.18.0.0/16 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --opt &lt;span class="s2"&gt;&amp;#34;com.docker.network.bridge.name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker1&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; mynetwork
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 用指定 IP 启动容器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -itd --name test5 --net mynetwork --ip 172.18.0.10 centos /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;参数说明&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--subnet&lt;/code&gt;：定义子网范围&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--opt &amp;quot;com.docker.network.bridge.name&amp;quot;=&amp;quot;docker1&amp;quot;&lt;/code&gt;：让 &lt;code&gt;ifconfig -a&lt;/code&gt; 看到的是 &lt;code&gt;docker1&lt;/code&gt;，而不是 &lt;code&gt;br-110eb56a0b22&lt;/code&gt; 这种随机名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mynetwork&lt;/code&gt;：网络名，&lt;code&gt;docker network ls&lt;/code&gt; 里的 &lt;code&gt;NAME&lt;/code&gt; 列&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why 用自定义网络&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容器 DNS 自动解析（容器名 → IP），默认 bridge 不支持&lt;/li&gt;
&lt;li&gt;可以在创建时规划 IP 段&lt;/li&gt;
&lt;li&gt;适合需要稳定网络拓扑的复杂部署&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;配套的清理命令&lt;/strong&gt;：当自定义网络不再需要时：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 临时把容器从指定网络断开（排查网络问题很有用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker network disconnect -f bridge &amp;lt;container_name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 禁用并删除 docker0 网桥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig docker0 down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brctl delbr docker0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：手工 &lt;code&gt;brctl delbr docker0&lt;/code&gt; 之后，下次 daemon 启动（未指定 &lt;code&gt;-b&lt;/code&gt; 参数）会&lt;strong&gt;自动重建&lt;/strong&gt; &lt;code&gt;docker0&lt;/code&gt;。要真正控制默认网桥，需要在 &lt;code&gt;daemon.json&lt;/code&gt; 里写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;iptables&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;bridge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h2 id="五存储卷volume让数据活过容器生命周期"&gt;五、存储卷（Volume）：让数据活过容器生命周期
&lt;/h2&gt;&lt;p&gt;容器的文件系统是&lt;strong&gt;临时&lt;/strong&gt;的——&lt;code&gt;docker rm&lt;/code&gt; 时容器层全部销毁。&lt;strong&gt;任何需要持久化的数据，都必须挂载到 Volume 或 bind mount。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="51-volume-操作四件套"&gt;5.1 Volume 操作四件套
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker volume create mydata
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查看&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker volume ls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删除单个&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker volume rm mydata
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 清理（删所有未挂载的 volume —— 危险）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker volume prune
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="52-两种挂载方式"&gt;5.2 两种挂载方式
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 命名卷（推荐，Docker 自动管理）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d -v mydata:/var/lib/mysql mysql:5.7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. bind mount（直接挂主机目录，运维最常用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d -v /host/path:/container/path nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;Volume&lt;/th&gt;
					&lt;th&gt;Bind Mount&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;路径&lt;/td&gt;
					&lt;td&gt;Docker 管理（默认 &lt;code&gt;/var/lib/docker/volumes/&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;任意宿主机路径&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;迁移&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker volume&lt;/code&gt; 命令一键迁移&lt;/td&gt;
					&lt;td&gt;手动 rsync&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;权限&lt;/td&gt;
					&lt;td&gt;Docker 自动设&lt;/td&gt;
					&lt;td&gt;手动 chmod&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适用&lt;/td&gt;
					&lt;td&gt;数据库、共享数据&lt;/td&gt;
					&lt;td&gt;配置文件、日志、特殊路径&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="53-关键避坑"&gt;5.3 关键避坑
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;docker volume prune&lt;/code&gt; 会删所有未挂载的卷&lt;/strong&gt;——生产环境跑这个命令之前必须 &lt;code&gt;docker volume ls&lt;/code&gt; 确认&lt;/li&gt;
&lt;li&gt;bind mount 时容器内 UID 与宿主机不一致会导致权限问题——用 &lt;code&gt;user: &amp;quot;1000:1000&amp;quot;&lt;/code&gt; 显式指定&lt;/li&gt;
&lt;li&gt;Volume 在多容器间共享非常合适（如配置中心、日志聚合），但&lt;strong&gt;不能用 tmpfs 替代&lt;/strong&gt;——重启数据就没了&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="54-配合清理"&gt;5.4 配合清理
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 只删除未使用的网络&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker network prune -f
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删除 12 小时前创建的网络&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker network prune -a --filter &lt;span class="s2"&gt;&amp;#34;until=12h&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="六镜像代理与加速"&gt;六、镜像代理与加速
&lt;/h2&gt;&lt;p&gt;国内服务器拉 Docker Hub 镜像&lt;strong&gt;默认会非常慢甚至超时&lt;/strong&gt;。除了 &lt;code&gt;daemon.json&lt;/code&gt; 里配 &lt;code&gt;registry-mirrors&lt;/code&gt;，还可以直接用&lt;strong&gt;镜像代理&lt;/strong&gt;拉特定 registry 的镜像。&lt;/p&gt;
&lt;h3 id="61-docker-hub-镜像代理"&gt;6.1 Docker Hub 镜像代理
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;官方命令&lt;/th&gt;
					&lt;th&gt;代理命令&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;用户镜像&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker pull stilleshan/frpc:latest&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker pull dockerproxy.com/stilleshan/frpc:latest&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;根镜像（library）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker pull nginx:latest&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker pull dockerproxy.net/library/nginx:latest&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;dockerproxy.com&lt;/code&gt; 和 &lt;code&gt;dockerproxy.net&lt;/code&gt; 是两个常用的镜像代理。&lt;strong&gt;根镜像（&lt;code&gt;library/xxx&lt;/code&gt;）必须显式写 &lt;code&gt;library/&lt;/code&gt;&lt;/strong&gt;——这是和用户镜像最大的区别。&lt;/p&gt;
&lt;h3 id="62-github-container-registry-ghcrio"&gt;6.2 GitHub Container Registry (ghcr.io)
&lt;/h3&gt;&lt;p&gt;2019 年 9 月 GitHub 即将开放公开测试的 &lt;code&gt;ghcr.io&lt;/code&gt;，配合 GitHub Actions 的 &lt;code&gt;docker push&lt;/code&gt; 流程，越来越多的开源项目（包括很多 K8s 生态组件）开始把镜像推到 ghcr 而非 Docker Hub。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 官方&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull ghcr.io/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull ghcr.dockerproxy.com/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;南京大学的 ghcr 加速&lt;/strong&gt;：&lt;code&gt;ghcr.nju.edu.cn&lt;/code&gt; 是高校里对 ghcr 比较稳定的镜像（南大信管系维护）。速度通常比走 dockerproxy 更快，适合学术 / 教学环境。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="63-google-container-registry-gcrio-与-k8sgcrio"&gt;6.3 Google Container Registry (gcr.io) 与 k8s.gcr.io
&lt;/h3&gt;&lt;p&gt;K8s 自身组件（&lt;code&gt;coredns&lt;/code&gt;、&lt;code&gt;kube-proxy&lt;/code&gt;、&lt;code&gt;etcd&lt;/code&gt; 等）都托管在 &lt;code&gt;k8s.gcr.io&lt;/code&gt;（2018 年起）或新地址 &lt;code&gt;registry.k8s.io&lt;/code&gt;（2019 年开始迁移）。国内拉这些镜像&lt;strong&gt;几乎必走代理&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# GCR 官方&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull gcr.io/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# GCR 代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull gcr.dockerproxy.com/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# K8s 镜像（CNCF 仓库，从 k8s 1.11 开始 CoreDNS 取代 kube-dns 成为默认 DNS）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull k8s.gcr.io/coredns:1.6.5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull registry.k8s.io/coredns:1.6.5
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull k8s.dockerproxy.com/coredns:1.6.5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;CoreDNS 1.6.5&lt;/code&gt; 是 2019 年中比较常用的稳定版本——CNI 插件、&lt;code&gt;KubeDNS&lt;/code&gt; 替换等场景都会用到。&lt;/p&gt;
&lt;h3 id="64-quayio"&gt;6.4 Quay.io
&lt;/h3&gt;&lt;p&gt;Red Hat 系镜像（&lt;code&gt;coreos/etcd&lt;/code&gt; 旧版本、Operator Framework 等）大多托管在 Quay：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 官方&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull quay.io/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull quay.dockerproxy.com/username/image:tag
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="65-加速效果对比"&gt;6.5 加速效果对比
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 测速（删本地缓存后用 time 计时）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker rmi node:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;time&lt;/span&gt; docker pull node:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;直连 Docker Hub：~1m14s（国内典型）&lt;/li&gt;
&lt;li&gt;用镜像代理：~5-15s（视镜像大小）&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：公开镜像代理可能因合规或运营原因失效。生产环境建议&lt;strong&gt;自建 mirror&lt;/strong&gt;（用 &lt;code&gt;registry&lt;/code&gt; 镜像 + 反代），或者用云厂商（阿里云 ACR、DaoCloud）的企业级加速服务。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="七常见问题与排障"&gt;七、常见问题与排障
&lt;/h2&gt;&lt;h3 id="71-warning-ipv4-forwarding-is-disabled"&gt;7.1 WARNING: IPv4 forwarding is disabled
&lt;/h3&gt;&lt;p&gt;容器网络不通，dockerd 启动时打这条警告。&lt;strong&gt;生产环境装完 Docker 必须先修这个&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 临时启用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sysctl -w net.ipv4.ip_forward&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 永久（任选其一）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;net.ipv4.ip_forward=1&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 或&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;net.ipv4.ip_forward=1&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /usr/lib/sysctl.d/00-system.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 生效&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sysctl -p
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sysctl net.ipv4.ip_forward
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望输出：net.ipv4.ip_forward = 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="72-unknown-or-invalid-runtime-name-docker-runc"&gt;7.2 unknown or invalid runtime name: docker-runc
&lt;/h3&gt;&lt;p&gt;从老版本（Docker 18.06 之前）升级到 Docker 18.09+ 后，runtime 名从 &lt;code&gt;docker-runc&lt;/code&gt; 改为 &lt;code&gt;runc&lt;/code&gt;，老容器的 &lt;code&gt;hostconfig.json&lt;/code&gt; 还引用老名字，导致容器起不来。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 批量替换&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rl &lt;span class="s1"&gt;&amp;#39;docker-runc&amp;#39;&lt;/span&gt; /var/lib/docker/containers/ &lt;span class="p"&gt;|&lt;/span&gt; xargs sed -i &lt;span class="s1"&gt;&amp;#39;s/docker-runc/runc/g&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="73-live-restore让容器在-daemon-重启时不停机"&gt;7.3 live-restore：让容器在 daemon 重启时不停机
&lt;/h3&gt;&lt;p&gt;升级 Docker daemon 或 daemon 崩溃时，&lt;strong&gt;默认会停掉所有正在运行的容器&lt;/strong&gt;。开启 &lt;code&gt;live-restore&lt;/code&gt; 可让容器继续运行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;live-restore&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload docker.service &lt;span class="c1"&gt;# 注意是 reload 不是 restart&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker info &lt;span class="p"&gt;|&lt;/span&gt; grep -i live &lt;span class="c1"&gt;# 验证：Live Restore Enabled: true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;之后 &lt;code&gt;systemctl restart docker&lt;/code&gt; 时，容器不会停。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;多机同步&lt;/strong&gt;：在 K8s 集群里，可以用脚本批量同步 &lt;code&gt;daemon.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in master2 master3 worker1 worker3 worker4 worker5 worker6 worker7 worker8 worker9&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$NODE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /etc/docker/daemon.json &lt;span class="nv"&gt;$NODE&lt;/span&gt;:/etc/docker/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemctl daemon-reload &amp;amp;&amp;amp; systemctl reload docker &amp;amp;&amp;amp; systemctl restart docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h3 id="74-network-disconnect容器临时断网"&gt;7.4 network disconnect：容器临时断网
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 临时把容器从指定网络断开&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker network disconnect -f bridge &amp;lt;container_name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;排查网络问题时很有用——能快速判断&amp;quot;是容器问题还是网络问题&amp;quot;。&lt;/p&gt;
&lt;h2 id="八核心要点--常见坑"&gt;八、核心要点 / 常见坑
&lt;/h2&gt;&lt;p&gt;把这一篇的要点压缩成 8 条：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;bridge 模式是默认&lt;/strong&gt;（90% 场景），host 模式换性能换隔离，none 模式是沙箱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;端口映射必须用 &lt;code&gt;-p&lt;/code&gt;&lt;/strong&gt;——bridge 模式下不映射外部访问不了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器共享 netns&lt;/strong&gt;用 &lt;code&gt;container&lt;/code&gt; 模式，sidecar 利器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;指定固定 IP&lt;/strong&gt;必须用自定义网络，默认 bridge 不支持&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据持久化&lt;/strong&gt;用 Volume，&lt;code&gt;docker volume prune&lt;/code&gt; 是危险命令&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bind mount vs Volume&lt;/strong&gt;：配置/日志用 bind mount，数据库用 Volume&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;国内拉镜像&lt;/strong&gt;必须用代理或 mirror——&lt;code&gt;dockerproxy&lt;/code&gt; 系列、&lt;strong&gt;&lt;code&gt;ghcr.nju.edu.cn&lt;/code&gt;&lt;/strong&gt;、阿里云、DaoCloud 都要会&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;live-restore&lt;/strong&gt; 是 daemon 升级不停机的关键配置&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="九小结"&gt;九、小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;网络模式&lt;/strong&gt;：4 种核心模式（bridge / host / none / container）+ 自定义网络，理解 veth pair 是关键&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储卷&lt;/strong&gt;：Volume 管数据生命周期，bind mount 管配置文件，两手都要硬&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;镜像代理&lt;/strong&gt;：&lt;code&gt;dockerproxy&lt;/code&gt; 系列覆盖 Docker Hub / GCR / k8s.gcr.io / Quay，&lt;code&gt;ghcr.nju.edu.cn&lt;/code&gt; 补足 ghcr&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排障思路&lt;/strong&gt;：先看 &lt;code&gt;docker info&lt;/code&gt; 状态、再看 &lt;code&gt;journalctl -u docker&lt;/code&gt; 日志、最后看 iptables 和 netns&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;下一步&lt;/strong&gt;：单机 Docker 玩熟之后，下一步就是 Swarm / Kubernetes 的多机编排——那时网络（overlay / flannel / calico）、存储（Rexray / CSI）、调度（scheduler）都会变成新的核心议题。在 2019 年的 K8s 生态里，&lt;strong&gt;CoreDNS 已经取代 kube-dns 成为默认 DNS&lt;/strong&gt;，&lt;code&gt;ghcr.io&lt;/code&gt; 即将开放公开测试，镜像分发的格局正在重写——提前理解这些变化能少踩很多坑。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/network/drivers/" target="_blank" rel="noopener"
 &gt;Docker 网络驱动官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/network/" target="_blank" rel="noopener"
 &gt;Docker 网络模式详解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/storage/volumes/" target="_blank" rel="noopener"
 &gt;Docker Volume 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://dockerproxy.com/" target="_blank" rel="noopener"
 &gt;dockerproxy 镜像代理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://ghcr.nju.edu.cn" target="_blank" rel="noopener"
 &gt;南京大学 ghcr 镜像加速&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/coredns/coredns" target="_blank" rel="noopener"
 &gt;CoreDNS 官方仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.blog/2019-09-12-introducing-github-container-registry/" target="_blank" rel="noopener"
 &gt;GitHub Container Registry 公告&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.aliyun.com/product/acr" target="_blank" rel="noopener"
 &gt;阿里云容器镜像服务 ACR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/config/containers/live-restore/" target="_blank" rel="noopener"
 &gt;Live Restore 特性说明&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Docker 容器启动命令还原：cucker / runlike 工具对比</title><link>https://liangweidonggood.github.io/p/docker-recover-run-command/</link><pubDate>Wed, 15 Mar 2017 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/docker-recover-run-command/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/docker-recover-run-command/image/cover.jpg" alt="Featured image of post Docker 容器启动命令还原：cucker / runlike 工具对比" /&gt;&lt;p&gt;容器跑久了之后，&lt;strong&gt;谁、用什么参数起的&lt;/strong&gt;经常说不清。&lt;code&gt;docker inspect&lt;/code&gt; 能看到参数但格式反人类，&lt;strong&gt;没有一个工具能直接还原成 &lt;code&gt;docker run&lt;/code&gt; 命令&lt;/strong&gt;就是问题。&lt;/p&gt;
&lt;p&gt;社区里有三个工具专门干这事：&lt;strong&gt;cucker/get_command_4_run_container&lt;/strong&gt;、&lt;strong&gt;assaflavie/runlike&lt;/strong&gt;、&lt;strong&gt;joinsunsoft/runcommand&lt;/strong&gt;。这一篇把它们的使用、差异、坑点一次性说清楚。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：需要批量迁移容器、查历史启动参数、自动化复现容器配置的运维 / 开发者
&lt;strong&gt;覆盖范围&lt;/strong&gt;：三个工具的对比 + 实战演示 + 自定义 alias + 边界场景&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一问题为什么看启动参数这么难"&gt;一、问题：为什么&amp;quot;看启动参数&amp;quot;这么难
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;docker inspect&lt;/code&gt; 能看所有配置，但&lt;strong&gt;输出的 JSON 字段名和 &lt;code&gt;docker run&lt;/code&gt; 参数不一一对应&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker inspect mysql01 &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.[0].Config.Env&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;MYSQL_ROOT_PASSWORD=py123456&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;PATH=/usr/local/sbin:/usr/local/bin:...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker inspect mysql01 &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.[0].HostConfig.PortBindings&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;3306/tcp&amp;#34;&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;HostIp&amp;#34;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;HostPort&amp;#34;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;#34;13306&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;要把这些&lt;strong&gt;反向工程&lt;/strong&gt;成 &lt;code&gt;docker run -d --name mysql01 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=py123456 mysql&lt;/code&gt;，&lt;strong&gt;光看 JSON 就要在脑子里做几层翻译&lt;/strong&gt;。三个工具就是干这个的。&lt;/p&gt;
&lt;h2 id="二cuckerget_command_4_run_container"&gt;二、cucker/get_command_4_run_container
&lt;/h2&gt;&lt;p&gt;最老牌、用得最多的工具，&lt;strong&gt;Docker Hub 上被 pull 了 100w+ 次&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="21-拉取--跑"&gt;2.1 拉取 + 跑
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 拉镜像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull cucker/get_command_4_run_container:1.3
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 还原容器的启动命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cucker/get_command_4_run_container:1.3 &amp;lt;container-name-or-id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--rm&lt;/code&gt;——跑完就删容器&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v /var/run/docker.sock:/var/run/docker.sock&lt;/code&gt;——挂载 docker daemon 的 socket，&lt;strong&gt;让容器内的工具能跟宿主机的 daemon 通信&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;h3 id="22-输出示例"&gt;2.2 输出示例
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cucker/get_command_4_run_container:1.3 mysql01
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name mysql01 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --env &lt;span class="nv"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;py123456 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p 13306:3306/tcp &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;直接复制粘贴就能跑&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="23-配合-alias-用"&gt;2.3 配合 alias 用
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ~/.bashrc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;get_run_command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run_container:1.3&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get_run_command mysql01
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="三assaflavierunlike"&gt;三、assaflavie/runlike
&lt;/h2&gt;&lt;p&gt;另一个流行工具，&lt;strong&gt;和 cucker 类似但输出格式略有不同&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="31-用法"&gt;3.1 用法
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 拉镜像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull assaflavie/runlike
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 还原&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; assaflavie/runlike &amp;lt;container-name-or-id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="32-差异"&gt;3.2 差异
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;cucker&lt;/th&gt;
					&lt;th&gt;runlike&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;输出格式&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker run -d \\\n --name xxx \\\n ...&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker run -d --name xxx ...&lt;/code&gt;（一行）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;命名&lt;/td&gt;
					&lt;td&gt;短名（&lt;code&gt;mysql01&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;FQDN（&lt;code&gt;/mysql01&lt;/code&gt;，带斜杠）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;网络&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--network=bridge&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;--network=bridge&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多网络&lt;/td&gt;
					&lt;td&gt;部分支持&lt;/td&gt;
					&lt;td&gt;支持更全&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;维护&lt;/td&gt;
					&lt;td&gt;偶尔更新&lt;/td&gt;
					&lt;td&gt;较活跃&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="四joinsunsoftruncommand"&gt;四、joinsunsoft/runcommand
&lt;/h2&gt;&lt;p&gt;第三个工具，相对小众，&lt;strong&gt;但支持输出 docker-compose 格式&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; joinsunsoft/runcommand loki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;特色&lt;/strong&gt;：能输出 YAML 格式的 docker-compose 配置。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="五批量还原所有容器"&gt;五、批量还原所有容器
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 所有运行中容器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; CONTAINER in &lt;span class="k"&gt;$(&lt;/span&gt;docker ps --format &lt;span class="s1"&gt;&amp;#39;{{.Names}}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== &lt;/span&gt;&lt;span class="nv"&gt;$CONTAINER&lt;/span&gt;&lt;span class="s2"&gt; ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cucker/get_command_4_run_container:1.3 &lt;span class="nv"&gt;$CONTAINER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;典型场景&lt;/strong&gt;：接手一个&amp;quot;无文档&amp;quot;的 Docker 主机，&lt;strong&gt;用这个脚本快速还原整个部署&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="六还原-docker-compose-配置"&gt;六、还原 Docker Compose 配置
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;cucker&lt;/code&gt; 输出的是 &lt;code&gt;docker run&lt;/code&gt; 单条命令。如果容器是用 &lt;code&gt;docker-compose up&lt;/code&gt; 启动的，&lt;strong&gt;实际配置在 &lt;code&gt;docker-compose.yml&lt;/code&gt; 里&lt;/strong&gt;——还原不回来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变通方案&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 看容器实际配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker inspect &amp;lt;container&amp;gt; &amp;gt; /tmp/container.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 用 jq 提取关键字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker inspect &amp;lt;container&amp;gt; &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.[0].Config.Env&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker inspect &amp;lt;container&amp;gt; &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.[0].HostConfig.PortBindings&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker inspect &amp;lt;container&amp;gt; &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;.[0].Mounts&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者用社区脚本 &lt;a class="link" href="https://github.com/nexdrew/rekcod" target="_blank" rel="noopener"
 &gt;&lt;code&gt;rekcod&lt;/code&gt;&lt;/a&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 把任意容器还原成 docker-compose.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; nexdrew/rekcod &amp;lt;container&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="七常见坑"&gt;七、常见坑
&lt;/h2&gt;&lt;h3 id="71-permission-denied-挂载-socket"&gt;7.1 &lt;code&gt;permission denied&lt;/code&gt; 挂载 socket
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run_container:1.3 mysql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker: error during connect: ... permission denied
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linux&lt;/strong&gt;：当前用户在 &lt;code&gt;docker&lt;/code&gt; 用户组里，或者用 &lt;code&gt;sudo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mac/Windows (Docker Desktop)&lt;/strong&gt;：socket 路径在 VM 里，默认配置应该 OK&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Linux 上加 docker 组&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo usermod -aG docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;newgrp docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="72-还原出来的命令跑不起来"&gt;7.2 还原出来的命令&lt;strong&gt;跑不起来&lt;/strong&gt;
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Why&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;镜像已被删除（&lt;code&gt;docker rmi&lt;/code&gt; 过）&lt;/li&gt;
&lt;li&gt;网络 / 卷不存在&lt;/li&gt;
&lt;li&gt;端口冲突&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;cucker&lt;/code&gt; / &lt;code&gt;runlike&lt;/code&gt; 只还原&lt;strong&gt;配置&lt;/strong&gt;，不还原&lt;strong&gt;前置依赖&lt;/strong&gt;。&lt;strong&gt;先验证镜像还在&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker images &lt;span class="p"&gt;|&lt;/span&gt; grep mysql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mysql latest 7d0a4dc9b... &lt;span class="m"&gt;2&lt;/span&gt; weeks ago 546MB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="73-容器里有-bind-mount-到宿主机路径"&gt;7.3 容器里有 bind mount 到宿主机路径
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;cucker&lt;/code&gt; 还原的命令&lt;strong&gt;会保留&lt;/strong&gt; &lt;code&gt;-v /host/path:/container/path&lt;/code&gt;，但如果目标宿主机上 &lt;code&gt;/host/path&lt;/code&gt; 不存在，启动会失败。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配合 &lt;code&gt;creates&lt;/code&gt; 标记&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在还原的命令前先确保路径&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /host/path
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 再跑还原的命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d --name xxx -v /host/path:/container/path ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="74-docker-run-输出和-docker-composeyml-不一样"&gt;7.4 &lt;code&gt;docker run&lt;/code&gt; 输出和 &lt;code&gt;docker-compose.yml&lt;/code&gt; 不一样
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;实例&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 实际启动：docker-compose.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;version: &lt;span class="s2"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;services:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; nginx:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; image: nginx:1.19
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ports:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &lt;span class="s2"&gt;&amp;#34;8080:80&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - ./html:/usr/share/nginx/html
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; restart: always
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# cucker 还原&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d --name nginx -p 8080:80 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /root/project/html:/usr/share/nginx/html &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart&lt;span class="o"&gt;=&lt;/span&gt;always nginx:1.19
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Why 不一样&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compose 会自动加 &lt;code&gt;--name &amp;lt;project&amp;gt;_&amp;lt;service&amp;gt;_&amp;lt;index&amp;gt;&lt;/code&gt;（如 &lt;code&gt;project_nginx_1&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;compose 自动加 &lt;code&gt;com.docker.compose.*&lt;/code&gt; 标签&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bind mount 的相对路径&lt;/strong&gt;变成绝对路径&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;生产建议&lt;/strong&gt;：&lt;strong&gt;别用 cucker 还原 compose 启动的容器&lt;/strong&gt;——直接读 compose 文件最准。&lt;/p&gt;
&lt;h2 id="八工具对比"&gt;八、工具对比
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;cucker&lt;/th&gt;
					&lt;th&gt;runlike&lt;/th&gt;
					&lt;th&gt;runcommand&lt;/th&gt;
					&lt;th&gt;rekcod&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;输出格式&lt;/td&gt;
					&lt;td&gt;docker run&lt;/td&gt;
					&lt;td&gt;docker run&lt;/td&gt;
					&lt;td&gt;docker run&lt;/td&gt;
					&lt;td&gt;docker-compose&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;镜像大小&lt;/td&gt;
					&lt;td&gt;~30MB&lt;/td&gt;
					&lt;td&gt;~20MB&lt;/td&gt;
					&lt;td&gt;~25MB&lt;/td&gt;
					&lt;td&gt;~30MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多网络支持&lt;/td&gt;
					&lt;td&gt;部分&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;维护活跃&lt;/td&gt;
					&lt;td&gt;偶尔&lt;/td&gt;
					&lt;td&gt;活跃&lt;/td&gt;
					&lt;td&gt;少更新&lt;/td&gt;
					&lt;td&gt;活跃&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;推荐&lt;/td&gt;
					&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
					&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
					&lt;td&gt;⭐⭐&lt;/td&gt;
					&lt;td&gt;⭐⭐⭐&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="九最佳实践"&gt;九、最佳实践
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;核心生产环境&lt;/strong&gt;：&lt;strong&gt;写好 &lt;code&gt;docker-compose.yml&lt;/code&gt; + Git 版本管理&lt;/strong&gt;——别依赖&amp;quot;事后还原&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应急查命令&lt;/strong&gt;：&lt;code&gt;cucker&lt;/code&gt; / &lt;code&gt;runlike&lt;/code&gt; 一键还原&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量盘点&lt;/strong&gt;：用 for 循环扫所有容器，输出成文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要&lt;/strong&gt;把&amp;quot;还原命令&amp;quot;作为&amp;quot;日常运维工具&amp;quot;——&lt;strong&gt;SSoT 应该是 compose 文件 / K8s manifest&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="十要点回顾"&gt;十、要点回顾
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;cucker / runlike / runcommand / rekcod&lt;/strong&gt; 是社区主流的&amp;quot;反查启动命令&amp;quot;工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须挂载 &lt;code&gt;/var/run/docker.sock&lt;/code&gt;&lt;/strong&gt;——容器内的工具才能跟 daemon 通信&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;还原的命令可能不能直接跑&lt;/strong&gt;——镜像删除 / 路径不存在 / 端口冲突都常见&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;compose 启动的容器还原出来是 docker run 格式&lt;/strong&gt;——不是 compose&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生产 SSoT 应该是 compose / K8s manifest&lt;/strong&gt;——还原工具只应急&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="十一小结"&gt;十一、小结
&lt;/h2&gt;&lt;p&gt;&amp;ldquo;还原启动命令&amp;quot;是接手历史部署、自动化盘点、应急迁移的利器。但&lt;strong&gt;最佳实践仍然是把启动配置写在文件里&lt;/strong&gt;——&lt;code&gt;docker-compose.yml&lt;/code&gt; / K8s manifest，&lt;strong&gt;让 Git 成为 SSoT&lt;/strong&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;下一步&lt;/strong&gt;：理解了&amp;quot;还原单条启动命令&amp;rdquo;，下一步是&amp;quot;还原整套部署&amp;quot;——&lt;code&gt;rekcod&lt;/code&gt; 风格的 docker-compose 还原、Helm chart 模板化、Kustomize 跨环境覆盖——把&amp;quot;凭记忆启动&amp;quot;变成&amp;quot;声明式部署&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/docker-community-tools/docker-runcommand" target="_blank" rel="noopener"
 &gt;cucker/get_command_4_run_container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/lavie/runlike" target="_blank" rel="noopener"
 &gt;assaflavie/runlike&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/joinsunsoft/runcommand" target="_blank" rel="noopener"
 &gt;joinsunsoft/runcommand&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/nexdrew/rekcod" target="_blank" rel="noopener"
 &gt;nexdrew/rekcod&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>宝塔与 1Panel：两款 Linux 服务器管理面板的 Docker 部署实战</title><link>https://liangweidonggood.github.io/p/bao-ta-yu-1panel/</link><pubDate>Mon, 15 Dec 2014 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/bao-ta-yu-1panel/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/bao-ta-yu-1panel/image/cover.jpg" alt="Featured image of post 宝塔与 1Panel：两款 Linux 服务器管理面板的 Docker 部署实战" /&gt;&lt;p&gt;Linux 服务器的&amp;quot;装系统、装环境、装服务&amp;quot;过去全靠命令行——装一个 Nginx 要写一长串 apt / yum 指令，配置 SSL 还要碰 openssl 的细节，对刚入门的人来说门槛不低。&amp;ldquo;服务器管理面板&amp;quot;就是为了把这套流程做成 Web 化、可视化的产品：宝塔、1Panel、AppNode、URLOS、aaPanel 都是这一脉的代表。这篇文章聚焦两款最常见的产品——&lt;strong&gt;宝塔（pch18/baota）&lt;/strong&gt; 和 &lt;strong&gt;moelin/1Panel&lt;/strong&gt;——把它们的 Docker 部署、目录映射、默认凭据和排错一次性说清楚。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：刚接触 Linux、想把日常运维（站点、数据库、SSL、计划任务）从命令行解放出来的同学；以及需要在容器里跑管理面板的 CI/CD / 演示环境搭建者。
&lt;strong&gt;覆盖范围&lt;/strong&gt;：宝塔（CentOS/Debian 一键脚本 + pch18/baota 镜像）的安装与目录映射；1Panel 的 docker run / docker-compose 启动、目录约定、默认账户与首次进入。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一为什么需要服务器管理面板"&gt;一、为什么需要&amp;quot;服务器管理面板&amp;rdquo;
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;痛点&lt;/th&gt;
					&lt;th&gt;命令行解法&lt;/th&gt;
					&lt;th&gt;面板解法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;装 Nginx/PHP/MySQL/Redis 一套 LNMP&lt;/td&gt;
					&lt;td&gt;多个 &lt;code&gt;apt install&lt;/code&gt; + 手动改配置&lt;/td&gt;
					&lt;td&gt;选 LNP/MPN 模板，一键安装&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;给站点申请/部署 SSL 证书&lt;/td&gt;
					&lt;td&gt;手写 &lt;code&gt;acme.sh&lt;/code&gt; cron + nginx 站点配置&lt;/td&gt;
					&lt;td&gt;域名 → 申请 → 自动续期&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;看磁盘/CPU/网络&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;df -h&lt;/code&gt; / &lt;code&gt;top&lt;/code&gt; / &lt;code&gt;vmstat&lt;/code&gt; 拼图&lt;/td&gt;
					&lt;td&gt;仪表盘一屏看完&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多用户/多站点权限隔离&lt;/td&gt;
					&lt;td&gt;nginx vhost + sudo 配置&lt;/td&gt;
					&lt;td&gt;图形化&amp;quot;网站 → 权限&amp;quot;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器化部署&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;docker run&lt;/code&gt; / &lt;code&gt;docker compose&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&amp;ldquo;应用商店&amp;rdquo; 里点一下&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;：单台/几台机器、想快速搞起一套 Web 环境、不想折腾配置时；或团队需要让非运维同学也能上手时。Kubernetes 集群级别仍然不靠面板，而是 Helm + GitOps。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二宝塔面板pch18baota"&gt;二、宝塔面板（pch18/baota）
&lt;/h2&gt;&lt;p&gt;宝塔是国产老牌面板，最早（2014 年）发布的是一键安装脚本，覆盖 CentOS/Debian/Ubuntu。后来社区出了 &lt;code&gt;pch18/baota&lt;/code&gt; 镜像，让它可以跑在 Docker 里——非常适合演示、CI、临时环境。&lt;/p&gt;
&lt;h3 id="21-原生安装一键脚本"&gt;2.1 原生安装（一键脚本）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# CentOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yum install -y wget &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; wget -O install.sh https://download.bt.cn/install/install_6.0.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sh install.sh ed8484bec
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Debian / Ubuntu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo bash install.sh ed8484bec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装完后会输出管理地址（通常是 &lt;code&gt;http://&amp;lt;IP&amp;gt;:8888/&amp;lt;随机入口&amp;gt;&lt;/code&gt;）和默认账号。&lt;/p&gt;
&lt;h3 id="22-docker-部署-pch18baota"&gt;2.2 Docker 部署 pch18/baota
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;核心思路&lt;/strong&gt;：把 &lt;code&gt;/www&lt;/code&gt; 目录从容器里拷出来挂到宿主机，这样重启/升级容器不会丢数据。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 第一次启动（host 网络，端口全开）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -tid --name baota --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p 8002:80 -p 8043:443 -p 8808:8888 -p 808:888 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --privileged&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --shm-size&lt;span class="o"&gt;=&lt;/span&gt;1g &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pch18/baota:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 把容器里的 /www 拷出来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker cp baota:/www /home/docker/baota
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 关掉临时容器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker rm -f baota
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;接下来用持久化的方式重新启动（推荐）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /home/docker/baota/www/wwwroot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# host 网络（推荐：避免端口转发的性能损失）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -tid --name baota --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --net&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --privileged&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --shm-size&lt;span class="o"&gt;=&lt;/span&gt;1g &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /home/docker/baota/www:/www &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /home/docker/baota/www/wwwroot:/www/wwwroot &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pch18/baota:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bridge 网络（如需端口隔离）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -tid --name baota --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p 8002:80 -p 8043:443 -p 8808:8888 -p 808:888 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --privileged&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --shm-size&lt;span class="o"&gt;=&lt;/span&gt;1g &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /home/docker/baota/www:/www &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /home/docker/baota/www/wwwroot:/www/wwwroot &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pch18/baota:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;端口说明&lt;/strong&gt;：&lt;code&gt;80:80&lt;/code&gt;（HTTP）、&lt;code&gt;443:443&lt;/code&gt;（HTTPS）、&lt;code&gt;8888:8888&lt;/code&gt;（面板）、&lt;code&gt;888&lt;/code&gt;（phpMyAdmin）。&lt;code&gt;--shm-size=1g&lt;/code&gt; 给 PHP 足够的共享内存，&lt;code&gt;--privileged=true&lt;/code&gt; 让面板能在容器里调 systemd / mount 等特权操作。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;访问入口&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;http://&amp;lt;宿主机IP&amp;gt;:8808/login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;默认账号 &lt;code&gt;username/password&lt;/code&gt; 会在控制台输出，登录后必须改密码。&lt;/p&gt;
&lt;h3 id="23-进入容器操作"&gt;2.3 进入容器操作
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker logs -f --tail&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt; baota
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it baota bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 容器内的命令行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@&amp;lt;container&amp;gt; wwwroot&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# bt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;===============&lt;/span&gt;&lt;span class="nv"&gt;宝塔面板命令行&lt;/span&gt;&lt;span class="o"&gt;==================&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt; 重启面板服务 &lt;span class="o"&gt;(&lt;/span&gt;8&lt;span class="o"&gt;)&lt;/span&gt; 改面板端口
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt; 停止面板服务 &lt;span class="o"&gt;(&lt;/span&gt;9&lt;span class="o"&gt;)&lt;/span&gt; 清除面板缓存
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt; 启动面板服务 &lt;span class="o"&gt;(&lt;/span&gt;10&lt;span class="o"&gt;)&lt;/span&gt; 清除登录限制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt; 重载面板服务 &lt;span class="o"&gt;(&lt;/span&gt;11&lt;span class="o"&gt;)&lt;/span&gt; 取消入口限制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;5&lt;span class="o"&gt;)&lt;/span&gt; 修改面板密码 &lt;span class="o"&gt;(&lt;/span&gt;12&lt;span class="o"&gt;)&lt;/span&gt; 取消域名绑定限制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;6&lt;span class="o"&gt;)&lt;/span&gt; 修改面板用户名 &lt;span class="o"&gt;(&lt;/span&gt;13&lt;span class="o"&gt;)&lt;/span&gt; 取消IP访问限制
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;7&lt;span class="o"&gt;)&lt;/span&gt; 强制修改MySQL密码 &lt;span class="o"&gt;(&lt;/span&gt;14&lt;span class="o"&gt;)&lt;/span&gt; 查看面板默认信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;22&lt;span class="o"&gt;)&lt;/span&gt; 显示面板错误日志 &lt;span class="o"&gt;(&lt;/span&gt;15&lt;span class="o"&gt;)&lt;/span&gt; 清理系统垃圾
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;23&lt;span class="o"&gt;)&lt;/span&gt; 关闭BasicAuth认证 &lt;span class="o"&gt;(&lt;/span&gt;16&lt;span class="o"&gt;)&lt;/span&gt; 修复面板
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;24&lt;span class="o"&gt;)&lt;/span&gt; 关闭谷歌认证 &lt;span class="o"&gt;(&lt;/span&gt;17&lt;span class="o"&gt;)&lt;/span&gt; 设置日志切割是否压缩
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;25&lt;span class="o"&gt;)&lt;/span&gt; 设置是否保存文件历史副本 &lt;span class="o"&gt;(&lt;/span&gt;18&lt;span class="o"&gt;)&lt;/span&gt; 设置是否自动备份面板
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt; 取消
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="24-常见问题"&gt;2.4 常见问题
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Q1：&lt;code&gt;lsattr: Operation not supported While reading flags on python&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;容器化宝塔有时会触发这个错误（共享卷的属性查询在内核层不支持）。解决：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /www/server/panel/pyenv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl http://download.bt.cn/install/update_panel.sh &lt;span class="p"&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Q2：&lt;code&gt;Error: BT-Panel service startup failed.&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;通常是端口被占用或权限问题。重新跑一次安装脚本即可。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三1panelmoelin1panel"&gt;三、1Panel（moelin/1Panel）
&lt;/h2&gt;&lt;p&gt;1Panel 是 2022 年开源的新一代面板（飞致云出品），定位&amp;quot;现代化、开源、安全&amp;quot;，界面更现代，自带&amp;quot;应用商店&amp;quot;。Docker 化的 &lt;code&gt;moelin/1Panel&lt;/code&gt; 镜像让体验完整保留。&lt;/p&gt;
&lt;h3 id="31-docker-run-启动"&gt;3.1 docker run 启动
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name 1panel &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --restart always &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p 10087:10086 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /var/lib/docker/volumes:/var/lib/docker/volumes &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /opt:/opt &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /root:/root &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -v /data:/data &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -e &lt;span class="nv"&gt;TZ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Asia/Shanghai &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; moelin/1panel:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="32-docker-compose-启动"&gt;3.2 docker-compose 启动
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1panel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1panel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;network_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/var/lib/docker/volumes:/var/lib/docker/volumes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/opt:/opt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/root:/root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;TZ=Asia/Shanghai&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;moelin/1panel:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;createdBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Apps&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="33-首次进入"&gt;3.3 首次进入
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it 1panel bash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;root@&amp;lt;host&amp;gt;:/$ 1pctl user-info
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;面板地址: http://&lt;span class="nv"&gt;$LOCAL_IP&lt;/span&gt;:10086/entrance
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;面板用户: 1panel
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;面板密码: &amp;lt;随机生成&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;提示：修改密码可执行命令：1pctl update password
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;访问 &lt;code&gt;http://&amp;lt;宿主机IP&amp;gt;:10086/entrance&lt;/code&gt;（不是 10087，是容器内 10086 端口暴露给宿主的入口）。&lt;/p&gt;
&lt;h3 id="34-关键约定"&gt;3.4 关键约定
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;项&lt;/th&gt;
					&lt;th&gt;值&lt;/th&gt;
					&lt;th&gt;备注&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;默认端口&lt;/td&gt;
					&lt;td&gt;10086&lt;/td&gt;
					&lt;td&gt;通过 &lt;code&gt;-p 10087:10086&lt;/code&gt; 映射&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;默认账号&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;1panel&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;默认密码&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;1panel_password&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;第一次安装随机生成&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;默认入口&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;entrance&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;即 URL 末尾的 &lt;code&gt;entrance&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="35-注意事项"&gt;3.5 注意事项
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;容器化部署的 1Panel 升级&lt;/strong&gt;：不要点 UI 里的&amp;quot;立即更新&amp;quot;，&lt;strong&gt;应该拉新镜像 → 删除旧容器 → 用同样的目录映射重新部署&lt;/strong&gt;。容器内 systemd 不完整，UI 升级路径会卡住。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不可调整的挂载&lt;/strong&gt;：&lt;code&gt;/var/run/docker.sock&lt;/code&gt;（必须挂，否则 1Panel 不能管理宿主机上的容器）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可调整的挂载&lt;/strong&gt;：&lt;code&gt;/opt&lt;/code&gt;（应用数据）、&lt;code&gt;/root&lt;/code&gt;（可选）、&lt;code&gt;/var/lib/docker/volumes&lt;/code&gt;（Docker 卷）、&lt;code&gt;TZ=Asia/Shanghai&lt;/code&gt;（时区）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;systemd 限制&lt;/strong&gt;：因为容器内 systemd 不完整，部分面板功能（开机自启、服务守护）可能表现异常，复杂场景仍建议在裸机上跑 1Panel。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="四宝塔-vs-1panel怎么选"&gt;四、宝塔 vs 1Panel：怎么选
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;宝塔&lt;/th&gt;
					&lt;th&gt;1Panel&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;起源&lt;/td&gt;
					&lt;td&gt;2014 国产老牌&lt;/td&gt;
					&lt;td&gt;2022 飞致云开源&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;资源占用&lt;/td&gt;
					&lt;td&gt;较低（约 200MB）&lt;/td&gt;
					&lt;td&gt;较高（Go 后端 + 前端）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Docker 支持&lt;/td&gt;
					&lt;td&gt;较弱（&amp;ldquo;Docker 容器&amp;quot;模块粗糙）&lt;/td&gt;
					&lt;td&gt;原生设计（&amp;ldquo;应用商店&amp;quot;直接装 WordPress / Halo / Halo 2）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;应用商店&lt;/td&gt;
					&lt;td&gt;第三方脚本合集&lt;/td&gt;
					&lt;td&gt;内置官方市场（MySQL、Redis、Nginx、PHP 一键装）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;主机防火墙&lt;/td&gt;
					&lt;td&gt;无图形化（要装 iptables 插件）&lt;/td&gt;
					&lt;td&gt;内置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Web 终端&lt;/td&gt;
					&lt;td&gt;宝塔 SSH 终端&lt;/td&gt;
					&lt;td&gt;内置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HTTPS 证书&lt;/td&gt;
					&lt;td&gt;一键申请 + 自动续期&lt;/td&gt;
					&lt;td&gt;一键申请 + 自动续期&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;备份&lt;/td&gt;
					&lt;td&gt;面板级 + 站点级&lt;/td&gt;
					&lt;td&gt;面板级 + 计划任务 cron&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适合&lt;/td&gt;
					&lt;td&gt;老项目、LAMP/LNMP 站群、内存小的机器&lt;/td&gt;
					&lt;td&gt;新项目、容器化部署、想要现代 UI&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;经验法则&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内存 ≥ 4GB + 想&amp;quot;装 WordPress / 各类应用&amp;rdquo; → 1Panel&lt;/li&gt;
&lt;li&gt;内存 ≤ 2GB + 老项目维护 + 习惯原生命令 → 宝塔&lt;/li&gt;
&lt;li&gt;临时演示 / CI 环境 → pch18/baota 镜像（不用装扩展）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="五扩展阅读"&gt;五、扩展阅读
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;宝塔官方：&lt;a class="link" href="https://www.bt.cn/" target="_blank" rel="noopener"
 &gt;bt.cn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1Panel 官方：&lt;a class="link" href="https://1panel.cn/" target="_blank" rel="noopener"
 &gt;1panel.cn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;pch18/baota 镜像：&lt;a class="link" href="https://hub.docker.com/r/pch18/baota" target="_blank" rel="noopener"
 &gt;hub.docker.com/r/pch18/baota&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;moelin/1panel 镜像：&lt;a class="link" href="https://hub.docker.com/r/moelin/1panel" target="_blank" rel="noopener"
 &gt;hub.docker.com/r/moelin/1panel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Docker 数据目录搬家：磁盘满的根治方案</title><link>https://liangweidonggood.github.io/p/docker-data-dir-move/</link><pubDate>Sat, 15 Mar 2014 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/docker-data-dir-move/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/docker-data-dir-move/image/cover.jpg" alt="Featured image of post Docker 数据目录搬家：磁盘满的根治方案" /&gt;&lt;p&gt;服务器跑 Docker 一段时间后，最常见的事故就是 &lt;strong&gt;&lt;code&gt;/&lt;/code&gt; 分区被 &lt;code&gt;/var/lib/docker&lt;/code&gt; 吃满&lt;/strong&gt;——尤其是 &lt;code&gt;/var&lt;/code&gt; 单独分区且容量规划不足的老机器。&lt;code&gt;overlay2&lt;/code&gt; 一旦把某个容器层写满，&lt;strong&gt;容器起不来、镜像拉不下，连 &lt;code&gt;docker ps&lt;/code&gt; 都可能 hang&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这一篇把&amp;quot;如何把 Docker 数据目录整体搬家到大容量磁盘&amp;quot;的完整流程串起来，覆盖 &lt;code&gt;--graph&lt;/code&gt;（旧）、&lt;code&gt;data-root&lt;/code&gt;（新）、systemd 配置改写、systemd 重新加载四大关键步骤。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;阅读对象&lt;/strong&gt;：在生产环境管理 Docker 主机、被 &lt;code&gt;/var/lib/docker&lt;/code&gt; 撑爆过的运维同学
&lt;strong&gt;覆盖范围&lt;/strong&gt;：磁盘诊断 + 备份停机 + 移动 / 软链 / 修改 data-root + systemd reload 验证&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一为什么需要搬家"&gt;一、为什么需要搬家
&lt;/h2&gt;&lt;p&gt;典型事故现场：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ df -h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Filesystem Size Used Avail Use% Mounted on
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/dev/sda1 11G 8.4G 2.0G 82% /
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/dev/sda5 2.3G 2.3G &lt;span class="m"&gt;0&lt;/span&gt; 100% /var
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/dev/sda8 82G 204M 78G 1% /home
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# overlay 挂载点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;overlay 2.3G 2.3G &lt;span class="m"&gt;0&lt;/span&gt; 100% /var/lib/docker/overlay2/f18.../merged
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;/var&lt;/code&gt; 满了，&lt;strong&gt;&lt;code&gt;/var/lib/docker/overlay2/&lt;/code&gt; 的容器可写层跟着满&lt;/strong&gt;。容器进程写文件会 ENOSPC，dockerd 也会大量报错。&lt;/p&gt;
&lt;p&gt;常见解法（按推荐度）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;加大 &lt;code&gt;/var&lt;/code&gt; 分区&lt;/strong&gt;（最干净，但需要停机 + 重新分区）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迁移到 &lt;code&gt;/home&lt;/code&gt; 大分区&lt;/strong&gt;（推荐，本文重点）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;清理无用镜像 / 卷 / 容器&lt;/strong&gt;（治标不治本）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LVM 动态扩容&lt;/strong&gt;（要预先用 LVM）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;优先选 2&lt;/strong&gt;：风险可控、几分钟内完成、不需要动分区表。&lt;/p&gt;
&lt;h2 id="二核心机制docker-把数据放哪"&gt;二、核心机制：Docker 把数据放哪
&lt;/h2&gt;&lt;p&gt;Docker 把所有持久化数据（images、containers、volumes、networks、build cache、overlay2 层）放在一个&lt;strong&gt;根目录&lt;/strong&gt;，Linux 上默认是 &lt;code&gt;/var/lib/docker&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker info &lt;span class="p"&gt;|&lt;/span&gt; grep -i &lt;span class="s1"&gt;&amp;#39;root dir\|storage driver&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Docker Root Dir: /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Storage Driver: overlay2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Docker 1.3+（2014-10 GA）开始支持&lt;strong&gt;自定义根目录&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docker 1.3 ~ 17.05&lt;/strong&gt;：用 &lt;code&gt;--graph&lt;/code&gt; 参数（旧）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker 17.05+（2017-05 GA）&lt;/strong&gt;：用 &lt;code&gt;daemon.json&lt;/code&gt; 的 &lt;code&gt;data-root&lt;/code&gt; 字段（新）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两种方式&lt;strong&gt;二选一，不要混用&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="三搬家完整流程"&gt;三、搬家完整流程
&lt;/h2&gt;&lt;h3 id="31-第一步停-docker"&gt;3.1 第一步：停 Docker
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;必须先停 daemon&lt;/strong&gt;——&lt;code&gt;/var/lib/docker&lt;/code&gt; 在被读写时直接 mv 会损坏文件系统层。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停 containerd（如果装了新版 Docker）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop containerd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证：进程应该没了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ps -ef &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s1"&gt;&amp;#39;dockerd|containerd&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -v grep
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;不要用 &lt;code&gt;kill -9&lt;/code&gt;&lt;/strong&gt;：dockerd 收到 SIGKILL 不会做优雅清理，可能留下半完成的 overlay 层。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="32-第二步移动目录"&gt;3.2 第二步：移动目录
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 假设 /home 是大容量盘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv /var/lib/docker /home/docker-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证大小一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;du -sh /var/lib/docker /home/docker-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证空间释放&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;df -h
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Why 必须 &lt;code&gt;mv&lt;/code&gt; 而不是 &lt;code&gt;cp&lt;/code&gt;&lt;/strong&gt;：mv 在同文件系统是 rename（原子操作），跨文件系统 mv 是 copy + delete。&lt;strong&gt;跨盘 mv 等价于 cp&lt;/strong&gt;——这是 Linux 文件系统层面的事，确保 &lt;code&gt;mv&lt;/code&gt; 源和目标是同一文件系统。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证是否同文件系统&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stat -c &lt;span class="s1"&gt;&amp;#39;%m&amp;#39;&lt;/span&gt; /var /home
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 输出相同数字 = 同文件系统（不需要重命名）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 输出不同 = 跨文件系统（需要走 rsync 校验）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;跨文件系统的&amp;quot;安全搬家&amp;quot;姿势：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -aHAX /var/lib/docker/ /home/docker-data/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证 md5 一致&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;diff -r /var/lib/docker /home/docker-data &lt;span class="c1"&gt;# 不应有输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 然后删旧的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="33-第三步告诉-docker-新位置"&gt;3.3 第三步：告诉 Docker 新位置
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;方式 A（推荐，新写法）&lt;/strong&gt;：编辑 &lt;code&gt;daemon.json&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vim /etc/docker/daemon.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;data-root&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/home/docker-data&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Why 优先 &lt;code&gt;data-root&lt;/code&gt;&lt;/strong&gt;：JSON 配置可被 &lt;code&gt;dockerd&lt;/code&gt; 热加载（&lt;code&gt;SIGHUP&lt;/code&gt; 触发），版本升级时&lt;strong&gt;不会&lt;/strong&gt;因为 &lt;code&gt;docker.service&lt;/code&gt; 被包管理器重写而失效。&lt;code&gt;--graph&lt;/code&gt; 在 &lt;code&gt;docker.service&lt;/code&gt; 里，包升级可能被覆盖。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;方式 B（旧写法，已不推荐）&lt;/strong&gt;：改 &lt;code&gt;docker.service&lt;/code&gt; 的 &lt;code&gt;ExecStart&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/dockerd \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; -H fd:// --containerd=/run/containerd/containerd.sock \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; --graph /home/docker-data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="34-第四步让-systemd-重新加载"&gt;3.4 第四步：让 systemd 重新加载
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;这一步 90% 的事故都出在这里&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 重新加载 systemd 的 unit 文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 重新 enable（重要！某些版本不 re-enable 会用旧路径）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl disable docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;常见错误&lt;/strong&gt;：跳过 &lt;code&gt;daemon-reload&lt;/code&gt;。systemd 把 unit 文件缓存在内存里，&lt;strong&gt;不 reload 就 start 等于用旧配置&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="35-第五步验证"&gt;3.5 第五步：验证
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 看根目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker info &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;&amp;#39;Docker Root Dir&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望：Docker Root Dir: /home/docker-data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 看镜像和容器还在不在&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker images
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker ps -a
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 看磁盘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;df -h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /home 应该有显著使用量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;完整验证输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ docker info &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s1"&gt;&amp;#39;Root Dir|Storage Driver&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Docker Root Dir: /home/docker-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Storage Driver: overlay2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="四补充用软链代替改配置"&gt;四、补充：用软链代替改配置
&lt;/h2&gt;&lt;p&gt;如果不想动 &lt;code&gt;daemon.json&lt;/code&gt; / &lt;code&gt;docker.service&lt;/code&gt;，&lt;strong&gt;最轻量的方案是软链&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 停 docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 移动数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv /var/lib/docker /home/docker-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建软链&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s /home/docker-data /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 期望：/var/lib/docker -&amp;gt; /home/docker-data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;优缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不改任何配置，包升级不会破坏&lt;/li&gt;
&lt;li&gt;适合&amp;quot;快速止血&amp;quot;——几秒钟搞定&lt;/li&gt;
&lt;li&gt;软链对部分工具不友好（如 &lt;code&gt;realpath&lt;/code&gt;、监控脚本可能误判）&lt;/li&gt;
&lt;li&gt;不能跨机器迁移&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;h2 id="五多机同步批量改所有-docker-节点"&gt;五、多机同步：批量改所有 Docker 节点
&lt;/h2&gt;&lt;p&gt;在 K8s 集群或 Docker Swarm 集群里，所有节点的 Docker 数据目录最好一致。用 SSH 批量同步：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 假设 master1 已经改好&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in master2 master3 worker1 worker2 worker3&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;=== &lt;/span&gt;&lt;span class="nv"&gt;$NODE&lt;/span&gt;&lt;span class="s2"&gt; ===&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemctl stop docker &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; rsync -aHAX --delete root@master1:/home/docker-data/ /home/docker-data/ &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; cp /etc/docker/daemon.json /etc/docker/ &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl daemon-reload &amp;amp;&amp;amp; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; systemctl start docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者用 &lt;code&gt;scp&lt;/code&gt; 单文件同步（更轻量，但只适合 daemon.json 小配置）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 同步 daemon.json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; NODE in worker1 worker2&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$NODE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; scp /etc/docker/daemon.json &lt;span class="nv"&gt;$NODE&lt;/span&gt;:/etc/docker/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssh root@&lt;span class="nv"&gt;$NODE&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemctl daemon-reload &amp;amp;&amp;amp; systemctl reload docker &amp;amp;&amp;amp; systemctl restart docker&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;生产警示&lt;/strong&gt;：在 K8s 集群里改 &lt;code&gt;data-root&lt;/code&gt;，&lt;strong&gt;需要先 drain 节点&lt;/strong&gt;（&lt;code&gt;kubectl drain &amp;lt;node&amp;gt; --ignore-daemonsets&lt;/code&gt;），否则上面跑的 Pod 会被 dockerd 重启打断。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="六回滚"&gt;六、回滚
&lt;/h2&gt;&lt;p&gt;万一新位置起不来：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 停 docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl stop docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 改回原路径&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 方式 A：改 daemon.json 的 &amp;#34;data-root&amp;#34; 为 /var/lib/docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 方式 B：删软链，恢复原目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv /home/docker-data /var/lib/docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 重启&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;保留原目录一段时间再删&lt;/strong&gt;——线上至少保留 24-48h，确认新位置稳定后再清理。&lt;/p&gt;
&lt;h2 id="七要点回顾"&gt;七、要点回顾
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;停 docker → mv → 改配置 → daemon-reload → start&lt;/strong&gt;，五步缺一不可&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优先用 &lt;code&gt;daemon.json&lt;/code&gt; 的 &lt;code&gt;data-root&lt;/code&gt;&lt;/strong&gt;（2017-05+），&lt;code&gt;--graph&lt;/code&gt; 是旧写法&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须 &lt;code&gt;systemctl daemon-reload&lt;/code&gt;&lt;/strong&gt;，否则 systemd 用缓存的旧 unit 文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨文件系统搬家用 &lt;code&gt;rsync -aHAX&lt;/code&gt;&lt;/strong&gt;，再用 &lt;code&gt;diff -r&lt;/code&gt; 校验&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;软链是快速止血方案&lt;/strong&gt;，但不适合监控 / 巡检脚本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K8s 集群里改 &lt;code&gt;data-root&lt;/code&gt; 要先 &lt;code&gt;kubectl drain&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="八小结"&gt;八、小结
&lt;/h2&gt;&lt;p&gt;Docker 数据目录搬家是&lt;strong&gt;最朴素也最容易踩坑&lt;/strong&gt;的运维操作——错一步可能就是&amp;quot;daemon 起不来 + 容器全失联&amp;quot;。把&amp;quot;停 → 移 → 配 → reload → 验&amp;quot;这套流程跑成肌肉记忆，&lt;strong&gt;比记命令更重要&lt;/strong&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;下一步&lt;/strong&gt;：理解数据目录结构后，下一层是清理策略——&lt;code&gt;docker system prune&lt;/code&gt; 是什么、&lt;code&gt;dangling&lt;/code&gt; 镜像和未使用卷如何批量清，以及怎么写一个不丢数据的&amp;quot;安全清理&amp;quot;脚本。&lt;code&gt;/var/lib/docker&lt;/code&gt; 的体积管理是一个长期工程。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-data-root" target="_blank" rel="noopener"
 &gt;Docker daemon 配置 data-root&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/config/daemon/" target="_blank" rel="noopener"
 &gt;Docker &amp;ndash;graph 参数（已废弃）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.freedesktop.org/software/systemd/man/systemctl.html" target="_blank" rel="noopener"
 &gt;systemctl daemon-reload 的必要性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://rsync.samba.org/examples.html" target="_blank" rel="noopener"
 &gt;rsync -aHAX 跨文件系统数据迁移&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Windows 系统快捷键 + Alt 码速查：研发与运维都该会的几组组合</title><link>https://liangweidonggood.github.io/p/windows-system-shortcuts-2013/</link><pubDate>Sun, 15 Dec 2013 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/windows-system-shortcuts-2013/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/windows-system-shortcuts-2013/image/cover.jpg" alt="Featured image of post Windows 系统快捷键 + Alt 码速查：研发与运维都该会的几组组合" /&gt;&lt;h2 id="一为什么快捷键是最低成本的提效"&gt;一、为什么&amp;quot;快捷键&amp;quot;是最低成本的提效
&lt;/h2&gt;&lt;p&gt;2013 年的 Windows 8 把开始菜单藏了、Win 键组合被大面积改写，Win 10/11 又把搜索框塞到任务栏——但&lt;strong&gt;最经典的几个组合&lt;/strong&gt;始终没变。运维和研发每天面对 10+ 个窗口、PowerShell、VS Code、远程桌面，&lt;strong&gt;5 个手指不动到鼠标&lt;/strong&gt;就能完成的操作才是真效率。&lt;/p&gt;
&lt;p&gt;本文按&amp;quot;日常 → 窗口管理 → 文字编辑 → 特殊字符 → 系统调试&amp;quot;五层递进，每组都给最短路径。&lt;/p&gt;
&lt;h2 id="二5-个必会的救命组合"&gt;二、5 个必会的&amp;quot;救命&amp;quot;组合
&lt;/h2&gt;&lt;h3 id="21-win--s-打开搜索"&gt;2.1 &lt;code&gt;Win + S&lt;/code&gt; 打开搜索
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;全宇宙最常用的 Windows 快捷键&lt;/strong&gt;。Win 8 开始就是打开&amp;quot;开始菜单 + 搜索&amp;quot;二合一：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入 &lt;code&gt;powershell&lt;/code&gt; 直接回车，启动 PowerShell&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;cmd&lt;/code&gt; 直达命令提示符&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;regedit&lt;/code&gt; 进注册表&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;mstsc&lt;/code&gt; 远程桌面&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;ncpa.cpl&lt;/code&gt; 进网络连接&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-win--d-显示桌面"&gt;2.2 &lt;code&gt;Win + D&lt;/code&gt; 显示桌面
&lt;/h3&gt;&lt;p&gt;一键最小化所有窗口到任务栏，&lt;strong&gt;再按一次还原&lt;/strong&gt;。比鼠标找右下角快一个量级。&lt;/p&gt;
&lt;h3 id="23-win--i-打开设置"&gt;2.3 &lt;code&gt;Win + I&lt;/code&gt; 打开设置
&lt;/h3&gt;&lt;p&gt;替代 2013 年开始被弱化的&amp;quot;控制面板&amp;quot;（Win 10/11 上是新版&amp;quot;设置&amp;quot;），常用入口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;网络：&lt;code&gt;Win + I&lt;/code&gt; → 网络和 Internet&lt;/li&gt;
&lt;li&gt;蓝牙 / 设备：&lt;code&gt;Win + I&lt;/code&gt; → 设备&lt;/li&gt;
&lt;li&gt;主题 / 锁屏：&lt;code&gt;Win + I&lt;/code&gt; → 个性化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="24-win--l-锁屏"&gt;2.4 &lt;code&gt;Win + L&lt;/code&gt; 锁屏
&lt;/h3&gt;&lt;p&gt;离开工位一秒就锁，&lt;strong&gt;比 &lt;code&gt;Ctrl + Alt + Del&lt;/code&gt; 快得多&lt;/strong&gt;，且不需要二次确认。&lt;/p&gt;
&lt;h3 id="25-win--e-打开文件资源管理器"&gt;2.5 &lt;code&gt;Win + E&lt;/code&gt; 打开文件资源管理器
&lt;/h3&gt;&lt;p&gt;直接进入&amp;quot;此电脑&amp;quot;，比开始菜单点&amp;quot;我的电脑&amp;quot;快很多。&lt;/p&gt;
&lt;h2 id="三窗口管理"&gt;三、窗口管理
&lt;/h2&gt;&lt;h3 id="31-win----win---贴靠分屏"&gt;3.1 &lt;code&gt;Win + ←&lt;/code&gt; / &lt;code&gt;Win + →&lt;/code&gt; 贴靠分屏
&lt;/h3&gt;&lt;p&gt;把当前窗口&lt;strong&gt;吸附到屏幕左半 / 右半&lt;/strong&gt;——再按一次就变 1/4 屏。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;实测：3 个窗口分屏（左 / 右 / 右上）非常适合对照看代码 + 文档 + 日志。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="32-win----win---最大化--最小化"&gt;3.2 &lt;code&gt;Win + ↑&lt;/code&gt; / &lt;code&gt;Win + ↓&lt;/code&gt; 最大化 / 最小化
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;在普通状态按 &lt;code&gt;↑&lt;/code&gt; → 最大化&lt;/li&gt;
&lt;li&gt;在最大化按 &lt;code&gt;↓&lt;/code&gt; → 还原&lt;/li&gt;
&lt;li&gt;还原后按 &lt;code&gt;↓&lt;/code&gt; → 最小化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="33-win--shift---移到另一显示器"&gt;3.3 &lt;code&gt;Win + Shift + ←/→&lt;/code&gt; 移到另一显示器
&lt;/h3&gt;&lt;p&gt;多显示器场景下，把当前窗口甩到左 / 右侧屏幕。&lt;strong&gt;比手动拖快 10 倍&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="34-win--tab-任务视图--虚拟桌面"&gt;3.4 &lt;code&gt;Win + Tab&lt;/code&gt; 任务视图 / 虚拟桌面
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;第一次按：打开&amp;quot;任务视图&amp;quot;&lt;/li&gt;
&lt;li&gt;在任务视图里点 &lt;code&gt;+ 新建桌面&lt;/code&gt; → 创建虚拟桌面&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + Ctrl + ←/→&lt;/code&gt; 切换虚拟桌面&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + Ctrl + D&lt;/code&gt; 直接新建虚拟桌面&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + Ctrl + F4&lt;/code&gt; 关闭当前虚拟桌面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实际用法&lt;/strong&gt;：把&amp;quot;开发环境&amp;quot;和&amp;quot;沟通环境&amp;quot;分两个桌面，&lt;strong&gt;写代码时一个 &lt;code&gt;Win + Ctrl + ←&lt;/code&gt; 就把微信 / 钉钉隔离掉&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="四文字编辑类vs-code--office-通用"&gt;四、文字编辑类（VS Code / Office 通用）
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;快捷键&lt;/th&gt;
					&lt;th&gt;功能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + A&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;全选&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + C&lt;/code&gt; / &lt;code&gt;Ctrl + V&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;复制 / 粘贴&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + X&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;剪切&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + Z&lt;/code&gt; / &lt;code&gt;Ctrl + Y&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;撤销 / 重做&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + F&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查找&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + H&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;替换&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + S&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;保存（&lt;strong&gt;每个工种都该改成肌肉记忆&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + Shift + Esc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;任务管理器（&lt;strong&gt;比 &lt;code&gt;Ctrl + Alt + Del&lt;/code&gt; 少一次确认&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + Shift + N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;新建文件夹（资源管理器） / 隐身窗口（Chrome）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Alt + Tab&lt;/code&gt; / &lt;code&gt;Alt + Shift + Tab&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;切换窗口&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Alt + F4&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;关闭窗口（&lt;strong&gt;经典永不消失&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="五特殊字符alt-码全集"&gt;五、特殊字符：Alt 码全集
&lt;/h2&gt;&lt;p&gt;按住 &lt;code&gt;Alt&lt;/code&gt; 键不放，在数字小键盘上输入数字序列，&lt;strong&gt;松开 Alt&lt;/strong&gt; 字符出现在光标位置。中文输入法和外接键盘没切数字键盘模式时&lt;strong&gt;会失效&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="51-高频-32-个"&gt;5.1 高频 32 个
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;字符&lt;/th&gt;
					&lt;th&gt;Alt 码&lt;/th&gt;
					&lt;th&gt;用途&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;°&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0176 / 248&lt;/td&gt;
					&lt;td&gt;度数符号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;±&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0177&lt;/td&gt;
					&lt;td&gt;正负号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;×&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0215&lt;/td&gt;
					&lt;td&gt;乘号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;÷&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0247&lt;/td&gt;
					&lt;td&gt;除号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;µ&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0181&lt;/td&gt;
					&lt;td&gt;微（10⁻⁶）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ω&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;234&lt;/td&gt;
					&lt;td&gt;欧姆&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;©&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0169&lt;/td&gt;
					&lt;td&gt;版权&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;®&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0174&lt;/td&gt;
					&lt;td&gt;注册商标&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;™&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0153&lt;/td&gt;
					&lt;td&gt;商标&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;§&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0167&lt;/td&gt;
					&lt;td&gt;章节&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;¶&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0182&lt;/td&gt;
					&lt;td&gt;段落&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;¥&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0165&lt;/td&gt;
					&lt;td&gt;人民币&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;€&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0128&lt;/td&gt;
					&lt;td&gt;欧元&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;£&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0163&lt;/td&gt;
					&lt;td&gt;英镑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;→&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;26&lt;/td&gt;
					&lt;td&gt;右箭头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;←&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;27&lt;/td&gt;
					&lt;td&gt;左箭头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;↑&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;24&lt;/td&gt;
					&lt;td&gt;上箭头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;↓&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;25&lt;/td&gt;
					&lt;td&gt;下箭头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;★&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;9733&lt;/td&gt;
					&lt;td&gt;实心星&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;☆&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;9734&lt;/td&gt;
					&lt;td&gt;空心星&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;✓&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;10003&lt;/td&gt;
					&lt;td&gt;对勾&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;✗&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;10007&lt;/td&gt;
					&lt;td&gt;叉&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt; &lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0160&lt;/td&gt;
					&lt;td&gt;不间断空格（防换行）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;–&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0150&lt;/td&gt;
					&lt;td&gt;短破折号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;—&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0151&lt;/td&gt;
					&lt;td&gt;长破折号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;…&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0133&lt;/td&gt;
					&lt;td&gt;省略号（比输入三个句点更专业）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;·&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0183&lt;/td&gt;
					&lt;td&gt;中点&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;«&lt;/code&gt; / &lt;code&gt;»&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0171 / 0187&lt;/td&gt;
					&lt;td&gt;法式引号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;‹&lt;/code&gt; / &lt;code&gt;›&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0139 / 0155&lt;/td&gt;
					&lt;td&gt;单法式引号&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;†&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0134&lt;/td&gt;
					&lt;td&gt;剑标&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;‡&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0135&lt;/td&gt;
					&lt;td&gt;双剑标&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;•&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0149&lt;/td&gt;
					&lt;td&gt;项目符号&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="52-几个特别说明"&gt;5.2 几个特别说明
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Alt + 0133&lt;/code&gt; = &lt;code&gt;…&lt;/code&gt;（省略号，&lt;strong&gt;比手动打三个点更标准&lt;/strong&gt;，Word 会自动判断）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Alt + 0149&lt;/code&gt; = &lt;code&gt;•&lt;/code&gt;（项目符号，&lt;strong&gt;比 &lt;code&gt;*&lt;/code&gt; 更显专业&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Alt + 0160&lt;/code&gt; = 不间断空格（在排版中&amp;quot;5 6 月&amp;quot;中间用，防止在 5 和 6 之间换行）&lt;/li&gt;
&lt;li&gt;4 位 Alt 码（0256+）可以打 Unicode 字符，比如 &lt;code&gt;Alt + 10003&lt;/code&gt; = &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六power-user-菜单--任务栏"&gt;六、Power User 菜单 / 任务栏
&lt;/h2&gt;&lt;h3 id="61-win--x-打开-power-user-菜单"&gt;6.1 &lt;code&gt;Win + X&lt;/code&gt; 打开 Power User 菜单
&lt;/h3&gt;&lt;p&gt;这个是 2012 年 Win 8 引入的&amp;quot;高级用户开始菜单&amp;quot;，&lt;strong&gt;右手按 &lt;code&gt;Win + X&lt;/code&gt; + 左手按字母键&lt;/strong&gt;就能触发：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Win + X, I&lt;/code&gt; → 设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + X, T&lt;/code&gt; → 任务管理器&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + X, A&lt;/code&gt; → PowerShell（管理员）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + X, E&lt;/code&gt; → 资源管理器&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + X, U, U&lt;/code&gt; → 关机&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Win + X, U, R&lt;/code&gt; → 重启&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="62-win--1--win--2-切换任务栏应用"&gt;6.2 &lt;code&gt;Win + 1&lt;/code&gt; / &lt;code&gt;Win + 2&lt;/code&gt; 切换任务栏应用
&lt;/h3&gt;&lt;p&gt;任务栏上钉的应用，按 &lt;code&gt;Win + 数字&lt;/code&gt; 直接打开 / 切换。&lt;strong&gt;比鼠标找图标快 3 倍&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="63-win---预览桌面"&gt;6.3 &lt;code&gt;Win + ,&lt;/code&gt; 预览桌面
&lt;/h3&gt;&lt;p&gt;按住显示桌面，松开还原。&lt;strong&gt;比 &lt;code&gt;Win + D&lt;/code&gt; 切换更精准&lt;/strong&gt;，不会&amp;quot;切过去忘了怎么回来&amp;quot;。&lt;/p&gt;
&lt;h2 id="七屏幕截图--录屏"&gt;七、屏幕截图 / 录屏
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;快捷键&lt;/th&gt;
					&lt;th&gt;功能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;PrtScn&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;全屏截图（保存到剪贴板）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Alt + PrtScn&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;当前窗口截图（保存到剪贴板）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + PrtScn&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;全屏截图（&lt;strong&gt;自动保存到 &lt;code&gt;图片/屏幕截图/&lt;/code&gt;&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + Shift + S&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;区域截图（弹出截图工具栏）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + G&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Xbox Game Bar（录屏）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;2019 年之后&lt;/strong&gt;：Win 10/11 推出的 &lt;code&gt;Snip &amp;amp; Sketch&lt;/code&gt;（&lt;code&gt;Win + Shift + S&lt;/code&gt;）已经替代了老 Snipping Tool。&lt;strong&gt;Snipaste 是更高级的第三方替代&lt;/strong&gt;——支持贴图 + 像素标注，几乎是开发者标配。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="八运维专用的系统级快捷键"&gt;八、运维专用的&amp;quot;系统级&amp;quot;快捷键
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;快捷键&lt;/th&gt;
					&lt;th&gt;功能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Ctrl + Shift + Esc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;任务管理器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + R&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;运行（输入 &lt;code&gt;mstsc&lt;/code&gt; / &lt;code&gt;regedit&lt;/code&gt; / &lt;code&gt;services.msc&lt;/code&gt; / &lt;code&gt;ncpa.cpl&lt;/code&gt; 等）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + Pause&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;系统属性（设备名 / 内存 / 处理器）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + L&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;锁屏&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Win + U&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;辅助功能中心（&lt;strong&gt;远程协助时让用户开&amp;quot;讲述人&amp;quot;很方便&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="81-win--r-速查"&gt;8.1 &lt;code&gt;Win + R&lt;/code&gt; 速查
&lt;/h3&gt;&lt;p&gt;运维最常用 &lt;code&gt;Win + R&lt;/code&gt; + 命令：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;命令&lt;/th&gt;
					&lt;th&gt;功能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;mstsc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;远程桌面&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;regedit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;注册表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;services.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;服务管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;ncpa.cpl&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;网络连接&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;diskmgmt.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;磁盘管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;devmgmt.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;设备管理器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;compmgmt.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;计算机管理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;eventvwr.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;事件查看器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;gpedit.msc&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;本地组策略（Win 10 家庭版没有）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;appwiz.cpl&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;程序和功能&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;taskmgr&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;任务管理器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;powershell&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;PowerShell&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;cmd&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;命令提示符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;msconfig&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;系统配置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;cleanmgr&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;磁盘清理&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="九常见-5-个坑"&gt;九、常见 5 个坑
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Alt&lt;/code&gt; 码打不出&lt;/strong&gt;——检查是否在中文输入法、是否有 NumLock、外接键盘没切换数字键盘模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Win + L&lt;/code&gt; 后远程桌面连不上&lt;/strong&gt;——远程桌面会话被锁屏会显示&amp;quot;仅允许一个用户&amp;quot;，需要本地解锁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Win + E&lt;/code&gt; 打开的不是&amp;quot;此电脑&amp;quot;而是&amp;quot;快速访问&amp;quot;&lt;/strong&gt;——可以在&amp;quot;文件资源管理器选项&amp;quot;里改成&amp;quot;打开此电脑&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Win 10 家庭版没有 &lt;code&gt;gpedit.msc&lt;/code&gt;&lt;/strong&gt;——需要手动安装 Group Policy Editor 补丁，或者用 &lt;code&gt;regedit&lt;/code&gt; 改对应注册表。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Win + Shift + S&lt;/code&gt; 截图后没保存提示&lt;/strong&gt;——截图只在剪贴板，按 &lt;code&gt;Ctrl + V&lt;/code&gt; 粘到画图 / 微信 / 文档；想要&amp;quot;自动保存&amp;quot;还是用 &lt;code&gt;Win + PrtScn&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="十总结"&gt;十、总结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;5 个救命键&lt;/strong&gt;：&lt;code&gt;Win + S&lt;/code&gt; 搜索、&lt;code&gt;Win + D&lt;/code&gt; 桌面、&lt;code&gt;Win + L&lt;/code&gt; 锁屏、&lt;code&gt;Win + E&lt;/code&gt; 资源管理器、&lt;code&gt;Ctrl + Shift + Esc&lt;/code&gt; 任务管理器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;窗口分屏&lt;/strong&gt;：&lt;code&gt;Win + ←/→&lt;/code&gt; 贴靠，&lt;code&gt;Win + Tab&lt;/code&gt; 虚拟桌面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alt 码&lt;/strong&gt;：°×÷©®™→←↑↓✓✗——记 20 个覆盖 80% 场景&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运维调试&lt;/strong&gt;：&lt;code&gt;Win + R&lt;/code&gt; + &lt;code&gt;mstsc&lt;/code&gt; / &lt;code&gt;services.msc&lt;/code&gt; / &lt;code&gt;regedit&lt;/code&gt; / &lt;code&gt;ncpa.cpl&lt;/code&gt; 是 4 大天王&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;截图录屏&lt;/strong&gt;：&lt;code&gt;Win + Shift + S&lt;/code&gt; 区域截图，&lt;strong&gt;Snipaste&lt;/strong&gt; 是 3.0 升级版&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://support.microsoft.com/zh-cn/windows/windows-%e7%9a%84%e9%94%ae%e7%9b%98%e5%bf%ab%e6%8d%b7%e6%96%b9%e5%bc%8f-dcc61a57-8ff0-cffe-9796-cb9706ae75ff" target="_blank" rel="noopener"
 &gt;Microsoft Support - Windows 键盘快捷键&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Alt_code" target="_blank" rel="noopener"
 &gt;Alt Code Reference - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/zh-cn/windows/configuration/" target="_blank" rel="noopener"
 &gt;Windows 虚拟桌面使用指南&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>