<?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>Os on Tarragon</title><link>https://tarrragon.github.io/blog/tags/os/</link><description>Recent content in Os on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 26 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/os/index.xml" rel="self" type="application/rss+xml"/><item><title>OS 與基礎軟體更換</title><link>https://tarrragon.github.io/blog/infra/upgrade/os-base-software-upgrade/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/infra/upgrade/os-base-software-upgrade/</guid><description>&lt;p>作業系統到達 end-of-life（EOL）後不再收到安全修補——每一個新發現的漏洞都會永久敞開。EOL OS 上跑的服務不是「可能有風險」，而是「風險只會隨時間單調增加」。遷移的問題是何時做和怎麼做，不是要不要做。&lt;/p>
&lt;h2 id="eol-風險評估">EOL 風險評估&lt;/h2>
&lt;p>EOL 在操作層面的意義是三件事同時停止：安全修補（CVE 不再被回填到該版本的 patch release）、核心更新（kernel 的錯誤修正與硬體支援停止）、套件庫維護（官方 repository 凍結或下架，新裝套件或更新依賴都做不到）。&lt;/p>
&lt;h3 id="風險時間軸">風險時間軸&lt;/h3>
&lt;p>EOL 是一段逐漸惡化的過程，而非單一時間點：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>事件&lt;/th>
 &lt;th>影響&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>宣告&lt;/td>
 &lt;td>官方公布 EOL 日期（通常提前 1-2 年）&lt;/td>
 &lt;td>開始規劃遷移的訊號&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>正式 EOL&lt;/td>
 &lt;td>最後一個安全修補發布&lt;/td>
 &lt;td>新 CVE 不再有 patch&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>套件庫凍結&lt;/td>
 &lt;td>官方 mirror 停止同步或下架&lt;/td>
 &lt;td>&lt;code>yum update&lt;/code> / &lt;code>apt update&lt;/code> 失敗&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>合規失效&lt;/td>
 &lt;td>稽核認定執行環境不符標準&lt;/td>
 &lt;td>PCI DSS / SOC 2 / ISO 27001 判定不合規&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="常見的-eol-情境">常見的 EOL 情境&lt;/h3>
&lt;p>CentOS 7 在 2024 年 6 月結束支援，但仍有大量 production 環境在使用。CentOS 8 在 2021 年 12 月被轉向 CentOS Stream，打破了原本預期到 2029 年的支援承諾，迫使使用者重新選型。Ubuntu 18.04 的標準支援在 2023 年 4 月結束，Canonical 提供 ESM（Extended Security Maintenance）付費延長到 2028 年，但 ESM 只涵蓋 main 套件庫。&lt;/p>
&lt;p>ESM 或類似的付費延長支援（RHEL 的 ELS、CentOS 的第三方 TuxCare）是「買時間做遷移」的合理策略——付月費取得額外 2-5 年的安全修補，讓團隊有餘裕規劃平行建置而非被迫緊急遷移。Ubuntu Pro 免費涵蓋 5 台 instance 的 ESM，超過才需要付費。ESM 是給遷移專案爭取時間的保險，而非長期方案——延長支援的套件覆蓋範圍通常比標準期窄。&lt;/p>
&lt;p>合規的影響很直接：PCI DSS 要求所有面對持卡人資料的系統都執行在有安全修補支援的軟體上；SOC 2 和 ISO 27001 的定期稽核會檢查作業系統的支援狀態。在 EOL OS 上跑的 production 環境會讓稽核結果出現 finding，需要額外的補償控制（compensating control）才能通過——而補償控制的維護成本通常高於遷移本身。&lt;/p>
&lt;h2 id="目標-os-選型">目標 OS 選型&lt;/h2>
&lt;p>選型看四個維度：LTS 發布週期（支援年限多長）、社群與商業支援（問題能不能查到答案、能不能買付費支援）、套件可用性（應用層需要的 runtime 和 library 在官方 repo 裡有沒有）、團隊熟悉度（操作指令和設定路徑的學習成本）。&lt;/p>
&lt;h3 id="常見選擇">常見選擇&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>OS&lt;/th>
 &lt;th>支援週期&lt;/th>
 &lt;th>適用情境&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Ubuntu 22.04 / 24.04 LTS&lt;/td>
 &lt;td>5 年標準 + 5 年 ESM&lt;/td>
 &lt;td>社群最大、套件最新、學習資源最多&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Debian 12 (Bookworm)&lt;/td>
 &lt;td>~5 年&lt;/td>
 &lt;td>穩定性優先、更新保守&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon Linux 2023&lt;/td>
 &lt;td>5 年&lt;/td>
 &lt;td>AWS 生態深度整合、EC2 預設選項&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rocky Linux 9 / AlmaLinux 9&lt;/td>
 &lt;td>~10 年&lt;/td>
 &lt;td>CentOS 替代、RHEL 相容&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="同家族-vs-跨家族">同家族 vs 跨家族&lt;/h3>
