Learn how to manage groups of GameServers with Fleets and scaling strategies
A Fleet is a high-level abstraction for managing a group of identical GameServers. Similar to Kubernetes Deployments, Fleets provide declarative updates, rolling deployments, and automatic scaling capabilities for game server workloads.
# Get ready countkubectl get fleet simple-fleet -o jsonpath='{.status.readyReplicas}'# Get all status fieldskubectl get fleet simple-fleet -o jsonpath='{.status}' | jq# Watch status changeskubectl get fleet simple-fleet -w
Gradually replaces old GameServers with new ones:Source: fleet.go:156-177
spec: strategy: type: RollingUpdate rollingUpdate: maxSurge: 25% # Max new GameServers to create maxUnavailable: 25% # Max old GameServers to terminate
1
Calculate bounds
Based on maxSurge and maxUnavailable, determine how many GameServers to create/delete per iteration.
2
Create new GameServers
Spin up new GameServers with updated configuration (up to maxSurge).
3
Wait for Ready
Wait for new GameServers to become Ready before proceeding.
4
Delete old GameServers
Remove old non-allocated GameServers (up to maxUnavailable).
5
Repeat
Continue until all GameServers are updated.
Configuration options:
Percentage
Absolute
rollingUpdate: maxSurge: 25% # 25% of replicas maxUnavailable: 25% # Must be 1-99%
Validation (fleet.go:190-201):
Must be between 1% and 99%
Calculated by rounding up
rollingUpdate: maxSurge: 5 # Exactly 5 GameServers maxUnavailable: 3 # Must be >= 1
Validation (fleet.go:190-201):
Must be at least 1
Allocated GameServers are never deleted during a rolling update. Only Ready and Reserved GameServers are replaced.
Define which GameServers are most important to keep during scale-down:Source: fleet.go:71-83
spec: priorities: - type: Counter # Sort by Counter or List key: rooms # Name of the Counter/List order: Ascending # Ascending or Descending - type: List key: players order: Descending
How it works:
Position 0 has highest priority (checked first)
Compares available capacity: Capacity - Count (Counters) or Capacity - len(Values) (Lists)
Ascending: GameServers with less available capacity are removed first
Descending: GameServers with more available capacity are removed first
Impact by scheduling strategy:
Packed
Distributed
Priorities are a tie-breaker within the same node:
Choose least utilized node (fewest GameServers)
Within that node, use priorities to pick GameServer to delete
# Via kubectl rollout (if using Deployment-like workflow)kubectl rollout undo fleet/simple-fleet# Via direct patch (revert to previous template)kubectl patch fleet simple-fleet --type=merge -p "$(cat previous-template.yaml)"
GameServerSet resources are not automatically deleted. Old GameServerSets remain with 0 replicas for rollback purposes.
# Blue fleet (current version)apiVersion: agones.dev/v1kind: Fleetmetadata: name: game-bluespec: replicas: 10 template: metadata: labels: version: blue spec: # ... game server v1 config---# Green fleet (new version)apiVersion: agones.dev/v1kind: Fleetmetadata: name: game-greenspec: replicas: 0 # Scale up when ready to switch template: metadata: labels: version: green spec: # ... game server v2 config
Switch traffic:
# Start green fleetkubectl scale fleet game-green --replicas=10# Wait for readykubectl wait --for=jsonpath='{.status.readyReplicas}'=10 fleet/game-green# Update allocations to prefer greenkubectl patch gameserverallocation ... -p '{"spec":{"selectors":[{"matchLabels":{"version":"green"}}]}}'# Scale down blue when no allocations remainkubectl scale fleet game-blue --replicas=0
# Verify strategy configurationkubectl get fleet <name> -o jsonpath='{.spec.strategy}'# Check if GameServers are allocated (won't be deleted)kubectl get gs -l agones.dev/fleet=<name> -o jsonpath='{.items[*].status.state}'# Force delete old GameServerSet if needed (careful!)kubectl delete gameserverset <old-gss-name>