# 負載平衡與高可用性 [TOC] ## 開始前的小故事 [日本KDDI大當機事件過程追追追](https://www.ithome.com.tw/news/153210) - 事件說明 - 2022/07/02 日本第二大電信商 KDDI 因為更新硬體的過程中出現差錯,使得網路節點出現壅塞的狀況,且從原本單一地區的通訊中斷,逐漸擴大成全國性的通訊事故。 - 最後,他們花了三天左右的時間才將一切恢復正常。 - 這個事件造成什麼影響? - 最終評估高達 3915 萬線路中斷。 - 當時正值颱風來襲,除了氣象廳無法提供完整氣象資訊以外,報案電話打不通、登山者受傷無法通報,也有醫院因為聯繫不上醫生而無法為病患進行緊急手術。 - 不少企業因仰賴網路提供的服務中斷,系統也跟著故障出問題。 - 所以? - 如果服務很常故障,或是一個小地方故障就整個不能用,消費者自然不會喜歡。 - 就算真的有消費者願意使用,也有可能因為達不到原本承諾維持運作的服務時間而需要進行賠償。 - 結論:服務的可用性很重要。 ## 高度可用性 :::info ### SRE - Site Reliability Engineer 網站可靠性工程師 - 結合軟體工程與系統管理,透過處理基礎架構與作業問題,確保網站系統穩定、可靠、容易擴充,讓系統在遇到高流量或突發狀況等問題時也能維持正常服務。 - 最早由 Google 推出這項職務,想要更清楚瞭解這項職業的話,可以參考 Google 的電子書:[SRE Books](https://sre.google/books/) ::: :::info ### SLI、SLO 跟 SLA #### SLI - Service Level Indicator,服務水準指標 - 系統實際運作時的表現 - 舉例: - 可用性(Availability)高達 99.95% - 回應時間(Latency)為 200 ms - 吞吐量(Throughput)有多少 #### SLO - Service Level Objective,服務級別目標 - 為自己的服務訂下一個期望達到的目標 - 舉例: - 可用性要維持在 99.9% #### SLA - Service Level Agreement,服務級別協定 - 服務供應商給予客戶的承諾,常以合約的形式呈現。 - 內容可能會有以下幾項: - 服務範圍 - 服務水準 - 可用性可以達到多少(等等會說到的「幾個九」的服務等級) - 回應時間多久 - 吞吐量多少 - 服務中斷的補償 - 如果沒有達到合約所承諾的服務水準,會怎麼賠償,賠償的計算方式。 - 基本上會透過折扣的方式做賠償,畢竟服務就算不穩定還是需要負擔相關成本。 - 通常會注重於產品能夠成功運行的時間百分比。 ::: ### 可用性(Availability) - 在一段時間內,可成功運行時間的百分比,大多以一個月或一年作為標準。 - 通常會用百分比的方式呈現,並以「幾個9」的方式來判斷服務品質,例如:99%(0.99)是 2 個 9、99.99%(0.9999)是 4 個 9 ,9的數量越多表示在相同的時間中,系統可以正常運行的時間越多。 - 計算方式: $A=\frac{正常運行時間}{(正常運行時間 + 停機時間)}=\frac{MTBF}{(MTBF + MTTR)}$ :::info - **A** (**A**vailability):可用性 - **MTBF** (**M**ean **T**ime **B**etween **F**ailures):平均故障間隔 - **MTTR** (**M**ean **T**ime **T**o **R**ecovery):平均修復時間 - Uptime:上線時間(正常運作時間) - Downtime:停機時間 ::: - 假設: - 某個系統平均 20 年發生一次故障 - MTBF = 20 x 365 x 24 = 175200(小時) - 每次故障平均要花 1 小時復原 - MTTR = 1(小時) - 則可用性為 $\frac{175200}{175200+1}$ = 0.9999942922700 ≈ 99.999% - 所以這個系統的可用性為 5 個 9 - 以下是可用性跟停機時間的對照表(參考資料:[Availability vs. Reliability](https://shwang1979.medium.com/availability-vs-reliability-bc91fa8108a4)) |可用性(%)|停機時間(每年)|停機時間(每月)|停機時間(每周)| |--|--|--|--| |90%|36.5 天|72 小時|16.8 小時| |99%|3.65 天|7.20 小時|1.68 小時| |99.5%|1.83 天|3.60 小時|50.4 分鐘| |99.9%|8.76 小時|43.8 分鐘|10.1 分鐘| |99.95%|4.38 小時|21.56 分鐘|5.04 分鐘| |99.99%|52.56 分鐘|4.32 分鐘|1.01 分鐘| |99.999%|5.26 分鐘|25.9 秒|6.05秒| |99.9999%|31.5秒|2.59 秒|0.605 秒| |99.99999%|31.5 秒|0.259 秒|0.0605 秒| :::success 目前最有名的服務是 AWS S3 雲端物件儲存(號稱有到 11 個 9) ::: :::info 可靠性(Reliability) vs 可用性(Availability) ||定義|衡量方式| |--|--|--| |可靠性|系統在特定時間內可以成功執行的機率(沒發生故障)|MTBF| |可用性|系統正常運作時間的百分比|運作時間/總時間| ::: ### 高度可用性(High Availability) - 讓系統可以長時間維持服務運作,不會一直中斷 ## 什麼樣的服務需要高度可用性 - 生命攸關系統 - 如果停擺會造成人員傷亡、設備毀損或環境傷害的系統。 - 像是醫療系統、核反應爐控制系統。 - 金融交易所 - 服務如果在交易的過程中中斷,可能會有金錢、法規相關的問題。 - 銀行、證券交易、線上支付等服務。 - 通訊相關服務 - 需要即時的傳遞訊息,如果中斷會影響通訊效率,甚至會有安全問題。 - 即時通訊、警報系統。 - 國家基礎建設 - 攸關國家民生的系統,不小心停擺會讓生活極度不方便,或是無法及時傳遞災害警報。 - 水、電、網路 - 災害預警系統(地震、颱風、洪水等) ### 單點故障 ![image](https://hackmd.io/_uploads/ryPWSsxJxl.png) >圖片來源:[談談何謂「單點故障」?](https://ithelp.ithome.com.tw/m/articles/10263600) - 當系統中的單一節點失效時,導致整個系統都無法運作。 - 像圖中的 SAN Switch 如果不小心故障,VM 系統就會無法運作。 - 會造成單點故障的原因 - 硬體 - 如果硬體的設計不良,或是在考量經費的情況下,只能盡量滿足硬體需求,就有可能因為設備不足而出現單點故障。 - 網路 - 防火牆、交換器故障。 - 環境 - 降溫系統故障、停電、地震、淹水等。 - 人 - 操作失誤(手滑誤刪、關機等等)、設定錯誤,缺少應對突發狀況的 SOP 等。 - 高可用性就是為了避免單點故障這個情形發生。 ## 怎麼達成高度可用性 ### 冗餘(Redundancy) - 為了避免單點故障,最簡單的說法就是:什麼都要有兩個以上(就算其中一個不能用,另一個也可以接手,替補上去)。 - 在系統中擁有備分或重複項,讓這個系統就算有地方壞掉,還是可以持續運作。 #### 叢集架構(Cluster) - 達成冗餘的一種方式。 - 透過多台 Server 共同提供服務,確保服務的可用性。 - 主要分成兩種 - Active - Standby (Passive) 主動被動 - Active - Active 雙主動 - Active - Standby ![image](https://hackmd.io/_uploads/BJI6keCyxl.png) > 上面兩張的圖片參考自 [Active-active vs. active-passive high-availability clustering](https://www.jscape.com/blog/active-active-vs-active-passive-high-availability-cluster) - 主要是 Active 在提供服務,Standby 則會跟 Active 做同步,準備隨時接手 Active 的工作,當 Active 出現問題的時候 Standby 就會出來接手。 :::info - Cold Standby - 僅提供最基本的環境,在沒有故障發生時通常處於關機狀態,發生故障以後需要再部署伺服器、設定網路、還原資料,才能讓系統恢復服務。 - 舉例來說,就像是一個空房間,裡面沒有任何設備,如果要讓這個房間能夠住人的話,要先搬入家具、布置、安裝用品等等,downtime 最久,但平時維護的成本跟時間也最少。 - 常見於:非關鍵任務、使用率低,或是更新頻率較低的系統。 - Warm Standby - 會先將環境跟軟體等設定好,並持續接收更新,等到系統失效時,會先取得最新資料並啟動服務。 - Warm Standby 就像是有床架、書桌椅、衣櫃等基本配備,但住進去之前還是得先鋪床、打掃環境等等。 - 常見於:有可用性需求,但預算並不高,或是可以容忍較長停機時間的系統,像是客戶關係管理系統等。 - Hot Standby - 所有硬體、軟體的資料都跟 Active 的一樣,故障發生的時候可以在很短的時間內接手。 - 就像是一間設備、用品都準備好,可以直接入住的房間,維護成本極高,但 downtime 最少。 - 常見於:對高可用性有極高需求的系統,像是金融交易、電信、醫療系統等。 ::: - 優點 - 在設計上比較簡單,不用擔心資料同步的問題。 - 缺點 - 會浪費硬體資源(不是 Active 的 server 會閒置) - 因為維護成本跟部署門檻都比較低,多數企業還是會出於預算跟設備考量選擇 Active - Standby - 如果是沒有提供雲端服務的廠商,可能連 Active - Standby 的設備都會省略,因為 Standby 的設備在沒有故障的情況下基本上都是處在閒置狀態。 :::warning 資料再怎麼傳輸,還是沒辦法做到即時性,也會有時間差、資料遺失的狀況,就算是使用 Active - Standby 的架構,也只能保證幾分鐘內的資料,還是會有部分資料遺失的風險。 Active - Standby 還可以從軟硬體的層面去看,從硬體的層面來說,Standby 可能會處在閒置的狀態,但如果是從軟體的層面去看,以資料庫為例,也有可能會設定成 Read - only,如果需要的資料並不是需要即時更新的那種,就可以讀取 Standby 裡的資料。 ::: - Active - Active ![image](https://hackmd.io/_uploads/HJ9H-royxe.png) - 系統的各個元件(component)都會同時提供服務,當其中一台故障時,另一台會接手他的工作。 - 優點 - 在沒有故障的時候,兩台 Server 會同時提供服務,不會浪費資源。 - 缺點 - 會需要考慮資料共有的問題(如果共用資料庫的話,會有單點故障的風險,如果分成兩個資料庫,會有同步資料庫的問題),在設計上會比較複雜。 - 通常會用在需要高可用或是高效能的系統(因為有多台 server 在運作,速度上會有所提升,故障轉移的速度也較快) - 資料的分流 - Shared-disk - 所有節點共用一樣的資料庫 ![image](https://hackmd.io/_uploads/rkgh7DoJgl.png) - 優點:可以維持資料的一致性、因為只有一個資料庫,所以設計上較簡單 - 缺點:如果同時修改資料庫可能會造成故障等問題,資料庫故障的話就會造成系統故障(單點故障) - 可能的解決方式 - Lock Management:會運行在每個節點上,控制叢集中節點對資料庫的存取,有點像是管理流量的角色。(延伸閱讀:[MySQL 的 Lock 是什麼? Table Lock 與 Row Lock 有哪些不同?](https://www.mysql.tw/2023/05/mysql-lock.html)) :::info 資料庫中的 Active - Active SQL server 中,最怕的事情是同時間將兩個以上的資料寫入資料庫中,為了避免這樣的事情發生,所以出現了 Lock 這樣的機制。 但這樣會導致採用 Active - Active 架構的資料庫,設計上還是會偏向 Active - Standby。 ::: - Shared-nothing - 每個節點都有自己的資料庫 ![image](https://hackmd.io/_uploads/HyVRvvskge.png) - 優點:有多個資料庫跟節點,不用擔心單點故障。 - 缺點:為了維持一致性,要不斷的複製(Replication)。 :::info - Session 分配問題 - 如果網站是透過 session 存取使用者的狀態,但若使用者請求的資料庫跟接收使用者 session 的資料庫不一樣的話,會影響到個人化的體驗,而資料複製有可能會造成使用者體驗不佳。 - 有幾個解決方式 - 把 session 都存到同一個專用的資料庫中,只要去那個資料庫找 session 就好。 - 用 JSON Web Token(JWT)將使用者的狀態編碼後儲存在前端,但需要考慮安全性的部分,所以不建議將敏感資料存在裡面。 ::: #### 資料複製(Data Replication) 在 Share-nothing 中,要透過複製(Replication)來同步資料,主要分成兩種方式 - 主從複製(Primary-Secondary Replication) - 一個主節點負責處理資料的寫入,資料寫入後,會將更動的部分送到其他節點做同步 - 適合讀取量大的系統,像是社群軟體、YouTube 等有很多人會讀取,但上傳量相對少的系統。 - 如果主節點失效的話,其他的節點會無法更新資料庫,所以出現了多領導者複製(Multi-leader replication)。 - 多領導者複製(Multi-leader replication) - 有多個主節點在進行複製,並同步到其他節點。 - 適合在多個國家有服務的企業(可以向最近的節點提交請求)、需要高可用的系統等。 :::info #### CDC - 資料異動擷取(Change Data Capture) - 在資料庫發生異動時,可以記錄資料庫發生的寫入、更新、刪除,只要資料發生變化,就會記錄下來,而且可以即時或定期的將變更的資訊同步到其他的資料庫,達到資料同步的效果。 ::: :::success 補充:備份、備援、複製的不同 - 備份: - 定期將資料複製,儲存到不同的設備,避免資料因為各種原因遭到破壞。 - 3-2-1 備份原則:至少有 3 份備份,存放在 2 個性質不同的儲存媒體中,至少要有 1 份存在不一樣的地方。 - 備份的目的就是要能夠回溯到某個時間點。 - 備援: - 利用備份的資料與事先準備好的設備跟環境恢復系統運作。 - 複製: - 在資料修改以後就同步到其他節點。 ::: ### 監控(Monitoring) - 設備跑起來了以後,為了在真正無法挽回前可以及時修復,所以要能夠監控設備狀態 #### 監控什麼? - 一般的情況下,網路監控通常會先監控流量,透過流量看有沒有發現異常,等到流量出現異常以後,再根據分析封包內容、ICMP 訊息、通訊協定等方式找問題。 #### 網路監控協定類型 - NetFlow - Cisco 開發的網路協定 - 蒐集進入系統的封包數量及資訊,可以透過封包來源及目的、服務種類來知道網路壅塞的原因。 - 傳統上,一個 IP Flow 根據 5 到 7 個封包屬性去做定義,封包在傳送時, router 跟 switch 會檢查封包的 IP 屬性,判斷這個封包是唯一的還是跟其他封包相似,屬性有以下七種: - IP source address - IP destination address - Source port - Destination port - Layer 3 protocol type ( TCP、UDP、ICMP ) - Class of Service ( CoS ) - Router or switch interface - SNMP - 簡單網路管理協定,全名是 Simple Network Management Protocol,屬於應用層的協定。 - 三個主要版本: - SNMPv1:最早發布的版本,提供的讀取、設置、告警等基本的網路管理功能,透過 community strings 進行身分驗證,且只用 UDP 作為傳輸層協議。 - SNMPv2:改進了 SNMPv1 的 MIB 結構元素、transport mappings 跟協議封包類型,可以用 UDP 或是 TCP 作為傳輸層協議,而下面的分支版本 SNMPv2c 還是用 community strings 作為身分驗證。 - SNMPv3:用 Hash 為基礎的 MAC,並用 MD5 或 SHA 做認證,隱私的部分則是用 DES - 56 作保護,支援 UDP 和 TCP 傳輸。 - 目前最推薦的版本是 v2c 跟 v3,因為 v2c 支援大多數的設備,v3 則可以提升資料傳輸的安全性。 - 三個關鍵元件 - 網路管理系統(NMSs,Network-management systems):安裝在 Manager 的應用程式,用來向代理者查詢被管理裝置的相關資訊。 - 被管理裝置(Managed Device):被監控的設備。 - 代理者(Agent):安裝在 Managed Device,負責監控和回傳監控結果。 :::info SNMP 封包格式 ![image](https://hackmd.io/_uploads/HJG6690Jgx.png) > 資料來源:[TCP/IP 協定與 Internet 網路:第十六章 SNMP 網路管理協定](https://www.tsnien.idv.tw/Internet_WebBook/chap16/16-3%20SNMP%20%E5%8D%94%E5%AE%9A.html) - 訊息標頭(Message Header):包含兩個欄位 - 版本(Version):表示封包版本,0 代表 SNMPv1,1 代表 SNMPv2。 - 共同體(Community):由同一群管理組織(管理系統、代理者)組成的共同體名稱,預設值是 public。 - SNMPv1 一般協定資料單元 - PDU Type:PDU 的命令型態 - 0 -> Get - Request - 1 -> Get - Next - Request - 2 -> Set - Request - 3 -> Get - Response - Request ID:SNMP Manager 會對每個下達的命令編碼一個 Request ID(隨機變數),SNMP Agent 會再針對 Request ID 回應訊息。 - Error Status:Set - Response PDU 存放發生的錯誤訊息,如果 SNMP Manager 下達的命令沒辦法達成時,會根據錯誤狀態回應給 SNMP Manager。其他的命令(Set、Get、GetNext)沒有使用此欄位。 - Error Index:Set - Response PDU 存放錯誤發生的索引位置,表示錯誤是發生在哪個後面可變連結。 - 管理物件:用《物件名稱,數值》(Object-n, Value-n)來表示每一個管理物件。 ::: - 以上的資料參考自 [TCP/IP 協定與 Internet 網路:第十六章 SNMP 網路管理協定](https://www.tsnien.idv.tw/Internet_WebBook/chap16/16-3%20SNMP%20%E5%8D%94%E5%AE%9A.html)、[Simple Network Management Protocol (SNMP)](https://www.geeksforgeeks.org/simple-network-management-protocol-snmp/)、[上學期的 Monitoring 講義](https://hackmd.io/@ncnu-opensource/ryAgx86Qyl) - 想看更多監控相關的資料,可以參考[上學期的 Monitoring 講義 SNMP 的部分](https://hackmd.io/@ncnu-opensource/ryAgx86Qyl#SNMP) - ICMP - 網際網路控制訊息協定,全名是 Internet Control Message Protocol,屬於網路層的協定。 - 用來交換網路目前的狀況訊息,ICMP 封包要像 TCP 封包一樣嵌入 IP 封包內,用 IP 的方式傳送,有兩種情況會產生 ICMP 訊息: - 障礙通知:IP 封包傳送時,如果某一網路發生問題導致無法傳送,就會把 ICMP 訊息傳送給原本的傳送端。 ![image](https://hackmd.io/_uploads/HkddwsAJgl.png) - 查詢網路狀況:發送 ICMP 封包查詢目前網路狀況。 ![image](https://hackmd.io/_uploads/rJY1djAkee.png) > 上面兩張圖片來源:[ICMP 協定與分析](https://www.tsnien.idv.tw/Manager_WebBook/chap4/4-5%20ICMP%20%E5%8D%94%E5%AE%9A%E8%88%87%E5%88%86%E6%9E%90.html) :::info 包裝在 IP 內的 ICMP 封包格式 ![image](https://hackmd.io/_uploads/BkY95iA1xe.png) - 訊息型態(Message Type):表示 ICMP 欲控制的訊息型態,有 13 種 ![image](https://hackmd.io/_uploads/ByHwTjAyel.png) > 圖片來源:[TCP/IP 與 Internet 連結技術](https://www.tsnien.idv.tw/Network_WebBook/chap13/13-5%20ICMP%20%E9%80%9A%E8%A8%8A%E5%8D%94%E5%AE%9A.html) - 編碼(Code):對各種訊息型態進一步說明內容。 - 檢查集檢查碼(Checksum):對封包檢察集的錯誤偵測。 - 訊息說明(Message description):根據不同的控制訊息做不同的說明。 - 訊息資料(Message Data):根據不同的控制訊息有不同的資料表示。 ::: #### 幾個開源監控工具 - Nagios([官網](https://www.nagios.org/)) - 可以運行在 Linux 和 Unix 平台上,且提供一個 WEB 介面,方便管理員監控網路狀態。 - 透過四種抽象屬性(OK、WARNING、CRITICAL、UNKNOWN)描述被監控對象的狀態,管理者只要關注出現 WARNING 跟 CRITICAL 的被監控對象就好。 - 監控對象有 - 本機運行狀態 - 本機服務運行狀態 - 遠端主機及上面運行的服務 - 網路服務(SMTP、POP3、HTTP、PING等) - 主機資源(process load、磁碟利用率等) - Cacti([官網](https://www.cacti.net/)) - Data Sources 可以透過 SNMP Host 或外部的腳本做利用。 - 使用 RRDTool 製作前端圖檔,並利用其中的 Round Robin Archives 儲存時間序列資料 - Round Robin Archives:新的數據會自動複寫舊數據,讓資料庫的大小固定。 - 時間序列資料:隨著時間不斷產生的連續測量值,透過紀錄時間的順序達到最佳化的儲存。 - Zabbix([官網](https://www.zabbix.com/)) - 涵蓋資料收集、呈現、警告等功能,除了監控服務和伺服器外,還可以監控網路設備。 - 在 Application services 可以監控 JVM 的服務 - 主要透過 Server - Client 架構收集、處理資料(Client 收集,Server 儲存),主要組成有 - Zabbix Server:負責接收、儲存資料、觸發警告,也可以主透過發送 Request 監控外部服務,屬於核心部分。 - Web interface:用來操作、檢視資料,還有設定監控項目。 - Zabbix Proxy:Server 與 Client 不能直接連線時,作為中繼使用。 - Zabbix Agent:負責收集資料,並回傳給 Server(就是 Client) - Prometheus([官網](https://prometheus.io/)) - 會將及時的指標(Metrics)資料存到時間序列資料庫,透過 HTTP 讓使用者查詢及設定預警的規則 - 包含以下元件 - Retrieval:負責蒐集 Metrics 資料。 - TSDB:時間序列資料庫。 - HTTP Server:提供 API 讓使用者可以查詢蒐集到的資料。 - Pushgateway:開放接口,被動蒐集 Metrics 資料。 - Alertmanager:收到警告後會發送警告給使用者。 - Prometheus Web UI:可以在 GUI 中查詢 Metrics 資料。 #### 出事了以後要怎麼辦 :::warning 情境:企業的網路流量異常 ::: 根據 NIST SP 800-61 Rev. 2 (全名為 NIST Special Publication 800-61, Revision 2: Computer Security Incident Handling Guide,由美國國家標準與技術研究院發行) 提供的資安事件應變處理有以下幾點 1. 做好準備、預防 2. 檢測跟分析 3. 抑制影響範圍、恢復 4. 追蹤檢討及改善 ![image](https://hackmd.io/_uploads/SJZ74rJgee.png) > 圖片來源:[Computer Security Incident Handling Guide](https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-61r2.pdf) - 準備、預防階段 - 建立並定義事件的分類、優先順序、通報流程 - 部署監控工具,確保 SNMP、ICMP、NetFlow 等工具正常運作 - 定期演練 - 檢測與分析 - 偵測到異常流量以後發送警告 - 利用 NetFlow 等工具分析流量、確認來源跟目的,檢查異常 - 抑制及恢復 - 隔離受影響的伺服器,避免其他的系統受到影響 - 透過備份、故障轉移的方式恢復系統 - 事後檢討 - 撰寫事件經過的詳細報告、影響範圍、怎麼處理的 - 分析原因 - 強化系統 #### Status Page - Status Page 是什麼? - 透過定期對網站發出請求,根據收到的回覆(包含 http 的 status code、回應時間、回覆內容等),讓我們知道網站有沒有在正常運作的服務。 - server 會將收到的資訊放在前端的頁面,只要使用者打開瀏覽器就可以看到服務運作的情況。 - 有很多教學,設定上也不困難,而且也有許多網站可以進行實作。 - Uptime Kuma - 這次會用 Uptime Kuma 進行小小的實作 - 首先,先進到 [Uptime Kuma 的頁面](https://uptime.kuma.pet/) - 點 Live Demo,進去以後要抓緊時間,因為我們只有十分鐘。 ![image](https://hackmd.io/_uploads/HkYUyX2kge.png) ![螢幕擷取畫面 2025-04-28 052012](https://hackmd.io/_uploads/H15jl7hyel.png) - 資料庫選擇 SQLite。 ![螢幕擷取畫面 2025-04-28 052033](https://hackmd.io/_uploads/r1lRem31gg.png) - 帳號密碼隨便亂填就好,因為十分鐘以後就不見了,密碼記得要有英文跟數字,不然會過不了關。 ![image](https://hackmd.io/_uploads/HJZBmQ3yxx.png) - 進去以後長這樣。 ![螢幕擷取畫面 2025-04-28 052139](https://hackmd.io/_uploads/BJfeWQh1xg.png) - 選右上角的新增監測器。 ![螢幕擷取畫面 2025-04-28 052148](https://hackmd.io/_uploads/rJqZZX3Jxx.png) - 填寫你要監控的網站(我是放資管系系網),心跳次數最低只能 20 秒檢查一次,其他都可以根據網站的情況做調整,好了就按儲存。 ![螢幕擷取畫面 2025-04-28 052313](https://hackmd.io/_uploads/HyQWG72kel.png) - 這樣就可以監控網站的各種狀態啦! ![螢幕擷取畫面 2025-04-28 052348](https://hackmd.io/_uploads/rkMtMmhkee.png) - 還可以去設定通知,在網站沒有回應的時候,會透過機器人通知使用者。 ![螢幕擷取畫面 2025-04-28 052946](https://hackmd.io/_uploads/HktCfXhJlg.png) ![螢幕擷取畫面 2025-04-28 052955](https://hackmd.io/_uploads/SJTAGmh1xx.png) #### 應用 - Health Check 跟 Heartbeat - Health Check - 由監控系統主動去確認服務的健康度。 - Heartbeat - 由被監控的系統每過一段時間後傳送心跳包給監控系統,證明被監控的系統還在運作中。 - 也可以用兩台或以上的伺服器定時互相檢查心跳,有伺服器的心跳消失(沒有在運作)就立刻轉移。 - 幾個監控小指令 - 直接 `ping`:就是發 ICMP 封包,看回應時間 - `iftop`:看網路封包流量 - `sudo iftop -Pp`:顯示完整的連線資訊,且僅顯示本機有參與的封包。 - `traceroute`:顯示封包經過的每個 route,如果傳送的過程中斷掉比較好找。 - `tcpdump`:捕捉、顯示封包。 - 想知道更多監控相關可以參考第五組的共筆:[系統安全強化與效能監控調教](https://hackmd.io/@-dqF--JHRweGqr2SXT6qZw/rJb8IE2A1g) ### 故障轉移(Fail-over) - 如果設備真的出事,要能夠將工作轉移給沒出事的設備,讓服務不會中斷。 #### bonding - 是將多個網路連線、網卡合併成一個連線的技術,最主要的目的是提升頻寬流量、負載平衡、容錯(故障轉移)。 - 有七種模式,有些模式只能實現負載平衡,有些只能做故障轉移,有些則兩者皆可實現,預設模式是 mode 0: balance-rr。 - mode 0: balance-rr (Round-robin) - 輪循策略:按照順序,從第一個 slave 開始,一路將封包傳到最後一個。 - mode 1: active-backup - 只有一張網卡(slave)是正在運作中的,在原本運作的那個 slave 故障以後,才會換成另一個。 - 為了避免 switch 混淆,active-backup 只會顯示目前是 active 那張網卡的 MAC 位址。 - mode 2: balance-xor - 利用 XOR 政策 xmit_hash_policy 決定要從哪張網卡傳送資料。 - XOR(互斥或):兩個數值相同的時候為 false,數值不同的時候為 true,用來快速混合資料(來源跟目的的 MAC 位址、封包 ID) - 預設公式是 ``` vb (source MAC XOR destination MAC XOR packet type ID) % slave count ``` - mode 3: broadcast - 將所有封包傳送給所有 slave。 - 很穩定但浪費頻寬。 - 基本上會用在可靠性要求極高的系統(因為很多條線在送) - mode 4: 802.3ad - IEEE 802.3ad Dynamic link aggregation(動態鏈路聚合):會建立聚合的群組,群組中的成員會共享一樣的速度和雙工設定(duplex settings:兩台通訊裝置中有雙向的資料傳輸,有分成可以同時傳送的全雙工,跟同一時間只能有一個裝置傳送的半雙工) - 用 xmit_hash_policy (預設是 XOR 政策,但可以調整)選擇要傳送的網卡,但不是所有的 hash 政策都符合 802.3ad 的標準(尤其是在封包順序上的要求)。 - 交換器要可以支援 802.3ad 的規範才可以用。 - mode 5: balance-tlb ( Transmit Load Balance ) - 有兩種模式: - tlb_dynamic_lb=1:根據目前的負載、速度分配流量(動態分配)。 - tlb_dynamic_lb=0:只透過 hash 計算來分配流量。 - 不需要 switch 支援。 - 傳入的資料會由目前是 active 的網卡處理,如果目前的失效了才會由其他的網卡接手他的 MAC 位址。 - mode 6: balance-alb ( Adaptive Load Balance ) - 不需要特殊的 switch 支援。 - 以 balance-tlb 為基礎,加上 receive load balancing (rlb),且支援 IPV4。 - 透過 ARP negotiation(ARP 協商)分配流量 - bonding driver 會攔截從本機發出的 ARP Reply,然後把 reply 的 MAC 位址改成 bond 裡面其中一個 slave 的位址,這樣就不會讓流量都跑到同一個位址,達到分流的效果。 - 如果有新的 slave 被加進來,bonding driver 會重新發一輪 ARP Reply 給各個對端,重新分配位址。 :::info #### xmit_hash_policy - 為什麼要用 hash ? - 同樣的值 hash 出來的結果會一樣 - 如果來源跟目的一樣,計算出來的結果一樣,那就會固定走同一條線。 - 不同的值 hash 出來的結果一定不一樣 - 不同的連線會走不同的 slave,達到分流的效果。 #### 為什麼 mode 5 跟 mode 6 不需要交換機支援? - 他們靠主機分配封包、控制 MAC 位址,所以不需要 switch 就可以 bonding。 - mode 5 靠動態分配或 hash 計算分配流量,mode 6 則透過 ARP 協商達到分流的效果。 ::: 根據上面的介紹稍微做了整理 |模式|名稱|特點|實現| |--|--|--|--| |0|balance-rr|按照順序將封包從第一個傳到最後一個|負載平衡、容錯| |1|active-backup|只有一張網卡是啟用的狀態,其他的會等原本的失效以後才會啟用|容錯| |2|balance-xor|利用 hash 運算決定要從哪裡傳資料|負載平衡、容錯| |3|broadcast|讓所有的網卡都接收一樣的資料|極高的容錯能力| |4|802.3ad|聚合群組中的成員共享一樣的速度跟雙工設定,利用雜湊運算選擇從哪裡傳封包,但要符合 802.3ad 的標準|負載平衡、容錯| |5|balance-tlb|透過動態分配或是 hash 運算分配流量,且不需要 switch 支援|負載平衡(接收不行)、容錯| |6|balance-alb|利用 ARP 協商分配流量,不需要 switch 支援|負載平衡、容錯| ## 故障轉移實作 這次實作會教大家怎麼用 Netplan 將虛擬機中的兩張網卡綁定, #### 前置作業 - 因為需要兩張網卡,所以要先去設定開兩張網卡,設定的部分按照上面就好,記得把 MAC 位址重置,避免不小心重複到同樣的位址,好了就開機! - 兩張都這樣設定就好 ![image](https://hackmd.io/_uploads/HJ5Qzflggl.png) #### 實作 - 確認 bonding 模組有沒有載入,通常都會有啦 - `modinfo bonding | more` - 沒有的話就 `sudo apt install ifenslave` - 先載入 bonding 模組 - `sudo modprobe bonding` - 用 `sudo lsmod | grep bonding` 確定有載入 - 用 `ifconfig`,找到兩張網卡的 ip link(也可以用 `ip link` 啦) - 記得把 ip link 記起來,等一下會用到。 ![image](https://hackmd.io/_uploads/ByoXH8Yygx.png) - 進去 netplan 的設定檔 - `cd /etc/netplan` 後 ls 看檔名(其實也可以直接 `sudo vim <Tab>`),因為設定檔名字可能不一樣,但可以先試試看下面的。 - `sudo vim /etc/netplan/01-network-manager-all.yaml` - 修改設定檔 ``` network: version: 2 renderer: networkd # 要改成 networkd,不然可能不會成功 ethernets: enp0s3: # 改成你剛剛找到的 ip link dhcp4: false enp0s8: # 這裡也要改 dhcp4: false bonds: bond0: dhcp4: true interfaces: - enp0s3 # 這邊 - enp0s8 # 這邊也是 nameservers: # DNS addresses: - 8.8.8.8 - 1.1.1.1 parameters: mode: active-backup # 模式可以參考上面的那七個 primary: enp0s3 # 這邊可以二選一 mii-monitor-interval: 100 ``` :::info mii-monitor-interval: 100 每 100 ms 檢查 Media Independent Interface 提供的訊息,如果訊息中出現某個網路設備故障,Bonding Driver 會把故障的設備標記為關閉。 ::: - 改好設定檔以後,將權限設定成只有擁有者可以讀寫,避免被奇奇怪怪的人亂改。 - `sudo chmod 600 /etc/netplan/01-network-manager-all.yaml` - 開啟 networkd 服務,為了避免打架,也要把 Network Manager 關掉。 - ``` sudo systemctl start systemd-networkd sudo systemctl stop NetworkManager ``` - 先試試看可不可以運作。 - `sudo netplan try` - 出現這個錯誤訊息可以不用理他,等一下有抓到檔案就好。 ![image](https://hackmd.io/_uploads/BJWmX0iyle.png) - 套用 Netplan 設定。 - `sudo netplan apply` - 這個錯誤訊息是說沒有虛擬交換機(vSwitch),但是 active-backup 不需要所以可以忽略。 ![image](https://hackmd.io/_uploads/SJl4qm0iJgl.png) - `cat /proc/net/bonding/bond0` 這邊如果可以抓到的話,就是成功建立了。 ![螢幕擷取畫面 2025-04-26 162911](https://hackmd.io/_uploads/r11K9M51le.png) - 可以下 `watch -n 0.1 cat /proc/net/bonding/bond0`,看每 0.1 秒的變化。 ![image](https://hackmd.io/_uploads/Sy2JLGxlel.png) - 好了以後,再開一個 Terminal `ping 8.8.8.8` 有跑起來就可以下一步了。 - 再開一個 Terminal,把 primary 的網卡關掉 `sudo ip link set enp0s3 down`,如果他還有繼續傳的話就是成功了。 - 這時再去看剛剛 cat 的檔案,會發現 primary 變另一張網卡了 ![image](https://hackmd.io/_uploads/rJ5V8Mgleg.png) :::info #### 為什麼會無線網路可能會失敗? - bonding 是將多個有線網路結合成單一的連線 - 無線網路跟有線網路有什麼不一樣 - 連接方式:有線網路使用網路線直接和路由器或網路交換器連接,而無線網路則是用 Wi - Fi 技術透過無線訊號連接到無線路由器。 - 速度跟穩定性:有線的網路速度較快,不容易受到距離或環境干擾,無線則是會因為距離或環境等因素干擾。 - Wi - Fi 的驅動可能不支援某些 bonding 的功能,像是 media-independent interface (MII)是用來讓 MAC 和 PHY (乙太物理層)通訊的。 ::: ## 小結 在剛剛的高可用性中,要達成高可用性的三個重點 - 冗餘 - 監控 - 故障轉移 在一個系統的架構中,如果透過多個重複的元件達成冗餘,但流量每次都只從同一個節點通過,是沒辦法真正達到高可用性的。 所以必須考慮流量分配的問題,這時候就需要討論到負載平衡了。 ## 負載平衡(Load Balancing) 負載平衡是負責將使用者的請求或流量依照特定演算法分配到多台後端伺服器(Real server)上,確保系統可以快速回應使用者請求並維持高可用性。且廣泛應用在 Web 服務、應用程式服務、資料庫和儲存系統等等地方。 ![image](https://hackmd.io/_uploads/H1oNO_tklx.png) >圖片來源: https://zindagitech.com/understanding-virtual-server-to-real-server-load-balancing/ :::info Virtual Server : 負責接收使用者的 request 並代表 Real Server 回應請求 Real Server : 真正在提供 services 的 Server ::: ### OSI 七層模型下的負載平衡 ![image](https://hackmd.io/_uploads/SyV7INWJgg.png) >圖片來源:https://www.cloudflare.com/zh-tw/learning/ddos/glossary/open-systems-interconnection-model-osi/ 通常大型網站會以 OSI 模型為基礎,把負載平衡設計在不同 Layer ,最常見的組合是以 Layer 4 搭配 Layer 7 的雙層架構做設計。 :::info 而為什麼會特別在 Layer 4 跟 Layer 7 進行討論呢? - 在 Layer 4 做負載平衡的**速度很快、效能好**,是因為它只根據傳輸層的資訊(像是source IP、destination IP、Port)來決定如何轉發流量。 - 而 Layer 7 負載平衡則可以跟據應用去修改( URL、Host、Header、Cookie ) 相關的封包內容,**靈活度較高**。 <!-- >https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For --> >下面會有例子幫助說明 ::: ### L4 / L7 Load Balancing 其實,Layer 4(Transport Layer)負載平衡並不是最底層的實作方式。根據不同的需求與網路環境,負載平衡還可以向下延伸到 Layer 3(Network Layer)甚至 Layer 2(Data Link Layer)。 ![image](https://hackmd.io/_uploads/rJlCa5skeg.png) >圖片來源:https://freeloadbalancer.com/load-balancing-layer-4-and-layer-7 - **Layer 2 Load Balance (MAC address)** * Layer 2 是基於網路鏈結層在做的負載平衡,把 Load Balancer 跟 Real Server 綁定同一個 IP(VIP),使用者發出 requests ,Load Balancer 拿到封包後將封包轉發給 Real Server。 * e.g. LVS(Linux Virtual Server)Direct Routing(DR 模式)、 Google 曾使用 Netscalers 作為 Layer 2 Load Balancer,後來被 Maglev 取代。 * >[延伸閱讀: Maglev: A Fast and Reliable Software Network Load Balancer](https://www.hwchiu.com/docs/2017/paper-maglve) :::info - VIP (Virtual IP):給外網看的 public IP - 如何區分相同 IP 下的不同機器呢?就是用 MAC address,每台 Real Server 的 MAC address 都會不相同 - 也因為 IP 沒變,Real Server 可以直接回應 client(沒經過 Load Balancer),所以非常快速、效率極高。 - 在這過程中 Load Balancer 只擔任轉發封包的角色,所以壓力也比較小。 ::: ![image](https://hackmd.io/_uploads/ryYzMOGJex.png) >圖片來源:https://medium.com/google-cloud/understand-cloud-load-balancer-like-a-senior-engineer-d4f55f3111fc - **Layer 3 Load Balance (IP)** * Layer 3 是基於網路層在做的負載平衡,透過 rewrite IP header,來修改 source 與 destination IP address,並且每一台 Real Server 都有屬於自己的 IP。 * 簡單一點講就是按照不同機器不同 IP 把封包轉發到不同的 Real Server 上 * e.g. LVS Tunnel、 LVS NAT,只不過兩者對 IP Packet 處理的方式不同而區分開來,LVS Tunnel 會在 packet 外面再封裝一層 ip 變成 ipip, LVS NAT 則修改 destination ip、source ip。 :::info - Load Balancer 會有一個對外的 public IP (VIP) 跟一個對內的 private IP - Load Balancer 必須負責處理全部的流量,性能相比之下也絕對比第 2 層還差。 ::: ![image](https://hackmd.io/_uploads/HyLmhYMJxg.png) >圖片來源:https://medium.com/google-cloud/understand-cloud-load-balancer-like-a-senior-engineer-d4f55f3111fc - **Layer 4 Load Balance (TCP、UDP)** * 在 Layer 3 的基礎再加上 Layer 4 ,以 VIP + Port 判斷封包走向,以常見的 TCP 為例 ,Load Balancer 接收到 Client request時,會執行DNAT,把 destination IP 改成實際要處理請求的 Real Server 的 IP。 * response 的時候,Load Balancer 用 SNAT 把 Real Server response 封包的 source IP 改成 Load Balancer的 IP。 * Load Balancer 如果以硬體方面來看的話有 F5 BIG-IP、A10、L4 Swithches、Citrix Netscaler,軟體來看有 LVS(Linux Virtual Server)、Nginx、Haproxy(mode tcp) * Layer 4 Load Balancer 可以起到過濾封包的作用,透過設定 SYN cookie,抵擋 SYN flood 攻擊。 > 有興趣再看這篇:https://chunchaichang.blogspot.com/2018/09/syn-cookies.html :::info 再複習一下 ## NAT ![image](https://hackmd.io/_uploads/SJPxvEfGke.png) - 網路位址轉譯 (Network Address Translation) - 改變網路封包中的來源位置跟目的位置,使不同網路之間能夠進行通訊 - 主要有 **SNAT (Source Network Address Translation)** 跟 **DNAT (Destination Network Address Translation)** - 可以節省 IP 位置 (一個組織 or 一間公司需要一個 public ip 可以對外) ### SNAT #### 情境: 內網主機 (192.168.1.100) 要連線到 yahoo.com.tw ![image](https://hackmd.io/_uploads/S1bsCBzMJx.png) 1. 內網主機 192.168.1.100 發送封包給 Firewall (NAT 主機) 2. Firewall 尋找路由表,發現目的地不在直接連接的網路,也沒有紀錄指定該往哪裡送,所以透過路由表找到「default gateway」並使用對應的網路介面卡 3. 因目前封包的 source IP 是內網 IP,直接送出去的話會造成對方的錯亂,誤會來源位置,所以,會在 `POSTROUTING` chain 把來源 IP 修改成 Firewall 對外的 IP,這時 **NAT translation table** 把這兩個來源 IP、port 的對應關係記錄起來,之後回應封包傳回來時就能知道要傳給內網的哪台主機 ![image](https://hackmd.io/_uploads/ByOQ-Lfz1l.png) ![image](https://hackmd.io/_uploads/HJRNbLGGye.png) 4. 封包從外部網路傳回來,目的地是 Firewall 的外網 IP 5. 在 `PREROUTING` chain 根據 **NAT translation table** 的紀錄更改封包目的地 `sudo iptables -t nat -I PREROUTING -o {外網網卡} -j SNAT --to {NAT 主機的外網網卡 IP}` 6. 封包轉發給內網主機 (192.168.1.100) >(很像 DNAT 但實際上沒有做 DNAT 的動作,而是用 NAT translation table 來做地址轉換 ### DNAT #### 情境: 在內網主機架了 Web Server,要讓外網能夠連進來 ![image](https://hackmd.io/_uploads/SylASUzz1x.png) 1. 外網主機先向 Firewall 發送請求 2. Firewall 收到封包後,在 `PREROUTING` chain 將目的 IP 從 Firewall 的外網 IP 改成內網 Web Server 的 IP,然後也會在 **NAT translation table** 把這兩個目的 IP、port 的對應關係記錄起來 `sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 192.168.1.210:80` 3. 封包會路由到內網網卡 (192.168.1.2),然後再傳送到目的地 (192.168.1.210) ![image](https://hackmd.io/_uploads/S1BTDUMMkg.png) ### 統整 附一張自己做的圖 ![DNAT_SNAT](https://hackmd.io/_uploads/rkoOZC2yll.jpg) | | SNAT | DNAT | |:-------- |:---------------------- |:------------------------ | | 功用 | 更改封包的來源 IP | 更改封包的目的 IP | | 使用場景 | 讓內網主機可以連線外網 | 讓外網能主動連到內網主機 > [資料來源: Josh 的 LSA Firewall](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FSd59QRjvRHGNSpyHHdpccg#SNAT) ::: - **Layer 7 Load Balance (TCP、UDP)** * Load Balancer 會根據應用層封包的內容(e.g. URL、Host、Header、Cookie )來決定轉發給哪台 Server,所以必須先與 Client 建立 TCP 連線,等待資料傳送過來後去分析封包內容,再與 Real Server建立 TCP 連線。 * Load Balancer 要能讀懂應用層協定(e.g. HTTP、HTTPS、FTP…),也可能會做到加/解密、壓縮/解壓縮的動作,計算成本必定提高。 * 如果跟 Layer 4 相比的話,更以做更靈活的應用,(e.g.根據 JWT 等做更靈活的封包過濾) * 常見於網站、API、電商平台或影音串流服務 * e.g. HAProxy(mode http)、Nginx、Apache、MySQL Proxy :::info ### Reverse-Proxy 在 Layer 7 講到 Load Balancer 也一定會講到 Reverse-Proxy 原因是 Reverse-Proxy 通常也會同時扮演 Load Balancer 的角色,例如 Nginx 就同時提供 Reverse-Proxy 與 Load Balancer 2 種功能可以使用,而且它們在後端系統架構的位置也很相似。 不過 Load Balancer 專注於分配 requests 給多個伺服器;而 Reverse-Proxy 專注於接收 requests,並根據 requests 的不同(例如根據 HTTP request 的 path),轉給不同的伺服器處理,從以下 Nginx 設定可以感受到其差異,例如 load balancer 並不管 location 的差異: >學長補充:在 Reverse-Proxy 下, Real Server 只能知道 Reverse-Proxy 的 IP,如果想要知道 Client 端的 IP 的話,就得去檢查 `X-Forwarded-For` 這種 HTTP header >[X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For) ```nginx http { upstream backendv1 { least_conn; server backend1.example.com; server backend2.example.com; } server { location /api/v1/ { proxy_pass http://backendv1; } location /api/v2/ { proxy_pass http://backend3.example.com:8000; } } ``` 畫成圖表示的話:![image](https://hackmd.io/_uploads/SJ3QtjX1lx.png) 而且 reverse proxy 還有個特點是能夠進行快取,將特定的 response 快取起來,減少後端伺服器的負擔,並提升 response 的速度,例如下列 Nginx 設定: ```nginx http { proxy_cache_path /var/www/cache levels=1:2 keys_zone=one:10m; proxy_temp_path /var/www/cache/tmp; upstream backendv1 { least_conn; server backend1.example.com; server backend2.example.com; } server { location /api/v1/ { proxy_pass http://backendv1; } location /api/v2/ { proxy_pass http://backend3.example.com:8000; } location /static/ { proxy_pass http://static.example.com; proxy_cache one; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; } } } ``` 整理一下 Reverse Proxy 的功能: 1. 使用者不知道後端伺服器的位置 2. 做 SSL/TLS 加解密 3. 做快取(Cache),加速 response 4. 可以順便做基本流量控制 >文章擷取自:[後端工程師面試考什 麼 — Load Balancer vs. Reverse Proxy vs. API Gateway vs. HAProxy](https://myapollo.com.tw/blog/backend-load-balancer-reverse-proxy-api-gateway/) ### Forward-Proxy ![image](https://hackmd.io/_uploads/HkJOfuiJgx.png) - 眾多 Client 跟一個 Forward-Proxy 溝通 讓它幫我們把請求導到 Server , Server 不知道發請求的 Client 是誰 - 提升 request 速度,proxy server 會將部分的 request 的 response 做暫存,其他人再來打相同的 request 時,就快速地返回 > [圖片來源: jyt0532's Blog ](https://www.jyt0532.com/2019/11/18/proxy-reverse-proxy/) ::: ### 負載平衡演算法 在上一小節中,Load Balancer 選擇 Real Server 的策略,其實就是透過負載平衡演算法來實現,那這一部分除了講最常看到的演算法以外還會再加上下一章節的 LVS 演算法。 #### Round Robin(輪詢) 每台伺服器會依照固定順序輪流接收 requests ![image](https://hackmd.io/_uploads/HytufqiJgl.png) >圖片來源:https://www.jscape.com/blog/load-balancing-algorithms * 優點: 1. 實做簡單、理解起來比較容易 2. 適用於伺服器規格相近的情況 * 缺點: 1. 沒有 Session Affinity (會話保持),因為每一次 requests 都被分散到不同的伺服器上面去做服務。 2. 伺服器規則差很多的情況下效能會不佳。 3. 流量是可預測的,所以可能會被有心人士利用。 :::info Session Affinity 有時也稱作 Sticky Sessions 將來自同個使用者的 requests 都轉發到相同的伺服器做處理。 ::: #### Least Connections (最少連線) 將 requests 導向目前連線數最少的伺服器,屬於動態負載平衡演算法的一種 ![image](https://hackmd.io/_uploads/ryYCMcjylg.png) >圖片來源:https://www.jscape.com/blog/load-balancing-algorithms * 優點: 1. 有效利用伺服器現有資源 2. 可以馬上知道伺服器負載的情況 * 缺點: 1. Load Balancer 要隨時知道每一台 Server 的狀態,會有 overhead 產生。 #### Weighted Round Robin(加權輪詢) 每台伺服器分配一個權重,依比例輪詢流量,效能好的伺服器多做一點,效能較差的做少一點 ![image](https://hackmd.io/_uploads/Syfsz5jygl.png) >圖片來源:https://www.jscape.com/blog/load-balancing-algorithms * 優點: 1. 當新增或淘汰伺服器的時候,可以快速調整權重。 2. 避免效能較差的伺服器被 overload。 * 缺點: 1. 如何把權重值設定到一個理想的狀態,是不是流量變化大了或是伺服器效能變了,還需要重新評估權重值? #### Least Response Time - 找出活躍連線數最少的伺服器。 - 如果有好幾台 Real Server 且活躍連線數量一樣的話,再找回應時間最短的伺服器。 - 常見在電子商務網站、串流服務 ![image](https://hackmd.io/_uploads/rykUjLTklx.png) >圖片來源:https://www.geeksforgeeks.org/load-balancing-algorithms/#22-least-response-time-method-load-balancing-algorithms * 優點: 1. 性能最佳化(Optimized Performance), requests 會被送到回應速度最快的 Server。整體系統的反應速度提升,使用者體驗變好。 2. requests 分配比較平均,避免集中在少數 Server 上導致 Overload。 * 缺點: 1. 實作起來更複雜,需要持續記錄和管理每台伺服器的回應時間 ____ LVS 內有的演算法 #### Locality-Based Least Connections (基於局部性的最少連接) - 為了 proxy-cache server cluster (代理快取伺服器群集)而設計的 - 將相同 destination IP 的request 轉發到同一台 Server,來提高各台 Server Cache 命中率,從而提升整個 Cluster systems 的處理能力。而 Least Connections 在這邊比較像是備用方案,等到 Server 負載過重了才會採用。 - 例子: 假設現在有很多來自 Client 的 requests 要查詢` www.example.com。` ,我後端有 3 台 Server a、b、c,這些 requests 的 destination IP 都是 93.184.216.34。都先交由 Server a 來處理,等到 Overload 後才採用 Least Connections 交給其他 Server 做處理。 :::info #### Locality 被分為空間局部性(Spatial Locality)、時間局部性(Temporal Locality) #### 定義: 空間局部性(Spatial Locality): 如果在時間上被引用的資料在空間位置上也很接近(例如,相鄰的記憶體地址、磁碟上鄰近的扇區),則認為這個引用序列具有空間局部性。 時間局部性(Temporal Locality): 如果某個資料在一段時間內被多次訪問,則認為這個引用序列具有時間局部性。 #### 通俗解釋: 空間局部性: 如果一個記憶體位置被存取,那麼很可能接下來它附近的記憶體位置也會被存取。 時間局部性: 如果一個記憶體位置曾經被存取過,那麼不久之後很可能再次被存取(例如:迴圈中重複使用相同的變數或資料)。 ::: #### Locality-Based Least Connections with Replication (帶複製的基於局部性最少連接) - 適用於大規模分散式系統 - 跟上面的 Locality-Based Least Connections 很像,只是這裡負責處理 Requests 是以一組 Server 為單位,Server pool (a、b、c )。 #### Destination Hashing - 主要是設計給 proxy-cache server cluster - 先對 destination IP 進行 hash 計算,然後 hash value 再去 mod Real Server 的數量總和。 ![image](https://hackmd.io/_uploads/SkCKPjoJxe.png) >圖片來源:https://www.cnblogs.com/edward-han/p/13714500.html #### Source Hashing - 主要是設計給有多個 firewall 的 LVS router - Source IP Hashing 是根據每個 requests 的 source IP 來計算 hash value,然後 hash value 再去 mod Real Server 的數量總和。 - 有 Sticky Session ![image](https://hackmd.io/_uploads/BybpPii1ge.png) >圖片來源:https://www.cnblogs.com/edward-han/p/13714500.html #### Shortest Expected Delay Scheduling 最少期望延遲 - 指定期望中最短 delay 時間的 Real Server,expected delay 是以 (Ci + 1) / Ui 計算,i 是第 i 個 server,Ci 是第 i 個 server 的連線數,Ui 是固定的服務速度,也可以視為加權值,服務速度越短,計算出來的結果越大。 #### Never Queue Scheduling - 如果有 idle Server,就會馬上選擇這個 Server,如果沒有 idle Server,就採用上面的 Shortest Expected Delay Scheduling 演算法,找到適合的 server。 :::info Kernel Version 4.15 後還有再新增 2 個演算法 - Weighted Fail Over - Overflow-connection ::: ### LVS (Linux Virtual Server)是什麼? LVS 是一個開源的軟體,可以在 Linux 平台下實現簡單的負載平衡。大家常常利用 LVS 在 Layer 4 進行負載平衡再加上 Linux 作業系統實現一個高性能高可用的 Linux Cluster Server。 - 主要由2個部份組成: ipvsadm、ipvs - ipvsadm 則在 User space 當指令列工具,負責為 ipvs 定義規則,透過 get/set socketopt 與 kernel space 溝通 >ipvsadm 本身使用上不需要先自己安裝相關的 Kernel Module,這部分是因為 ipvsadm 的原始碼裡面會先幫忙檢查當前系統是否已經存在對應的 ipvs.ko,如果不存在,則透過 modprobe 這個工具來安裝 ip_vs。 - ipvs 在 Linux kernel space 中的 netfilter 框架下工作,支援 TCP/UDP/STCP 等協定來進行流量轉發,根據不同的演算法封包分配到後端不同的 Real Server。 ![image](https://hackmd.io/_uploads/S1pKS_vyle.png) >[圖片來源: HWCHIU學習筆記](https://www.hwchiu.com/docs/2020/ipvs-4) :::info 學長補充: socket 讓兩個 process 之間進行溝通 ,不用去管實際的網路架構是什麼。 在 C 語言中建立 Socket 時,會使用跟網路相關的功能,需要呼叫系統提供的 socket() system call。 作業系統在建立時會開一個 Socket 對應的檔案 ( File Descriptor)。 建立完後,若需要調整行為或設定選項,可以用 setsockopt() 或 getsockopt() 來修改或取得 Socket 的設定。 ::: #### LVS 常用名詞 | 名稱 | 英文全名 | 說明 | | :--- | :--- | :--- | | DS | Director Server | 前端負載平衡器節點,也就是運行 LVS 的伺服器 | | RS | Real Server | 後端真實的工作伺服器 | | VIP | Virtual Server IP | 面向 Client 請求的虛擬 IP,通常也是 DS 的外部 IP | | DIP | Director Server IP | DS 內部 IP,負責和內部主機通訊 | | RIP | Real Server IP | 後端伺服器(RS)的 IP 位址 | | CIP | Client IP | 訪問 Client 端的 IP 位址 | #### LVS 運作原理 <!-- 關鍵字 lvs netfilter --> LVS 是基於 Linux 核心中的 Netfilter 框架實現的負載平衡功能,因此在學習 LVS 之前,必須再複習一下 Netfilter 。 > 想看完整的可以去 [Josh 的 Netfilter](https://hackmd.io/@jtr860830/Bk6iI02WJg#Netfilter) > 或是[鳥哥的 Linux 防火牆設定](https://linux.vbird.org/linux_server/rocky9/0180firewall.php) - 這裡簡單提一下 Netfilter 的 5 個 hooks: - `PREROUTING` :剛進入網路層且還沒經過 routing decision 的封包第一個碰到的 hook 點 - `INPUT` :經過 routing decision 確定要送到本機會碰到的 hook 點 - `FORWARD` :經過 routing decision 確定要轉發的封包(不是給本機),且必定在 `POSTROUTING`之前 - `OUTPUT` :從本機產生的封包會經過的 hook 點 - `POSTROUTING` :只要送往外部的封包都過經過這個 hook 點(包含`FORWARD`、`OUTPUT`) ![image](https://hackmd.io/_uploads/r1qmLDDkgg.png) - 當一個封包進入網卡再經過網路鏈結層進到網路層之後就會進入到`PREROUTING`,然後根據目標 IP 進行 routing decision ,如果確定是要送到本機的封包,就送到`INPUT`這個 hook 裡面,`INPUT` 再層層往上送到應用層。 - 應用層處理完後會把封包送到`OUTPUT`,最後從`POSTROUTING`發送給網卡。 - 如果目標 IP 不是本機,且 Server 有啟動 forward 功能,就會送到`FORWARD`,最後再從`POSTROUTING`出去。 - Netfilter/iptables 和 IPVS ![user space](https://hackmd.io/_uploads/BJgGflqJgg.jpg) >圖片來源: - 當使用者向 Director Server 發出 requests, Load Balancer 會把 request 送到 kernel space。 - `PREROUTING` chain 首先會接收到封包,如果目標 IP 是本機 IP (VIP),會把封包送到 `INPUT` chain。 - IPVS是工作在 `INPUT` chain 上的,當封包到達`INPUT` chain 時,IPVS 在 `INPUT` chain 上做判斷,修改封包的 IP/port,然後把封包送到 `POSTROUTING` chain 準備送給後端的 Real Server。 - `POSTROUTING` chain 接收封包後發現目標 IP 剛好是自己的 Real Server,此時透過 Default Gateway,把封包送過去。 #### LVS 下的三種負載平衡模式 在最一開始的Layer 2 、 Layer 3 的地方有小提一下 LVS 的三種不同工作模式,這一小節將進一步說明這三種模式的工作方式與差異 | 模式 | 特點 | 適用網路 | | -------- | ------------- | ------------- | | LVS/DR | 修改 MAC,Real Server 可以把 response 直接給 Client | LAN,同一物理網段 | | LVS/NAT | 修改 IP 為 RS 的 IP,由 Load Balancer 將 response 回傳給 Client | LAN,內網 | | LVS/TUN | 不修改 IP,但包裝一個新的 IP Header,Real Server response 回傳給 Client | LAN、WAN | ##### Network Address Translation(LVS/NAT) - Load Balancer 接收到外網使用者的 request 時,會先送到 `PREROUTING` chain, 此時封包 source IP 是 Client IP(CIP) 、Destination IP 是 Virtaul IP(VIP) - `PREROUTING` chain 檢查後發現封包要送到本機再送到 `INPUT` chain。 - IPVS 檢查後把封包 Source IP 改為 Real Server IP 並送到 `POSTROUTING` chain。 - `POSTROUTING` chain 透過 default gateway 把封包送給 Real Server。 - 要回應 Client 端的時候 Source IP 是 Real Server 自己的 IP,Destination IP 是 Client IP(CIP)。 - Load Balancer 會在 response Client 端前把 Source IP 改為自己的 VIP。 ![nat](https://hackmd.io/_uploads/HkSUne51xe.jpg) >圖片來源:https://wsgzao.github.io/post/lvs-keepalived/ 比較好看懂的圖 ![lvs nat](https://hackmd.io/_uploads/S1y2OA3Jee.jpg) >圖片來源: by me :::info 注意: 1. Real Server 和 Director Server 應該在同一個網段 2. Real Server 的 RIP 一般為 Private IP 3. Director Server 負責處理 client 和 Real Server 之間的所有進出的封包 4. Real Server 將 Director Server 的內網 IP 作為 default gateway 5. 只需要在 Director Server 上設定一個 Public IP 就可以了 6. Director Server 支援 Port Mapping 7. 可以修改封包的目標 PORT 8. Director Server 必須是 Linux 系統, Real Server 可以是任意系統。 #### 缺點:因為 Director Server 負責所有資料的進出,所以在大型應用場景中,Director Server 容易成為系統瓶頸。因為 NAT 的關係,Director Server 必須將 reqeust 和 response 進行 IP rewrite。 #### 優點:設定跟管理上比較方便 >LVS的NAT模式需要開啟 LB 的 kernel space 中的 ip_forward 功能 ::: ##### IP Tunneling(LVS/TUN) 在原有的 IP 封包外面在多封裝一層 IP header,內部 Source IP 是 CIP,Destination IP 是 VIP,外部 Source IP 是 DIP(LVS 自己的 IP,用來跟 Real Server 溝通),Destination IP 是 RIP。 :::info 注意: 1.RIP、VIP、DIP 全部都是 Public IP 2.Load Balancer 只需要處理 reqeust,response 由 Real Server 直接發送給 client 3.Real Server 的作業系統要支援 IPIP protocol 4.Load Balancer 不支援 Port Mapping #### 缺點:Real Server 需要租借大量 IP #### 優點:LVS 跟 Real Server 不用在同一個網段,可以跨地區部署 Server ::: ![tun](https://hackmd.io/_uploads/B1OEcX9ygx.jpg) 比較好看懂的圖 ![image](https://hackmd.io/_uploads/ryn8_phJxx.png) >圖片來源:https://learnku.com/articles/32077 >在linux、docker下也會有一個 kernel module 可以去看一下 ##### Direct Routing(LVS/DR) requests 封包在經過 `INPUT `chain 的時候把 Source MAC 改為 DIP-MAC、 Destination MAC 改為挑選出來的 RIP-MAC。 response 的時候只看 Source IP 是 VIP ,Destination IP 是 CIP。 :::info 1.Load Balancer 與 Real Server 必須在同一個物理網路中 2.Real server 與 Load balancer 同時擁有相同的 VIP 3.Load Balancer 只負責處理 request,response 由 Real Server直接發往 client 4.Real Server 需要將 VIP 綁定到它的 lo(loopback)介面 ,但需要設定 ARP 5.Real Server 可以用 Private IP 也可以用 Public IP ::: ![dr3](https://hackmd.io/_uploads/S18is-5Jeg.jpg) 比較好看懂的圖 ![image](https://hackmd.io/_uploads/HyQMP_C1xg.png) >三種模式的主要區別 ![image](https://hackmd.io/_uploads/HJxUtV5Jee.png) >圖片來源:https://blog.maxkit.com.tw/2016/05/lvs-lvs-natlvs-tunlvs-dr.html <!-- https://wsgzao.github.io/post/lvs/ --> <!-- https://wsgzao.github.io/post/lvs-keepalived/ --> <!-- #### LVS 實作 https://www.hwchiu.com/docs/2020/ipvs-1 https://www.kuajingnet.com/pages/lvs/1f86b4/#_2-6-2-dr%E6%A8%A1%E5%BC%8F%E5%AE%9E%E6%88%98 --> ### KeepAlived 是什麼? Keepalived 是 Linux 上常見的高可用性解決方案,最初是為了搭配 LVS 做 health check 而設計的,但後來也支援其他服務(e.g. nginx、haproxy)的 HA。主要負責監控 Real Server 的健康狀態,並在 Load Balancer 之間進行故障切換。 #### KeepAlived 原理介紹 KeepAlived 是基於 **VRRP (Virtual Router Redundancy Protocol , 虛擬路由器冗餘協定)** 來實現 HA 的。 - VRRP 可在不改變網路的情況下將多個路由設備虛擬化成一個 Virtual Router,Virtual IP 被設為 Default Gateway,一個 Virtual Router 擁有相同的 VRID 及相同的 Virtual IP,一旦有一台 Router 同樣也有跑 VRRP,但 VRID 或 Virtual IP 不同,就會被當作另一個 Virtual Router Group。 ![image](https://hackmd.io/_uploads/B1M3vFoklx.png) - 機制:選出 Virtual Router Master 一台最高優先權的 Router,其餘的為 Virtual Router Backup,若 VRRP 的 Virtual Router Master 掛了,會從 Virtual Router Backup 中選擇一台成為 Virtual Router Master。 ![image](https://hackmd.io/_uploads/BygyPtsyee.png) >圖片來源: https://hackmd.io/@nobodyprogramming/Sy_k_wRpu - Virtual Router Master,每隔一段時間間隔( Advertisement Time )要發送 multicast (說我還活著)。若經過了 Advertisement Time * 3 + 偏移時間尚未間聽到相關活著的封包,擁有較高 Priority 的 Router 會優先發出 multicast 成為 Master,而其他的 Router 則仍維持 Virtual Router Backup 的角色。 #### Virtual Router 名詞解釋 | 名稱 | 全名 | 說明 | | :--- | :--- | :--- | | Virtual Router | - | 由一個 Master Router 和多個 Backup Router 組成 | | VRID | Virtual Router ID | 一個 Group 只有一個 VRID | | Master Router | - | Virtual Router 中負責封包轉發的主節點,處理 ARP 回應與 IP 封包轉發 | | Backup Router | - | 當 Master Router 故障時,能接手成為新的 Master 的備用節點 | | VIP | Virtual IP | 一個 Virtual Router 可以有一個或多個 VIP | | VMAC | Virtual MAC address | 一個 Virtual Router 擁有一個 VMAC,回應 ARP requests 使用 | >[RFC 5798 Virtual Router Redundancy Protocol (VRRP) Version 3 for IPv4 and IPv6](https://datatracker.ietf.org/doc/html/rfc5798) | #### KeepAlived 模組架構 ![image](https://hackmd.io/_uploads/HJBmISHkll.png) >圖片來源: https://ivanzz1001.github.io/records/post/lb/2018/06/02/lb_keepalived - VRRP Stack 負責處理 Load Balancer 之間的 FailOver - Checkers 負責檢查 Real Server 或是 Upstream Server 的健康狀況 - WatchDog 負責監控 Checkers 和 VRRP 進程的狀況 - IPVS warapper 將設定好的 ipvs 規則送到 kernel space 並送到 ipvs module - Netlink Reflector 可以把 IP 改到其他地方 :::info #### WatchDog - Watchdog 可以是硬體或軟體,在硬體上可以第一個想到的就是 Timer - 當偵測到異常行為或故障時,Watchdog 可以自動重啟系統( rebooting )。 - watchdog timer 會一直 \--(減減) 到 timeout,timeout就會觸發整個硬體重啟 ![image](https://hackmd.io/_uploads/H1IsnFjyll.png) >圖片來源:https://www.amebaiot.com/zh/amebad-arduino-watchdog/ 對於需要高可用性的任務關鍵系統(mission-critical systems),Watchdog 非常重要(e.g.遠端伺服器、太空船上的嵌入式裝置),這些系統需要在無人干預時,自動偵測異常並重啟硬體。 ::: 為了確保穩定性和穩健性,daemon 被分為 3 個不同的進程: - 一個簡化的父行程,負責 fork 和監控子行程。 - 兩個子行程,一個負責 VRRP 框架,另一個負責 health check。 ![image](https://hackmd.io/_uploads/BknPQHq1eg.png) >圖片來源: > https://app.readthedocs.org/projects/keepalived/downloads/pdf/stable/ ### LVS 基本指令 前面有講到 LVS 的操作主要是用 ipvsadm 來操作,常用到的 LVS 指令如下: #### 常用指令 :::info 環境描述: - VIP:192.168.56.254(DS 上的虛擬 IP) - RS:192.168.56.102、192.168.56.103、192.168.56.104,皆執行 nginx 並開啟 80 端口 ::: 顯示虛擬服務(VIP)及對應的實體伺服器(RS) `ipvsadm -Ln` 查看連線資訊(Connection) `ipvsadm -lnc` 查看統計與流量速率資訊 `ipvsadm -Ln --stats` `ipvsadm -Ln --rate` 新增虛擬服務(以 round-robin 為排程) `ipvsadm -A -t 192.168.56.254:80 -s rr` 修改虛擬服務排程演算法為 weighted least connection `ipvsadm -E -t 192.168.56.254:80 -s wlc` 刪除虛擬服務 `ipvsadm -D -t 192.168.56.254:80` 新增實體伺服器(NAT 模式),-m 為 NAT 模式,-w 設定權重 - `ipvsadm -a -t 192.168.56.254:80 -r 192.168.56.102:80 -m` - `ipvsadm -a -t 192.168.56.254:80 -r 192.168.56.103:80 -m` - `ipvsadm -a -t 192.168.56.254:80 -r 192.168.56.104:80 -m -w 1` 測試訪問服務 `curl 192.168.56.254` 修改實體伺服器權重 `ipvsadm -a -t 192.168.56.254:80 -r 192.168.56.102:80 -m -w 2` 刪除實體伺服器 `ipvsadm -d -t 192.168.56.254:80 -r 192.168.56.103:80` 歸零統計資料 `ipvsadm -Z` 清空所有 IPVS 規則 `ipvsadm -C` 儲存 IPVS 規則 `ipvsadm-save > /path/to/ipvsadm` 載入 IPVS 規則 `ipvsadm-restore < /path/to/ipvsadm` 自訂 VIP 建立方式(將 10.0.0.10 加到主機的虛擬網卡(如 enp0s3:0)並設定為新的 VIP。) - `ip addr add 10.0.0.10/24 dev enp0s3:0` - `ipvsadm -A -t 10.0.0.10:80 -s rr` - `ipvsadm -a -t 10.0.0.10:80 -r 192.168.56.102:80 -m` - `curl 10.0.0.10` | Command (完整指令) | Short Option (縮寫) | English Description | 中文解釋 | |--------------------|---------------------|----------------------|----------| | --add-service | -A | Add virtual service with options | 新增虛擬服務 | | --edit-service | -E | Edit virtual service with options | 編輯虛擬服務 | | --delete-service | -D | Delete virtual service | 刪除虛擬服務 | | --clear | -C | Clear the whole table | 清除整個服務表 | | --restore | -R | Restore rules from stdin | 從標準輸入還原規則 | | --save | -S | Save rules to stdout | 將規則儲存到標準輸出 | | --add-server | -a | Add real server to service | 新增實體伺服器 | | --edit-server | -e | Edit real server | 編輯實體伺服器 | | --delete-server | -d | Delete real server | 刪除實體伺服器 | | --list | -L / -l | List the table | 列出服務表 | | --zero | -Z | Zero counters in a service or all services | 歸零計數器 | | --set | 無 | Set connection timeout values | 設定連線逾時時間 | | --start-daemon | 無 | Start connection sync daemon | 啟動同步守護程式 | | --stop-daemon | 無 | Stop connection sync daemon | 停止同步守護程式 | | --help | -h | Display help message | 顯示幫助訊息 | #### Options (選項) | Option (完整指令) | Short Option (縮寫) | English Description | 中文解釋 | |--------------------|---------------------|----------------------|----------| | --tcp-service | -t | TCP service address | TCP 服務地址 | | --udp-service | -u | UDP service address | UDP 服務地址 | | --fwmark-service | -f | Firewall mark-based service | 防火牆標記服務 | | --ipv6 | -6 | Use IPv6 for fwmark entry | 使用 IPv6 版本 | | --scheduler | -s | Set scheduling algorithm | 設定排程演算法 | | --pe | 無 | Set persistence engine (e.g. sip) | 設定持久性引擎 | | --persistent | -p [timeout] | Enable persistent service | 啟用會話保持服務 | | --netmask | -M netmask | Netmask for session persistence | 設定會話持久的網段遮罩 | | --real-server | -r | Specify real server address | 指定實體伺服器 | | --gatewaying | -g | Use direct routing | 使用直接路由 | | --ipip | -i | Use IPIP tunneling | 使用 IPIP 封裝 | | --masquerading | -m | Use NAT (masquerading) | 使用 NAT 偽裝 | | --weight | -w weight | Weight of real server | 實體伺服器的權重 | | --u-threshold | -x uthreshold | Upper threshold of connections | 上限閾值 | | --l-threshold | -y lthreshold | Lower threshold of connections | 下限閾值 | | --mcast-interface | 無 | Multicast interface for sync | 同步用多播介面 | | --syncid | 無 | Sync group ID | 同步群組編號 | | --connection | -c | Show current IPVS connections | 顯示當前連線 | | --timeout | 無 | Show timeout values | 顯示逾時設定 | | --daemon | 無 | Show daemon information | 顯示同步守護程序資訊 | | --stats | 無 | Show statistics | 顯示統計資料 | | --rate | 無 | Show rate information | 顯示速率資訊 | | --exact | 無 | Show exact numbers | 顯示完整數值 | | --thresholds | 無 | Show thresholds information | 顯示閾值資訊 | | --persistent-conn | 無 | Show persistent connection info | 顯示持久連線資訊 | | --nosort | 無 | Disable sorting | 停用排序輸出 | | --sort | 無 | Compatibility (does nothing) | 相容選項,無作用 | | --ops | -o | One-packet scheduling | 單封包排程模式 | | --numeric | -n | Show numeric addresses and ports | 顯示數字格式 IP/Port | | --sched-flags | -b flags | Scheduler flags | 排程器旗標 | ### LVS/NAT + KeepAlived 架構圖 ![structure](https://hackmd.io/_uploads/SJizxvkxgx.jpg) <!-- > https://www.jianshu.com/p/76645e76f975> > https://segmentfault.com/a/1190000019967549 --> - 這次會用到 4 台虛擬機 | 主機 | IP | 角色 | 安裝 | | ------------ | ----------------- | ------ | ------------------- | | Director1 | 192.168.246.10/24 | Master | ipvsadm、keepalived| | Director2 | 192.168.246.11/24 | Backup | ipvsadm、keepalived| | Real Server1 | 192.168.246.20/24 | RS 1 | nginx | | Real Server2 | 192.168.246.21/24 | RS 2 | nginx | |VIP|192.168.246.100 :::info 如果要短暫改主機名字用 `hostnamectl hostname New_Name_Here` ::: > 先處理 Director Server 1. 安裝 ipvsadm、keepalived、curl -y->yes `sudo apt install ipvsadm keepalived curl -y` 安裝好後,可以看一下 ipvsadm 內預設的規則(除了看到版本以外應該沒有東西) `ipvsadm -Ln` 2. 設定固定 IP(每台主機) 以 **Director1** 為例,使用 Netplan: `sudo vim /etc/netplan/00-installer-config.yaml` ``` network: version: 2 renderer: networkd ethernets: ens33: dhcp4: no addresses: - 192.168.246.10/24 #修改這行 gateway4: 192.168.246.2 nameservers: addresses: - 8.8.8.8 - 8.8.4.4 ``` ![image](https://hackmd.io/_uploads/rJMT-Vwgge.png) 套用設定: `sudo netplan apply` 3. **Director1 & Director2** 開啟 IP forwarding ``` echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf sudo sysctl -p ``` ![image](https://hackmd.io/_uploads/HJ7GzVvgle.png) 4. 設定 iptables (**Director1 & Director2**) ``` sudo iptables -A INPUT -p vrrp -j ACCEPT sudo iptables -A INPUT -p igmp -j ACCEPT sudo iptables -A INPUT -d 224.0.0.18 -j ACCEPT sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE ``` :::info 如果想要保存規則,下次開機不用重設的話可以用 - `sudo apt install iptables-persistent` - `sudo netfilter-persistent save` > `sudo apt install iptables-persistent` 會詢問你是否要「儲存現有的 iptables 規則」,請選擇 是(Yes),如果不能安裝就 `sudo apt update` ![image](https://hackmd.io/_uploads/HkDMENvegg.png) ![image](https://hackmd.io/_uploads/H1_4NEPxxl.png) ![image](https://hackmd.io/_uploads/HkYSVVwexl.png) ::: 5. **Director1 & Director2** 關閉 ICMP Redirect ``` echo 0 | sudo tee /proc/sys/net/ipv4/conf/all/send_redirects echo 0 | sudo tee /proc/sys/net/ipv4/conf/default/send_redirects echo 0 | sudo tee /proc/sys/net/ipv4/conf/ens33/send_redirects ``` 6. 設定 Keepalived(**Director1 - Master**),這邊直接調整 KeepAlived 設定檔。 `sudo vim /etc/keepalived/keepalived.conf` ``` vrrp_instance VI_1 { state MASTER #這台是 Master , 另一台是 Backup interface ens33 virtual_router_id 51 # 虛擬路由器 ID,同一組 VIP 要一樣 priority 100 # 優先權,數字越大越優先 advert_int 1 authentication { auth_type PASS auth_pass 1234 } virtual_ipaddress { 192.168.246.100 # 要提供給 Client 的虛擬 IP(VIP) } } virtual_server 192.168.246.100 80 { delay_loop 5 # 每 5 秒檢查一次 Real Server 狀態 lb_algo rr # 負載平衡演算法:round robin lb_kind NAT protocol TCP real_server 192.168.246.20 80 { weight 1 TCP_CHECK { connect_timeout 3 connect_port 80 } } real_server 192.168.246.21 80 { weight 1 TCP_CHECK { connect_timeout 3 connect_port 80 } } } ``` :::info 下面這段是用 ipvsadm 手動下規則 ``` # 建立 VIP 對 port 80 的虛擬服務 sudo ipvsadm -A -t 192.168.246.100:80 -s rr # 加入 Real Servers sudo ipvsadm -a -t 192.168.246.100:80 -r 192.168.246.20:80 -m sudo ipvsadm -a -t 192.168.246.100:80 -r 192.168.246.21:80 -m # 查看 LVS 設定 sudo ipvsadm -L -n ``` ::: <!-- 7. 在 Director Server 1 上保留對外的路由(`192.168.246.2`),並刪除` 192.168.246.10` 這條: ``` sudo ip route del default via 192.168.246.10 ``` --> 7. 設定 Keepalived(**Director2 - Backup**) `sudo vim /etc/keepalived/keepalived.conf` ``` vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1234 } virtual_ipaddress { 192.168.246.100 } } virtual_server 192.168.246.100 80 { delay_loop 5 lb_algo rr lb_kind NAT protocol TCP real_server 192.168.246.20 80 { weight 1 TCP_CHECK { connect_timeout 3 connect_port 80 } } real_server 192.168.246.21 80 { weight 1 TCP_CHECK { connect_timeout 3 connect_port 80 } } } ``` 8. 啟動 Keepalived(Director 1 & Director 2) ``` sudo systemctl enable keepalived sudo systemctl restart keepalived ``` 9. 最後檢查一下 VIP 是否會變動 - 在 Master 上: `ip a show ens33` - 應該會看到: `inet 192.168.246.100/32 scope global ens33` - 把 Master 停掉: `sudo systemctl stop keepalived` - 再去 Backup 看看:`ip a show ens33` - 要開啟的話就再: `sudo systemctl start keepalived` > 再處理 Real Server 1. 設定固定 IP(每台主機) 以 **Real Server1** 為例,使用 Netplan: `sudo vim /etc/netplan/00-installer-config.yaml` ``` network: version: 2 renderer: networkd ethernets: ens33: dhcp4: no addresses: - 192.168.246.20/24 #修改這行 gateway4: 192.168.246.2 nameservers: addresses: - 8.8.8.8 - 8.8.4.4 ``` 套用設定: `sudo netplan apply` 2. **Real Server 1 & Real Server 2** 安裝 Nginx `sudo apt install nginx -y` 3. 在 `/var/www/html/index.html` 加上文字幫助辨識哪台 Real Server Real server1 `echo "This is realserver1" | sudo tee /var/www/html/index.html > /dev/null ` Real server2 `echo "This is realserver2" | sudo tee /var/www/html/index.html > /dev/null ` 4. **Real Server 1 & Real Server 2** Default Gateway 指向 Director `sudo ip route add default via 192.168.246.10` 5. 在 **Director1 **查看 LVS 狀態 `sudo watch ipvsadm -L -n --stats ` :::info 測試階段 - VIP 存在於 Master `ip a | grep 192.168.246.100` 從 Client 發送請求測試 `curl http://192.168.246.100` 應會輪流看到: ``` This is realserver1 This is realserver2 ``` 可以看到 InBytes 有封包進來 ![image](https://hackmd.io/_uploads/r1j09hA1ll.png) 可以再測試完後再把 Director Server 1 KeepAlived 關掉 ``` sudo systemctl stop keepalived ``` 再去 `curl http://192.168.246.100` 能不能正常回應,或是去看 Director Server 2 用 `sudo watch ipvsadm -L -n --stats` 跟 `ip a | grep 192.168.246.100` 看看 VIP 有沒有轉移過來,這樣就順便達成了 FailOver,想把 master 復活 `sudo systemctl restart keepalived` ::: >後來 Demo 時不知道為什麼 windows 裡面的 `services.msc ` 的 `VMware NAT Services` 關掉了,所以有遇到這個問題的把它啟用就好了 <!-- ### LVS/DR + KeepAlived ### LVS/TUN + KeepAlived --> <!-- ### 補充 https://www.kawabangga.com/posts/5301 https://blog.cre0809.com/archives/653/ --> ## References: 高度可用性: - [負載平衡器解說 – 系統設計 07](https://hogantechs.com/zh_tw/%E8%B2%A0%E8%BC%89%E5%B9%B3%E8%A1%A1%E5%99%A8-system-design-what-is-load-balancer/) - [小信豬的原始部落-[架構設計] 高性能負載均衡](https://godleon.github.io/blog/Architecture_Design/Architecture-Design-High-Performance-Load-Balance/) - [矽谷銀行的啟示:銀行業的單點故障(SPOF)帶來的系統性崩潰](https://linyiru.medium.com/%E7%9F%BD%E8%B0%B7%E9%8A%80%E8%A1%8C%E7%9A%84%E5%95%9F%E7%A4%BA-%E9%8A%80%E8%A1%8C%E6%A5%AD%E7%9A%84%E5%96%AE%E9%BB%9E%E6%95%85%E9%9A%9C-spof-%E5%B8%B6%E4%BE%86%E7%9A%84%E7%B3%BB%E7%B5%B1%E6%80%A7%E5%B4%A9%E6%BD%B0-7ffb74bcba53) - [Ubuntu 20.04 網路綁定](https://roychou121.github.io/2021/02/04/ubuntu-network-bond/) - [談談何謂「單點故障」?](https://ithelp.ithome.com.tw/m/articles/10263600) - [Configuring LACP on Ubuntu 18.04 and Ubuntu 20.04](https://portal.novoserve.com/knowledgebase/70/Configuring-LACP-on-Ubuntu-18.04-and-Ubuntu-20.04.html) - [高有效性 (High Availability) 初論 30 講](https://ithelp.ithome.com.tw/users/20000065/ironman/279) - [SRE工程師武器庫:3種服務監控指標 SLA/SLO/SLI — 精通網站可靠性工程](https://medium.com/@minghunghsieh/sre%E5%B7%A5%E7%A8%8B%E5%B8%AB%E6%AD%A6%E5%99%A8%E5%BA%AB-3%E7%A8%AE%E6%9C%8D%E5%8B%99%E7%9B%A3%E6%8E%A7%E6%8C%87%E6%A8%99sla-slo-sli-%E7%B2%BE%E9%80%9A%E7%B6%B2%E7%AB%99%E5%8F%AF%E9%9D%A0%E6%80%A7%E5%B7%A5%E7%A8%8B-8be8606694a8) - [了解可用性](https://docs.aws.amazon.com/zh_tw/whitepapers/latest/availability-and-beyond-improving-resilience/understanding-availability.html) - [重新定義高可用性(HA)儲存系統](https://storage.qsan.com/tw/blog/redefine-storage-for-high-availability/) - [Availability vs. Reliability](https://shwang1979.medium.com/availability-vs-reliability-bc91fa8108a4) - [淺談高可用性系統架構](https://www.cc.ntu.edu.tw/chinese/epaper/0037/20160620_3706.html) - [叢集技術與雲端服務<一>](https://www.cc.ntu.edu.tw/chinese/epaper/0015/20101220_1505.htm) - [B計畫與R計畫](https://www.ithome.com.tw/voice/151017) - [HA cluster 筆記和 Application 設計](https://klee1611.github.io/posts/ha-cluster-app-architecture.html/) - [維基百科 - 生命攸關系統](https://zh.wikipedia.org/wiki/%E7%94%9F%E5%91%BD%E6%94%B8%E9%97%9C%E7%B3%BB%E7%B5%B1) - [維基百科 - 系統冗餘](https://zh.wikipedia.org/zh-tw/%E7%B3%BB%E7%BB%9F%E5%86%97%E4%BD%99) - [簡易 Cluster 架設](https://linux.vbird.org/linux_server/others/0600cluster.php#theory_whatiscluster) - [Network Redundancy and Why It Matters](https://www.auvik.com/franklyit/blog/simple-network-redundancy/) - [ Sun Java System Messaging Server 6.3 管理指南 > 第 3 章 配置高可用性 > 3.2 高可用性模式](https://docs.oracle.com/cd/E19957-01/820-0514/geduu/index.html) - [What is Cold Standby?](https://www.geeksforgeeks.org/what-is-cold-standby/) - [了解叢集(Cluster)、叢集運算(Cluster Computing)與分散式運算](https://www.gigabyte.com/tw/Article/cluster-computing-an-advanced-form-of-distributed-computing-a-tech-guide-by-gigabyte) - [Backup Sites: Cold, Warm, and Hot](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/4/html/introduction_to_system_administration/s2-disaster-recovery-sites#s2-disaster-recovery-sites) - [異地備援是什麼?與「備份」有何差異?運作機制、建議距離一次看](https://www.chirue.com/disaster-recovery/) - [網路監控簡介](https://www.whatsupgold.com/tw/what-is-network-monitoring) - [Linux 網路結合(network bonding)技術與實務](https://www.lijyyh.com/2011/11/0-balance-rr-l-round-robin-salve-salve.html) - [Linux Ethernet Bonding Driver HOWTO](https://www.kernel.org/doc/Documentation/networking/bonding.txt) - [充分利用入門級NAS多網路埠的效益](https://www.ithome.com.tw/tech/96900) - [什麼是網站可靠性工程 (SRE)?](https://www.netapp.com/zh-hant/devops-solutions/what-is-site-reliability-engineering/) - [What is a High Availability Cluster?](https://www.netapp.com/blog/cvo-blg-high-availability-cluster-concepts-and-architecture/) - [Data Replication 如何優化資料庫?- 系統設計 09](https://hogantechs.com/zh_tw/data-replication-system-design-database-hogantech/#%e5%96%ae%e4%b8%bb%e4%b8%bb%e5%be%9e%e8%a4%87%e8%a3%bd-single-leader-primary-secondary-replication) - [Cold Standby vs. Warm Standby](https://www.geeksforgeeks.org/cold-standby-vs-warm-standby/) - [讓我看看你狀態正不正常啊 - 架設 status page](https://ithelp.ithome.com.tw/m/articles/10266262) - [109-2 負載平衡和高度可用性講義](https://hackmd.io/@jiazheng/rJ-B1-QHd) - [113-1 Monitoring 講義](https://hackmd.io/@ncnu-opensource/ryAgx86Qyl) - [Simple Network Management Protocol (SNMP)](https://www.geeksforgeeks.org/simple-network-management-protocol-snmp/) - https://medium.com/moda-it/snmp-7335b2ad9f60 - [ICMP 協定與分析](https://www.tsnien.idv.tw/Manager_WebBook/chap4/4-5%20ICMP%20%E5%8D%94%E5%AE%9A%E8%88%87%E5%88%86%E6%9E%90.html) - https://www.whatsupgold.com/tw/network-traffic-monitoring/netflow - [Nagios](https://twoss.gitbook.io/open-source-use-case/jian-kong/nagios) - [來從 TimescaleDB 認識 Time-Series Database 吧!](https://medium.com/@henry-chou/%E4%BE%86%E5%BE%9Etimescaledb%E8%AA%8D%E8%AD%98time-series-database%E5%90%A7-603603506d09) - [Zabbix - 指標界的沙場老兵](https://ithelp.ithome.com.tw/articles/10327855) - [輕鬆管理 Metrics 的工具,Prometheus 介紹](https://ithelp.ithome.com.tw/articles/10299053) 負載平衡 - [Jiazheng's HA with Load Balancer](https://hackmd.io/@jiazheng/rJ-B1-QHd) - [How do Layer 4 Load Balancing and Layer 7 Load Balancing Differ?](https://www.a10networks.com/glossary/how-do-layer-4-and-layer-7-load-balancing-differ/) - [What Is Layer 7 Load Balancing?](https://www.f5.com/glossary/layer-7-load-balancing) - [Understand Cloud Load Balancer Like a Senior Engineer](https://medium.com/google-cloud/understand-cloud-load-balancer-like-a-senior-engineer-d4f55f3111fc) - [負載平衡介紹(簡體中文)](https://blog.csdn.net/sxc1414749109/article/details/137564017?ops_request_misc=%257B%2522request%255Fid%2522%253A%252285132e33044e53de8cd816be9ffd0106%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=85132e33044e53de8cd816be9ffd0106&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-137564017-null-null.142^v102^pc_search_result_base1&utm_term=%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1&spm=1018.2226.3001.4187) - [LVS 三種模式介紹(簡體中文)](https://tinychen.com/20200427-lvs-principle-introduction/) - [LVS Scheduling Algorithms](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/4/html/virtual_server_administration/s1-lvs-scheduling-vsa#s2-lvs-sched-VSA) - [LVS 演算法](https://blog.maxkit.com.tw/2016/05/lvs-lvs-natlvs-tunlvs-dr.html) - [LVS Scheduling Algorithms(簡體中文)](https://blog.csdn.net/liupeifeng3514/article/details/79038498) - [LSA FIrewall](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FSd59QRjvRHGNSpyHHdpccg#SNAT) - [防火牆與 NAT 伺服器](https://linux.vbird.org/linux_server/centos6/0250simple_firewall.php) - [輕鬆搞懂首站備援(VRRP)](https://itlocation.blogspot.com/2013/03/vrrp-virtual-router-redundancy-protocol.html) - [Virtual Router Redundancy Protocol (VRRP)](https://hackmd.io/@nobodyprogramming/Sy_k_wRpu) - [RFC 5978](https://rfc2cn.com/rfc5798.html) - [Keepalived User Guide](https://app.readthedocs.org/projects/keepalived/downloads/pdf/stable/) - [Keepalived User Guide(簡體中文)](https://keepalived-doc.readthedocs.io/zh-cn/latest/%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1.html) - [LVS + KeepAlived 原理介紹(簡體中文)](https://wsgzao.github.io/post/lvs-keepalived/) - [LVS 指令](https://www.voidking.com/dev-ipvs-start/)