【问题标题】:K8s Game Servers: Dynamically forward TCP & UDP for Pods via Service/IngressK8s 游戏服务器:通过 Service/Ingress 为 Pod 动态转发 TCP 和 UDP
【发布时间】:2020-11-10 14:32:09
【问题描述】:

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

我可以使用 Kubernetes API 为每个单独的游戏服务器动态创建命名空间、Pod(由 Stateful Sets 控制)、PVC、服务和入口。每个游戏服务器都位于自己的命名空间中,彼此完全分开。我保证服务器在后台运行,Pod 也在运行且处于活动状态,日志很好。

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

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

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

我已经尝试过,还没有运气:

NGINX

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

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

Traefik

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

过去

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

流程

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

Steam Dedicated Server workflow

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"]

编辑:凹凸

【问题讨论】:

    标签: nginx kubernetes traefik agones


    【解决方案1】:

    附注!

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


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

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

    免责声明!

    这个解决方案supports only one当时的协议,或者TCP或者UDP

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

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

    在此设置中,Ingress 不需要像 TraefikNginx 这样的控制器,因为它们只是您的 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
    

    如果您打算将AWSEKS 一起使用,请参阅它的文档:

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

    • 对于每个“游戏-X”:
      • 创建一个namespace“game-X-namespace”
      • 创建一个deployment“game-X-deployment”
      • 创建一个类型为 LoadBalancer“game-X-”的 service,它将指向一个“game-X-deployment”
      • 创建一个DNS记录,将“game-X.com”指向上一步创建的LoadBalancer的IP。

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

    • awesome-game.com,IP 为123.123.123.123,端口连接到28015/TCP
    • magnificent-game.com,IP 为234.234.234.234,端口连接到28015/TCP

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


    其他资源:

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2017-11-28
        • 2017-06-20
        • 2015-11-24
        • 1970-01-01
        • 2021-07-05
        • 2019-11-26
        • 2011-01-19
        • 2018-08-24
        • 2019-10-07
        相关资源
        最近更新 更多