PlanyDocs
Agones Autopilot

Using Agones Autopilot

Applying Agones manifests with no cluster: what is supported and refused, how servers are sized, allocation, sleep, and the Agones SDK.

projects/{project}/locations/{location}/fleets/{fleet}
projects/{project}/locations/{location}/fleetAutoscalers/{autoscaler}
projects/{project}/locations/{location}/gameServers/{game_server}

Applying manifests

apply takes what kubectl apply -f would: one or more YAML documents — Fleet, GameServer and FleetAutoscaler — in any order, across any number of files.

Agones Autopilot → Apply manifests → paste your manifests → Check → Apply

A manifest like Agones' own example runs unchanged:

YAML
apiVersion: agones.dev/v1
kind: Fleet
metadata:
name: lobby
spec:
replicas: 2
template:
spec:
ports:
- name: default
containerPort: 7654
template:
spec:
containers:
- name: lobby
image: .plany.cr//lobby:v1
resources:
requests:
memory: 512Mi
cpu: 500m
---
apiVersion: autoscaling.agones.dev/v1
kind: FleetAutoscaler
metadata:
name: lobby-autoscaler
spec:
fleetName: lobby
policy:
type: Buffer
buffer:
bufferSize: 2
minReplicas: 2
maxReplicas: 20

What an apply does:

  • It is all or nothing. Every document is checked before anything changes, so a file whose third document is refused changes nothing.
  • Applying the same manifest twice changes nothing. Each object comes back as created, updated or unchanged, with its warnings.
  • Changing a fleet's template rolls its servers the way Agones does, within strategy.rollingUpdate's maxSurge and maxUnavailable (25% each unless you say otherwise), or all at once with type: Recreate. An Allocated server is never replaced mid-match; it is replaced once it shuts down.
  • A GameServer with generateName is a new server every time it is applied, as with kubectl create.
  • --dry-run (Check, in the console; validate_only on the API) reports what would change and changes nothing. Terraform runs this check during plan, so a refusal fails the plan rather than half-way through an apply.

In Terraform, an object you remove from the manifest is deleted on the next apply, as kubectl apply --prune would — so renaming a fleet is a new fleet and the old one's deletion.

Names are lower-case letters, digits and hyphens, up to 40 characters, and unique per kind within a project and region. metadata.namespace is kept as a label and returned to the SDK, but nothing is scoped by it.

Choosing a network

New fleets and game servers join the project's default private network unless you pass --vpc (vpc in Terraform and on ApplyManifests). A fleet keeps the network it was created on: applying it again with a different --vpc is refused rather than moving servers players are on. To move one, delete it and apply it again.

What is supported

Anything Autopilot cannot run the way a cluster would is refused by name at apply — Fleet "lobby": spec.template.spec.template.spec.containers[1]: one container per game server is supported — never quietly dropped. A field Autopilot does not recognise is refused too. Fields that mean nothing without a cluster are accepted and listed as warnings.

SupportedRefused
One container per game server, from .plany.cr or any public registryMore than one container, init containers, sidecars, volumes
One port: Dynamic policy, protocol UDP, TCP or TCPUDPStatic and Passthrough ports, hostPort, more than one port, a port range other than the default
command, args, workingDir, literal env, resourcesenv[].valueFrom, envFrom, privileged, added capabilities
Labels, annotations, health, strategy, evictionhostNetwork, hostPID, hostIPC, serviceAccountName
Buffer autoscaling, as a count or a percentageWebhook, Counter and List policies
SDK: Ready, Allocate, Reserve, Shutdown, Health, labels, annotations, GetGameServer, WatchGameServerSDK counters, lists and player tracking; allocationOverflow and priorities
affinity, tolerations, nodeSelector, priorityClassName

Accepted and ignored, with a warning: a fleet's own scheduling (there are no nodes to pack), terminationGracePeriodSeconds (a server is given sixty seconds to stop), restartPolicy (a fleet replaces a server that exits), a container's imagePullPolicy (the image is pinned to a digest when it is applied), its ports, livenessProbe, readinessProbe and startupProbe (use Agones health through the SDK), imagePullSecrets, and the pod's securityContext.

The SDK is always on its standard ports, 9357 and 9358; an sdkServer naming any other port is refused.

A FleetAutoscaler with minReplicas equal to maxReplicas is a fixed-size fleet, and is accepted. A percentage buffer needs minReplicas of at least 1. Deleting an autoscaler leaves its fleet at the size it had; the fleet returns to spec.replicas on its next apply.

Sizing

There are no nodes, so each game server gets a machine of its own, sized from its container's resources:

  • CPU is the limit, or the request where there is no limit, rounded up to whole vCPUs. A server with neither gets one vCPU.
  • Memory is the limit, or the request, plus 256 MiB for the server's own system, and at least 512 MiB.

