Set Up a Xonotic Game Server with K3s and Agones

Create a Linode account to try this guide with a $ credit.

This guide demonstrates how to install and manage software for a Xonotic server, a free and fast arena shooter game. Resources are deployed on Akamai Cloud using Terraform, an infrastructure-as-code (IaC) tool, and the game server installation is supported by K3s and Agones.

K3s is a lightweight Kubernetes distribution. This tutorial deploys K3s on a single compute instance running the Ubuntu 20.04 LTS Linux distribution and uses it to manage your game server software. Agones is an open-source, Kubernetes-native project specifically designed for managing dedicated game servers, and it is deployed on the K3s installation in this guide. Agones is then used to deploy and manage containers for the Xonotic server software.

Before You Begin

  1. Install Terraform on your local machine or workstation.

  2. Create an Akamai Cloud account if you do not already have one.

  3. Create a Linode personal access token. This token is used later by Terraform to create resources on your Akamai Cloud account.

Configure Terraform

  1. Create a directory for the Terraform project on your workstation:

    Your workstation
    mkdir xonotic
    cd xonotic
  2. Inside the new directory, create a Terraform configuration file named main.tf, and paste in the following code. This code defines a Linode instance type and sets up a firewall.

    Be sure to replace LINODE_REGION on line 47 with a slug for a region (e.g. us-central for the Dallas, TX region) that’s geographically closest to your location. Regions and slugs are listed on the region availability page. Closer locations reduce lag/latency for players on your game server.

    File: main.tf
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    
    # Specify the required Terraform provider
    terraform {
      required_providers {
        linode = {
          source = "linode/linode"
          version = ">= 1.27.0"  # Ensure a version that supports metadata
        }
      }
    }
    # Define variables for sensitive information
    variable "linode_token" {
      description = "Linode API token"
      type        = string
      sensitive   = true
    }
    variable "root_password" {
      description = "Root password for the instance"
      type        = string
      sensitive   = true
    }
    variable "admin_ip" {
      description = "IPv4 address to be used to access the instance"
      type        = string
      sensitive   = true
    }
    
    # Configure the Linode provider
    provider "linode" {
      token = var.linode_token
    }
    
    # Define the cloud-init configuration
    data "template_file" "cloud_init" {
      template = <<EOF
    #cloud-config
    package_update: true
    package_upgrade: true
    
    runcmd:
      - apt update -y
      - apt upgrade -y
    EOF
    }
    # Create a 8GB dedicated Linode instance in Denver
    resource "linode_instance" "my_instance" {
      label     = "xonotic-game-server"
      region    = "LINODE_REGION"
      type      = "g6-dedicated-4"
      image     = "linode/ubuntu20.04"
      root_pass = var.root_password
      booted    = true
      metadata {
        user_data = base64encode(data.template_file.cloud_init.rendered)
      }
    }
    # Create a firewall to allow incoming traffic on port 22 and 7000-8000
    resource "linode_firewall" "my_firewall" {
      label = "xonotic-firewall"
    # Drop everything that is not covered by an explicit rule
      inbound_policy = "DROP"
    # Allow all outbound traffic
      outbound_policy = "ACCEPT"
      # Rule to allow SSH (port 22)
      inbound {
        label    = "allow-ssh"
        action   = "ACCEPT"
        protocol = "TCP"
        ports    = "22"
        ipv4     = [var.admin_ip]
      }
      # Rule to allow custom port range (7000-8000)
      inbound {
        label    = "allow-custom-ports"
        action   = "ACCEPT"
        protocol = "UDP"
        ports    = "7000-8000"
        ipv4     = ["0.0.0.0/0"]
        ipv6     = ["::/0"]
      }
      # Rule to allow Agones port 8080
      inbound {
        label    = "allow-custom-ports"
        action   = "ACCEPT"
        protocol = "TCP"
        ports    = "8080"
        ipv4     = ["0.0.0.0/0"]
        ipv6     = ["::/0"]
      }
      # Associate the firewall with the instance
      linodes = [linode_instance.my_instance.id]
    }
    # Output the instance's IP address
    output "instance_ip" {
      value = linode_instance.my_instance.ip_address
    }
    Note

    Akamai now offers an expanded set of distributed compute regions. Deploying in these regions is currently in limited availability. These regions may include locations that are closer to you than the set of core compute regions.

    To access these regions, contact customer support.

    When deploying in a distributed compute region, note that there is a different list of supported instance types. The recommended distributed instance type for the deployment in this guide is a g6-dedicated-edge-4 dedicated server. The instance type can be updated in your Terraform configuration on line 48 of the main.tf file under the “type” field.

  3. In the xonotic directory, create a file named terraform.tfvars with the following code. Insert your personal access token, create a unique and complex root password, and insert your workstation’s IP address (maintain the /32 suffix after the IP).

    File: terraform.tfvars
    1
    2
    3
    
    linode_token  = "PERSONAL_ACCESS_TOKEN"
    root_password = "LINODE_ROOT_PASSWORD"
    admin_ip = "WORKSTATION_IP_ADDRESS/32"

    If you’re not sure of your IP address, you can use the following command which will return your current public IP address.

    curl http://whatismyip.akamai.com
    
    Caution
    Keep your terraform.tfvars file safe, and never commit it to a public repository.

