Skip to main content
A GameServer is the fundamental building block in Agones. It represents a single dedicated game server instance running in your Kubernetes cluster, complete with networking, health checking, and lifecycle management.

GameServer Resource

The GameServer CRD combines Kubernetes Pod management with game-server-specific features:
apiVersion: agones.dev/v1
kind: GameServer
metadata:
  name: simple-game-server
spec:
  ports:
    - name: default
      portPolicy: Dynamic
      containerPort: 7654
      protocol: UDP
  template:
    spec:
      containers:
        - name: simple-game-server
          image: us-docker.pkg.dev/agones-images/examples/simple-game-server:0.41

Lifecycle States

GameServers progress through a well-defined lifecycle. Understanding these states is crucial for building robust game server systems.

State Diagram

State Definitions

Source: pkg/apis/agones/v1/gameserver.go:38-75
1

PortAllocation

When: GameServer has Dynamic or Passthrough port policiesWhat happens: The port allocator assigns host ports from the available poolDuration: Typically milliseconds
2

Creating

When: Before the Pod is createdWhat happens: GameServer controller prepares Pod specification with SDK sidecarDuration: Usually < 1 second
3

Starting

When: Pod is created but not yet scheduledWhat happens: Kubernetes scheduler finds a suitable nodeDuration: Depends on cluster capacity
4

Scheduled

When: Pod has been assigned to a nodeWhat happens: Kubelet pulls images and starts containersDuration: Varies based on image size and node resources
5

RequestReady

When: Game server calls SDK.Ready()What happens: GameServer transitions to Ready and becomes allocatableDuration: Controlled by game server initialization

Port Configuration

Agones provides flexible port management with four port policies:

Port Policies

Source: gameserver.go:77-92
The system automatically allocates an available host port.Configuration:
ports:
  - name: game-port
    portPolicy: Dynamic
    containerPort: 7654
    protocol: UDP
Behavior:
  • hostPort is automatically assigned from the available pool
  • containerPort remains as specified
  • Port mapping is created: hostPortcontainerPort
Best for: Most production deployments
You specify both host and container ports explicitly.Configuration:
ports:
  - name: game-port
    portPolicy: Static
    containerPort: 7654
    hostPort: 7777
    protocol: UDP
Behavior:
  • Both ports are as specified
  • You must ensure the hostPort is available
  • Required for development GameServers (with dev-address annotation)
Best for: Local development, testingSource: gameserver.go:566-568
The containerPort is dynamically set to match the allocated hostPort.Configuration:
ports:
  - name: game-port
    portPolicy: Passthrough
    protocol: UDP
Behavior:
  • System allocates a hostPort
  • containerPort is set to the same value
  • Game server must query SDK for the actual port: SDK.WatchGameServer()
Best for: Game servers that can bind to any portSource: gameserver.go:88-89
No host port is allocated; only the container port is configured.Configuration:
ports:
  - name: game-port
    portPolicy: None
    containerPort: 7654
    protocol: UDP
Behavior:
  • No hostPort mapping is created
  • Only containerPort is configured in the container
  • Useful for non-networked game servers or custom networking
Feature Gate: PortPolicyNoneSource: gameserver.go:90-91

Protocol Support

Agones supports multiple network protocols:
ports:
  - name: tcp-port
    containerPort: 7654
    protocol: TCP
  - name: udp-port
    containerPort: 7655
    protocol: UDP
  - name: dual-port
    containerPort: 7656
    protocol: TCPUDP  # Exposes both TCP and UDP
Source: gameserver.go:124-125

Port Ranges (Alpha)

You can define custom port ranges for better organization:
ports:
  - name: game-port
    range: game-traffic  # Custom range name
    portPolicy: Dynamic
    containerPort: 7654
Feature Gate: PortRanges

Health Checking

