iTranslated by AI
Agones: Fleet
Hello, I'm @sugar235711.
This article is for the 3rd day of the "Reading all the source code of OSS I'm interested in by myself and doing something Advent Calendar 2025."
- Overview Edition
- GameServer Edition
- Fleet Edition ← You are here
- GameServerAllocation Edition
- FleetAutoscaler Edition
What is a Fleet?
Here is the Fleet you've been waiting for.
A Fleet is a Custom Resource that represents a collection of GameServers.
Instead of handling GameServers individually, it allows you to manage pre-warmed GameServers collectively. You can perform management tasks like scaling and updates on a per-Fleet basis.
Internally, a Fleet manages GameServerSets, and GameServerSets manage the actual GameServer instances, forming a hierarchical structure. This enables rolling updates and version management similar to Kubernetes Deployments/ReplicaSets/Pods.
Implementation of the Fleet Controller
Let's look at the controller implementation to see how it actually manages GameServers.
The syncFleet method is registered with the WorkQueue, and it operates according to the following workflow:
- Retrieve all GameServerSets within the relevant Namespace.
- Filter GameServerSets that are under the Fleet's management.
- Execute processes according to the deployment Strategy (RollingUpdate/Recreate).
- Calculate the required number of GameServers and compare it with the actual number of replicas.
- Scale up or down the GameServerSet based on the difference.
There are two types of Strategies, and the default is RollingUpdate.
Parent-Child Relationship Management via OwnerReference
The IsControlledBy method is used to determine whether a resource is under the management of a Fleet. This method performs comparisons on a per-UID basis using the OwnerReference mechanism from Kubernetes apimachinery.
References are established using the NewControllerRef method within the respective packages for Fleet → GameServerSet and GameServerSet → GameServer.
OwnerReference is a mechanism for defining parent-child relationships between Kubernetes objects.
- Dependent objects are automatically garbage collected when the parent object is deleted.
- A valid OwnerReference consists of the name and UID of an object in the same Namespace as the dependent object.
- References across Namespaces are not permitted by design.
Thanks to this mechanism, deleting a Fleet results in the sequential deletion of the associated GameServerSets and GameServers, automating the management of the resource lifecycle.
Looking at it this way, the relationship of Fleet → GameServerSet → GameServer is very similar to Deployment → ReplicaSet → Pod. It becomes apparent that Fleet achieves rolling updates by managing multiple generations of GameServerSets.
It differs from a standard Deployment in aspects such as tracking the number of Allocated replicas in line with GameServer status management and handling the RollingUpdate and Garbage Collection logic accordingly.
These processes ensure that GameServers can be updated safely without disrupting active game sessions.
GameServer Details
AllocationOverflow Feature
Finally, let's touch upon AllocationOverflow.
Fleets and GameServerSets have a feature called allocationOverflow.
# Labels and/or Annotations to apply to overflowing GameServers when the number of Allocated GameServers is more
# than the desired replicas on the underlying `GameServerSet`
allocationOverflow:
labels:
mykey: myvalue
version: "" # empty an existing label value
annotations:
otherkey: setthisvalue
During rolling updates or scaling down, older versions of GameServers might remain in an Allocated state (while a game is in progress), leading to a situation where there are more GameServers than specified in the Fleet's Spec.Replicas.
When Status.AllocatedReplicas > Spec.Replicas occurs, the AllocationOverflowController triggers, adding defined labels or annotations to the overflowing GameServers. This allows them to integrate with resources outside of the GameServer itself.
For example, when integrated with the Cluster Autoscaler, you can add the cluster-autoscaler.kubernetes.io/safe-to-evict: "true" label to exclude nodes containing Allocated GameServers from being targeted for scale-down.
allocationOverflow:
labels:
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
Note that disruption control for GameServers can also be adjusted through eviction settings:
Summary
We've explored Fleets. We've seen how they are managed as collections of GameServers using OwnerReference, and that they provide all the necessary features for efficient GameServer management.
Tomorrow, we will look into GameServerAllocation.
Discussion