news 2026/10/21 13:46:56

HAProxy实现Harbor高可用架构:负载均衡与故障转移实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HAProxy实现Harbor高可用架构:负载均衡与故障转移实战

1. 項目概述與痛點分析,為什麼 Harbor 也需要高可用

1.1 單節點 Harbor 的隱患,鏡像倉庫掛了會發生什麼

先講一個我親身經歷的案例。某公司在內部推行容器化改造,開發環境、測試環境、預生產環境的鏡像全都推到一台 Harbor 伺服器上。前期一切正常,直到某天上午,那台伺服器的磁碟因為鏡像堆積被寫滿,Harbor 直接拒絕服務。開發那邊 deploy 流程全部卡住,測試環境沒法更新版本,運維這邊也因為沒法拉取基礎鏡像,連故障排查的容器都起不來。整個研發節奏被打斷了將近半天,最後還是臨時騰了一台機器手動恢復數據,才勉強把服務拉起來。

鏡像倉庫這個東西,平時存在感很低,但它實際上是整個容器化體系裡的核心樞紐。CI/CD 流水線、Kubernetes 集群拉取鏡像、開發人員本地調試,全都依賴它。一旦它掛了,影響的不是某一個服務,而是整條交付鏈路。

單節點 Harbor 的問題,歸納起來主要是三類:

  • 沒有故障轉移能力:硬體故障、系統崩潰、內存洩漏,任何一種情況都可能讓服務直接中斷。沒有備用節點,就只能等人工介入。
  • 升級維護必須停機:Harbor 版本升級、配置變更、證書輪換,都需要重啟服務。單節點架構下,這些操作只能選在深夜低峰期做,或者直接冒著影響業務的風險硬上。
  • 性能瓶頸無法橫向擴展:並發拉取量大、鏡像體積大,單節點的 CPU、內存、帶寬都會成為瓶頸,尤其在高併發 CI 場景下特別明顯。

當時我們團隊內部的結論很直接:鏡像倉庫必須做高可用。至少要保證一台節點掛了,服務還能繼續轉。這就是這篇文章的出發點——用 HAProxy 做入口調度,配合 Harbor 多節點部署,構建一套可靠的高可用架構。

1.2 方案選型,為什麼入口層選 HAProxy 而不是 Nginx 或 F5

在做入口選型的時候,市面上常見的無外乎三類:軟體負載均衡(HAProxy、Nginx)、雲廠商 LB、硬體負載均衡(F5 那類)。從成本和运维靈活度來考慮,我們當時直接排除了硬體設備,雲廠商 LB 在自建機房的場景下也壓根不適用,剩下就是 HAProxy 和 Nginx 之間的抉擇。

HAProxy 在負載均衡領域是專精選手,它的設計目標就是做高併發代理。跟 Nginx 相比,它有幾個很關鍵的優勢:

一是連接調度能力更強。HAProxy 對 TCP 層的代理支持非常成熟,可以做到連接級別的負載和健康檢查,而且支持基於 Cookie 的 session 保持。Harbor 的客戶端既有 Docker CLI 也有 HTTP API,連接模型複雜,HAProxy 處理起來更穩。

二是健康檢查手段豐富。除了基礎的端口探測,HAProxy 支持 HTTP 層的http-check,可以直接請求 Harbor 的/api/v2.0/ping接口來判斷節點是否真的健康。Nginx 被動式的健康檢查需要商業版才支持,開源版只能靠上游服務器返回的錯誤來間接判斷,靈活性差很多。

三是性能開銷極低。HAProxy 是事件驅動的單進程模型,在同樣的硬體條件下,能支撐的併發連接數遠高於 Nginx。作為流量入口,不希望它本身成為瓶頸,HAProxy 在這方面非常值得信賴。

另外,HAProxy 的配置語法非常直白,frontend、backend、listen三個段搞定所有的代理邏輯,沒有 Nginx 那麼多模塊化的規則。後期維護成本也低。

注意:如果你對 Nginx 特別熟悉,硬要用它來做也並非不行。但 Harbor 這種多協議、多端口(HTTP 443、Harbor 內部組件通信)的場景,HAProxy 的 TCP 代理能力和健康檢查機制明顯更合適。別在入口層複雜化問題。

