Higress × OpenKruiseGame 遊戲網關最佳實踐

作者:趙偉基、力銘、澄潭

OpenKruiseGame(下文簡稱:OKG)是一個面向多雲的開源遊戲服 Kubernetes 工作負載,是 CNCF 工作負載開源項目 OpenKruise 在遊戲領域的子項目,其提供了熱更新、原地升級、定向管理等常用的遊戲服管理功能。而遊戲作爲典型的流量密集型場景,在吞吐量、延遲性能、彈性與安全性等方面對入口網關提出了很高的要求。

Higress 是基於阿里內部兩年多的 Envoy 網關實踐沉澱,以開源 Istio 與 Envoy 爲核心構建的下一代雲原生網關。Higress 實現了安全防護網關、流量網關、微服務網關三層網關合一,可以顯著降低網關的部署和運維成本。Higress 可以作爲 K8s 集羣的 Ingress 入口網關,並且兼容了大量 K8s Nginx Ingress 的註解,可以從 K8s Nginx Ingress 快速平滑遷移到 Higress。同時也支持 K8s Gateway API 標準,支持用戶從 Ingress API 平滑遷移到 Gateway API。

本文將演示 Higress 如何無縫對接 OKG 遊戲服,併爲其帶來的優秀特性。

Higress 無縫接入 OKG

前置步驟:

  1. 安裝 OpenKruiseGame [ 1]

  2. 安裝 Higress [ 2]

OKG 提供諸多遊戲服熱更新和遊戲服伸縮的優秀特性,便於遊戲運維人員管理遊戲服的全生命週期。遊戲不同於無狀態類型的服務,玩家戰鬥的網絡流量是不允許被負載均衡的,因此每一個遊戲服需要獨立的訪問地址。

使用原生工作負載(如 Deployment 或 StatefulSet)時,運維工程師需要爲衆多遊戲服一一配置接入層網絡,這無疑阻礙了開服效率,同時手動配置也無形中增加了故障的概率。OKG 提供的 GameServerSet 工作負載可以自動化地管理遊戲服的接入網絡,大幅度降低運維工程師的負擔。

對於 TCP/UDP 網絡遊戲,OKG 提供了諸如 HostPort、SLB、NATGW 等網絡模型;而對於 H5/WebSocket 類型的網絡遊戲,OKG 也相應提供了 Ingress 網絡模型,如 Higress、Nginx、ALB 等。

本文采用了一款開源遊戲 Posio 來構建 demo 遊戲服。下述配置中,IngressClassName="higress" 指定了 Higress 作爲遊戲服的網絡層,Higress 通過下面配置可以無縫接入 Posio 遊戲服,並且可以基於 Annotation 實現 Higress 定義的高階流量治理等功能。示例 Yaml 如下所示,GameServerSet 生成的遊戲服對應的訪問域名與遊戲服 ID 相關。

在此例中,遊戲服 0 的訪問域名爲 game0.postio.example.com,遊戲服 1 的訪問域名爲 game1.postio.example.com. 客戶端以此來訪問不同的遊戲服。

piVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
  name: postio
  namespace: default
spec:
  replicas: 1
  updateStrategy:
    rollingUpdate:
      podUpdatePolicy: InPlaceIfPossible
  network:
    networkType: Kubernetes-Ingress
    networkConf:
    - name: IngressClassName
      value: "higress"
    - name: Port
      value: "5000"
    - name: Path
      value: /
    - name: PathType
      value: Prefix
    - name: Host
      value: game<id>.postio.example.com
  gameServerTemplate:
    spec:
      containers:
        - image: registry.cn-beijing.aliyuncs.com/chrisliu95/posio:8-24
          name: postio

OKG 水平伸縮 [ 3] 提供自動擴容、根據遊戲服的 OpsState 縮容、根據 DeletionPriority 縮容、根據遊戲服序號縮容等功能來支持遊戲運維的業務需求。水平伸縮的特性在給遊戲開發者帶來便利的同時,也對入口網關提出了更高的要求:入口網關必須具備配置熱更新的能力,完成路由配置的平滑下發。

原因在於: 在進行遊戲服的擴容時,OKG 會同步創建 Ingress 等相關網絡相關資源,以此來保障遊戲服的自動上線。如果入口網關不具備配置熱更新的能力,在擴容時就,線上玩家就會遇到連接斷開等問題,影響遊玩體驗。

Nginx reload 無法優雅熱更新

在遊戲服出現擴容,或者定義的路由策略發生變更時,Nginx 的配置變更會觸發 reload,導致上下游的連接都斷開並觸發重連。

我們以 Posio 遊戲服爲例,模擬 Nginx+OKG 在遊戲服擴容時出現的問題。Posio 服務端依賴於 Socket 連接與客戶端通信。遊戲服擴容時,觸發對應的 Ingress 資源創建,此時 Nginx-ingress-controller 監聽到 Ingress 資源變更,觸發自身 reload 機制,此時原來與遊戲服建立的連接(如本例中的 Socket 連接會被斷開)。在正在遊戲的玩家側的體感便是出現了異常卡頓。

