controllers

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 6, 2022 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	InitContainerName = "initcontainer"

	GameServerKind      = "GameServer"
	GameServerBuildKind = "GameServerBuild"

	DataVolumeName         = "gsdkdata"
	DataVolumeMountPath    = "/gsdkdata"
	DataVolumeMountPathWin = "c:\\gsdkdata"
	RandStringSize         = 5

	LabelBuildID          = "BuildID"
	LabelBuildName        = "BuildName"
	LabelOwningGameServer = "OwningGameServer"
	LabelOwningOperator   = "OwningOperator"
	LabelNodeName         = "NodeName"

	GsdkConfigFile                = DataVolumeMountPath + "/Config/gsdkConfig.json"
	LogDirectory                  = DataVolumeMountPath + "/GameLogs/"
	CertificatesDirectory         = DataVolumeMountPath + "/GameCertificates"
	GameSharedContentDirectory    = DataVolumeMountPath + "/GameSharedContent"
	GsdkConfigFileWin             = DataVolumeMountPathWin + "\\Config\\gsdkConfig.json"
	LogDirectoryWin               = DataVolumeMountPathWin + "\\GameLogs\\"
	CertificatesDirectoryWin      = DataVolumeMountPathWin + "\\GameCertificates"
	GameSharedContentDirectoryWin = DataVolumeMountPathWin + "\\GameSharedContent"

	DaemonSetPort int32 = 56001

	LabelGameServerNode string = "mps.playfab.com/gameservernode"
)
View Source
const (
	ActiveServerStatus       = "active"
	StandingByServerStatus   = "standingby"
	InitializingServerStatus = "initializing"
	PendingServerStatus      = "pending"
)
View Source
const SafeToEvictPodAttribute string = "cluster-autoscaler.kubernetes.io/safe-to-evict"

Variables

View Source
var (
	GameServersCreatedCounter = registry.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "thundernetes",
			Name:      "gameservers_created_total",
			Help:      "Number of GameServers created",
		},
		[]string{"BuildName"},
	)
	GameServersSessionEndedCounter = registry.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "thundernetes",
			Name:      "gameservers_sessionended_total",
			Help:      "Number of GameServer sessions ended",
		},
		[]string{"BuildName"},
	)
	GameServersCrashedCounter = registry.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "thundernetes",
			Name:      "gameservers_crashed_total",
			Help:      "Number of GameServers sessions crashed",
		},
		[]string{"BuildName"},
	)
	GameServersDeletedCounter = registry.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "thundernetes",
			Name:      "gameservers_deleted_total",
			Help:      "Number of GameServers deleted",
		},
		[]string{"BuildName"},
	)
	CurrentGameServerGauge = registry.NewGaugeVec(
		prometheus.GaugeOpts{
			Namespace: "thundernetes",
			Name:      "gameservers_current_state_per_build",
			Help:      "Gameserver gauges by state per build",
		},
		[]string{"BuildName", "state"},
	)
	AllocationsCounter = registry.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "thundernetes",
			Name:      "allocations_total",
			Help:      "Number of GameServers allocations",
		},
		[]string{"BuildName"},
	)
)
View Source
var InitContainerImage string
View Source
var InitContainerImageWin string

Functions

func GetNodeDetails added in v0.4.0

func GetNodeDetails(ctx context.Context, r client.Reader, nodeName string) (string, string, int, error)

GetNodeDetails returns the Public IP of the node and the node age in days if the Node does not have a Public IP, method returns the internal one

func IsNodeReadyAndSchedulable added in v0.3.0

func IsNodeReadyAndSchedulable(node *corev1.Node) bool

IsNodeReadyAndSchedulable returns true if the node is ready and schedulable

func NewGameServerForGameServerBuild

func NewGameServerForGameServerBuild(gsb *mpsv1alpha1.GameServerBuild, portRegistry *PortRegistry) (*mpsv1alpha1.GameServer, error)

NewGameServerForGameServerBuild creates a GameServer for a GameServerBuild

func NewPodForGameServer

func NewPodForGameServer(gs *mpsv1alpha1.GameServer) *corev1.Pod

NewPodForGameServer returns a Kubernetes Pod struct for a specified GameServer Pod has the same name as the GameServer It also sets a label called "GameServer" with the value of the corresponding GameServer resource

Types

type AllocateArgs added in v0.4.0

type AllocateArgs struct {
	SessionID      string   `json:"sessionID"`
	BuildID        string   `json:"buildID"`
	SessionCookie  string   `json:"sessionCookie"`
	InitialPlayers []string `json:"initialPlayers"`
}