2. Harbor 高可用的架構設計思路

2.1 整體架構與流量路徑,一張圖講清楚各組件關係

HAProxy 實現 Harbor 高可用的核心思路,就是「前面加調度,後面做冗餘」。整個架構可以分為四層:

客戶端層:包含 Docker CLI、Kubernetes 節點、CI/CD 工具。它們訪問的是統一的虛擬地址(VIP 或域名),而不是具體的 Harbor 節點。

入口調度層:也就是 HAProxy。它負責接收所有請求,按策略轉發到後端 Harbor 節點,同時通過健康檢查來剔除異常節點。

Harbor 節點層:兩個或以上的 Harbor 實例部署在不同的物理機或虛擬機上,互為主備或雙活。每個節點上都運行著完整的 Harbor 服務棧,包括核心服務、註冊表、入口控制器等。

共享數據層:這是整個架構能否成立的關鍵。Harbor 的運行狀態分為兩大塊——存儲在 PostgreSQL 和 Redis 中的元數據,以及存放在對象存儲或文件系統中的鏡像層數據。高可用架構下,這兩個部分必須由所有 Harbor 節點共享。

流量路徑是這樣的:客戶端請求到 HAProxy → HAProxy 通過負載均衡算法選中一個 Harbor 節點 → Harbor 節點處理請求,讀寫共享的 PostgreSQL/Redis/存儲 → 返回結果給客戶端。

關鍵點在於,任何一個 Harbor 節點收到請求後,讀寫的都是同一份底層數據,所以無論請求被轉發到哪個節點,最終結果都是一致的。這就是「共享一切」架構的含義。

2.2 兩種高可用模式,雙活模式和主備模式該怎麼選

Harbor 高可用有兩種常見的部署模式,區別在於 Harbor 配置文件中harbor.yml的external_url和資料庫連線設置。

雙活模式(Active-Active)

兩個節點同時工作,都對外提供服務。HAProxy 把流量均勻分散到兩個節點上。這種模式的優勢是資源利用率高,整個系統的吞吐能力是兩台節點的疊加。但前提是底層的共享層必須支持併發讀寫,PostgreSQL 和 Redis 都必須配置成集群或主從模式,存儲層則需要支持多節點同時掛載。

主備模式(Active-Standby)

只有主節點在提供服務,備用節點處於空閒狀態,但保持數據同步。HAProxy 通過健康檢查監控主節點狀態,一旦主節點掛了,流量自動切到備用節點。這種模式的好處是配置簡單,對共享層的併發壓力小,但也意味着有一台機器長期閒置,存在資源浪費。

我們的建議是:如果你的 Harbor 承載的是核心生產業務,雙活是值得投入成本的,因為它能同時解決高可用和性能擴展兩個問題。如果鏡像倉庫只是輔助角色,流量不大,主備模式就夠用了,後期也能平滑切換到雙活。

2.3 共享層的關鍵角色,存儲、資料庫、Redis 一個都不能少

為什麼說共享層是整個方案的成敗關鍵?我拆開來講。

鏡像存儲:Harbor 底層本質上是 Docker Distribution,鏡像的 blob 數據存儲在文件系統或對象存儲中。高可用架構下,如果兩個 Harbor 節點各存各的,就會出現「節點 A 能拉到的鏡像,節點 B 上根本不存在」的情況。所以必須讓所有節點訪問同一份存儲,通常是 NFS、CephFS、GlusterFS、MinIO 這類方案。

PostgreSQL:Harbor 的用戶、項目、鏡像清單、審計日誌、權限策略全都存在 PostgreSQL 裡。單節點 PostgreSQL 在高可用架構下就是一個新的單點。你可以給它做主從複製,也可以用 Patroni 這類工具做自動故障轉移,在雲環境下直接用託管的 PostgreSQL 服務也是一種思路。

Redis:Harbor 用 Redis 做緩存和會話管理。Redis 掛了,Harbor 雖然不一定立刻崩潰,但會出現會話丟失、掃描任務異常等問題。同樣需要考慮高可用,Redis Sentinel 或 Redis Cluster 都可以。

