K8s 游戏服务器:通过服务/入口动态转发 Pod 的 TCP 和 UDP



所以在过去的几天里,我试图找到一种方法来动态附加入口名称(如game-1.myapp.com),以解决Kubernetes上Steam专用服务器的TCP和UDP。我附上了下图,说明我是如何计划的,但是我遇到了一些问题。

我可以使用 Kubernetes API 为每个单独的游戏服务器动态创建命名空间、Pod(由有状态集控制)、PVC、服务和入口。每个游戏服务器都位于自己的命名空间中,与其他服务器完全分开。我保证服务器在引擎盖下运行,Pod 也在运行并处于活动状态,日志很好。

当我需要将有状态集服务分配给入口时,我被锁定了,该入口能够使用命名空间的DNS持续回复TCP/UDP流量,该入口路由到集群的入口控制器(在Minikube中;对于生产,应使用ALB/NLB,AFAIK)。

不知何故,我需要一种方法将game-xxxxx.myapp.com引入特定game-xxxxx命名空间的 pod。它们是否会附加端口并不重要。

为此,我可以简单地对 DNS 求解器进行 API 调用myapp.com,并在需要时添加或删除A Records。这似乎没问题,但我发现我可以使用外部DNS(https://github.com/bitnami/charts/tree/master/bitnami/external-dns)根据现有的服务自动为我执行此操作。

我试过了,还没有运气:

设置 NGINX,但我必须为每个服务定义公开的端口。根据他们的文档(https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services),每次修改该ConfigMap并重新创建NGINX pod是矫枉过正的,因为可能会有很多更改,这似乎不可行。另外,我非常怀疑NGINX在重负载下会轻而易举,我发现它更适合Web服务器而不是游戏服务器。

另外,我可能需要一种方法来确保我可以有重复的端口。例如,我无法在NGINX中将相同的28015端口分配给许多其他服务器,即使它们位于不同的命名空间中也是如此。如果我使用 Agones (https://github.com/googleforgames/agones/blob/release-1.9.0/examples/gameserver.yaml) 分配随机端口,在某些时候我可能会用完它们来分配。

特雷菲克

我曾尝试使用Traefik,但没有运气。入口路由允许 TCP/UDP 路由从路由器路由到入口点,然后将其路由到分配的服务。我不太确定这是如何工作的,我尝试为服务设置注释并定义入口点,但它仍然拒绝工作:https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#kind-ingressroutetcp

阿贡斯

Agones 应该适用于游戏服务器,它支持TCPUDP服务端口的协议,但同样,这没有运气。

我已经在图表下面发布了关于事情应该如何运作的信息。我还有以下 YAML 文件,它将创建有状态集、PVC 和服务。您可以清楚地看到我尝试了外部名称设置,因此也许我可以将Minikube IP设置为该名称并能够连接,但又一次没有运气:

Steam 专用服务器工作流程

apiVersion: v1
kind: Service
metadata:
name: rust-service
labels:
game: rust
spec:
# type: ExternalName
# externalName: rust-1.rust.coal.app
# clusterIP: ""
selector:
game: rust
ports:
- name: rust-server-tcp
protocol: TCP
port: 28015
targetPort: 28015
- name: rust-server-udp
protocol: UDP
port: 28015
targetPort: 28015
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rust-server
spec:
selector:
matchLabels:
game: rust
replicas: 1
serviceName: rust-service
template:
metadata:
name: rust-server
labels:
game: rust
spec:
containers:
- name: rust
image: didstopia/rust-server:latest
ports:
- name: rust-server-tcp
protocol: TCP
containerPort: 28015
- name: rust-server-udp
protocol: UDP
containerPort: 28015
volumeClaimTemplates:
- metadata:
name: local-disk
spec:
resources:
requests:
storage: "10Gi"
accessModes: ["ReadWriteOnce"]

编辑:凹凸

旁注!

如果使用/提及入口资源,则是指HTTP/HTTPS流量。


您发布的图表看起来是使用类型LoadBalancerService的好机会。

LoadBalancer类型的服务用于处理外部TCP/UDP流量(第 4 层)。

免責聲明!

此解决方案仅支持一次一个协议,TCPUDP

要将两个协议放在同一个端口上,您需要回退到NodePort类型的Service(将节点上的端口从30000分配到32767)。

您可以通过以下链接阅读有关创建使用NodePort类型服务的云无关负载均衡器的更多信息:

  • Medium.com:为 Kubernetes 应用程序构建自己的云不可知的 tcp udp 负载均衡器

在此设置中,不需要IngressTraefikNginx等控制器,因为它们只是ClientPod之间的额外步骤。

您在YAML定义中已经有的此类LoadBalancer示例(我稍微修改了一下):

apiVersion: v1
kind: Service
metadata:
name: rust-service
labels:
game: rust
spec:
type: LoadBalancer # <-- THE CHANGE
selector:
game: rust
ports:
- name: rust-server-tcp
protocol: TCP
port: 28015
targetPort: 28015

如果您打算将AWS与它的EKS一起使用,请参阅其文档:

  • Docs.aws.amazon.com:EKS:用户指南:入门

可能的设置示例(步骤):

  • 对于每个"游戏-X":
    • 创建namespace"游戏 X 命名空间">
    • 创建deployment"游戏 X 部署">
    • 创建类型LoadBalancer"game-X-"的service,该将指向"game-X-部署">
    • 创建一个DNS记录,将"game-X.com"指向上一步中创建LoadBalancer的 IP。

每个LoadBalancer都有自己的 IP 和与之关联的DNS名称,如下所示:

  • awesome-game.com具有123.123.123.123IP 和端口以连接到28015/TCP
  • magnificent-game.com具有234.234.234.234IP和端口以连接到28015/TCP

我认为这个创建专用 Steam 服务器的中型指南可能会很有用:

  • Medium.com:在 Kubernetes 上部署 Steam 专用服务器
<小时 />

其他资源:

  • Kubernetes.io:文档:概念:服务 网络:服务

因此,正如之前的回复所说,入口用于网络流量。我没有使用入口实现工作设置,但是我已经设法将该服务与NodePort一起使用,并确保使用外部DNS创建DNS记录,该记录将自定义子域名绑定到正确的IP:https://github.com/kubernetes-sigs/external-dns

现在,问题存在于必须创建一个部署的想法之后,等待 Pod 被分配,并确保 pod 坚持使用该节点,或者在节点被耗尽的情况下,以某种方式保留相同的节点 IP(非临时的),只要部署不被删除,它就会继续留在 pod 中。这样,我应该确保在需要现有部署来部署 Pod 时标记节点。

最新更新