When hosting real-time games, there is a need for configuration updates to be handled flawlessly. Suppose commonly used Ingress controllers like Nginx, HAProxy, etc. are used. In that case, we will encounter lost connection issues whenever configuration changes are made, or the game servers are scaled up to meet demands. Due to these reasons, we will have to find a different Ingress controller immune to the issues.

An Ingress controller that is specific to our use case is the Octops Ingress Controller. It was specifically made to work with Real-time Websocket Traffic and is easy to integrate with Agones.

Continuing from my last blog, Deploying GameServers using Agones, we will learn to expose our Agones GameServers to the public internet using an Ingress controller.  

Pre-requisites

  • Kubernetes Environment
  • Agones GameServers
  • Domain Name (pointed towards the Kubernetes cluster)

How Octops Works

Octops is not a complete Ingress controller. It does not carry the traditional abilities of an Ingress controller like Nginx or HAProxy. It needs a secondary Ingress controller to work because it works like an extension which provides websocket support for real-time games (which work with websockets).

Contour Ingress Controller has good support for WebSocket Traffic because it's built on top of Envoy Proxy. Envoy can handle updates smoothly when the game servers and Ingress resources are reconciled by the Octops Controller.

Due to this reason, we will use Octops with Contour Ingress Controller. For more information regarding this issue, please check this discussion in the Octops community.

Routing in Octops

Octops supports two types of routing modes: Domain-based and Path-based.

Routing is a GameServer-scoped configuration. The Agones GameServer Fleet manifest defines routing details for all GameServers running under that particular Fleet. For GameServers that run independently of a Fleet, the routing config is specified in the GameServer manifest.

Domain Routing

Every instance of the game server that has the domain routing mode configured will get its own specific domain (for example: gs1.ktm.octops.example.com)

Example Config:

apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
  name: fly-game-fleet-ktm-1
spec:
  replicas: 3
  template:
    metadata:
      annotations:
        octops-kubernetes.io/ingress.class: "contour" #required for Contour to handle ingress
        octops-projectcontour.io/websocket-routes: "/" #required for Contour to enable websocket
        octops.io/gameserver-ingress-mode: "domain"
        octops.io/gameserver-ingress-domain: "ktm.octops.example.com"
Domain Routing Config

Path-Based

A single domain will be used to expose all game servers that have path-based routing configured. The GameServers will be available in a single domain via specific paths (for example: ktm.Octops .example.com/game-server-name).

Example Config:

apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
  name: fly-game-fleet-ktm-1
spec:
  replicas: 3
  template:
    metadata:
      annotations:
        octops-kubernetes.io/ingress.class: "contour" #required for Contour to handle ingress
        octops-projectcontour.io/websocket-routes: "/{{ .Name }}" #required for Contour to enable websocket for exact path. This is a template that the controller will replace by the name of the game server
        octops.io/gameserver-ingress-mode: "path"
        octops.io/gameserver-ingress-fqdn: ktm.octops.example.com
Path-Based Routing Config

Here is a summarized view of the entire process:

Once a GameServer is created by Agones as a part of a fleet or a standalone GameServer, the Octops controller handles the provisioning of the domain name and the routing depending upon the annotations and metadata specified in the fleet/GameServer configuration.

ℹ️
Interested in learning more about Octops? Check out Octops.io.

The Setup

We will start by installing the Contour Ingress Controller and Octops.

Installing Octops and Contour

Let's create a directory to store our configuration files,

mkdir octops

Now run the command below to deploy the Octops Ingress controller.

kubectl apply -f https://github.com/Octops/gameserver-ingress-controller/blob/main/deploy/install.yaml

To deploy the Contour Ingress controller, use the command below:

kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/release-1.25/examples/render/contour.yaml

After deploying Octops and Contour, we will deploy our existing GameServer Fleet with new configurations. Copy the YAML manifest provided below into a file with the name updated-fleet-spec.yaml inside the Octops directory.

apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
  name: gameserver-fleet
spec:
  strategy:
    type:
      Recreate
  replicas: 1
  template:
    metadata:
      annotations:
        octops-kubernetes.io/ingress.class: "contour"
        octops-projectcontour.io/websocket-routes: "/"
        octops.io/gameserver-ingress-mode: "domain"
        octops.io/gameserver-ingress-domain: "fly.ktm.octops.example.com"
octops"
    spec:
      players:
        initialCapacity: 101
      health:
        initialDelaySeconds: 300
        periodSeconds: 25
      ports:
        - name: dummy-gameserver
          portPolicy: Dynamic
          containerPort: 8818
          protocol: TCP
      container: gameserver-image
      template:
        spec:
          containers:
            - name: fly
              image: example-user/agones-dummy:v1.5
              imagePullPolicy: IfNotPresent
              securityContext:
                allowPrivilegeEscalation: false
              resources:
                requests:
                  cpu: "0m"
                  memory: "0Mi"
                limits:
                  cpu: "1000m"
                  memory: "1000Mi"
Game Server Fleet YAML

Use the following command to deploy the Fleet with updated configuration,

kubectl apply -f updated-fleet-spec.yaml -n agones

Once the Fleet is deployed, we can check for Ingresses, which are automatically made by Octops. We should see the GameServer along with its Ingress URL, IP and Ports!

NAMESPACE		NAME		CLASS		HOSTS			ADDRESS		PORTS		AGE
agones			fly-4c56c44c31ed	<none>		fly-4c56c44c31ed.fly.ktm.octops.example.com	192.168.1.109	80, 443		1h12m
Output of kubectl get Ingress -n agones

Browsing the URL http://fly-4c56c44c31ed.fly.ktm.Octops .example.com, we will be able to access the individual GameServer via the browser.

GameServer Page in Browser

Following the steps above, we exposed our Agones GameServers on the public internet. Now, our game clients can connect to the game servers.

Thank you for reading, please comment below if you have any queries. I  try to update my articles periodically to ensure legibility.