我當時踩過一個很典型的坑:Harbor 兩個節點都配好了,HAProxy 也轉發正常,但鏡像推送偶爾會出問題。排查了半天發現,問題出在兩個 Harbor 共享了同一個 PostgreSQL,但是 Redis 是各自獨立的。用戶的 session 信息沒有共享,導致請求被轉發到不同節點時,登入狀態會丟失。後來把 Redis 改成共享模式,問題立刻消失。

忠告:架構容易畫,但共享層往往決定成敗。動手之前,先把存儲、資料庫、緩存這三層的高可用方案確定下來,否則整個方案就是空中樓閣。

3. 實戰部署:從環境準備到 HAProxy 配置

3.1 環境規劃與前置準備

我們用一台 HAProxy 節點加兩台 Harbor 節點來演示,具體規劃如下。實際項目中為了避免 HAProxy 自身成為單點,建議再部署一台備用 HAProxy 節點,搭配 Keepalived 做 VIP 漂移。

角色規劃說明
HAProxy 節點10.10.1.10入口調度層,對外提供服務
Harbor Node110.10.1.21第一台 Harbor 節點,雙活模式
Harbor Node210.10.1.22第二台 Harbor 節點,雙活模式
NFS 共享存儲10.10.1.30提供 /data/nfs/harbor 目錄作為鏡像存儲
PostgreSQL10.10.1.31主從複製,對應 Harbor 元數據庫
Redis10.10.1.32Sentinel 模式,供 Harbor 做會話和緩存