Agones monitors GameServer health through SDK callbacks:
spec:
  health:
    disabled: false
    initialDelaySeconds: 5  # Wait before first check
    periodSeconds: 5        # Check every 5 seconds
    failureThreshold: 3     # Unhealthy after 3 failures
Health Check Logic (gameserver.go:414-426):
  • Default period: 5 seconds
  • Default failure threshold: 3 consecutive failures
  • Default initial delay: 5 seconds
  • If Health() is not called within period × failureThreshold, GameServer becomes Unhealthy
Health checking is based on SDK callbacks, not Kubernetes liveness/readiness probes. Your game server must call SDK.Health() periodically.

Counters and Lists (Beta)

Counters and Lists provide flexible capacity tracking for game sessions:

Counters

Track integer values (e.g., player count, room count):
spec:
  counters:
    rooms:
      count: 1        # Current count
      capacity: 100   # Maximum capacity
    sessions:
      count: 0
      capacity: 50
Operations (gameserver.go:1003-1048):
  • UpdateCount(): Increment or decrement
  • UpdateCounterCapacity(): Change maximum capacity
  • Automatically clamped to [0, capacity]

Lists

Track string values (e.g., player IDs, session tokens):
spec:
  lists:
    players:
      capacity: 10
      values:
        - player-123
        - player-456
    rooms:
      capacity: 100
      values: []  # Empty initially
Operations (gameserver.go:1065-1098):
  • AppendListValues(): Add unique values
  • DeleteListValues(): Remove specific values
  • UpdateListCapacity(): Change maximum capacity
  • Maximum capacity: 1000 items per list
Feature Gate: CountsAndLists

SDK Server Configuration

The Agones SDK Server runs as a sidecar and can be configured:
spec:
  sdkServer:
    logLevel: Info     # Info, Debug, Error, or Trace
    grpcPort: 9357     # gRPC API port
    httpPort: 9358     # HTTP API port
Log Levels (gameserver.go:109-121):
  • Info (default): Standard operational messages
  • Debug: Includes debug information
  • Error: Only error messages
  • Trace: Detailed tracing for troubleshooting

Eviction Control

Control whether GameServers can be evicted during node maintenance:
spec:
  eviction:
    safe: Never  # Never, OnUpgrade, or Always
Options (gameserver.go:94-107):
GameServer should run to completion. Blocks both cluster autoscaler scale-down and node upgrades.Best for: Game sessions that cannot be interrupted

Scheduling Strategy

Choose how GameServers are distributed across nodes:
spec:
  scheduling: Packed  # or Distributed
  • Packed (default): Concentrates GameServers on fewer nodes
  • Distributed: Spreads GameServers evenly across nodes
Source: gameserver.go:475-479, gameserver.go:889-912

Working with GameServers

Create a GameServer

kubectl apply -f gameserver.yaml
kubectl get gameserver

Check GameServer Status

kubectl describe gameserver <name>
kubectl get gs <name> -o jsonpath='{.status.state}'

View GameServer Details

# Get connection info
kubectl get gs <name> -o jsonpath='{.status.address}:{.status.ports[0].port}'

# Watch state changes
kubectl get gs <name> -w

# View events
kubectl get events --field-selector involvedObject.kind=GameServer

Delete a GameServer

kubectl delete gameserver <name>
Deleting an Allocated GameServer will forcefully terminate the game session. Use SDK.Shutdown() from within the game server for graceful termination.

Best Practices

Always use health checks

Disable only for testing. Production GameServers should implement health checking.

Call SDK.Ready() explicitly

Don’t rely on automatic readiness. Signal when your game server is fully initialized.

Handle SDK.Shutdown() gracefully

Save game state and close connections before exiting.

Use Dynamic port policy

Simplifies deployment and prevents port conflicts.

Next Steps

Fleets

Learn about managing groups of GameServers

Allocation

Allocate GameServers to players

SDK Integration

Integrate the Agones SDK into your game server

Port Policy Guide

Deep dive into port configuration options

Build docs developers (and LLMs) love