AllocateArgs contains information necessary to allocate a GameServer

type AllocationApiServer added in v0.4.0

type AllocationApiServer struct {
	Client client.Client
	// CrtBytes is the PEM-encoded certificate
	CrtBytes []byte
	// KeyBytes is the PEM-encoded key
	KeyBytes []byte
	// contains filtered or unexported fields
}

AllocationApiServer is a helper struct that implements manager.Runnable interface so it can be added to our Manager

func NewAllocationApiServer added in v0.4.0

func NewAllocationApiServer(crt, key []byte, cl client.Client) *AllocationApiServer

func (*AllocationApiServer) Reconcile added in v0.4.0

func (s *AllocationApiServer) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile gets triggered when there is a change on a game server object

func (*AllocationApiServer) SetupWithManager added in v0.4.0

func (s *AllocationApiServer) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the allocation api controller with the manager

func (*AllocationApiServer) Start added in v0.4.0

func (s *AllocationApiServer) Start(ctx context.Context) error

Start starts the HTTP(S) allocation API service if user has provided public/private cert details, it will create a TLS-auth HTTPS server otherwise it will create a HTTP server with no auth

type GameServerBuildReconciler

type GameServerBuildReconciler struct {
	client.Client
	Scheme       *runtime.Scheme
	PortRegistry *PortRegistry
	Recorder     record.EventRecorder
}

GameServerBuildReconciler reconciles a GameServerBuild object

func (*GameServerBuildReconciler) Reconcile

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state. For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile

func (*GameServerBuildReconciler) SetupWithManager