在動手之前,有幾個前置條件必須確認:

  • 所有節點的時間要同步,建議配置 NTP。時間不一致會導致 token 校驗失敗,這是個很隱蔽的問題。
  • 所有節點的主機名要解析正常,公私鑰認證不是必須,但 Harbor 節點之間如果要互相調用 API,配一下會方便不少。
  • Harbor 的harbor.yml配置中,external_url要設定成對外的虛擬地址(例如https://harbor.example.local),兩個節點上的配置保持一致。千萬別把external_url寫成節點自己的 IP。

3.2 共享存儲和共享資料庫的部署細節

NFS 是最容易上手的共享存儲方案。服務端在 10.10.1.30 上安裝nfs-kernel-server,編輯/etc/exports:

/data/nfs/harbor 10.10.1.21(rw,sync,no_root_squash,no_subtree_check) 10.10.1.22(rw,sync,no_root_squash,no_subtree_check)

Harbor 節點上掛載:

mount -t nfs 10.10.1.30:/data/nfs/harbor /data/harbor

需要特別注意:掛載參數的選擇直接影響性能和數據一致性。no_root_squash是必須的,否則 Harbor 容器內 root 使用者寫入的文件會因為權限被壓縮而報錯。sync是為了保證數據即時落盤,防止宕機時丟失資料。實測下來,NFS 在最壞情況下吞吐會有一定衰減,如果你的場景是高併發大量鏡像推送,建議直接上 CephFS 或 MinIO 這種更大規模的存儲方案,架構上更穩,後期也好擴展。

PostgreSQL 的配置相對獨立,這裡說幾個要點。Harbor 需要的是「專用的資料庫實例」,官方支援 PostgreSQL 9.6 及以上版本。如果資料庫和 Harbor 在同一台機器上,配置基本上不用改,直接裝好就行。分離部署的話,需要修改harbor.yml中database部分的連線信息:

database: type: external external: host: 10.10.1.31 port: 5432 username: harbor password: harbor_password db_name: harbor max_idle_conns: 50 max_open_conns: 100

主從複製的配置不在本文的範圍內,網上文章很多,基本的思路就是pg_basebackup做基礎備份,再配置primary_conninfo做流式複製。Redis 也是同理,建議用 Sentinel 模式,兩個 Harbor 節點連的是同一個 Sentinel 集群,而不是各自連一個 Redis。

3.3 兩台 Harbor 節點的部署,harbor.yml 的關鍵配置

Harbor 的離線安裝包解壓後,會有一個harbor.yml.tmpl範本,複製成harbor.yml,然後逐項修改。兩個節點的配置要一致,除了hostname不同(但需要指向同一個對外域名)。

核心配置大概長這樣:

hostname: harbor.example.local http: port: 80 https: port: 443 certificate: /data/certs/harbor.crt private_key: /data/certs/harbor.key external_url: https://harbor.example.local harbor_admin_password: Harbor12345 database: type: external external: host: 10.10.1.31 port: 5432 username: harbor password: harbor_password db_name: harbor data_volume: /data/harbor storage_service: ca_bundle: /data/certs/harbor_ca.crt filesystem: maxkeys: 100000 maxsize: 1000000 redis: type: external external: addr: 10.10.1.32:6379 sentinel_master_set: mymaster sentinel_addrs: 10.10.1.32:26379 db: 0 password: redis_password

幾個關鍵點:

  • data_volume必須指向共享存儲,也就是 NFS 掛載的那個目錄。Harbor 的所有持久化數據,包括鏡像層、資料庫備份、證書等,都會寫到這個目錄。
  • storage_service裡的filesystem可以配置,但如果你用的是 S3 兼容的對象存儲,Harbor 也支援直接對接。實測中,對象存儲的並發讀寫能力比 NFS 強很多,是更推薦的生產方案。
  • 證書的配置要特別小心。所有節點的證書必須是同一套,不然客戶端在切換節點時會看到證書不匹配的警告。用內部 CA 簽發即可,但docker login的客戶端需要信任這個 CA。

配置完成後,執行./install.sh。Harbor 會以 docker-compose 的方式啟動一堆容器,包括harbor-core、harbor-registry、harbor-portal、registryctl等。可以先用docker ps確認容器是否都在運行。

3.4 HAProxy 的安裝與配置

HAProxy 安裝很簡單,用發行版自帶的包管理器即可:

apt install haproxy

主要是要做好配置。先看一下我們最終的完整配置,再逐段解釋。

# /etc/haproxy/haproxy.cfg global log /dev/log local0 maxconn 4096 chroot /var/lib/haproxy user haproxy group haproxy daemon defaults log global mode http option httplog option dontlognull option forwardfor option http-server-close timeout connect 5s timeout client 30s timeout server 30s frontend harbor_https bind *:443 mode tcp default_backend harbor_nodes backend harbor_nodes mode tcp balance roundrobin option tcp-check stick-table type ip size 1m expire 30m stick on src server harbor1 10.10.1.21:443 check inter 5s fall 3 rise 2 server harbor2 10.10.1.22:443 check inter 5s fall 3 rise 2

等等,為啥用mode tcp而不是mode http?這個問題很多人問過。Harbor 的 443 端口上跑的是 HTTPS,如果 HAProxy 用mode http,就得承擔 SSL 終結和重新加密的任務,要麼你告訴它後端服務用的是 HTTP 還是 HTTPS,SSL 證書的管理也會變複雜。用mode tcp是最省事的方式,HAProxy 只做四層轉發,把 TLS 加密的裸流量直接透傳到後端,證書的驗證完全由 Harbor 自己處理。這樣一來,HAProxy 不需要管證書,後端節點換證書也不需要動 HAProxy 配置。

balance roundrobin是預設的負載均衡算法,兩個節點輪流接收請求。stick-table的作用是讓同一個來源 IP 的請求,在存在健康節點的情況下,盡量定向到同一個後端節點。這個特性對 Harbor 是加分的——有些客戶端(比如 Kubernetes 的 containerd)會持有多個連接,如果這些連接被分散到不同節點,雖然底層數據一致,但連接建立的成本會更高。

最重要的一段是健康檢查:

option tcp-check server harbor1 10.10.1.21:443 check inter 5s fall 3 rise 2

inter 5s表示每 5 秒探測一次,fall 3表示連續失敗 3 次才判定節點不可用,rise 2表示連續成功 2 次才恢復可用。這個參數組合比較保守,能有效避免短暫抖動造成的誤判。

如果你希望健康檢查更貼近業務層,可以改用 HTTP 檢查。把後端節點的檢查切換成:

backend harbor_nodes mode http option httpchk GET /api/v2.0/ping http-check expect status 200 server harbor1 10.10.1.21:443 ssl verify none check inter 5s fall 3 rise 2 server harbor2 10.10.1.22:443 ssl verify none check inter 5s fall 3 rise 2

ssl verify none的意思是檢查時不驗證後端證書,這樣可以避免內部 CA 證書未被信任的問題。expect status 200確保後端真的能回應請求,而不只是端口通。

3.5 Keepalived 做 HAProxy 高可用

HAProxy 自己掛了怎麼辦?這個問題得提前考慮。我們的做法是在 HAProxy 前面再架一層 Keepalived,用 VIP 提供虛擬位址。

配置非常簡單。兩台 HAProxy 節點上,安裝 Keepalived,/etc/keepalived/keepalived.conf寫成下面這樣:

vrrp_script chk_haproxy { script "/usr/bin/kill -0 $(cat /var/run/haproxy.pid)" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 10.10.1.10/24 } track_script { chk_haproxy } }

解釋一下:Keepalived 的vrrp_script會去檢查 HAProxy 進程是否還活著,如果掛了,自身的優先級會降低 20,心跳間隔後,另一個節點就搶佔 VIP。服務對外始終是 10.10.1.10,對客戶端來說,HAPROXY 節點的故障是無感知的。

注意,兩台 HAProxy 節點的state可以都寫成MASTER(配合不同的priority),也可以一台MASTER一台BACKUP,後者比較直觀,但前者的 failover 速度更快。我個人傾向於都寫MASTER,讓 priority 決定誰優先。

3.6 客戶端側的配置,docker 如何信任自簽證書

這是整個方案落地時最容易出現問題,但往往被忽略的一步。Docker 默認只信任系統 CA 機構頒發的證書,你內部 CA 簽發的 Harbor 證書,如果不做配置,docker login必然失敗。

如果客戶端是和 Harbor 在同一網段內的伺服器,最簡單的方案是把 CA 證書放到 Docker 的信任目錄:

cp harbor_ca.crt /etc/docker/certs.d/harbor.example.local/ca.crt

如果 Harbor 監聽的是非標準端口,比如harbor.example.local:8443,目錄名要寫成harbor.example.local:8443,格式對應 IP 和端口。

配置完重啟 Docker 即可:

systemctl restart docker

如果客戶端是開發筆記型電腦,要確保使用正確的解析——域名要解析到 VIP(10.10.1.10),而不是某個 Harbor 節點的 IP。在/etc/hosts或者 DNS 伺服器裡配置好就行,否則流量根本不會走到 HAProxy。

4. 驗證與測試,如何確認高可用架構真的可用

4.1 基本功能驗證:推送、拉取、登入

配置完成後,第一個要驗證的是基本功能。兩台 Harbor 節點都正常運行時,執行以下操作:

# 登入 Harbor docker login harbor.example.local -u admin -p Harbor12345 # 打標籤並推送 docker tag nginx:latest harbor.example.local/library/nginx:latest docker push harbor.example.local/library/nginx:latest # 拉取 docker pull harbor.example.local/library/nginx:latest

如果這三步都通了,說明整個鏈路是通的。接下來可以進一步觀察請求是否被輪流分發到了兩個節點。登入 Harbor 的 Web 管理介面,查看「審計日誌」,會看到來自同一客戶端的推拉操作時而落在節點 A,時而落在節點 B。在雙活模式下,這種現象是正常的,也是預期的。

4.2 故障注入測試:停掉一台 Harbor 節點

這一步是整個高可用驗證的核心。模擬一台 Harbor 節點宕機,看看整個系統是否還能正常提供服務。

這裡的操作順序很關鍵。先不要直接停服務,建議先觀察 HAProxy 的狀態頁面或日誌,確認它對後端每個節點的監控狀態都是綠色的。然後在 Node2 上執行:

docker-compose stop # 在 Node2 的 Harbor 安裝目錄下執行