&lt;p>CentOS → Rocky Linux / AlmaLinux 是同家族遷移：套件名稱、設定路徑、init 系統（systemd）幾乎不變，應用層的改動最少。CentOS → Ubuntu 是跨家族遷移：套件管理從 yum/dnf 換成 apt、設定路徑從 &lt;code>/etc/httpd/&lt;/code> 變成 &lt;code>/etc/apache2/&lt;/code>、某些服務名稱不同。&lt;/p>
&lt;p>同家族遷移的優勢是應用層風險低——多數設定檔可以直接搬過去。跨家族遷移的優勢是可以借機切到更活躍的生態（Ubuntu 的社群回答量和第三方套件支援在多數指標上領先），代價是設定檔要全面調整。&lt;/p>
&lt;p>選型判準：如果團隊已經有 Ubuntu 經驗、或其他系統已經跑 Ubuntu，統一到 Ubuntu 的長期維護成本較低。如果團隊對 RHEL 系操作更熟、或有 RHEL 付費支援合約，Rocky/Alma 是阻力最小的路。&lt;/p></description><content:encoded><![CDATA[<p>作業系統到達 end-of-life（EOL）後不再收到安全修補——每一個新發現的漏洞都會永久敞開。EOL OS 上跑的服務不是「可能有風險」，而是「風險只會隨時間單調增加」。遷移的問題是何時做和怎麼做，不是要不要做。</p>
<h2 id="eol-風險評估">EOL 風險評估</h2>
<p>EOL 在操作層面的意義是三件事同時停止：安全修補（CVE 不再被回填到該版本的 patch release）、核心更新（kernel 的錯誤修正與硬體支援停止）、套件庫維護（官方 repository 凍結或下架，新裝套件或更新依賴都做不到）。</p>
<h3 id="風險時間軸">風險時間軸</h3>
<p>EOL 是一段逐漸惡化的過程，而非單一時間點：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>事件</th>
          <th>影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>宣告</td>
          <td>官方公布 EOL 日期（通常提前 1-2 年）</td>
          <td>開始規劃遷移的訊號</td>
      </tr>
      <tr>
          <td>正式 EOL</td>
          <td>最後一個安全修補發布</td>
          <td>新 CVE 不再有 patch</td>
      </tr>
      <tr>
          <td>套件庫凍結</td>
          <td>官方 mirror 停止同步或下架</td>
          <td><code>yum update</code> / <code>apt update</code> 失敗</td>
      </tr>
      <tr>
          <td>合規失效</td>
          <td>稽核認定執行環境不符標準</td>
          <td>PCI DSS / SOC 2 / ISO 27001 判定不合規</td>
      </tr>
  </tbody>
</table>
<h3 id="常見的-eol-情境">常見的 EOL 情境</h3>
<p>CentOS 7 在 2024 年 6 月結束支援，但仍有大量 production 環境在使用。CentOS 8 在 2021 年 12 月被轉向 CentOS Stream，打破了原本預期到 2029 年的支援承諾，迫使使用者重新選型。Ubuntu 18.04 的標準支援在 2023 年 4 月結束，Canonical 提供 ESM（Extended Security Maintenance）付費延長到 2028 年，但 ESM 只涵蓋 main 套件庫。</p>
<p>ESM 或類似的付費延長支援（RHEL 的 ELS、CentOS 的第三方 TuxCare）是「買時間做遷移」的合理策略——付月費取得額外 2-5 年的安全修補，讓團隊有餘裕規劃平行建置而非被迫緊急遷移。Ubuntu Pro 免費涵蓋 5 台 instance 的 ESM，超過才需要付費。ESM 是給遷移專案爭取時間的保險，而非長期方案——延長支援的套件覆蓋範圍通常比標準期窄。</p>
<p>合規的影響很直接：PCI DSS 要求所有面對持卡人資料的系統都執行在有安全修補支援的軟體上；SOC 2 和 ISO 27001 的定期稽核會檢查作業系統的支援狀態。在 EOL OS 上跑的 production 環境會讓稽核結果出現 finding，需要額外的補償控制（compensating control）才能通過——而補償控制的維護成本通常高於遷移本身。</p>
<h2 id="目標-os-選型">目標 OS 選型</h2>
<p>選型看四個維度：LTS 發布週期（支援年限多長）、社群與商業支援（問題能不能查到答案、能不能買付費支援）、套件可用性（應用層需要的 runtime 和 library 在官方 repo 裡有沒有）、團隊熟悉度（操作指令和設定路徑的學習成本）。</p>
<h3 id="常見選擇">常見選擇</h3>
<table>
  <thead>
      <tr>
          <th>OS</th>
          <th>支援週期</th>
          <th>適用情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ubuntu 22.04 / 24.04 LTS</td>
          <td>5 年標準 + 5 年 ESM</td>
          <td>社群最大、套件最新、學習資源最多</td>
      </tr>
      <tr>
          <td>Debian 12 (Bookworm)</td>
          <td>~5 年</td>
          <td>穩定性優先、更新保守</td>
      </tr>
      <tr>
          <td>Amazon Linux 2023</td>
          <td>5 年</td>
          <td>AWS 生態深度整合、EC2 預設選項</td>
      </tr>
      <tr>
          <td>Rocky Linux 9 / AlmaLinux 9</td>
          <td>~10 年</td>
          <td>CentOS 替代、RHEL 相容</td>
      </tr>
  </tbody>
</table>
<h3 id="同家族-vs-跨家族">同家族 vs 跨家族</h3>
<p>CentOS → Rocky Linux / AlmaLinux 是同家族遷移：套件名稱、設定路徑、init 系統（systemd）幾乎不變，應用層的改動最少。CentOS → Ubuntu 是跨家族遷移：套件管理從 yum/dnf 換成 apt、設定路徑從 <code>/etc/httpd/</code> 變成 <code>/etc/apache2/</code>、某些服務名稱不同。</p>
<p>同家族遷移的優勢是應用層風險低——多數設定檔可以直接搬過去。跨家族遷移的優勢是可以借機切到更活躍的生態（Ubuntu 的社群回答量和第三方套件支援在多數指標上領先），代價是設定檔要全面調整。</p>
<p>選型判準：如果團隊已經有 Ubuntu 經驗、或其他系統已經跑 Ubuntu，統一到 Ubuntu 的長期維護成本較低。如果團隊對 RHEL 系操作更熟、或有 RHEL 付費支援合約，Rocky/Alma 是阻力最小的路。</p>
<h2 id="遷移策略原地升級-vs-平行建置">遷移策略：原地升級 vs 平行建置</h2>
<h3 id="原地升級">原地升級</h3>
<p>在現有伺服器上直接換 OS 版本。做法是用 OS 提供的升級工具（如 <code>do-release-upgrade</code>、<code>leapp</code>）在跑著的系統上切換。</p>
<p>風險集中在升級過程中系統處於不確定狀態——kernel 換了但 userland 還沒、init 系統切了但服務設定還指向舊路徑。如果中途失敗、伺服器可能開不了機，而 rollback 意味著從備份還原整台機器。原地升級只在同 OS 家族的小版本升級（如 Ubuntu 20.04 → 22.04）且有完整 VM 快照保底時才值得考慮。</p>
<h3 id="平行建置">平行建置</h3>
<p>在旁邊建一台新 OS 的伺服器、安裝應用層、遷移資料、用 DNS 或 load balancer 切換流量。舊伺服器保留作為 rollback 目標，確認新環境穩定後再退役。</p>
<p>平行建置的成本是短期多付一台伺服器的費用（通常是幾天到幾週）。收益是：升級失敗時舊伺服器完好無損、切回去只需要改 DNS 或 LB 的 target；新伺服器可以在切換前充分測試、不影響線上服務；整個過程可以在非尖峰時段進行。</p>
<p>對多數環境來說平行建置是預設策略。原地升級只在無法多開一台伺服器（預算極度受限、或裸機硬體無備品）時才退而求其次。</p>
<h2 id="應用層的遷移清單">應用層的遷移清單</h2>
<p>新 OS 上要重建整個應用執行環境。以下是逐項需要確認的面向：</p>
<h3 id="web-伺服器">Web 伺服器</h3>
<p>如果新舊 OS 都用 Apache，設定檔的路徑可能不同（RHEL 系 <code>/etc/httpd/conf.d/</code>、Debian 系 <code>/etc/apache2/sites-available/</code>），模組載入方式也不同（<code>LoadModule</code> 指令 vs <code>a2enmod</code> 工具）。逐一比對現有的 VirtualHost 設定、rewrite 規則、SSL 設定。</p>
<p>如果同時換成 nginx，見下一節。</p>
<h3 id="runtime-版本對齊">Runtime 版本對齊</h3>
<p>新 OS 的官方 repo 裡的 PHP / Node / Python 版本可能跟舊 OS 不同。Ubuntu 22.04 預設 PHP 8.1、如果應用需要 PHP 7.4 要加第三方 PPA（如 ondrej/php）。確認所有 PHP extension（mysqli、curl、gd、mbstring、redis）在新 OS 上都有對應的套件名稱且已安裝。</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"><span class="c1"># 舊伺服器：列出所有已載入的 PHP module</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">php -m &gt; old-php-modules.txt
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 新伺服器：比對缺了什麼</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">php -m &gt; new-php-modules.txt
</span></span><span class="line"><span class="ln">6</span><span class="cl">diff old-php-modules.txt new-php-modules.txt</span></span></code></pre></div><h3 id="資料庫客戶端程式庫">資料庫客戶端程式庫</h3>
<p>應用連接 MySQL / PostgreSQL 用的 client library（<code>libmysqlclient</code>、<code>libpq</code>）版本要跟資料庫伺服器相容。跨大版本（MySQL 5.7 client → MySQL 8.0 server）通常向前相容，但反過來可能有驗證方式不匹配的問題（如 MySQL 8.0 的 <code>caching_sha2_password</code> 預設驗證方式）。</p>
<h3 id="cron-jobs">Cron jobs</h3>
<p>從舊伺服器匯出 crontab（<code>crontab -l</code>），在新伺服器重建。如果舊 OS 使用 <code>/etc/cron.d/</code> 的檔案式 cron，確認新 OS 的 cron daemon 支援同樣的格式。Cron 的環境變數（PATH、MAILTO）在不同 OS 可能有不同預設。</p>
<h3 id="日誌路徑">日誌路徑</h3>
<p>Apache 的預設 log 路徑在 RHEL 系是 <code>/var/log/httpd/</code>、Debian 系是 <code>/var/log/apache2/</code>。應用程式如果 hardcode 了日誌路徑，要在新 OS 上對齊。同時確認 logrotate 的設定在新 OS 上存在且正確。</p>
<h3 id="檔案權限與使用者">檔案權限與使用者</h3>
<p>不同 OS 的 web server 執行使用者不同（RHEL 的 <code>apache</code>、Debian 的 <code>www-data</code>）。如果應用依賴特定使用者名稱的檔案權限（如 upload 目錄的 owner），遷移後要調整 <code>chown</code>。</p>
<h3 id="服務管理">服務管理</h3>
<p>現代 OS 都使用 systemd。但如果舊 OS 還有 sysvinit 腳本（<code>/etc/init.d/</code>），遷移時要轉換成 systemd unit file。轉換的核心是把 init 腳本的 start/stop/restart 邏輯對應到 systemd 的 <code>ExecStart</code>、<code>ExecStop</code>、<code>Restart</code> 欄位。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># /etc/systemd/system/myapp.service</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">My Application</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network.target mysql.service</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">www-data</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/php /var/www/myapp/worker.php</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">on-failure</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="na">RestartSec</span><span class="o">=</span><span class="s">5</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span></span></span></code></pre></div><h2 id="基礎軟體切換apache--nginx">基礎軟體切換（Apache → nginx）</h2>
<p>如果已經在為 OS 遷移建新伺服器，同時切換 web server 是成本最低的時機——反正設定檔要重寫、不如一次到位。分開做的話要拆兩次遷移、測兩次、承受兩次風險。</p>
<h3 id="htaccess--nginx-設定轉換">.htaccess → nginx 設定轉換</h3>
<p>Apache 的 .htaccess 是分散式設定——每個目錄可以有自己的 <code>.htaccess</code>，Apache 在每次請求時逐層讀取。nginx 沒有這個機制，所有設定集中在 <code>/etc/nginx/</code> 的設定檔裡。</p>
<p>轉換的第一步是找出所有 .htaccess 檔案：</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">find /var/www/ -name <span class="s2">&#34;.htaccess&#34;</span> -exec <span class="nb">echo</span> <span class="s2">&#34;=== {} ===&#34;</span> <span class="se">\;</span> -exec cat <span class="o">{}</span> <span class="se">\;</span></span></span></code></pre></div><p>常見的轉換對應：</p>
<table>
  <thead>
      <tr>
          <th>Apache .htaccess</th>
          <th>nginx 對應</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>RewriteRule ^old$ /new [R=301]</code></td>
          <td><code>rewrite ^/old$ /new permanent;</code></td>
      </tr>
      <tr>
          <td><code>RewriteCond %{HTTPS} off</code> + <code>RewriteRule</code></td>
          <td><code>if ($scheme = http) { return 301 https://...; }</code></td>
      </tr>
      <tr>
          <td><code>Options -Indexes</code></td>
          <td><code>autoindex off;</code>（通常是預設）</td>
      </tr>
      <tr>
          <td><code>php_flag engine off</code></td>
          <td><code>location /uploads/ { deny all; }</code> 或不傳給 PHP</td>
      </tr>
      <tr>
          <td><code>&lt;Files .env&gt;</code> + <code>Deny from all</code></td>
          <td><code>location ~ /\.env { deny all; }</code></td>
      </tr>
      <tr>
          <td><code>AuthType Basic</code> + <code>.htpasswd</code></td>
          <td><code>auth_basic</code> + <code>auth_basic_user_file</code></td>
      </tr>
  </tbody>
</table>
<h3 id="平行測試">平行測試</h3>
<p>在新伺服器上同時安裝 nginx（port 80）和 Apache（port 8080）。用 curl 比對兩者的回應：</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"><span class="c1"># 比對首頁</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">diff &lt;<span class="o">(</span>curl -s http://new-server/<span class="o">)</span> &lt;<span class="o">(</span>curl -s http://new-server:8080/<span class="o">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 比對一個有 rewrite 規則的 URL</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">diff &lt;<span class="o">(</span>curl -sI http://new-server/old-path<span class="o">)</span> &lt;<span class="o">(</span>curl -sI http://new-server:8080/old-path<span class="o">)</span></span></span></code></pre></div><p>回應一致後再把 Apache 移除。重點比對項：HTTP status code（rewrite 的 301/302）、response body（PHP 輸出）、response header（cache control、security header）。</p>
<h3 id="常見陷阱">常見陷阱</h3>
<p>.htaccess 的分散式設定在 WordPress 或其他 CMS 中常被用來動態控制 URL rewrite。WordPress 的 permalink 功能依賴根目錄的 <code>.htaccess</code>，切到 nginx 需要在設定檔裡加 <code>try_files $uri $uri/ /index.php?$args;</code> 才能讓 permalink 運作。其他 CMS（Drupal、Laravel）也有各自的 nginx 設定範例，通常在官方文件裡可以找到。</p>
<h2 id="時程與管理層溝通">時程與管理層溝通</h2>
<p>OS 遷移（平行建置）的時程取決於應用層的複雜度：</p>
<table>
  <thead>
      <tr>
          <th>環境複雜度</th>
          <th>時程估算</th>
          <th>典型特徵</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>簡單</td>
          <td>1-2 週</td>
          <td>單一 web app、標準 LAMP/LEMP stack</td>
      </tr>
      <tr>
          <td>中等</td>
          <td>2-3 週</td>
          <td>多個服務、自訂套件、cron 密集</td>
      </tr>
      <tr>
          <td>複雜</td>
          <td>3-4 週</td>
          <td>多台伺服器、叢集、自建 daemon</td>
      </tr>
  </tbody>
</table>
<p>跟管理層溝通時用三個框架：</p>
<p><strong>為什麼現在做</strong>：「目前的 OS 已經停止安全修補，每個月不遷移等於多一個月的曝險窗口。如果有合規要求（PCI DSS / SOC 2），下次稽核會被標記。」</p>
<p><strong>做什麼</strong>：「在旁邊建一台新 OS 的伺服器，把應用搬過去、驗證通過後切換。舊伺服器保留一到兩週作為 rollback。」</p>
<p><strong>花多久和多少錢</strong>：「工程師時間 1-3 週（依複雜度）。多一台伺服器的費用只有切換期間的短期成本。不做的隱藏成本是安全事故的潛在損失和合規罰款。」</p>
<h2 id="跨分類引用">跨分類引用</h2>
<ul>
<li>→ <a href="/blog/infra/upgrade/upgrade-framework/" data-link-title="升級的共通操作框架" data-link-desc="任何環境或系統升級的四階段模型：差異評估、平行環境驗證、分批切換、退役舊環境，以及貫穿全程的升級紀律">升級的共通操作框架</a>：四階段模型（評估差異 → 平行環境 → 分批切換 → 退役）</li>
<li>→ <a href="/blog/infra/upgrade/platform-migration/" data-link-title="平台遷移" data-link-desc="FTP 面板主機到 VPS、VPS 到雲端、地端到雲端的遷移路徑 — 資料同步策略、DNS 切換、驗證與回退">平台遷移</a>：如果 OS 遷移同時伴隨平台搬遷（地端 → 雲端）</li>
<li>→ <a href="/blog/infra/upgrade/runtime-version-upgrade/" data-link-title="Runtime 版本升級" data-link-desc="PHP / Node.js / Python 大版本升級的相容性評估、本地驗證、分批部署策略與常見陷阱">Runtime 版本升級</a>：PHP / Node 版本升級常伴隨 OS 遷移</li>
<li>→ <a href="/blog/infra/takeover/" data-link-title="接手維運：別人建的環境怎麼接管" data-link-desc="接手前人的專案時，怎麼在不搞壞東西的前提下盤點現況、建立維運能力、逐步正規化 — 從無 SSH 的 FTP 環境到有半套 IaC 的雲端環境都適用">接手維運</a>：接手一個 EOL OS 的環境後的下一步</li>
</ul>
]]></content:encoded></item></channel></rss>