func (r *GameServerBuildReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type GameServerForQueue added in v0.4.0

type GameServerForQueue struct {
	Name            string
	Namespace       string
	BuildID         string
	NodeAge         int
	ResourceVersion string
}

GameServerForQueue is a helper struct that encapsulates all the details we need from a GameServer object in order to store it on the queue

type GameServerQueue added in v0.4.0

type GameServerQueue []*GameServerForQueue

GameServerQueue implements a PriorityQueue for GameServer objects GameServers are sorted in the queue in ascending order based on the NodeAge field this queue is used by the allocation algorithm, to prioritize allocations on the Nodes that are newer based on https://pkg.go.dev/container/heap

func (GameServerQueue) Len added in v0.4.0

func (h GameServerQueue) Len() int

Len returns the number of elements in the heap

func (GameServerQueue) Less added in v0.4.0

func (h GameServerQueue) Less(i, j int) bool

Less returns true if the GameServerForHeap with index i is in a newer Node (smaller NodeAge) compared to the GameServerForHeap with index j

func (*GameServerQueue) Pop added in v0.4.0

func (h *GameServerQueue) Pop() interface{}

Pop pops the top interface{} element off the heap this is written just to help implement the heap interface PopFromQueue should be used instead

func (*GameServerQueue) PopFromQueue added in v0.4.0

func (h *GameServerQueue) PopFromQueue() *GameServerForQueue

PopFromQueue pops the top GameServerForHeap off the heap It should be used instead of heap.Pop

func (*GameServerQueue) Push added in v0.4.0

func (h *GameServerQueue) Push(x interface{})

Push pushes a interface{} element onto the heap this is written just to help implement the heap interface PopFromQueue should be used instead

func (*GameServerQueue) PushToQueue added in v0.4.0

func (h *GameServerQueue) PushToQueue(gs *GameServerForQueue)

PushToQueue pushes a GameServerForHeap onto the heap It should be used instead of heap.Push

func (GameServerQueue) Swap added in v0.4.0

func (h GameServerQueue) Swap(i, j int)

Swap swaps the GameServerForHeap with index i and the GameServerForHeap with index j

type GameServerQueueForBuild added in v0.4.0

type GameServerQueueForBuild struct {
	// contains filtered or unexported fields
}

GameServerQueueForBuild encapsulates a queue of GameServerForQueue for a specific GameServerBuild also contains a map of all the GameServers for that GameServerBuild

func NewGameServersPerBuildQueue added in v0.4.0

func NewGameServersPerBuildQueue() *GameServerQueueForBuild

NewGameServersPerBuildQueue returns a new priority queue for a single GameServerBuild

func (*GameServerQueueForBuild) PopFromQueue added in v0.4.0

func (gsqb *GameServerQueueForBuild) PopFromQueue() *GameServerForQueue

PopFromQueue pops the top GameServerForQueue off the queue

func (*GameServerQueueForBuild) PushToQueue added in v0.4.0

func (gsqb *GameServerQueueForBuild) PushToQueue(gs *GameServerForQueue)

PushToQueue pushes a GameServerForQueue onto the queue

func (*GameServerQueueForBuild) RemoveFromQueue added in v0.4.0

func (gsqb *GameServerQueueForBuild) RemoveFromQueue(namespace, name string)

RemoveFromQueue removes a GameServer from the queue based on the provided namespace/name tuple

type GameServerReconciler

type GameServerReconciler struct {
	client.Client
	Scheme                 *runtime.Scheme
	Recorder               record.EventRecorder
	PortRegistry           *PortRegistry
	GetNodeDetailsProvider func(ctx context.Context, r client.Reader, nodeName string) (string, string, int, error) // we abstract this for testing purposes
}

GameServerReconciler reconciles a GameServer object

func (*GameServerReconciler) Reconcile

func (r *GameServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state. For more details, check Reconcile and its Result here: - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile

func (*GameServerReconciler) SetupWithManager

func (r *GameServerReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type GameServersQueue added in v0.4.0

type GameServersQueue struct {
	// contains filtered or unexported fields
}

GameServersQueue encapsulates a map of GameServersPerBuildHeaps essentially a set of PriorityQueues, one for each GameServerBuild

func NewGameServersQueue added in v0.4.0

func NewGameServersQueue() *GameServersQueue

NewGameServersQueue returns a new GameServersQueue

func (*GameServersQueue) PopFromQueue added in v0.4.0

func (gsq *GameServersQueue) PopFromQueue(buildID string) *GameServerForQueue

PopFromQueue pops the top GameServerForHeap off the queue

func (*GameServersQueue) PushToQueue added in v0.4.0

func (gsq *GameServersQueue) PushToQueue(gs *GameServerForQueue)

PushToQueue pushes a GameServerForQueue onto the queue

func (*GameServersQueue) RemoveFromQueue added in v0.4.0

func (gsq *GameServersQueue) RemoveFromQueue(namespace, name string)

RemoveFromQueue removes a GameServer from the queue based on the provided namespace/name tuple

type MutexMap added in v0.4.0

type MutexMap struct {
	// contains filtered or unexported fields
}

Simple async map implementation using a mutex used to manage the expected GameServer creations and deletions

type PortRegistry

type PortRegistry struct {
	NodeCount        int           // the number of Ready and Schedulable nodes in the cluster
	HostPortsPerNode map[int32]int // a slice for the entire port range. increases by 1 for each registered port
	Min              int32         // Minimum Port
	Max              int32         // Maximum Port
	// contains filtered or unexported fields
}

PortRegistry implements a custom map for the port registry

func NewPortRegistry

func NewPortRegistry(client client.Client, gameServers *mpsv1alpha1.GameServerList, min, max int32, nodeCount int, useSpecificNodePool bool, setupLog logr.Logger) (*PortRegistry, error)

NewPortRegistry initializes the map[port]counter that holds the port registry The way that this works is the following: We keep a map (HostPortsPerNode) of all the port numbers every time a new port is requested, we check if the counter for this port is less than the number of Nodes if it is, we increase it by one. If not, we check the next port. the nextPortNumber facilitates getting the next port (port+1), since getting the same port again would cause the GameServer Pod to be placed on a different Node, to avoid collision. This would have a negative impact in cases where we want as many GameServers as possible on the same Node. We also set up a Kubernetes Watch for the Nodes When a new Node is added or removed to the cluster, we modify the NodeCount variable

func (*PortRegistry) DeregisterServerPorts

func (pr *PortRegistry) DeregisterServerPorts(ports []int32) error

DeregisterServerPorts deregisters all host ports so they can be re-used by additional game servers

func (*PortRegistry) GetNewPort

func (pr *PortRegistry) GetNewPort() (int32, error)

GetNewPort returns and registers a new port for the designated game server One may wonder what happens if two GameServer Pods get assigned the same HostPort The answer is that we will not have a collision, since Kubernetes is pretty smart and will place the Pod on a different Node, to prevent it

func (*PortRegistry) Reconcile added in v0.3.0

func (pr *PortRegistry) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile runs when a Node is created/deleted or the node status changes

func (*PortRegistry) SetupWithManager added in v0.3.0

func (pr *PortRegistry) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager registers the PortRegistry controller with the manager we care to watch for changes in the Node objects, only if they are "Ready" and "Schedulable"

type RequestMultiplayerServerResponse added in v0.4.0

type RequestMultiplayerServerResponse struct {
	IPV4Address string
	Ports       string
	SessionID   string
}

RequestMultiplayerServerResponse contains details that are returned on a successful GameServer allocation call

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL