網易伏羲雲原生遊戲中間件平臺實踐

網易伏羲成立於2017年,是國內專業從事遊戲與泛娛樂AI研究和應用的頂尖機構。爲了更好的爲遊戲提供中間件服務支持,伏羲雲計算團隊構建了伏羲雲原生遊戲中間件平臺。本文主要介紹伏羲雲原生遊戲中間件平臺的實踐過程。

背景與場景

伏羲私有云爲遊戲以及AI研究應用提供完善、可靠的計算能力。遊戲作爲網易的核心業務,如何更好的爲遊戲服務是平臺的重點。

遊戲是網易的核心業務。在遊戲項目中,從遊戲的開發、測試、到上線各個階段都具有各種中間件的需求。在此背景下,對我們如何爲遊戲提供高效、可靠的中間件服務提出巨大的挑戰。

傳統的方式是通過運維人員手動搭建維護,而這種方式主要存在下面問題:

  • 環境依賴:服務可能會因爲基礎環境的變化導致異常情況。

  • 缺少標準化:各個遊戲項目對中間件的使用方式存在差異。

  • 缺少平臺統一動態管理:缺少統一平臺進行創建、刪除等自主運維能力。

  • 服務可靠性低:服務不可用等狀態難以及時發現,以及人工修復效率比較低。

爲了解決這些問題,伏羲雲計算團隊構建了雲原生遊戲中間件平臺。伏羲雲原生遊戲中間件平臺基於Kubernetes技術,提供了基於容器的數據庫、CacheServer、SymbolServer等遊戲項目中的中間件服務,爲遊戲在開發、測試、上線各個階段需要各種中間件支持,幫助遊戲更好的專注於遊戲本身。

雲原生遊戲中間件平臺遇到的挑戰

雲原生遊戲中間件平臺作爲服務於遊戲業務的核心平臺,面臨着以下嚴峻的挑戰:

  • 靈活性:各個遊戲業務對基礎服務使用存在差異,需要滿足各個業務多樣化的需求。

  • 穩定性:雲環境中存在節點異常、網絡IO抖動,磁盤IO抖動等各種情況,這些情況都有可能導致服務異常,基礎服務直接影響上層業務的穩定性和項目的推進,因此如何保證服務的穩定性十分重要。

  • 故障自愈:由於各種異常情況,服務可能存在主動退出、或者被動退出的情況。當出現服務的情況,服務需要具備自愈能力,服務能夠被快速重新拉起,並且保證服務中數據的不丟失,從而避免人工介入修復。

  • 易觀測:中間件運行的過程中,運行日誌,指標參數需要能被完善收集便捷的展示,幫助用戶瞭解中間件服務運行的狀態。

  • 中間件生命週期管理:中間件服務的生命週期管理就是對中間件的各個狀態進行管理,各個狀態具有對應可執行的操作。

雲原生遊戲中間件平臺落地

在技術架構上,伏羲雲原生遊戲中間件平臺核心基於Kubernetes進行構建,充分利用了Kubernetes提供的容器編排管理能力。利用Kubernetes Operator模式擴展Kubernetes API,將各個中間件服務抽象成Kubernetes中的資源進行管理。

整體架構

雲原生遊戲中間件平臺分爲:用戶層、業務服務層、核心服務層以及基礎設施層。

核心服務層作爲平臺的大腦提供了Kubernetes擴展自定義中間件資源的生命週期管理能力,以及中間件資源的可觀測性等能力。

中間件生命週期管理

Kubernetes Operator模式

自定義資源(Custom Resource) 是對 Kubernetes API 的擴展,通過CRD(Custom Resource Definitions)動態註冊自定義資源類型,並可以與Kubernetes內置資源對象(如 Pod、Deployment等)相同的方式來管理它們。CRD可以充分利用Kubernetes已有的能力,核心能力包括:Schema定義校驗、多版本、status/scale子資源等。

CRD僅僅提供了自定義資源結構化數據的存儲能力。爲了使自定義資源成爲聲明式API(聲明資源的期望狀態,並嘗試讓Kubernetes對象的當前狀態同步到其期望狀態),資源達到期望狀態的邏輯就需要CRD Controller來實現。

Kubernetes Operator模式是將CRD與CRD Controller相結合,實現自定義資源以及資源自動化運維。

雲原生遊戲中間件平臺採用的是Operator模式管理遊戲中間件服務,每一個遊戲中間件對應一個Operator實現,通過Operator實現遊戲中間件服務的生命週期管理,自動化運維。

中間件可觀測性

中間件的可觀測性作爲中間件平臺的核心能力,目的是幫助檢測定位中間件服務的運行狀態(例如:服務異常、錯誤、響應緩慢等)。服務觀測主要包含日誌和指標監控兩個層面。

中間件服務日誌收集

