Kubernetes 在 GKE 上管理許多不同的 UDP 伺服器
我正在嘗試建立一個系統,該系統可以自動啟動和關閉影片遊戲伺服器作為 docker 圖像。在這種情況下,factoriotools/factorio-docker。每個遊戲都是該容器的不同的、不同的單 Pod 部署,因此(在簡化的情況下)需要自己的 IP 地址來偵聽特定的 UDP 埠。負載平衡器是多餘且無關緊要的,而且 Cloud NAT 似乎不容易允許入口流量。
我知道有幾種方法可以讓它發揮作用,兩者都有相當大的妥協:
- 我可以使用 NodePort 服務,而無法控制客戶端需要連接到哪個埠。這是一個問題,因為伺服器將自己註冊到伺服器列表中。
- 我可以使用主機網路。如果我的資訊是正確的,那就需要特權容器,這絕對不好。
- 我也許可以使用 UDP 負載平衡器,但即使它存在並且有效,它也很昂貴。
可能有一些方法可以解決這兩種方法的局限性(第二種方法是讓主機保持短暫的生命並保持防火牆嚴格,它應該大部分都可以嗎?),但我不禁認為有更好的選擇我在官方 kubernetes 文件中找不到描述。traefik 有什麼我不知道的技巧嗎?是否有某種方法可以獲得 MetalLB 的變體,它可以根據需要動態分配公共 IP 地址?
如何讓每個伺服器容器使用特定的 UDP 埠偵聽不同的公共 IP 地址,而不會使過程中的安全性變得不可能?
編輯:
- 埠是可以配置的,只要知道pod啟動前伺服器需要執行在哪個埠上即可。
- 除非我誤解了伺服器文件,否則客戶端需要能夠連接到伺服器正在偵聽的同一埠。在我的情況下,k8s 在應用程序偵聽埠和客戶端連接埠之間的區別是沒有幫助的。
- 解決這個問題,我不想要負載均衡器,因為它對我沒有任何作用。更改 IP 地址無關緊要,系統旨在處理該問題。如果伺服器宕機 15 秒,每個人都將不得不重新連接,然後他們會找到新的 IP 地址。伺服器無法處理同一個遊戲中的多個 Pod,因此永遠不會有多個副本。
- 我剛剛嘗試了一個
NodePort
帶有隨機公共埠的服務(還沒有看到我可以選擇外部埠),我得到了直接連接,但沒有伺服器列表連接。伺服器列表過程首先通過讓伺服器將出站 UDP 流量發送到給定端點來自動檢測如何連接到伺服器。因此,我不僅需要控制入站流量連接到的埠,還需要控制出站流量的路由方式,包括可能使用的任何 NAT。
發布這個社區 wiki 答案是為了為這個問題設置更多的基線方法,而不是給出一個明確的解決方案。
隨意編輯和擴展。
您可以使用
Services
. 有一些選項在某些方面與另一個選項不同:
ClusterIP
:在集群內部 IP 上公開服務。選擇此值使服務只能從集群內訪問。這是預設設置ServiceType
。- NodePort:在每個節點的 IP 上的靜態埠 (the
NodePort
) 上公開服務。ClusterIP
Service 路由到的ServiceNodePort
是自動創建的。您可以NodePort
通過請求從集群外部聯繫服務<NodeIP>:<NodePort>
。- LoadBalancer:使用雲提供商的負載均衡器在外部公開服務。自動創建外部負載均衡器路由到的服務
NodePort
。ClusterIP
- ExternalName :通過返回帶有其值的記錄,將服務映射到
externalName
欄位的內容(例如foo.bar.example.com
) 。CNAME
沒有設置任何類型的代理。
Google Kubernetes Engine
可以在此處找到特定於公開應用程序的文件:特別關注問題中包含的一些要點:
我可以使用 NodePort 服務,而無法控制客戶端需要連接到哪個埠。這是一個問題,因為伺服器將自己註冊到伺服器列表中。
您可以在YAML中指定
NodePort
埠(如或)。Service``nodePort: 32137``nodePort: 30911
您可以將您的應用程序配置為在與以下相同的埠上偵聽
nodePort
:
- 應用程序正在偵聽埠
30000
- 服務使用
nodePort
withport
:30000
(客戶端/使用者應連接到此埠)和 targetPort:30000
。在這種情況下,不會有埠更改。旁注!
預設情況下,
nodePort
埠範圍被GCP
防火牆阻止。您將需要創建一個允許它的規則(或一組規則)。我可以使用主機網路。如果我的資訊是正確的,那就需要特權容器,這絕對不好。
除非有充分的理由,否則我會建議不要使用特權容器。引用官方文件:
特權政策是有意開放的,並且完全不受限制。這種類型的策略通常針對由受信任的特權使用者管理的系統級和基礎架構級工作負載。
埠是可以配置的,只要知道pod啟動前伺服器需要執行在哪個埠上即可。
由於您將擁有大量單曲
Pods
(每個都有單獨的Deployment
),因此您可以對其進行參數化。我的意思是您可以創建一個模板並僅修改清單的一部分(如埠、環境變數等)。您可以將環境變數傳遞給您
Pod
,以便它可以用作命令中的參數。您還可以修改Pod
開頭的命令