或者乾脆模擬硬體故障,直接把 VM 關機。然後觀察 HAProxy 節點上的日誌:

tail -f /var/log/haproxy.log

正常情況下,幾秒內就能看到健康檢查開始失敗,fall 3之後,Node2 的狀態會變成紅色,HAProxy 自動停止向它轉發請求。

此時立刻執行之前的三步驗證流程:登入、推送、拉取。全部應該正常完成,沒有任何報錯。推送的鏡像會落到 Node1 上,但通過共享存儲,Node2 恢復後也能讀到同一份數據。

這就驗證了「業務無感知的故障轉移」。客戶端的請求被 HAProxy 自動切換到了健康的節點上。

4.3 恢復測試與資料最終一致性

讓 Node2 恢復服務。重啟 VM 後,執行:

cd /home/harbor/harbor docker-compose up -d

等待所有容器啟動完成,大概 30 秒到 1 分鐘。HAProxy 的健康檢查通過後,Node2 自動回到負載池中。

關鍵驗證點:剛才在 Node2 宕機期間,我們向 Node1 推送了一個新的鏡像,現在要在 Node2 上確認這個鏡像是否存在。執行:

# 從 Node2 本機上拉取 docker pull harbor.example.local/library/nginx:latest

如果拉取失敗或報找不到鏡像,說明共享存儲配置有問題,鏡像數據沒有被真正的共享。正常的結果是立即成功——因為鏡像數據存在共享存儲上,Node2 的 registry 服務只是作為一個讀入口,它本身不保存數據。

同樣的原理也適用於資料庫。在 Node2 恢復後,到 Harbor 的 Web 頁面上看一下,用戶、項目、權限設置都應該和宕機前保持一致,因為這些數據存在共享的 PostgreSQL 中。

4.4 性能與穩定性測試

高可用不光是「掛了能切」,還要驗證正常運行的性能。我建議做兩組測試:

RAID 隊列測試:用腳本並發推送幾十個鏡像,觀察兩個節點的 CPU、內存、網路吞吐曲線,確認負載是否被有效分散。

極端場景測試:找一台配置最低的客戶端,持續做大批量拉取,觀察整體吞吐是否有明顯下降。這能幫你發現 HAProxy 的連接數瓶頸。

5. 遇到的坑與排查經驗

5.1 健康檢查節點全部判定為 down,但 Harbor 本身是好的

這個問題出現的機率非常高。排查思路從以下幾步入手:

先用curl -k https://10.10.1.21/api/v2.0/ping在 HAProxy 節點上直接測試,確認 Harbor 介面是真的通。如果 curl 結果正常,說明問題在於 HAProxy 的檢查方式。

常見原因一:HAProxy 配置文件裡檢查的是 HTTP GET/api/v2.0/ping,但 Harbor 返回的不是純 200,而是帶了 JSON。確認expect status 200是否匹配實際回應碼。

常見原因二:證書問題。如果ssl verify參數不是none,HAProxy 在檢查時會去驗證後端證書,如果 CA 沒被信任,檢查就會失敗,節點被誤判為 down。

常見原因三:timeout 太短導致握手失敗。如果你的 Harbor 節點負載較高,SSL 握手可能會超過 HAProxy 配置的timeout connect值,健康檢查就會頻繁失敗。把timeout connect增到 10 秒左右。

5.2 docker login 成功,但 docker push 報 unauthorized

這個問題的本質是 Harbor 的 token 機制。Harbor 的 registry 元件在收到 push 請求時,會把 token 送回 core 元件驗證,如果 core 元件的資料庫連線的是不同的 PostgreSQL,token 驗證就會失敗。

這個問題在網上被討論過很多次,很多時候是因為配置的 PostgreSQL 不是同一個實例。你的兩個 Harbor 節點,必須連到同一個 PostgreSQL 和同一個 Redis,否則就會出現「A 節點登入成功,但請求到了 B 節點,B 節點驗證 token 時用的是自己的資料庫,查不到這個 token」的情況。

所以排查順序是:先確認 Redis 是否共享,再確認 PostgreSQL 是否共享,最後看兩個節點的時間是否同步。token 是有時效性的,時間不同步也可能導致驗證失敗。

