openkruise/kruise-game

Feat: Add GameServerConfig to patch different GameServers different labels/annotations

chrisliu1995 opened this issue · 0 comments

Background

Managing the configuration of game servers is a common issue after game containerization. The configuration of game servers can be presented through labels or annotations in Kubernetes (k8s), and then passed down to the containers using the Downward API for business awareness. However, in scenarios like PvE games or MMORPGs, each game server has its own unique configuration. This means that each game server requires distinct labels or annotations. Generally, the keys of these labels and annotations are the same across different game servers, only the values differ. We need a way to manage the different labels and annotations of different game servers in a batch, automatic, and persistent manner. Therefore, I propose a new custom resource definition (CRD) object called GameServerConfig.

Design

API


type GameServerConfigSpec struct {
	GameServerSetName string            `json:"gameServerSetName"`
	LabelConfigs      []StringMapConfig `json:"labelConfigs,omitempty"`
	AnnotationConfigs []StringMapConfig `json:"annotationConfigs,omitempty"`
}

type StringMapConfig struct {
	Type       StringMapConfigType `json:"type"`
	KeyName    string              `json:"keyName"`
	IdValues   []IdValue           `json:"idValues,omitempty"`
	RenderRule string              `json:"renderRule,omitempty"`
}

type StringMapConfigType string

const (
	SpecifyID StringMapConfigType = "SpecifyID"
	RenderID  StringMapConfigType = "RenderID"
)

type IdValue struct {
	IdList []int  `json:"idList,omitempty"`
	Value  string `json:"value,omitempty"`
}

type GameServerConfig struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   GameServerConfigSpec   `json:"spec,omitempty"`
	Status GameServerConfigStatus `json:"status,omitempty"`
}

type GameServerConfigList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []GameServer `json:"items"`
}

type GameServerConfigState string

const (
	Pending GameServerConfigState = "Pending"
	Succeed GameServerConfigState = "Succeed"
)

type GameServerConfigStatus struct {
	State              GameServerConfigState `json:"state,omitempty"`
	LastTransitionTime metav1.Time           `json:"lastTransitionTime,omitempty"`
}

Example

There are 8 GameServers managed by GameServerSet minecraft. If a GameServerConfig as follow is applied:

	gsc := GameServerConfig{
		Spec: GameServerConfigSpec{
			GameServerSetName: "minecraft",
			LabelConfigs: []StringMapConfig{
				{
					Type:    SpecifyID,
					KeyName: "zone-id",
					IdValues: []IdValue{
						{
							IdList: []int{1, 3, 4},
							Value:  "8001",
						},
						{
							IdList: []int{0, 2, 5},
							Value:  "8002",
						},
						{
							IdList: []int{6},
							Value:  "8003",
						},
						{
							IdList: []int{7},
							Value:  "8004",
						},
					},
				},
			},
			AnnotationConfigs: []StringMapConfig{
				{
					Type:       RenderID,
					KeyName:    "group-name",
					RenderRule: "group-<id>",
				},
			},
		},
	}

The GameServers' labels & annotations will be:

GameServer Name Label Annotation
minecraft-0 zone-id: 8002 group-name: group-0
minecraft-1 zone-id: 8001 group-name: group-1
minecraft-2 zone-id: 8002 group-name: group-2
minecraft-3 zone-id: 8001 group-name: group-3
minecraft-4 zone-id: 8001 group-name: group-4
minecraft-5 zone-id: 8002 group-name: group-5
minecraft-6 zone-id: 8003 group-name: group-6
minecraft-7 zone-id: 8004 group-name: group-7