Create Resources with Terraform

  1. While inside the xonotic directory, initialize Terraform:

    Your workstation
    terraform init

    This command downloads the necessary Linode Terraform provider.

  2. Apply the configuration defined in the previous section of this guide:

    Your workstation
    terraform apply
  3. When prompted to confirm the changes, type yes and hit Enter. Terraform provisions your Linode instance and sets up the firewall.

  4. Once Terraform is finished, it outputs the IP address of your new Linode instance. SSH into the instance as the root user using this IP address:

    Your workstation
    ssh root@LINODE_INSTANCE_IP_ADDRESS

    Enter the root password when prompted, which you defined in the terraform.tfvars file in the previous section of this guide.

  5. Before proceeding with game server software installation, take time to secure your new instance. Make sure to create a limited sudo user, set your timezone, configure your hostname, and harden SSH access.

Install K3s

Once fully deployed and secured, continue your server setup while logged into your instance. First, install K3’s using the following curl command:

Linode SSH session
curl -sfL https://get.k3s.io | sh -

Install Agones on K3s

While logged into your instance, continue your server configuration by installing Agones.

  1. Create a dedicated namespace for Agones, and deploy it to your K3s cluster via the installation YAML file hosted on GitHub:

    Linode SSH session
    kubectl create namespace agones-system
    kubectl apply --server-side -f https://raw.githubusercontent.com/googleforgames/agones/release-1.47.0/install/yaml/install.yaml
  2. Observe the new pods created by Agones:

    Linode SSH session
    kubectl describe --namespace agones-system pods

    You should see output indicating that the Agones pods are running. If the Agones pods are not running yet, wait until they are before proceeding to the next section.

Install Xonotic Game Server on K3s

  1. From your SSH session with your Linode instance, run this command to deploy a container for the Xonotic game server software using Agones:

    Linode SSH session
    kubectl apply -f https://raw.githubusercontent.com/googleforgames/agones/release-1.47.0/examples/xonotic/fleet.yaml
  2. Run this command to observe the newly deployed game server. The watch command will updated every 2 seconds:

    Linode SSH session
    watch kubectl describe gameserver

    Enter Ctrl + C to exit the watch command.

  3. Get a list of your game servers and their IP addresses and ports:

    Linode SSH session
    kubectl get gs

    Make a note of the IP address and port, which is used to configure the Xonotic client software in the next section.

Install and Configure Xonotic Client

  1. If you don’t have it already, download and install the Xonotic client for your workstation’s operating system from https://xonotic.org/. See the Xonotic Forums and FAQ for additional application support, docs, and in-game information.

  2. Launch the Xonotic client and choose the multiplayer game mode.

  3. Enter the IP address and port of your game server in the Address field of the Xonotic client UI, separated by a colon:

     GAME_SERVER_IP_ADDRESS:GAME_SERVER_PORT
    
  4. Click Join! to join the game server.

Clean Up Resources

Follow these steps to remove the software and resources created in this tutorial:

  1. To remove the Xonotic game server, run this kubectl command on your Linode instance:

    Linode SSH session
    kubectl delete -f https://raw.githubusercontent.com/googleforgames/agones/release-1.47.0/examples/xonotic/fleet.yaml
  2. To remove Agones, run this kubectl command on your Linode instance:

    Linode SSH session
    kubectl delete -f https://raw.githubusercontent.com/googleforgames/agones/release-1.47.0/install/yaml/install.yaml
  3. To remove the Linode instance and firewall created by Terraform, run this Terraform command from the xonotic directory on your workstation

    Your workstation
    terraform destroy

This page was originally published on


Your Feedback Is Important

Let us know if this guide was helpful to you.


Join the conversation.
Read other comments or post your own below. Comments must be respectful, constructive, and relevant to the topic of the guide. Do not post external links or advertisements. Before posting, consider if your comment would be better addressed by contacting our Support team or asking on our Community Site.
The Disqus commenting system for Linode Docs requires the acceptance of Functional Cookies, which allow us to analyze site usage so we can measure and improve performance. To view and create comments for this article, please update your Cookie Preferences on this website and refresh this web page. Please note: You must have JavaScript enabled in your browser.