5.3 切換節點後,Kubernetes 拉取鏡像偶爾失敗

Kubernetes 節點上的 kubelet 在拉取鏡像時,會並發建立多個連接。如果你的 HAProxy 沒有做 stick-table 配置,這些連接會被分散到兩個 Harbor 節點。理論上雙活架構下這完全沒問題,但實測中偶爾會出現 5xx 錯誤。

原因其實不在 Harbor,而在底層存儲的競爭。當兩個請求同時讀取同一個未緩存的 blob 層時,NFS 在高併發下可能出現短暫的延遲超限。解決方案有兩個方向:

一是給 HAProxy 加上 stick-table,讓同一個來源 IP 的請求盡量落在同一個節點,降低跨節點的存儲競爭。

二是把共享存儲從 NFS 換到對象存儲(比如 MinIO 或 Ceph RGW),對象存儲的併發讀寫能力遠超 NFS。

5.4 證書輪換後,docker 客戶端報 x509 驗證錯誤

Harbor 的證書快到期了,你重新簽發了一張新證書,更新到了 Harbor 節點上。然後客戶端報x509: certificate signed by unknown authority。

原因是 Docker 客戶端緩存了舊的 CA 證書。如果你使用的是內部 CA 或者自簽證書,CA 本身沒變,只是 Harbor 的服務端證書換了,客戶端理論上不需要任何操作。但如果 CA 也換了,就需要更新客戶端的/etc/docker/certs.d/harbor.example.local/ca.crt。

這裡要提醒的是,千萬只更新了 Harbor 節點上的證書,忽略了客戶端。這類問題通常不是 Harbor 的配置錯誤,而是證書鏈沒有傳遞完整。排查方法很簡單,在客戶端執行:

openssl s_client -connect harbor.example.local:443 -showcerts

看輸出的證書鏈,和你更新後的證書是否一致。

5.5 升級 Harbor 版本時要注意什麼

高可用架構下,Harbor 的升級流程可以做滾動升級,不用全量停機。我們的做法是:

先把其中一個節點從 HAProxy 的負載池中摘除。在 HAProxy 的後端配置中,把對應的節點注釋掉:

# server harbor2 10.10.1.22:443 check inter 5s fall 3 rise 2

重載 HAProxy,確認流量全部落在 Node1。然後對 Node2 執行升級操作:停止 Harbor、備份數據目錄、替換二進制包、執行遷移腳本、重啟。等 Node2 起來並通過健康檢查後,把它加回負載池。

接著重複同樣的流程升級 Node1。整個過程中,業務不會中斷,而且兩個節點的版本不會長時間不一致。

升級前一定要備份共享的 PostgreSQL 和存儲目錄,即使用了滾動升級,也要做全量備份,以防遷移腳本出問題。

5.6 高可用架構下的監控與告警配置

HAProxy 本身提供了一個統計頁面,通過 Web 介面可以看到每個後端節點的實時狀態。在配置中添加一個監聽段即可:

listen stats bind *:8404 mode http stats enable stats uri /stats stats auth admin:admin_password

這樣就可以在瀏覽器訪問HTTP://10.10.1.10:8404/stats,輸入用戶名密碼後看到後端節點的運行狀態。

建議對以下三個指標做監控告警:

  • 後端節點是否全部 down。如果兩個 Harbor 節點都不可用,說明整個服務已經中斷,需要緊急介入。
  • 健康檢查失敗的次數。如果某個節點頻繁出現檢查失敗又恢復,說明該節點可能存在隱患,比如磁碟快滿了或記憶體洩漏。
  • HAProxy 的連接數和會話數。這個數據能提前預警流量是否在快速增長,是否需要擴容節點或調整存儲。

6. 最終架構總結與運維建議

到這裡,整個 HAProxy 實現 Harbor 高可用的架構已經完整落地了。

流量入口是 Keepalived 提供的 VIP,底下掛著兩台 HAProxy 節點,HAProxy 把請求分發到兩台 Harbor 節點上,Harbor 底層共享同一套 PostgreSQL、Redis 和鏡像存儲。任何一個 Harbor 節點掛了,HAProxy 自動切走流量;HAProxy 本身掛了,Keepalived 自動切換 VIP;單台 Harbor 節點的升級維護也完全不影響業務。

