kubeCDN:一個基於Kubernetes的自託管CDN
在本篇博文中,作者主要討論了kubeCDN的設計和實現,這個工具旨在簡化Kubernetes叢集的跨地域複製,以便在全球範圍內部署高可用的CDN(內容分發網路)服務。
使用者越多,問題越多
網際網路的出現讓全世界的人們改變了交流和分享資訊的方式。但是,這種改變方式依然存在不少問題。由於網際網路已經變成了人們獲取資訊的首選途徑,網際網路中阻礙我們快速獲取資訊的任何障礙都會令人不爽。坐在電腦前等待文件或視訊緩衝,相信大家都經歷過,這種時候對我們來說幾分鐘甚至幾秒鐘都是一種煎熬。考慮到當今網際網路的普及程度,我們生活中的方方面面都非常依賴它,而且我們也不得不花費更多的時間來面對下圖中的情形。這種經歷極大地破壞了使用者體驗,但凡存在可替代方案,相信使用者都會趨之若鶩。沒有企業想因為這種方式失去客戶,但解決這類問題會涉及一些技術上的挑戰。
伺服器遠離使用者是造成服務延遲的主要原因。假設你的伺服器正在提供全球客戶服務,那麼位於世界另一端的使用者勢必會感受到更多的服務延遲。這種延遲減緩了資料獲取、導致了更多的動畫緩衝,使用者體驗也變得非常糟糕。
遠離伺服器的使用者會感受到更多的延遲(圖片來源)
將伺服器部署到離使用者儘可能近的地方可以減少這種延遲,但這種方法卻非常具有挑戰性,畢竟並不是每個公司都有能力在全球範圍部署基礎設施,這需要非常大的資本和人力投入。
當前解決方案:CDN服務供應商
我們可以藉助第三方CDN供應商來避免這種問題。一家公司完全可以只在一個地區部署基礎設施,然後利用Akamai、CloudFlare和Fastly等CDN供應商將服務分發到全世界。
CDN供應商在全球範圍內有很多PoPs(Points of Presensce - 入網點),節點通常由一些邊緣伺服器組成,伺服器則快取了像圖片這樣的靜態資源。當使用者請求資源時,邊緣伺服器可以直接提供快取內容;如果沒有找到請求的資源,邊緣伺服器將嘗試從客戶伺服器或附近的邊緣伺服器獲取該資源。這種設定大大降低了網路延遲以及資料包的丟失,極大地改善了跨地域使用者的使用體驗。
更多關於CDN的內容請參考此處。
使用CDN供應商的問題
使用CDN供應商的確是一個便捷的解決方案,但這種方案也存在一些問題。
第一個問題是,在使用第三方CDN服務的同時,我們也失去了對基礎設施的控制權。我們只能依賴外部實體來確保使用者能夠獲得最佳體驗。這裡還有一個更重要的因素,那就是使用者資料的安全性。第三方CDN供應商系統中的錯誤,例如2017年的那個錯誤,就可能對使用者的安全和隱私產生嚴重影響。
第二個問題則是,CDN供應商可能並不會把你的利益擺在第一位。畢竟你可能不是他們唯一的客戶,而且作為一個獨立企業,他們也需要優先考慮自身的利益。
最後也是最重要的問題,CDN供應商能夠監視你的業務資料。CDN供應商可以確定你的客戶的位置、客戶使用服務的時間以及客戶所使用的裝置型別。這樣的業務資料對你的競爭對手來說非常有價值,如果這類資訊洩露給第三方可能會讓你的客戶流失,從而讓你的業務蒙受重大損失。
對於許多團隊來說,這些問題的潛在危害可能已經遠遠超過了其所帶來的便利性。因此,像Netflix和LinkedIn這樣的頂級工程團隊都已經自主解決了這個問題。如果你也想構建自己的CDN,不妨嘗試一下kubeCDN。
kubeCDN
上述問題也是作者決定設計kubeCDN的根本原因。它是一個基於Kubernetes的自託管CDN方案,自託管也就意味著我們可以完全控制自己的基礎設施。通過kubeCDN,我們不再需要第三方的內容分發網路,重新控制了從伺服器到使用者裝置的資料流。
架構設計
kubeCDN使用Terraform在選定的區域部署EKS和其他AWS基礎設施元件。Route53是AWS提供的雲域名系統(DNS),用於多區域使用者間的路由;ExternalDNS用於在部署新服務時自動建立DNS記錄。
下圖演示瞭如何使通過Terraform來部署kubeCDN。
Terraform用於在選定的區域部署EKS基礎設施
Terraform用於部署kubeCDN所必需的基礎設施,而Route53用於將使用者流量路由到特定區域。為了演示kubeCDN,作者在兩個AWS區域(us-east-1和us-west-2)中分別部署了一個視訊伺服器,然後在Route53上設定了一個託管區域,併為叢集的每個區域都設定了A記錄。作者採用了基於延遲的路由策略,從而將使用者路由到能夠為他們提供最低延遲的區域。在此演示中,使用者總是被路由到地理上最接近的區域。然而,實際情況可能並非總是如此。因特網上的延遲可以隨著時間而改變,當採用基於延遲的路由策略時,Route53可以利用這些監測資料來確定如何路由使用者。更多資訊參考此處。
kubeCDN使用Route53將使用者流量路由到延遲較低的區域
上圖演示了Route53如何通過兩個區域中的叢集來路由使用者流量。舊金山的使用者被路由到us-west-2中的叢集,因為該區域提供了更低的延遲。
kubeCDN還可以使用Route53中一些別的路由策略,從而滿足不同應用程式的需求,詳情參閱這裡。
解決方案
kubeCDN讓我們在幾分鐘內就可以把服務和應用程式擴充套件到全球範圍。我們只需要15分鐘就能夠完成上述基礎設施的部署,與使用AWS控制檯的手動部署相比,這是一個顯著的改進。
除了易於擴充套件之外,kubeCDN還可以通過關閉一些低使用者活躍度的地區來優化基礎設施成本。在預算緊張或為了保證最大利潤的時候,這種型別的成本優化就顯得尤為重要。
開發挑戰
作者在開發kubeCDN時遇到了一系列的問題。它們大多數都是一些小問題,容易解決,但其中也不乏比較棘手的問題,下面著重分析其中的兩個。
Terraform程式碼重構
Terraform原本是HashiCorp公司為其網路研討會專案建立的程式碼,作者在該專案中對其進行了二次開發。雖然Terraform的程式碼非常清晰,並附有詳細的說明,但它還不能支援多區域部署。目標區域是通過程式碼寫死的,因此我們需要為每一個區域都複製一個程式碼庫。這是一個非常繁瑣的手動過程,非常容易因為人為因素而配置錯誤。這也會導致管理結構上的混亂,使基礎設施監控和成本優化變得非常困難。
重構Terraform程式碼是解決這個問題的一種方法,然而,難點在於如何重構。在查閱了相關文件以及一個類似的開源專案之後,作者決定採用下面的結構來組織專案現階段的基礎設施部署。
├── terraform (Dir containing all infrastructure code) ├── cluster (EKS cluster components) │ ├── main.tf │ ├── outputs.tf │ ├── rbac.yaml │ └── variables.tf ├── main.tf (Main .tf file where regions are specified) └── variables.tf (Some files have been removed for brevity)
在上面所示的目錄結構中,main.tf用來指定所有期望區域的位置。具體配置方式參照以下程式碼段:
module \u0026quot;\u0026lt;name-for-region-deployment\u0026gt;\u0026quot; {\tsource = \u0026quot;cluster\u0026quot;\tregion = \u0026quot;\u0026lt;AWS-region\u0026gt;\u0026quot;}
這樣我們就可以通過一個配置檔案來輕鬆地定義新區域,而且這也很容易管理。
ExternalDNS的問題
ExternalDNS是一個通過Kubernetes資源來動態配置DNS記錄的工具。該工具可以與Route53和一些其它的DNS供應商對接。在將新服務(如web伺服器)部署到Kubernetes叢集時,ExternalDNS會為其建立DNS記錄,這樣使用者就可以通過公共DNS伺服器解析到新部署的web伺服器。
對於kubeCDN,作者使用ExternalDNS為不同的區域自動建立DNS記錄,並將Route53配置為基於延遲的路由策略,從而將使用者路由到延遲最低的區域。作者在實現過程中遇到了一些問題,而這些問題使作者無法完全自動化實現ExternalDNS的動態配置。
作者原本設定了兩個A記錄,分別對應不同區域的域名,然後與Route53中基於延遲的路由策略相結合,從而將使用者引導到提供最低延遲的AWS區域。這樣,一個A記錄會指向東海岸基礎設施的域名,而另一個則指向西海岸基礎設施的域名。作者將ExternalDNS合併到kubeCDN中,並配置視訊測試服務去使用該工具,最後在部署時設定了一個DNS記錄。
即使域名的IP地址不同,ExternalDNS仍然會覆蓋相同域名的A記錄。這似乎是AWS在ExternalDNS中的一個臨時限制。考慮到ExternalDNS是一個新工具,仍然處於專案孵化階段,我們需要臨時手動解決這個問題。該專案在Github中有個非常類似的問題,但是在提交了一個拉取請求後,這個問題就被關閉了。至今,這個請求仍然沒有合併到ExternalDNS的主分支。
正如文中所指出的(撰寫本文時Github上尚未有解決方案),AWS在ExternalDNS中的另一個侷限性則是無法在Route53上設定基於延遲的路由策略,我們只能通過在AWS控制檯來手動設定這個路由策略。
以上都是針對ExternalDNS和AWS的問題,對於新版本的ExternalDNS或者其他雲供應商可能就不存在這樣的問題。隨著專案的發展和更多功能的實現,相信將來這些問題都會得到改善。
kubeCDN擴充套件
考慮到kubeCDN只是一個為期三週的短專案,它仍然有很多需要改進的地方,下面是作者的一些想法。
多雲支援
目前,kubeCDN僅支援AWS。這主要是因為Insight的研究員能夠在專案中使用AWS。只使用一個雲供應商會在服務中斷時造成問題,新增對多雲供應商(如GCP\u0026amp;Azure)的支援,可以在服務中斷時提供必要的故障轉移。
考慮到kubeCDN是基於Kubernetes的實現,這的確提出了一些挑戰。目前,kubeCDN使用AWS提供的EKS來管理的Kubernetes服務。新增對其他雲供應商的支援,至少需要滿足下面的一個條件:
- 整合所有云供應商提供的管理服務。雖然這將簡化部署,但是將不同的託管服務合併到kubeCDN將非常具有挑戰性。
- 使用自定義的Kubernetes部署。在選定供應商提供的基礎設施後,這裡需要使用kops來安裝自定義的Kubernetes叢集。它可以統一管理位於不同供應商的基礎設施上的叢集,並可以靈活部署一些比較特殊的場景。除此之外,在需要消除第三方依賴的時候,kops也可以讓團隊在本地裝置上部署kubeCDN。
雖然從長期來看,kops似乎是這個專案的最佳選擇,但這依然非常困難,仍需要大量的開發工作。即便如此,採用kops還是會給專案帶來巨大的好處。
區域自動伸縮
雖然在全球範圍內擴充套件基礎設施可以極大地改善使用者體驗,但也沒有必要在世界各處同時全天候執行服務。有時候,從利潤的角度來看,關閉某些只有少量使用者的區域的基礎設施反而是更好的做法。從財務角度來看,這種對基礎設施成本的優化是非常有益的。
為了實現這一點,我們需要一個監控解決方案來提供區域選擇的度量。當某個區域的指標達到預定義的閾值時,我們就可以關閉該區域的基礎設施。而如果來自特定區域的使用者數量出現激增,並超過了某個類似的閾值時,我們也可以在預先定義的區域中自動啟動新的基礎設施。
預定義區域列表
當前版本的kubeCDN可以很容易得將EKS叢集部署到新區域。目前,我們需要手動複製程式碼到每個區域來實現部署,但是我們可以通過一個檔案來配置所需的區域,部署過程也會變得更加清晰。
這個特性還可以與前面提到的區域自動伸縮特性很好地結合起來。我們可以向kubeCDN提供兩個區域列表,一個是需要連續執行基礎設施的區域,另一個是可用於基礎設施自動擴充套件的區域,這極大地簡化了基礎設施的管理。
使用Kubernetes的叢集聯邦(Federation)
Kubernetes聯邦可以很容易地管理多個叢集。聯邦所提供的特性列表可參閱這裡,雖然裡面的每一個特性都有利於kubeCDN,但其中跨叢集同步資源的能力尤為突出。跨叢集資源同步提出了一個巨大的管理挑戰,而聯邦則極大地簡化了這個挑戰。但是,聯邦目前還不是Kubernetes的一個成熟特徵,仍存在很多問題,Kubernetes開發團隊也正在努力解決中。
結語
當前的kubeCDN簡化了Kubernetes叢集的跨地域配置,並允許簡單的擴充套件。鑑於kubeCDN的自託管屬性,它可以滿足自定義的基礎設施需求,併為基礎設施的管理提供巨大的靈活性。
當然,kubeCDN也存在很多問題,但這些問題只會促使kubeCDN變的更加健壯。我們前面已經討論過了其中的一些問題,相信後續會有更多。另一方面,Kubernetes自身的改進也會影響到kubeCDN的未來發展。隨著Kubernetes聯邦特性的成熟,相信kubeCDN也會變得更加強大。
檢視英文原文:https://blog.insightdatascience.com/how-to-build-your-own-cdn-with-kubernetes-5cab00d5c258
相關文章
- 基於Gitea打造一個屬於你自己的程式碼託管平臺Git
- [小團隊自動化] 基於Gitea打造一個屬於你自己的程式碼託管平臺Git
- 一個基於SpringBoot實現的影像託管程式Spring Boot
- 一個自託管免費開源的人臉識別系統
- Signalr自託管最簡實踐SignalR
- Kubernetes:28---pod託管(Job:任務型pod)
- 6 個託管 git 倉庫的地方Git
- Uptime Kuma | 超棒的自託管監控工具
- 終極自託管解決方案指南
- Kubernetes stateful set講解以及一個基於postgreSQL的具體例子SQL
- 微信雲託管 WebSocket 實戰:基於模版實現訊息推送Web
- 基於Kubernetes的業務自動化BPMN流程工具:KogitoGit
- 看雲|專注於文件創作和託管
- 一文讀懂「雲託管」
- 自動定位問題、自動修復故障?託管雲這個功能有點心動
- 基於Kubernetes v1.24.0的叢集搭建(一)
- 基於kubernetes自研容器管理平臺的技術實踐
- 一個開源的、獨立的、可自託管的評論系統,專為現代Web平臺設計Web
- 基於kubernetes的分散式限流分散式
- 搭建自己的harbor(docker託管)Docker
- Kubernetes 實戰 —— 04. 副本機制和其他控制器:部署託管的 pod
- 自動共享和上傳檔案到相容的託管站點
- 博森量化軟體:託管錢包與非託管錢包的區別?
- 個性化定義多個 Git 託管平臺配置Git
- 一個可用於生產專案 基於 .NET 6 自研ORMORM
- Kubernetes學習筆記(二):部署託管的Pod -- 存活探針、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob筆記Controller
- 託管節點池助力使用者構建穩定自愈的 Kubernetes 叢集
- ASP.NET Core 託管和部署(一)【Kestrel】ASP.NET
- 伺服器託管是什麼意思,為什麼要託管?伺服器
- 基於Kubernetes的hpa實現pod例項數量的自動伸縮
- 四問四答 關於託管資料中心的那些事兒
- 重學c#系列——c# 託管和非託管資源(三)C#
- 伺服器託管和租用哪個更划算呢?伺服器
- 微信雲託管常見問題FAQ(一)
- GoDaddy被發現其在託管的網站的所有網頁嵌入了一個指令碼Go網站網頁指令碼
- C# 開源一個基於 yarp 的 API 閘道器 Demo,支援繫結 Kubernetes ServiceC#API
- 基於kubernetes平臺微服務的部署微服務
- 基於kubernetes構建混合雲的利弊