爲了直觀的展示 Nginx Ingress reload 帶來的影響,我們對 Nginx 默認配置參數進行一些更改:

kubectl edit configmap nginx-configuration -n kube-system
data:
  ...
  worker-shutdown-timeout: 30s # 一個很難做權衡的配置

Nginx 配置參數中 worker-shutdown-timeout 是 Nginx 的 worker 進程優雅下線的超時配置,worker 進程會先停止接收新的連接,並等待老的連接逐漸關閉,達到超時時間後,纔會去強制關閉當前的所有連接,完成進程退出。

此參數配置過小,會導致大量活躍連接瞬間斷開;而此參數配置過大時,又會導致 websocket 長連接始終維持住 Nginx 進程,當發生頻繁 reload 時會產生大量 shutting down 狀態的 worker 進程,老 worker 佔有的內存遲遲得不到釋放,可能會導致 OOM 引發線上故障:

實際遊玩的測試過程如下:客戶端訪問遊戲服,進行正常遊玩。在此過程中通過 OKG 能力觸發遊戲服擴容,查看此時客戶端的響應。通過網頁開發者工具可以看到,出現了兩條 Socket 連接,一條是原先瀏覽器訪問遊戲服建立,另一條是由於 Nginx 斷連後重連產生的 Socket 連接。

原有連接收到的最後一個包時間戳是 15:10:26。

而新建連接到獲取第一個正常遊戲包的時間是 15:10:37,網頁與遊戲服的斷連大概持續 5s 左右。

除了玩家的遊玩體驗受影響,這個機制也會給業務整體穩定性埋雷。在高併發場景下,因爲連接瞬斷,導致大批量客戶端的併發重連,會導致 Nginx 的 CPU 瞬間飆升;而後端遊戲服務器需要處理更多業務邏輯,一般比網關的資源需求更高,因此 Nginx 透傳過來的大量併發重連,也更容易打垮後端,造成業務雪崩。

Higress 如何實現優雅熱更新

Higress 支持採用 K8s Ingress 暴露遊戲服外部 IP 端口,供玩家連接訪問。當遊戲服伸縮或者定義的路由配置發生變化時,Higress 支持路由配置的熱更新,以此保障玩家連接的穩定性。

Higress 基於 Envoy 的精確配置變更管理,做到了真正的配置動態熱更新。在  Envoy 中 downstream 對應 listener 配置,交由 LDS 實現配置發現;upstream 對應 cluster 配置,交由 CDS 實現配置發現。listener 配置更新重建,只會導致 downstream 連接斷開,不會影響 upstream 的連接;downstream 和 upstream 的配置可以獨立變更,互不影響。再進一步,listener 下的證書(cert),過濾器插件(filter),路由(router)均可以實現配置獨立變更,這樣不論是證書/插件/路由配置變更都不再會引起 downstream 連接斷開。

精確的配置變更機制,除了讓 Envoy 可以實現真正的熱更新,也讓 Envoy 的架構變的更可靠,Envoy 配置管理從設計之初就是爲數據面(DP)和控制面(CP)分離而設計的,因此使用 gRPC 實現遠程配置動態拉取,並藉助 proto 來規範配置字段,並保持版本兼容。這個設計實現了數據面和控制面的安全域隔離,增強了架構的安全性。

使用 OKG 接入 Higress 後,下面依然模擬客戶端訪問遊戲服,進行正常遊玩。在此過程中通過 OKG 能力觸發遊戲服擴容,查看此時客戶端的響應。通過網頁開發者工具可以看到,在此過程中客戶端與遊戲服建立的連接穩定不受影響。

此外,在大規模遊戲服場景下,每個遊戲服對應一個獨立的 Ingress,會產生大量的 Ingress 資源,我們測試在達到 1k 級別規模時,Nginx Ingress 要新擴一個遊戲服需要分鐘級生效,而 Higress 可以在秒級生效。Nginx Ingress 的這一問題也被 Sealos 踩坑,並最終通過切換到 Higress 解決,有興趣可以閱讀這篇文章瞭解:《雲原生網關哪家強:Sealos 網關血淚史》


加入 OKG 和 Higress 開源社區交流

歡迎大家通過搜索羣號進入釘釘羣交流,雲原生遊戲交流羣的釘釘羣號爲:44862615,Higress 社區交流 2 羣的釘釘羣號爲:30735012403

相關鏈接:

[1] OpenKruiseGame

https://openkruise.io/zh/kruisegame/installation/

[2] Higress

https://higress.io/zh-cn/docs/user/quickstart/

[3] OKG 水平伸縮

https://openkruise.io/zh/kruisegame/user-manuals/gameservers-scale/

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