<?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>Harbor on Tarragon</title><link>https://tarrragon.github.io/blog/tags/harbor/</link><description>Recent content in Harbor 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/harbor/index.xml" rel="self" type="application/rss+xml"/><item><title>斷網環境的套件與容器映像 Registry</title><link>https://tarrragon.github.io/blog/infra/air-gapped/air-gapped-package-registry/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/infra/air-gapped/air-gapped-package-registry/</guid><description>&lt;p>連網環境的套件安裝和映像拉取，背後都有一個公開的 registry 在服務：apt 走 archive.ubuntu.com、npm 走 registry.npmjs.org、Docker 走 Docker Hub。斷網環境裡這些 endpoint 全部不可達，每一條 &lt;code>apt install&lt;/code>、&lt;code>npm install&lt;/code>、&lt;code>pip install&lt;/code>、&lt;code>docker pull&lt;/code> 都會失敗。替代做法是在內網部署自己的 registry，把需要的套件和映像從外部下載、經過安全審查後搬進來。&lt;/p>
&lt;p>本篇涵蓋兩個 registry 的部署與操作：Nexus Repository（多格式套件）和 Harbor（容器映像）。兩者可以獨立運作，也可以搭配使用——Nexus 管套件依賴、Harbor 管容器映像，各自負責不同的 artifact 類型。&lt;/p>
&lt;h2 id="nexus-repository統一的離線套件-proxy">Nexus Repository：統一的離線套件 proxy&lt;/h2>
&lt;p>Nexus Repository OSS（開源版）支援 apt、yum、npm、PyPI、Maven、NuGet、Go modules 等多種格式，用一個實例取代多個獨立的離線 repo mirror。部署在內網後，所有開發機器和 CI runner 把套件 source 指向 Nexus。&lt;/p>
&lt;h3 id="部署">部署&lt;/h3>
&lt;p>Nexus 本身是一個 Java 應用，用 Docker 部署最簡單。映像需要事先從外部搬進來：&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">&lt;span class="c1"># 外部機器下載映像&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">docker pull sonatype/nexus3:latest
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">docker save sonatype/nexus3:latest -o nexus3.tar
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 搬運到內網後載入&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">docker load -i nexus3.tar
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">docker run -d -p 8081:8081 --name nexus &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> -v nexus-data:/nexus-data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> sonatype/nexus3:latest&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>初始管理員密碼在容器內 &lt;code>/nexus-data/admin.password&lt;/code>，首次登入後強制修改。&lt;/p>
&lt;h3 id="hosted-repo-模式">Hosted repo 模式&lt;/h3>
&lt;p>連網環境的 Nexus 通常用 proxy repo（代理公開 registry、快取下載過的套件）。斷網環境 proxy 模式無法運作，改用 hosted repo——手動上傳套件到 Nexus，Nexus 作為唯一的分發來源。&lt;/p>
&lt;p>以 npm 為例，workflow 是在外部機器打包、搬運、上傳：&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">&lt;span class="c1"># 外部機器：打包專案的所有依賴&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">npm pack --pack-destination ./npm-packages/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="c1"># 或用 npm-offline-packager 批次下載整棵依賴樹&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">npx npm-offline-packager --package ./package.json --output ./npm-packages/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c1"># 搬運到內網後上傳到 Nexus&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="k">for&lt;/span> pkg in ./npm-packages/*.tgz&lt;span class="p">;&lt;/span> &lt;span class="k">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> curl -u admin:password &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --upload-file &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$pkg&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="s2">&amp;#34;http://nexus.internal:8081/repository/npm-hosted/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="k">done&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>apt 和 yum 的做法類似：外部機器用 &lt;code>apt-get download&lt;/code> 或 &lt;code>yumdownloader&lt;/code> 抓 .deb / .rpm 檔案，搬進來後上傳到 Nexus 的 hosted repo。&lt;/p>
&lt;h3 id="客戶端設定">客戶端設定&lt;/h3>
&lt;p>開發機器和 CI runner 的套件 source 指向 Nexus：&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">&lt;span class="c1"># npm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">npm config &lt;span class="nb">set&lt;/span> registry http://nexus.internal:8081/repository/npm-hosted/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># pip&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">pip install --index-url http://nexus.internal:8081/repository/pypi-hosted/simple/ package-name
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="c1"># apt（在 /etc/apt/sources.list.d/ 加一份）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">deb http://nexus.internal:8081/repository/apt-hosted/ focal main&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="harbor容器映像的-private-registry">Harbor：容器映像的 private registry&lt;/h2>
&lt;p>Harbor 是 CNCF 畢業專案的企業級容器 registry，支援映像簽章、漏洞掃描（Trivy）、存取控制、映像複製。在斷網環境裡它是 Docker Hub 和 ECR 的替代品。&lt;/p></description><content:encoded><![CDATA[<p>連網環境的套件安裝和映像拉取，背後都有一個公開的 registry 在服務：apt 走 archive.ubuntu.com、npm 走 registry.npmjs.org、Docker 走 Docker Hub。斷網環境裡這些 endpoint 全部不可達，每一條 <code>apt install</code>、<code>npm install</code>、<code>pip install</code>、<code>docker pull</code> 都會失敗。替代做法是在內網部署自己的 registry，把需要的套件和映像從外部下載、經過安全審查後搬進來。</p>
<p>本篇涵蓋兩個 registry 的部署與操作：Nexus Repository（多格式套件）和 Harbor（容器映像）。兩者可以獨立運作，也可以搭配使用——Nexus 管套件依賴、Harbor 管容器映像，各自負責不同的 artifact 類型。</p>
<h2 id="nexus-repository統一的離線套件-proxy">Nexus Repository：統一的離線套件 proxy</h2>
<p>Nexus Repository OSS（開源版）支援 apt、yum、npm、PyPI、Maven、NuGet、Go modules 等多種格式，用一個實例取代多個獨立的離線 repo mirror。部署在內網後，所有開發機器和 CI runner 把套件 source 指向 Nexus。</p>
<h3 id="部署">部署</h3>
<p>Nexus 本身是一個 Java 應用，用 Docker 部署最簡單。映像需要事先從外部搬進來：</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">docker pull sonatype/nexus3:latest
</span></span><span class="line"><span class="ln">3</span><span class="cl">docker save sonatype/nexus3:latest -o nexus3.tar
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># 搬運到內網後載入</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">docker load -i nexus3.tar
</span></span><span class="line"><span class="ln">7</span><span class="cl">docker run -d -p 8081:8081 --name nexus <span class="se">\
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="se"></span>  -v nexus-data:/nexus-data <span class="se">\
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="se"></span>  sonatype/nexus3:latest</span></span></code></pre></div><p>初始管理員密碼在容器內 <code>/nexus-data/admin.password</code>，首次登入後強制修改。</p>
<h3 id="hosted-repo-模式">Hosted repo 模式</h3>
<p>連網環境的 Nexus 通常用 proxy repo（代理公開 registry、快取下載過的套件）。斷網環境 proxy 模式無法運作，改用 hosted repo——手動上傳套件到 Nexus，Nexus 作為唯一的分發來源。</p>
<p>以 npm 為例，workflow 是在外部機器打包、搬運、上傳：</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">npm pack --pack-destination ./npm-packages/
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"># 或用 npm-offline-packager 批次下載整棵依賴樹</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">npx npm-offline-packager --package ./package.json --output ./npm-packages/
</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="c1"># 搬運到內網後上傳到 Nexus</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">for</span> pkg in ./npm-packages/*.tgz<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  curl -u admin:password <span class="se">\
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="se"></span>    --upload-file <span class="s2">&#34;</span><span class="nv">$pkg</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="se"></span>    <span class="s2">&#34;http://nexus.internal:8081/repository/npm-hosted/&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">done</span></span></span></code></pre></div><p>apt 和 yum 的做法類似：外部機器用 <code>apt-get download</code> 或 <code>yumdownloader</code> 抓 .deb / .rpm 檔案，搬進來後上傳到 Nexus 的 hosted repo。</p>
<h3 id="客戶端設定">客戶端設定</h3>
<p>開發機器和 CI runner 的套件 source 指向 Nexus：</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"># npm</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">npm config <span class="nb">set</span> registry http://nexus.internal:8081/repository/npm-hosted/
</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"># pip</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">pip install --index-url http://nexus.internal:8081/repository/pypi-hosted/simple/ package-name
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># apt（在 /etc/apt/sources.list.d/ 加一份）</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">deb http://nexus.internal:8081/repository/apt-hosted/ focal main</span></span></code></pre></div><h2 id="harbor容器映像的-private-registry">Harbor：容器映像的 private registry</h2>
<p>Harbor 是 CNCF 畢業專案的企業級容器 registry，支援映像簽章、漏洞掃描（Trivy）、存取控制、映像複製。在斷網環境裡它是 Docker Hub 和 ECR 的替代品。</p>
<h3 id="部署-1">部署</h3>
<p>Harbor 用 Docker Compose 部署。安裝包需要從外部下載後搬進來：</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">wget https://github.com/goharbor/harbor/releases/download/v2.11.0/harbor-offline-installer-v2.11.0.tgz
</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">tar xzf harbor-offline-installer-v2.11.0.tgz
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nb">cd</span> harbor
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"># 複製並編輯設定</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">cp harbor.yml.tmpl harbor.yml
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># 修改 hostname、storage 路徑、HTTPS 憑證（內部 CA 簽發）</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 安裝</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">./install.sh --with-trivy</span></span></code></pre></div><p><code>--with-trivy</code> 啟用內建的漏洞掃描。Trivy 的漏洞資料庫需要離線更新——從外部下載 DB 檔案、搬進來放到指定路徑。</p>
<h3 id="專案與存取控制">專案與存取控制</h3>
<p>Harbor 用「專案」（project）組織映像。每個專案可以設定獨立的存取控制：</p>
<ul>
<li><code>library</code>：公開專案、所有使用者可 pull</li>
<li><code>platform</code>：平台團隊專用、限定成員可 push</li>
<li><code>vendor</code>：第三方 base image、由 infra 團隊管理更新</li>
</ul>
<p>robot account 提供 CI/CD 用的非互動式認證（限定 pull / push 權限、可設定到期時間）。</p>
<h2 id="映像搬運-sop">映像搬運 SOP</h2>
<p>映像從外部搬進斷網環境是一個需要標準化的操作，涉及格式、大小、多架構支援：</p>
<h3 id="搬運工具比較">搬運工具比較</h3>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>優點</th>
          <th>限制</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>docker save/load</code></td>
          <td>最直覺、不需要額外安裝</td>
          <td>只能處理本地已 pull 的映像、不支援跨 registry 直接搬</td>
      </tr>
      <tr>
          <td><code>skopeo copy</code></td>
          <td>不需要 Docker daemon、支援跨 registry、支援 manifest list</td>
          <td>需要安裝 skopeo</td>
      </tr>
      <tr>
          <td><code>crane</code></td>
          <td>輕量 CLI、支援 manifest 操作</td>
          <td>功能比 skopeo 少</td>
      </tr>
  </tbody>
</table>
<p>skopeo 的操作流程：</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"># 外部機器：從 Docker Hub 複製到本地目錄</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">skopeo copy docker://nginx:1.25-alpine dir:./images/nginx-1.25-alpine
</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"># 搬運到內網後：從本地目錄推到 Harbor</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">skopeo copy dir:./images/nginx-1.25-alpine <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>  docker://harbor.internal/library/nginx:1.25-alpine <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>  --dest-tls-verify<span class="o">=</span><span class="nb">false</span>  <span class="c1"># 如果 Harbor 用內部 CA</span></span></span></code></pre></div><h3 id="多架構映像">多架構映像</h3>
<p>如果環境同時有 amd64 和 arm64 的機器，搬運時要帶整個 manifest list：</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">skopeo copy --all docker://nginx:1.25-alpine <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  dir:./images/nginx-1.25-alpine-multiarch
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># 內網：推送所有架構</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">skopeo copy --all dir:./images/nginx-1.25-alpine-multiarch <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>  docker://harbor.internal/library/nginx:1.25-alpine</span></span></code></pre></div><p><code>--all</code> flag 確保 manifest list 裡的每個架構都被複製，而非只複製本機架構。</p>
<h2 id="套件與映像的更新週期">套件與映像的更新週期</h2>
<p>斷網環境的套件和映像不會自動更新——每一次更新都是一次有意識的搬運操作。更新週期的頻率由安全需求決定：</p>
<table>
  <thead>
      <tr>
          <th>安全等級</th>
          <th>更新頻率</th>
          <th>適用場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一般</td>
          <td>每月一次</td>
          <td>開發工具、非直接面對外部的服務</td>
      </tr>
      <tr>
          <td>中等</td>
          <td>每兩週</td>
          <td>有外部接口的服務、包含網路元件</td>
      </tr>
      <tr>
          <td>高</td>
          <td>每週或 CVE 驅動</td>
          <td>安全敏感環境、合規要求</td>
      </tr>
  </tbody>
</table>
<p>每次更新的標準流程：</p>
<ol>
<li><strong>外部機器下載</strong>：按清單下載指定版本的套件和映像</li>
<li><strong>安全掃描</strong>：在外部（或 staging gateway）跑 Trivy / Snyk 掃描，確認沒有已知的高風險 CVE</li>
<li><strong>審查核准</strong>：掃描報告給安全團隊或負責人簽核</li>
<li><strong>搬運</strong>：核准的 artifact 寫入唯讀媒體或加密通道搬進內網</li>
<li><strong>上傳到 registry</strong>：推到 Nexus 和 Harbor</li>
<li><strong>通知團隊</strong>：哪些套件/映像有新版本可用</li>
</ol>
<p>這個流程的產出是一份更新清單（什麼版本、掃描結果、核准人），存進版控作為稽核紀錄。</p>
<h2 id="helm-chart-離線管理">Helm chart 離線管理</h2>
<p>Kubernetes 環境用 Helm 部署應用。斷網時 Helm chart 需要離線管理：</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"># 外部機器：下載 chart</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">helm repo add bitnami https://charts.bitnami.com/bitnami
</span></span><span class="line"><span class="ln">3</span><span class="cl">helm pull bitnami/postgresql --version 15.5.0
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># 搬運到內網後有兩個存放選項</span></span></span></code></pre></div><p><strong>選項一：Harbor 內建 chart 支援</strong>。Harbor 2.0+ 支援 OCI artifact，Helm chart 可以直接推到 Harbor：</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">helm push postgresql-15.5.0.tgz oci://harbor.internal/charts</span></span></code></pre></div><p><strong>選項二：ChartMuseum</strong>。獨立的 chart repository server：</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"># 上傳 chart</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">curl --data-binary <span class="s2">&#34;@postgresql-15.5.0.tgz&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  http://chartmuseum.internal:8080/api/charts</span></span></code></pre></div><p>Harbor 的 OCI 方式較簡單（不需要額外維護 ChartMuseum），但需要 Helm 3.8+ 的 OCI 支援。</p>
<h2 id="時程與管理層溝通">時程與管理層溝通</h2>
<table>
  <thead>
      <tr>
          <th>項目</th>
          <th>初次部署時間</th>
          <th>持續維護</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Nexus Repository</td>
          <td>1 天（部署 + 初始套件上傳）</td>
          <td>每次更新週期 2-4 小時</td>
      </tr>
      <tr>
          <td>Harbor</td>
          <td>1 天（部署 + 初始映像搬運）</td>
          <td>每次更新週期 2-4 小時</td>
      </tr>
      <tr>
          <td>搬運 SOP 建立</td>
          <td>半天（腳本化 + 文件）</td>
          <td>每次執行 1-2 小時</td>
      </tr>
      <tr>
          <td>Trivy 離線 DB 更新</td>
          <td>含在 Harbor 部署內</td>
          <td>每次更新週期 30 分鐘</td>
      </tr>
  </tbody>
</table>
<p>管理層需要知道的成本：registry 的維護不是一次性投入，每個更新週期都需要工程師時間執行搬運和掃描。這筆成本在連網環境裡由公開 registry 和自動更新吸收，斷網環境裡由團隊承擔。</p>
<h2 id="跨分類引用">跨分類引用</h2>
<ul>
<li>→ <a href="/blog/infra/air-gapped/air-gapped-principles/" data-link-title="斷網環境的通用原則" data-link-desc="離線套件管理、內容搬運、變更追蹤的共通操作模式 — 所有斷網情境都要先建立的基礎能力">斷網環境的通用原則</a>：content ferry pattern 和安全審查流程</li>
<li>→ <a href="/blog/infra/air-gapped/air-gapped-container/" data-link-title="斷網環境的容器與映像管理" data-link-desc="Private registry 架設、映像搬運（docker save/load、skopeo）、base image 更新週期、離線漏洞掃描">斷網環境的容器與映像管理</a>：映像搬運的更完整討論（本篇聚焦 registry 部署、該篇聚焦映像生命週期）</li>
<li>→ <a href="/blog/infra/air-gapped/air-gapped-iac/" data-link-title="斷網環境的 IaC" data-link-desc="Terraform provider mirror、離線 plugin cache、本地 state backend、沒有雲端時的 plan/apply 流程與內網 CI">斷網環境的 IaC</a>：Terraform provider 也需要離線 mirror、可用 Nexus 的 raw hosted repo 存放</li>
</ul>
]]></content:encoded></item></channel></rss>