這個方案我實際跑了將近一年,穩定性非常好。但有些經驗值得拿出來強調一下:

監控比架構本身更重要。高可用方案不是部署完就一勞永逸的,你需要知道節點的健康狀態,才能在故障發生前提前干預。磁碟空間尤其值得盯緊,鏡像倉庫的磁碟增長速度往往超出預期,存儲寫滿的時候,再好的高可用架構都白搭。

別把 HAProxy 本身搞成單點。很多團隊做完 Harbor 高可用就覺得萬事大吉,忘了 HAProxy 也是唯一的入口。配上 Keepalived 是必須的,這個成本很低,帶來的收益卻很大。

升級操作要走流程。高可用架構下,很多運維操作可以滾動進行,但前提是要有清晰的流程和預案。先摘除節點,再執行操作,最後加回節點。每一步之前都要想清楚「如果這一步失敗了,我該怎麼回滾」。

回顧整個過程,最有感觸的是:高可用架構的本質,是讓「故障」這件事從「事故」變成「演練」。鏡像倉庫掛掉的時長從數小時縮短到幾十秒,甚至業務層面完全無感知,這對研發團隊的交付效率提升是質變級的。如果你還沒做這套方案,趁早動手,別等鏡像倉庫真的掛了再後悔。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 13:46:50

生产级K8s高可用流量入口:haproxy+pacemaker负载均衡集群详解

把Kubernetes高可用集群里的“流量入口”这件事彻底讲透。之前不少朋友在搭生产级K8s时,习惯先把三个master节点装好,再在每台master前面挂一个Nginx或者用云厂商的SLB,结果要么单点还在,要么云上LB的会话保持和健康检查调得头疼。…

作者头像 李华
网站建设 2026/10/21 13:46:02

长者康复活动识别系统设计与实现:基于姿态估计的动作分析实践

去年年底我接了一个挺有意思的项目,给某养老机构做一套 长者康复活动识别系统 。简单说,就是用摄像头加算法,自动识别老人做康复训练时做了哪些动作、做了几组、动作标不标准,然后生成报告给康复师参考。项目做完到现在跑了几个…

作者头像 李华
网站建设 2026/10/21 13:45:57

量子云平台气象灾害预测应用:精度与效率双提升的技术拆解

最近量子计算圈子的一个明显风向是:云平台上的应用从实验室演示走向了有明确业务语义的闭环场景。上个月我注意到某量子科技公司的云平台发布了一个量子气象灾害预测应用,标题直接写着“精度与效率双提升”,这对量子机器学习落地来说是句很有…

作者头像 李华
网站建设 2026/10/21 13:45:18

lingbot-map轻量机器人建图:传感器接入与算法选型实战

1. 从“lingbot-map”这个名字说起:它到底想解决什么问题第一次看到“lingbot-map”这个项目名,我脑子里冒出来的第一个念头是:这大概率是一个跟“地图构建”或者“空间映射”相关的机器人项目。拆开来看,“ling”可能是某个前缀或…

作者头像 李华
网站建设 2026/10/21 13:45:03

Linux进程排查利器pstree:从进程树看懂父子、僵尸与孤儿进程

排查 Linux 进程问题的时候,大家最常用的一定是 ps aux 和 top ,前者看进程快照,后者看实时负载。可真要碰到“这个进程到底是谁拉起来的”“为什么它变成了孤儿”“那堆僵尸进程的爹是谁”这类问题时, ps 输出的那种扁平行…

作者头像 李华
网站建设 2026/10/21 13:44:34

从知道到创造价值:一套可落地的个人技能修炼框架

我做技能评审时,经常碰到一类很典型的人:简历上写着“熟练使用Office”“掌握基本数据分析”“具备项目管理经验”,可真拉出来做一次汇报,连最基础的数据透视表都操作得磕磕绊绊。问题不在智商,也不在努力程度&#xf…

作者头像 李华