中間件服務的日誌分爲兩種類型:

1、標準輸出、標準錯誤輸出日誌收集方案

  • 實時標準輸出、標準錯誤輸出日誌,業務服務層日誌查詢服務通過調用Kubernetes API獲取中間件容器的實時標準輸出、標準錯誤輸出日誌,然後展示到用戶層。

  • 日誌存儲及檢索,Kubernetes中容器重啓等場景會使得日誌丟失,因此需要將中間件容器的標準輸出、標準錯誤輸出日誌持久化的進行存儲,並且支持日誌檢索等需求。架構如下:


中間件服務容器的標準輸出、標準錯誤輸出的日誌會以文件的形式存儲在Pod所在宿主機上。通過Kubernetes DaemonSet方式在各個節點上部署Fluentd,並採用hostPath方式將宿主機上容器日誌掛載到Fluentd的Pod中。Fluentd將中間件容器的日誌發送到Kafka,最終存儲到ElasticSearch中。

2、容器內日誌收集方案

在一些場景下中間件日誌存儲在容器中,不同中間件的日誌文件命名也不相同。針對容器內日誌收集架構如下:

容器內日誌收集採用Sidecar模式中間件Pod中增加日誌收集容器Filebeat,Filebeat容器與中間件容器的日誌目錄通過emptyDir掛載的方式實現目錄共享。Filebeat根據ConfigMap定義的配置,將中間件日誌發送到Kafka,最終存儲到ElasticSearch中。

中間件服務監控

傳統的以主機爲中心的基礎設施中,我們僅監控兩個層次:中間件服務和運行它們的主機。而云原生平臺監控包含四個維度:節點監控、Kubernetes資源狀態監控、容器監控、遊戲中間件服務監控。整體架構如下:

exporter通過RESTful API的方式暴露指標數據,Prometheus從各個exporter中拉取指標數據,並進行持久化存儲。Alertmanager則是Prometheus內置的告警模塊。這裏主要介紹exporter實現四個維度監控。

  • 節點監控,節點的指標收集通過node exporter實現。node exporter通過DaemonSet方式部署在Kubernetes的每個節點上,用於採集節點的運行指標,包括節點CPU,內存,文件系統等指標。

  • Kubernetes資源狀態監控,kube-state-metrics採用Deployment方式部署,通過監聽Kubernetes apiserver將Kubernetes資源的數據生成相應指標。在雲原生遊戲中間件平臺場景下,我們需要對自定義遊戲中間件資源狀態進行監控。

  • 容器監控,cAdvisor對節點容器進行實時監控和性能數據採集,包括CPU使用情況、內存使用情況、網絡吞吐量及文件系統使用情況。cAdvisor以及集成在kubelet中,當kubelet啓動時會自動啓動cAdvisor。

  • 遊戲中間件服務監控,上述監控從Kubernetes資源狀態、節點、容器層進行,而更細粒度的就需要遊戲中間件服務本身進行監控,不同遊戲中間件需要監控的服務指標也不相同。遊戲中間件平臺層就需要針對各個中間件資源實現各自的exporter,從而達到服務級別的監控。

CacheServer中間件加速Unity開發

以上介紹了雲原生遊戲中間件平臺落地的核心通用層面。然而各個遊戲中間件具有不同的特點,爲了更好的實現遊戲中間件服務的靈活性、穩定性、以及故障自愈能力,就需要從Operator實現、CacheServer相關優化等深入考慮。

下面以CacheServer中間件爲例,介紹如何實現雲原生遊戲CacheServer中間件。

CacheServer介紹

CacheServer是Unity的緩存服務器。網易基於Unity CacheServer v1協議,自研了CacheServer服務,CacheServer由Nginx作爲入口,資源數據都存儲在ARDB中。ARDB是一個類似Redis的KV存儲,但相比Redis的優點就是數據都由底層的RocketsDB持久化存儲在磁盤上,在Redis服務中只存儲所有資源數據內容的key,以及在key上設置TTL,再由Cleaner Server負責清理。架構如下:

下文中出現的CacheServer即爲網易自研CacheServer。

雲原生CacheServer架構

上圖是CacheServer是基於Kubernetes的雲原生架構。CacheServer Pod包含了CacheServer容器和Cleaner容器。CacheServer容器提供了CacheServer核心服務能力包含了Nginx、CacheServer Server、ARDB和Redis服務。Cleaner容器以Sidecar的模式,提供緩存清理能力。ARDB數據以emptyDir方式進行掛載,隨Pod生命週期。CacheServer Service提供Kubernetes的訪問入口。

CacheServer Operator實現

CacheServer CRD定義:

type Cacheserver struct {  
    metav1.TypeMeta   `json:",inline"`  
    metav1.ObjectMeta `json:"metadata,omitempty"`  
  
    Spec   CacheserverSpec   `json:"spec,omitempty"`  
    Status CacheserverStatus `json:"status,omitempty"`  
} 