The server then runs at the smallest machine type that holds both — so a container asking for 2500m and 3Gi runs on a 4 vCPU, 8 GiB machine. A container no machine type can hold is refused at apply, naming the largest there is.

Allocation

A matchmaker allocates a server the way it does on a cluster. Three ways to do it:

Agones' own allocator. allocation.AllocationService/Allocate, from Agones' allocation.proto, over gRPC at api.plany.cloud:443. A matchmaker built on it changes two things and nothing else:

  • The credential. A Plany API key as a bearer token (authorization: Bearer …), instead of a client certificate. Its principal needs agones.allocations.create on the project — a permission that lets a matchmaker's key allocate and do nothing else.
  • The project. A cluster's allocator knows its namespace; this one needs a project. Set the allocation's namespace to your project id (), or send an x-plany-project header.

Multi-cluster allocation, and counter and list selectors, are refused.

The Plany API, or the CLI and console:

Agones Autopilot → lobby → Allocate a server

Selectors are tried in order. Each matches labels — Kubernetes-style match_expressions with In, NotIn, Exists and DoesNotExist work too — and may ask for Allocated servers rather than Ready ones, to put more players into a lobby that has room. Packed (the default) prefers a fleet's oldest servers; Distributed spreads. Labels and annotations on the request are written onto the allocated server, where the game reads them through the SDK.

Two servers can never be allocated to one request, and two requests can never take one server. Nothing matching is RESOURCE_EXHAUSTED, as Agones' allocator answers.

The address and port in the answer are where players connect. They stay the same across a sleep and a wake. Only servers Autopilot runs are ever allocated — never an ordinary Playpute server that happens to carry the same labels.

A buffer of Ready servers is how a lobby stays open: with bufferSize: 2, two servers are always accepting players however many are Allocated to matches. A server can also allocate itself by calling SDK.Allocate() when its match starts, which takes it out of the buffer and makes the fleet start another.

Pay when played

A Ready server nobody has connected to for ten minutes goes to sleep. While asleep it is not charged for CPU or memory, stays Ready, and can still be allocated. Allocating it — or a player connecting to its address — wakes it, and the first connection waits a few seconds while it resumes exactly where it was, with whatever it held in memory.

An allocation answers straight away even when it wakes a server; the response says it did (woken), and players connecting at once simply wait the few seconds.

An Allocated or Reserved server never sleeps, and neither does one Plany cannot tell is empty. A server that wakes is not marked unhealthy for the time it slept.

Change the idle time with an annotation on the Fleet (or standalone GameServer) itself — a duration of at least a minute, or "0" to keep servers awake:

YAML
apiVersion: agones.dev/v1
kind: Fleet
metadata:
name: lobby
annotations:
autopilot.plany.cloud/sleep-after-idle: "30m"
spec:
# ...

A manifest that does not mention it gets the ten-minute default, so nothing needs changing to get sleep.

The Agones SDK

Your game server's SDK client works unchanged. The SDK is served on localhost, gRPC on port 9357 and HTTP on 9358, and AGONES_SDK_GRPC_PORT and AGONES_SDK_HTTP_PORT are set in the container's environment, as on a cluster.

CallWhat happens
Ready()The server becomes Ready: in the buffer, and allocatable.
Allocate()Ready → Allocated, as a self-allocation.
Reserve(seconds)Reserved until the time runs out, then back to Ready.
Shutdown()A fleet's server is deleted and replaced; a standalone server is deleted.
Health()Missing it for longer than health.failureThreshold × health.periodSeconds marks the server Unhealthy.
SetLabel, SetAnnotationStored under agones.dev/sdk-, as Agones does.
GetGameServer, WatchGameServerThe Agones GameServer, including the address players connect to and the labels an allocation wrote.

WatchGameServer sees an allocation as soon as it is made, so a server waiting to be told its match starts does not wait for a poll. Counters, lists and player tracking return an error naming the feature.

Two things differ from a cluster:

  • There is no Kubernetes API inside the game server. Anything that reads or writes Kubernetes objects directly, rather than through the SDK, has nothing to talk to.
  • The game sees connections arriving from Plany's address, not the player's. A game that bans by IP address or passes client addresses to anti-cheat will see the same address for everyone.

Reading what is running

Agones Autopilot → a fleet → its servers, autoscaler, ignored fields and manifest

A fleet reports how many servers it has, how many are Ready (awake or asleep), Allocated and asleep, and how many are still on an earlier template while a rollout replaces them. A game server reports its Agones state — Ready, Allocated, Reserved, Unhealthy and the rest — whether it is asleep, and its address.

Deleting

Agones Autopilot → a fleet → Delete

Deleting a fleet deletes its servers; an Allocated one is left to finish its match first, as Agones does. Deleting one of a fleet's servers makes the fleet replace it.