
簡介面向ARM64架構(gòu)服務(wù)器的Harbor v2.13.1離線安裝包專為在鯤鵬、飛騰等國產(chǎn)化平臺及樹莓派環(huán)境中部署Docker鏡像倉庫的運維、開發(fā)人員準(zhǔn)備。由于官方安裝包長期以x86架構(gòu)為主要分發(fā)對象該資源精準(zhǔn)補(bǔ)齊ARM設(shè)備無法直接使用離線包的短板適用于Kubernetes集群鏡像流轉(zhuǎn)、多云場景下Harbor的快速搭建。壓縮包共6個文件包含負(fù)責(zé)安裝與公共配置的2個shell腳本、承載鏡像數(shù)據(jù)的gz核心包、以及配置模板、許可證和prepare預(yù)處理文件整體679.05MB覆蓋從環(huán)境檢查到服務(wù)啟動的關(guān)鍵環(huán)節(jié)。目前已有526人學(xué)習(xí)下載使用者可擺脫聯(lián)網(wǎng)拉取鏡像和手工編譯的麻煩借助內(nèi)置模板修改主機(jī)名、存儲目錄等參數(shù)后即可完成標(biāo)準(zhǔn)部署。資源還附帶用于定制HTTP/HTTPS訪問、TLS證書和端口參數(shù)的tmpl模板及prepare腳本既適合快速驗證也可作為中高級運維人員制定ARM生產(chǎn)環(huán)境鏡像管理方案的參考基線。1. 為什么生產(chǎn)環(huán)境都在找Harbor v2.13.1的ARM64離線安裝包它不是簡單的架構(gòu)替換在ARM64服務(wù)器上裝Harbor第一道坎不是配置而是找對安裝包。Harbor v2.13.1是目前最新的2.x維護(hù)版本但官方release里的離線安裝包默認(rèn)按amd64編譯直接拿到鯤鵬、飛騰這類ARM64機(jī)器上docker load能成功一啟動就報exec format error。真正的ARM64版離線安裝包不是換個文件名那么簡單它涉及鏡像清單、prepare工具和compose編排三處架構(gòu)一致性。我會把制作、校驗、部署和排雷的完整路徑講清楚適合正在維護(hù)國產(chǎn)化基礎(chǔ)設(shè)施的運維和容器平臺工程師。2. 為什么ARM64離線包不能直接用官方包鏡像清單與prepare工具的架構(gòu)陷阱2.1 官方離線包tgz里到底裝了什么install.sh怎么工作Harbor v2.13.1的官方離線安裝包文件名是harbor-offline-installer-v2.13.1.tgz解壓后是一個harbor目錄。里面結(jié)構(gòu)向來穩(wěn)定tar -zxf harbor-offline-installer-v2.13.1.tgz cd harbor ls -la # common.sh install.sh harbor.yml.tmpl prepare images/harbor.v2.13.1.tar.gzinstall.sh是總?cè)肟赾ommon.sh放著安裝時的公共變量和函數(shù)prepare是編譯器產(chǎn)物用來把harbor.yml轉(zhuǎn)換成docker-compose.yml最后是images目錄下的harbor.v2.13.1.tar.gz這是所有服務(wù)鏡像的打包文件。install.sh的執(zhí)行順序大致是加載common.sh、檢查docker和docker compose、調(diào)用prepare生成配置文件、再用docker load導(dǎo)入鏡像包最后docker compose up -d啟動全部容器。這里有個易忽略的環(huán)節(jié)install.sh生成的docker-compose.yml不是現(xiàn)成的而是prepare根據(jù)harbor.yml和自定義存儲路徑動態(tài)渲染出來的。prepare本身需要解析yaml、合并默認(rèn)值、生成nginx配置和若干子配置文件因此它對目標(biāo)主機(jī)的架構(gòu)非常敏感。如果你只替換了images/下的鏡像tar沒動prepare在ARM64機(jī)器上執(zhí)行./install.sh會直接在prepare那一步報Exec format error連鏡像都不會加載。很多拿到所謂“ARM64安裝包”的用戶在這里翻車回頭還以為是鏡像打包過程中漏了文件。common.sh里定義了Harbor安裝時的各種路徑和參數(shù)但它的重點不是架構(gòu)而是把prepare和docker compose的調(diào)用串聯(lián)起來。有人以為把common.sh里的uname判斷改了就算支持ARM64這不夠。prepare二進(jìn)制來自Go編譯Go本身是跨架構(gòu)的但官方在release流程里只產(chǎn)出了amd64的Linux編譯產(chǎn)物所以必須單獨提供arm64版prepare。這也是自制離線包和官方包唯一的本質(zhì)差異。2.2 exec format error背后是什么docker鏡像架構(gòu)和運行時校驗docker鏡像本身是一堆層每層是文件系統(tǒng)快照但最上面的config對象記錄了這個鏡像運行時需要的內(nèi)核和指令集架構(gòu)。當(dāng)你docker pull時默認(rèn)拉取當(dāng)前主機(jī)架構(gòu)對應(yīng)的變體除非顯式指定--platform。假如你把一份amd64的鏡像tar在arm64機(jī)器上docker load進(jìn)去docker不會攔你因為load出來的鏡像tag可能是一樣的。直到你docker compose up容器運行時去執(zhí)行第一個進(jìn)程CPU發(fā)現(xiàn)指令集對不上內(nèi)核直接拋exec format error容器秒退。docker image inspect --format {{.Architecture}} goharbor/harbor-core:v2.13.1 # amd64 或 arm64取決于你之前pull的是哪個變體這個Architecture字段是構(gòu)建鏡像時寫入的有時是arm64有時是aarch64腳本里判斷時要同時接受兩種寫法。更深一層的問題在于同一個鏡像tag在registry里往往同時存在多個架構(gòu)的manifest但docker save導(dǎo)出的只是本地緩存中的那個具體架構(gòu)。這是很多自制離線包翻車的根源——開發(fā)者在一臺x86_64機(jī)器上docker pull沒有加--platform拉下來的全是amd64然后docker save打包拿到ARM64機(jī)器上自然起不來。人眼看鏡像tag完全一致但實際架構(gòu)完全不同。所以在制作離線包時拉鏡像和導(dǎo)出鏡像必須嚴(yán)格控制在同一架構(gòu)下。2.3 哪些鏡像需要重新按ARM64拉取goharbor核心、postgres、nginx、redis與trivyHarbor v2.13.1的服務(wù)鏡像數(shù)量在12到15張左右具體取決于是否啟用trivy和chartmuseum。一個最小集至少包括這些goharbor/前綴的鏡像goharbor/harbor-core:v2.13.1goharbor/harbor-jobservice:v2.13.1goharbor/harbor-registryctl:v2.13.1goharbor/harbor-registry:v2.13.1goharbor/harbor-portal:v2.13.1goharbor/harbor-log:v2.13.1goharbor/harbor-db:v2.13.1goharbor/nginx-photon:v2.13.1goharbor/redis-photon:v2.13.1以上鏡像在Docker Hub和Quay上都有官方arm64構(gòu)建。harbor-db實際是postgresql的定制版arm64支持很成熟nginx-photon是Nginx加基礎(chǔ)調(diào)試工具arm64也沒問題。真正需要警惕的是基礎(chǔ)組件里不帶goharbor前綴的那幾張比如redis和postgresql原版鏡像有些歷史版本只有amd64或者多架構(gòu)發(fā)布不全。Harbor v2.13.1官方默認(rèn)捆綁的是photon-based的定制鏡像通常已經(jīng)發(fā)布arm64但如果你在制作時手滑用了社區(qū)版本的redis鏡像就可能在harbor-log或jobservice啟動時碰到exec format error。同樣trivy-adapter鏡像本身支持arm64但它啟動后要去聯(lián)網(wǎng)下漏洞數(shù)據(jù)庫離線環(huán)境要額外處理。如果要快速判斷一個鏡像是否支持arm64用docker manifest inspect看它的platform列表即可docker manifest inspect goharbor/harbor-core:v2.13.1 | grep -A6 arm64如果輸出里沒有arm64這張鏡像就不能用于ARM64離線包。這個檢查在開始制作前就要完成而不是等打包后才發(fā)現(xiàn)缺鏡像。3. 在QEMU模擬環(huán)境下制作Harbor v2.13.1 ARM64離線安裝包3.1 用qemu-user-static掛上ARM64執(zhí)行環(huán)境避免先買一臺實機(jī)制作ARM64離線包最穩(wěn)妥的辦法是直接在一臺ARM64機(jī)器上在線安裝一遍再打包但很多團(tuán)隊手頭沒有飛騰、鯤鵬機(jī)器。我一般會在x86_64開發(fā)機(jī)上用qemu用戶態(tài)模擬讓docker能夠拉取正確架構(gòu)的鏡像同時驗證prepare等二進(jìn)制能不能在模擬環(huán)境中跑通。第一步安裝和啟用sudo apt install -y qemu-user-static binfmt-support docker run --rm --privileged multiarch/qemu-user-static --reset -p yes第一條命令給系統(tǒng)裝上qemu對ARM64用戶態(tài)的支持和binfmt的注冊工具。第二條命令通過特權(quán)容器把binfmt的解析規(guī)則寫進(jìn)內(nèi)核系統(tǒng)重啟后會失效需要重新運行。注冊完成后可以驗證docker run --rm --platform linux/arm64 alpine uname -m # aarch64如果這里輸出的不是aarch64說明binfmt沒生效后續(xù)在你啟動任何arm64容器時都會遇到“exec format error”。要注意的是qemu模擬的是用戶態(tài)指令集不模擬硬件加速所以在模擬環(huán)境里完整跑Harbor所有容器會慢但用來做鏡像拉取和prepare替換是夠用的。在Ubuntu/Debian上包名叫qemu-user-static在CentOS 7上EPEL源里也有但版本較舊有時對ARM64新特性支持不全。更省心的做法是直接從多架構(gòu)鏡像項目里下載獨立的qemu-aarch64-static二進(jìn)制放到/usr/bin/后手動注冊binfmt。我用過的麒麟V10同樣適用這個思路因為系統(tǒng)自帶源里的qemu可能不完整。注冊binfmt的命令格式是echo :aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xa3\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64-static: /proc/sys/fs/binfmt_misc/register這段內(nèi)容看著像黑匣子但它解決的問題是讓Linux內(nèi)核能識別ARM64的ELF文件并交給qemu解釋執(zhí)行。x86_64主機(jī)上如果不注冊docker pull之后容器內(nèi)一啟動就會Exec format error和ARM64機(jī)器上遇到的現(xiàn)象一模一樣。3.2 按官方鏡像清單拉取linux/arm64鏡像并重新打包harbor.v2.13.1.tar.gz準(zhǔn)備好arm64執(zhí)行環(huán)境后第二步是按鏡像清單拉取。我先建一個image-list.txt把2.3節(jié)里列出的鏡像tag寫進(jìn)去然后循環(huán)拉取cat image-list.txt EOF goharbor/harbor-core:v2.13.1 goharbor/harbor-jobservice:v2.13.1 goharbor/harbor-registryctl:v2.13.1 goharbor/harbor-registry:v2.13.1 goharbor/harbor-portal:v2.13.1 goharbor/harbor-log:v2.13.1 goharbor/harbor-db:v2.13.1 goharbor/nginx-photon:v2.13.1 goharbor/redis-photon:v2.13.1 EOF while read -r img; do docker pull --platform linux/arm64 $img done image-list.txt注意--platform linux/arm64必須要加。因為docker在x86_64主機(jī)上默認(rèn)還是會拉amd64變體即使本機(jī)裝了qemupull階段仍然遵循Docker Hub的manifest選擇邏輯。只有顯式指定platformdocker拉下來的鏡像的Architecture字段才是arm64。如果某個鏡像只有amd64變體pull時會報“no matching manifest for linux/arm64”這就是早期預(yù)警需要換版本或者自行構(gòu)建。拉完后把本機(jī)所有g(shù)oharbor鏡像導(dǎo)出成一個tar文件替換離線包里的harbor.v2.13.1.tar.gzdocker save $(docker images --format {{.Repository}}:{{.Tag}} | grep ^goharbor/ | sort -u) -o harbor.v2.13.1.tar.gz cp harbor.v2.13.1.tar.gz ../harbor/images/harbor.v2.13.1.tar.gz這里有個坑docker save如果鏡像在本地存在多個架構(gòu)變體會把所有架構(gòu)的層都導(dǎo)出到tar里導(dǎo)致包體積變大而且load到目標(biāo)機(jī)上并不會自動過濾可能又出現(xiàn)架構(gòu)混用。更好的做法是先把本機(jī)不需要的鏡像tag清理掉確保只保留arm64變體。實際操作中我會先執(zhí)行docker image ls確認(rèn)每一張鏡像的架構(gòu)再save。3.3 用arm64版prepare替換install.sh依賴并修正common.sh里的架構(gòu)判斷鏡像tar換好后prepare是下一個必須處理的對象。官方離線包里的prepare在解壓目錄根下是amd64的ELF。在qemu環(huán)境下可以繼續(xù)從goharbor/prepare鏡像中把a(bǔ)rm64版提取出來docker pull --platform linux/arm64 goharbor/prepare:v2.13.1 docker create --name prepare-tmp goharbor/prepare:v2.13.1 docker cp prepare-tmp:/harbor/prepare ./prepare docker rm prepare-tmp chmod x ./preparegoharbor/prepare鏡像的入口是prepare程序它在鏡像里的路徑一般是/harbor/prepare。如果你的tag不是v2.13.1或者鏡像內(nèi)部路徑有變化可以先進(jìn)入容器找一下docker run --rm --entrypoint sh goharbor/prepare:v2.13.1 -c which prepare; ls -l /harbor把提取出來的./prepare覆蓋到離線包目錄下。然后打開common.sh搜索uname -m或uname。有的版本里有針對x86_64的架構(gòu)判斷例如case $(uname -m) in x86_64|amd64) ...如果遇到ARM64機(jī)器上被拒絕的情況把對應(yīng)分支改成同時接受aarch64和arm64。common.sh里的其他變量一般不用改因為prepare生成docker-compose時使用的是相對路徑和harbor.yml里的配置。這個替換動作做完后install.sh才能像在x86_64上一樣順暢走完。3.4 校驗產(chǎn)物docker manifest inspect與tar包內(nèi)的鏡像一一對應(yīng)打包完成別急著交付先在制作機(jī)上做一輪完整校驗。第一步對每一張鏡像執(zhí)行manifest驗證while read -r img; do echo $img docker manifest inspect $img | jq -r .manifests[] | .platform.architecture | sort | uniq done image-list.txt檢查輸出里是否有arm64。如果某張鏡像只有amd64這一項就會缺失。第二步解壓新生成的harbor.v2.13.1.tar.gz看看manifest.json里記錄的RepoTags和歸檔內(nèi)的層引用是否齊全tar -xOf harbor.v2.13.1.tar.gz manifest.json | jq .[].RepoTags這個輸出應(yīng)該和image-list.txt里的tag一致。第三步如果條件允許把整個離線包拷貝到一臺臨時ARM64機(jī)器上執(zhí)行./install.sh --with-trivy --with-chartmuseum然后docker compose ps看所有服務(wù)是否正常。這個“真機(jī)冒煙測試”比任何靜態(tài)校驗都可靠我每次交付前都至少做一遍。4. 把自制ARM64離線包部署到目標(biāo)機(jī)從harbor.yml到install.sh參數(shù)4.1 解壓后配置harbor.yml的hostname、端口和存儲路徑拿到做好的離線包在目標(biāo)ARM64服務(wù)器上先解壓tar -zxf harbor-offline-installer-v2.13.1-arm64.tgz cd harbor cp harbor.yml.tmpl harbor.yml vi harbor.ymlharbor.yml是安裝的唯一入口。最少要改四個位置。hostname填實際訪問域名或IP不能是localhost否則Harbor的頁面登錄會403。http部分是監(jiān)聽端口默認(rèn)80如果和系統(tǒng)Nginx或已有Web服務(wù)沖突改成8080。如果不用https把https段整個注釋掉因為prepare讀取到certificate和private_key路徑的文件不存在時會直接退出。harbor_admin_password設(shè)置初始化管理員密碼必須至少8位且?guī)Т笮懞蛿?shù)字。database的password是給Postgres用的建議也改掉避免弱密碼風(fēng)險。最后是data_volume這個目錄存放registry數(shù)據(jù)、數(shù)據(jù)庫和證書必須單獨掛載到大分區(qū)。一個常見誤區(qū)是只改hostname其他都用模板默認(rèn)值。這樣在純離線環(huán)境里確實能裝起來但后續(xù)要配https再回頭看harbor.yml時容易漏改。我習(xí)慣把所有涉及安全的口令都明確寫上哪怕保持默認(rèn)也在文件里留下痕跡方便交接。整段配置參考hostname: registry.internal.example.com http: port: 80 https: port: 443 certificate: /data/harbor/cert/server.crt private_key: /data/harbor/cert/server.key harbor_admin_password: N8sTrm64#2025 database: password: D8brm64#2025 max_idle_conns: 50 max_open_conns: 100 data_volume: /data/harbor注意這里的https端口和證書路徑要真實存在否則install.sh的prepare階段會報證書文件缺失。如果只是測試建議先把https段整個注釋掉用http跑通再說。4.2 install.sh常用參數(shù)--with-trivy、--with-chartmuseum以及證書模式下必開的選項執(zhí)行安裝sudo ./install.sh --with-trivy --with-chartmuseuminstall.sh支持的常見參數(shù)如下表。注意參數(shù)只在首次安裝時有效后續(xù)配置變更都要重新執(zhí)行prepare再compose up。參數(shù)作用適用場景--with-trivy啟用Trivy漏洞掃描需要安全漏洞報告--with-chartmuseum啟用ChartMuseum Helm倉庫需要管理Helm Chart--with-notary啟用Notary鏡像簽名需要內(nèi)容信任一般是金融政企強(qiáng)制要求--with-clair啟用Clair漏洞掃描老版本遺留新項目建議用Trivy-d以debug模式運行輸出腳本每一步日志排障時使用如果你在離線包制作時沒有啟用某組件那install.sh就不要帶對應(yīng)參數(shù)。比如image-list.txt里沒拉trivy-adapter執(zhí)行--with-trivy時Harbor會因找不到鏡像而報錯。在純離線環(huán)境--with-trivy還會帶來一個額外的坑trivy啟動后需要下載漏洞數(shù)據(jù)庫因此你需要在離線包中額外準(zhǔn)備goharbor/trivy-db或者調(diào)整trivy的離線掃描配置。這部分沒有絕對通用做法我通常是先不加trivy部署等后面有外網(wǎng)條件再補(bǔ)。同樣--with-chartmuseum只在你想要一個Helm Chart倉庫時才需要不是默認(rèn)功能。4.3 部署后健康檢查docker compose ps、curl /api/v2.0/pinginstall.sh結(jié)束后先看服務(wù)狀態(tài)docker compose ps所有服務(wù)應(yīng)該處于Upharbor-db和redis的health列是(healthy)。如果某個服務(wù)顯示Restarting馬上看日志docker logs --tail 50 harbor-core docker logs --tail 50 harbor-db再調(diào)用API做基本驗證curl -k -u admin:YourPassword https://127.0.0.1/api/v2.0/ping返回PONG表示core服務(wù)正常。最后創(chuàng)建項目docker login到Harborpush一個測試鏡像再pull回來形成閉環(huán)。注意docker客戶端如果報x509證書錯誤需要把Harbor的ca.crt添加到/etc/docker/certs.d/harbor域名/目錄下或者在daemon.json配置insecure-registries。在國產(chǎn)化操作系統(tǒng)上這個證書信任動作經(jīng)常被忽略導(dǎo)致能登錄但推送失敗日志提示“http: server gave HTTP response to HTTPS client”實際上是因為harbor.yml里配置了https而客戶端走h(yuǎn)ttp需要檢查harbor.yml中的http和https配置還要檢查容器內(nèi)的nginx端口映射。5. 避坑與排查ARM64離線包部署最容易踩的5個坑5.1 docker load成功但容器崩潰日志說exec format error現(xiàn)象docker compose up后harbor-core容器秒退docker logs顯示standard_init_linux.go:228: exec user process caused: exec format error。原因鏡像tar里的架構(gòu)仍然是amd64docker load時沒有做任何攔截它只是把層解開并不檢查是否能在本機(jī)運行。解決檢查制作流程里是否真的指定了--platform linux/arm64用docker image inspect逐一核對。如果只有少數(shù)服務(wù)報錯可以單獨拉取arm64變體再替換tar不需要全部重來。這個坑在所有跨架構(gòu)離線包里排第一因為很多人從網(wǎng)上下載一個“ARM64離線包”其實源頭機(jī)器是x86_64docker save導(dǎo)出的鏡像仍然是amd64。5.2 prepare執(zhí)行時Exec format error導(dǎo)致install.sh進(jìn)行到一半就?,F(xiàn)象執(zhí)行./install.sh屏幕顯示prepare: Exec format error但前面的腳本檢查都正常。原因官方離線包內(nèi)置的prepare是x86_64二進(jìn)制ARM64內(nèi)核無法執(zhí)行。解決使用3.3節(jié)的方法從goharbor/prepare鏡像里提取arm64版本并替換??梢栽谥谱麟x線包前先把這一步做掉也可以在目標(biāo)機(jī)上臨時用docker run方式單獨執(zhí)行prepare再接手工docker compose up后者適合著急上線的場景。如果不想動包里二進(jìn)制也可以改install.sh把./prepare那行替換成docker run --rm -v $PWD:/harbor goharbor/prepare:v2.13.1 prepare但這樣依賴網(wǎng)絡(luò)離線環(huán)境不推薦。5.3 harbor-db起來了但harbor-core連不上數(shù)據(jù)庫日志反復(fù)報password authentication failed現(xiàn)象harbor-core容器日志出現(xiàn)connection refused或password authentication failed但harbor-db容器狀態(tài)是healthy。原因harbor.yml中的database.password與數(shù)據(jù)庫初始化時使用的密碼不一致或者數(shù)據(jù)庫鏡像初始化時已經(jīng)用了舊密碼數(shù)據(jù)卷是舊的。解決如果數(shù)據(jù)卷里的postgresql數(shù)據(jù)已經(jīng)存在初始化腳本不會重復(fù)執(zhí)行改密碼也不會生效。要么刪除data_volume下的database子目錄重新初始化要么在harbor.yml中保持原密碼。這是Harbor一個老問題和ARM64無關(guān)但在離線包上更容易踩因為很多人是從amd64機(jī)器復(fù)制數(shù)據(jù)卷過來的。刪除數(shù)據(jù)卷的代價是丟失全部鏡像數(shù)據(jù)操作前務(wù)必備份data_volume。5.4 Trivy掃描報無法初始化漏洞數(shù)據(jù)庫不是架構(gòu)問題現(xiàn)象鏡像能push但點擊漏洞掃描后任務(wù)失敗日志提示failed to download the vulnerability database。原因trivy-adapter啟動后會去GitHub或官方鏡像源下載trivy-db離線環(huán)境沒有外網(wǎng)或者防火墻只允許走代理。解決在在線環(huán)境提前docker pull aquasec/trivy-db再手動導(dǎo)入到Harbor所在節(jié)點的docker鏡像緩存并修改harbor.yml中trivy相關(guān)的offline_scan為true。也可以更徹底地把trivy-db鏡像傳給用戶在離線包中額外附帶。要注意trivy-db也有arm64變體別又拉成amd64。這個坑跟ARM64沒有強(qiáng)關(guān)聯(lián)但很多人在前幾步折騰完架構(gòu)問題后會異想天開地懷疑是ARM64導(dǎo)致的實際上trivy鏡像本身是有arm64的。5.5 install.sh提示docker compose版本不滿足但docker-compose命令能執(zhí)行現(xiàn)象腳本檢查到docker compose不存在或版本低于2.0但docker-compose帶橫線能正常工作。原因Harbor install.sh判斷的是docker compose v2插件不是舊版python實現(xiàn)的docker-compose?,F(xiàn)在的發(fā)行版默認(rèn)裝的是docker-compose v1或者只有v2插件但沒鏈接到PATH。解決安裝插件版sudo apt install docker-compose-plugin或從docker官方二進(jìn)制包拷貝到/usr/local/lib/docker/cli-plugins/docker-compose并加執(zhí)行權(quán)限。ARM64的國產(chǎn)化系統(tǒng)有些源里沒有這個包需要從docker官方下載arm64編譯好的二進(jìn)制注意別下成amd64的。驗證命令是docker compose version而不是docker-compose version。這個坑和架構(gòu)無關(guān)但如果你用官方離線包在ARM64上栽在這一步會特別泄氣因為前面明明是架構(gòu)問題到這里又變成了工具鏈問題。6. 進(jìn)階用docker manifest自動校驗鏡像架構(gòu)并固化自制離線包的腳本上面幾條坑如果能挨著趟過去離線包基本能用了。我再分享一個自己常用的校驗?zāi)_本它在每次打包前后跑一遍目的只有一個確保images/目錄下的tar里每個鏡像的架構(gòu)都是arm64。#!/usr/bin/env bash set -euo pipefail image_list$(docker images --format {{.Repository}}:{{.Tag}} | grep ^goharbor/ | sort) for img in $image_list; do arch$(docker image inspect --format {{.Architecture}} $img) if [ $arch ! arm64 ]; then echo [FAIL] $img is $arch, not arm64 exit 1 fi done echo all matched arm64這段腳本的邏輯很直白docker image inspect輸出的Architecture就是鏡像配置里的原始架構(gòu)arm64或者aarch64都可能出現(xiàn)視構(gòu)建工具而定。如果腳本發(fā)現(xiàn)任何一個鏡像不是arm64就立刻退出。實際使用中我會把它放在一個build-offline.sh里讓它緊接著docker pull和docker save之后執(zhí)行。注意這里的鏡像范圍限定在goharbor/下如果你在離線包里額外加了redis等非goharbor鏡像要把正則再擴(kuò)大。如果想要更強(qiáng)的校驗可以進(jìn)一步比對docker-compose.yml里用到的鏡像tag是否都出現(xiàn)在tar中。做法是compose_refs$(grep -E image: docker-compose.yml | awk {print $2} | sort -u) tar_refs$(tar -xOf harbor.v2.13.1.tar.gz manifest.json | jq -r .[].RepoTags[] | sort -u) comm -23 (echo $compose_refs) (echo $tar_refs)如果輸出有內(nèi)容說明compose里引用了tar里沒有的鏡像tag啟動時必然報image not found。這個步驟在手工制作時容易漏掉因為在拉鏡像時少拉一個很簡單而docker compose up只會在用到時才發(fā)現(xiàn)。我自己的習(xí)慣是離線包在進(jìn)生產(chǎn)前一定在隔離環(huán)境里完整跑一遍install.sh加push/pull驗證再封裝成交付物。雖然多花十分鐘但它能把這些架構(gòu)陷阱、依賴缺失的后悔藥提前吃完。記住一條ARM64離線包的難點不在“包”而在包里的鏡像、prepare和compose配置三者是不是同一架構(gòu)。希望這套制作和排查路徑能幫你在國產(chǎn)化服務(wù)器上把Harbor順利跑起來少踩幾個坑。本文還有配套的精品資源點擊獲取