<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Nftables on Tarragon</title><link>https://tarrragon.github.io/blog/tags/nftables/</link><description>Recent content in Nftables on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 08 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/nftables/index.xml" rel="self" type="application/rss+xml"/><item><title>一個修法埋下三步後的雷：pacman 404 → -Syu 升 kernel → docker 起不來</title><link>https://tarrragon.github.io/blog/work-log/pacman_syu_kernel_reboot_docker/</link><pubDate>Wed, 08 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/work-log/pacman_syu_kernel_reboot_docker/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>核心議題&lt;/strong>：一個看似無關、且當下成功的修法，可能埋下三步之後才引爆的雷。症狀出現的層（docker / iptables）跟根因所在的層（執行中 kernel 與磁碟 module 版本錯配）可以隔很遠，照症狀直覺除錯會走錯方向。判讀的解法是讀權威狀態、把症狀層與根因層對開。
&lt;strong>案例骨幹&lt;/strong>：在一台 Arch Linux ARM VM 上要裝 mosh、&lt;code>pacman -S&lt;/code> 回 404，修法牽出 &lt;code>-Syu&lt;/code> 升級了 kernel，之後裝 docker、daemon 起不來、&lt;code>iptables&lt;/code> 報 &lt;code>nf_tables&lt;/code> 錯誤——三個步驟串成一條因果鏈。&lt;/p>&lt;/blockquote>
&lt;h2 id="問題情境三步串成的因果鏈">問題情境：三步串成的因果鏈&lt;/h2>
&lt;p>事情從一個單純的安裝開始，最後停在一個看起來毫不相關的 docker 故障。三步：&lt;/p>
&lt;p>第一步，&lt;code>pacman -S mosh&lt;/code> 中途對某個相依套件回 HTTP 404、&lt;code>failed to retrieve some files&lt;/code>。這不是網路問題——是本地套件資料庫過時，記錄的版本在 mirror 上已被新版取代（Arch 的 partial upgrade 陷阱：只裝新套件、沒同步整個系統）。&lt;/p>
&lt;p>第二步，修法是 &lt;code>sudo pacman -Syu&lt;/code> 把整個系統同步升級、對齊資料庫與 mirror。這步成功、mosh 也裝好了。但 &lt;code>-Syu&lt;/code> 順帶把 kernel 從一個版本升到了下一版——這個副作用當下沒有任何徵兆。&lt;/p>
&lt;p>第三步，繼續裝 docker、&lt;code>systemctl start docker&lt;/code>，daemon 起不來。journal 顯示：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">iptables (nf_tables): Could not fetch rule set generation id: Invalid argument
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">failed to register &amp;#34;bridge&amp;#34; driver: ... iptables ... (exit status 4)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>照這個症狀，直覺會往「docker 網路設定 / 防火牆規則 / iptables 版本」除錯——全部是錯的方向。&lt;/p>
&lt;h2 id="根因執行中-kernel-與磁碟上的-module-錯配">根因：執行中 kernel 與磁碟上的 module 錯配&lt;/h2>
&lt;p>真正的根因在第二步埋下：&lt;code>-Syu&lt;/code> 升級了 kernel，把新版的 kernel modules 裝到磁碟上，但&lt;strong>機器沒有重開機&lt;/strong>。於是系統處在一個錯配狀態——執行中的還是舊 kernel，而磁碟上舊 kernel 的 module 目錄已經被換成新版了（&lt;code>/usr/lib/modules/&lt;/code> 只剩新版）。執行中的 kernel 找不到自己對應版本的 modules，&lt;code>nf_tables&lt;/code> 這個 netfilter 模組載入失敗，docker 建 NAT chain 時透過 iptables 操作 nftables 就報了那個 &lt;code>Invalid argument&lt;/code>。&lt;/p>
&lt;p>症狀在 iptables / docker 這一層冒出來，根因卻在「kernel 與 module 版本錯配」這一層。兩層隔了三個操作步驟，這是為什麼照症狀查會鑽進 docker 網路設定的死巷。&lt;/p>
&lt;h2 id="解法讀權威狀態重開機">解法：讀權威狀態、重開機&lt;/h2>
&lt;p>判讀的關鍵是讀權威狀態、把「執行中的」跟「磁碟上的」對開：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">uname -r &lt;span class="c1"># 執行中的 kernel 版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">ls -d /usr/lib/modules/*/ &lt;span class="c1"># 磁碟上已裝的 kernel module 目錄&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>兩者不一致，就是 kernel 升級後未重開機。這一秒就定位了——不需要碰任何 docker 或 iptables 設定。解法是重開機進新 kernel，執行中版本與磁碟 module 對齊、&lt;code>nf_tables&lt;/code> 載得進來、docker daemon 正常啟動。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">sudo systemctl reboot
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1"># 重開後&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">uname -r &lt;span class="c1"># 對上磁碟版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">systemctl start docker &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> systemctl is-active docker &lt;span class="c1"># active&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="判讀徵兆什麼時候該懷疑這條鏈">判讀徵兆：什麼時候該懷疑這條鏈&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>一個服務突然起不來、而你剛跑過 &lt;code>-Syu&lt;/code> 或系統更新、且沒重開機&lt;/strong> → 先懷疑 kernel / module 錯配，&lt;code>uname -r&lt;/code> vs &lt;code>ls /usr/lib/modules&lt;/code> 一秒驗。這不限 docker——任何依賴 kernel module（netfilter、檔案系統、虛擬化）的服務都可能中招。&lt;/li>
&lt;li>&lt;strong>錯誤訊息指向一個「底層設施」（iptables、nftables、module load）而不是應用本身&lt;/strong> → 症狀層可能不是根因層，往「這個底層設施依賴的東西（kernel module）狀態對不對」查，而不是去調應用的設定。&lt;/li>
&lt;li>&lt;strong>一個修法「當下成功」不代表沒有副作用&lt;/strong> → &lt;code>-Syu&lt;/code> 修好了 404、也升了 kernel。修完一個問題後、下一個看似無關的故障要把最近的變更列進嫌疑名單，即使它們表面上不相干。&lt;/li>
&lt;/ul>
&lt;p>讀權威狀態、以機器實際狀態為準而非症狀表象，是這類「症狀與根因差好幾層」問題的通用解法。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p><strong>核心議題</strong>：一個看似無關、且當下成功的修法，可能埋下三步之後才引爆的雷。症狀出現的層（docker / iptables）跟根因所在的層（執行中 kernel 與磁碟 module 版本錯配）可以隔很遠，照症狀直覺除錯會走錯方向。判讀的解法是讀權威狀態、把症狀層與根因層對開。
<strong>案例骨幹</strong>：在一台 Arch Linux ARM VM 上要裝 mosh、<code>pacman -S</code> 回 404，修法牽出 <code>-Syu</code> 升級了 kernel，之後裝 docker、daemon 起不來、<code>iptables</code> 報 <code>nf_tables</code> 錯誤——三個步驟串成一條因果鏈。</p></blockquote>
<h2 id="問題情境三步串成的因果鏈">問題情境：三步串成的因果鏈</h2>
<p>事情從一個單純的安裝開始，最後停在一個看起來毫不相關的 docker 故障。三步：</p>
<p>第一步，<code>pacman -S mosh</code> 中途對某個相依套件回 HTTP 404、<code>failed to retrieve some files</code>。這不是網路問題——是本地套件資料庫過時，記錄的版本在 mirror 上已被新版取代（Arch 的 partial upgrade 陷阱：只裝新套件、沒同步整個系統）。</p>
<p>第二步，修法是 <code>sudo pacman -Syu</code> 把整個系統同步升級、對齊資料庫與 mirror。這步成功、mosh 也裝好了。但 <code>-Syu</code> 順帶把 kernel 從一個版本升到了下一版——這個副作用當下沒有任何徵兆。</p>
<p>第三步，繼續裝 docker、<code>systemctl start docker</code>，daemon 起不來。journal 顯示：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">iptables (nf_tables): Could not fetch rule set generation id: Invalid argument
</span></span><span class="line"><span class="ln">2</span><span class="cl">failed to register &#34;bridge&#34; driver: ... iptables ... (exit status 4)</span></span></code></pre></div><p>照這個症狀，直覺會往「docker 網路設定 / 防火牆規則 / iptables 版本」除錯——全部是錯的方向。</p>
<h2 id="根因執行中-kernel-與磁碟上的-module-錯配">根因：執行中 kernel 與磁碟上的 module 錯配</h2>
<p>真正的根因在第二步埋下：<code>-Syu</code> 升級了 kernel，把新版的 kernel modules 裝到磁碟上，但<strong>機器沒有重開機</strong>。於是系統處在一個錯配狀態——執行中的還是舊 kernel，而磁碟上舊 kernel 的 module 目錄已經被換成新版了（<code>/usr/lib/modules/</code> 只剩新版）。執行中的 kernel 找不到自己對應版本的 modules，<code>nf_tables</code> 這個 netfilter 模組載入失敗，docker 建 NAT chain 時透過 iptables 操作 nftables 就報了那個 <code>Invalid argument</code>。</p>
<p>症狀在 iptables / docker 這一層冒出來，根因卻在「kernel 與 module 版本錯配」這一層。兩層隔了三個操作步驟，這是為什麼照症狀查會鑽進 docker 網路設定的死巷。</p>
<h2 id="解法讀權威狀態重開機">解法：讀權威狀態、重開機</h2>
<p>判讀的關鍵是讀權威狀態、把「執行中的」跟「磁碟上的」對開：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">uname -r                                 <span class="c1"># 執行中的 kernel 版本</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">ls -d /usr/lib/modules/*/                <span class="c1"># 磁碟上已裝的 kernel module 目錄</span></span></span></code></pre></div><p>兩者不一致，就是 kernel 升級後未重開機。這一秒就定位了——不需要碰任何 docker 或 iptables 設定。解法是重開機進新 kernel，執行中版本與磁碟 module 對齊、<code>nf_tables</code> 載得進來、docker daemon 正常啟動。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">sudo systemctl reboot
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># 重開後</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">uname -r                                 <span class="c1"># 對上磁碟版本</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">systemctl start docker <span class="o">&amp;&amp;</span> systemctl is-active docker   <span class="c1"># active</span></span></span></code></pre></div><h2 id="判讀徵兆什麼時候該懷疑這條鏈">判讀徵兆：什麼時候該懷疑這條鏈</h2>
<ul>
<li><strong>一個服務突然起不來、而你剛跑過 <code>-Syu</code> 或系統更新、且沒重開機</strong> → 先懷疑 kernel / module 錯配，<code>uname -r</code> vs <code>ls /usr/lib/modules</code> 一秒驗。這不限 docker——任何依賴 kernel module（netfilter、檔案系統、虛擬化）的服務都可能中招。</li>
<li><strong>錯誤訊息指向一個「底層設施」（iptables、nftables、module load）而不是應用本身</strong> → 症狀層可能不是根因層，往「這個底層設施依賴的東西（kernel module）狀態對不對」查，而不是去調應用的設定。</li>
<li><strong>一個修法「當下成功」不代表沒有副作用</strong> → <code>-Syu</code> 修好了 404、也升了 kernel。修完一個問題後、下一個看似無關的故障要把最近的變更列進嫌疑名單，即使它們表面上不相干。</li>
</ul>
<p>讀權威狀態、以機器實際狀態為準而非症狀表象，是這類「症狀與根因差好幾層」問題的通用解法。</p>
]]></content:encoded></item></channel></rss>