type CacheserverSpec struct {    
    Storage int64 `json:"storage"`  
    Image string `json:"image"`  
    Resources corev1.ResourceRequirements `json:"resources"`  
    Cleaner Cleaner `json:"cleaner"`  
    Tolerations []corev1.Toleration `json:"tolerations"`  
    NodeSelector map[string]string `json:"nodeSelector"`  
    ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`  
}  

type CacheserverStatus struct {  
    Phase string `json:"phase"`  
}  

type Cleaner struct {   
    Webhook string `json:"webhook"`  
    Image string `json:"image"`  
}

CacheServer CRD定義包含了三部分:

  • 基礎信息:名稱、Namepace、CacheServer鏡像、Cleaner鏡像、鏡像拉取Secret等。

  • 資源配置:CPU、內存、持久化存儲大小。

  • 調度:CacheServer Pod調度配置Tolerance、NodeSelector等。

CacheServer Operator實現邏輯:

CacheServer Operator分爲資源管理和狀態管理兩個部分:

  • 資源管理:管理CacheServer所包含的Pod、Service等子資源。Operator通過list、watch監聽CacheServer事件(創建、更新、刪除),發送到Resource Handler的隊列中,由控制循環取出事件並處理。創建資源時將子資源的OwnerReference設置成父資源,可以在刪除CacheServer時利用kubernetes級聯刪除有效刪除子資源。

  • 狀態管理:實時更新CacheServer的運行狀態。Operator通過list、watch循環監聽CacheServer Pod資源,根據Pod運行狀態,更新CacheServer的狀態。

CacheServer優化

存儲優化

CacheServer使用場景下對數據的讀寫性能要求非常高,arbd數據的持久化存儲需要重點考慮。以往常用的網絡存儲Ceph Rbd等方案無法達到我們的性能要求。因此我們採用宿主機存儲的方案。Kubernetes提供了hostPath、emptyDir、local volume等。

  • hostPath:映射宿主機文件系統中的文件或者目錄到Pod,需要數據清理等管理。local volume需要維護掛載點。本方案採用emptyDir的方式。

  • emptyDir:Pod分配到Node上時被創建,Kubernetes會在Node上自動分配一個目錄,因此無需指定宿主機Node上對應的目錄文件。

  • local volume:通過PVC方式訪問宿主機的本地存儲,但靜態provisioner僅支持發現和管理掛載點,必須將它們通過bind-mounted的方式綁定到發現目錄中。

本方案採用emptyDir的方式,emptyDir數據生命週期與Pod的生命週期是一致的。並設置Pod的QoS等級避免被驅逐,從而高效的管理管理CacheServer數據存儲。

調度優化

CacheServer的資源數據上傳下載會對網絡、磁盤要求很高。爲了避免多個CacheServer集中在一個節點上而相互影響,我們採用了Kubernetes的反親和性特性,將CacheServer Pod進行節點維度的反親和。下面設置CacheServer Pod反親和性:

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - podAffinityTerm:
        labelSelector:
          matchLabels:
             app.kubernetes.io/managed-by: cacheserver-operator
        topologyKey: kubernetes.io/hostname
      weight: 100

節點優化

針對CacheServer的特性,我們需要對宿主機的內核參數,以及硬件設備進行優化升級。

  • 內核參數優化:包括net.ipv4.tcp_sack,net.core.rmem_max,net.core.wmem_max,net.core.wmem_default,net.ipv4.tcp_mem,net.ipv4.tcp_rmem,net.ipv4.tcp_wmem等。

  • 硬件升級:磁盤使用SSD,提升ardb數據的讀寫能力。

未來展望

遊戲雲原生中間件平臺後續將圍繞着全面性、平臺性、高性能、高可靠等繼續推進。核心包括:

  • 支持更多的遊戲中間件上雲,爲遊戲提供更全面支持。

  • 遊戲中間件Operator引擎:將遊戲中間件特點進行抽象,Yaml定義的方式實現遊戲中間件Operator通用特性,幫助快速實現遊戲中間件Operator。

  • 遊戲中間件調度:增加調度的維度,幫助中間件更合理的進行調度。提升資源利用率,和高性能等。

Kubernetes管理員認證(CKA)培訓

本次CKA培訓在上海開班,基於最新考綱,通過線下授課、考題解讀、模擬演練等方式,幫助學員快速掌握Kubernetes的理論知識和專業技能,並針對考試做特別強化訓練,讓學員能從容面對CKA認證考試,使學員既能掌握Kubernetes相關知識,又能通過CKA認證考試,學員可多次參加培訓,直到通過認證。點擊下方圖片或者閱讀原文鏈接查看詳情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章