diff --git a/build/Makefile b/build/Makefile index 5f5eb8e91c..d08ca52241 100644 --- a/build/Makefile +++ b/build/Makefile @@ -63,8 +63,11 @@ KIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane # Game Server image to use while doing end-to-end tests GS_TEST_IMAGE ?= us-docker.pkg.dev/agones-images/examples/simple-game-server:0.31 +# Enable all beta feature gates. Keep in sync with `true` (beta) entries in pkg/util/runtime/features.go:featureDefaults +BETA_FEATURE_GATES ?= "CountsAndLists=true&DisableResyncOnSDKServer=true" + # Enable all alpha feature gates. Keep in sync with `false` (alpha) entries in pkg/util/runtime/features.go:featureDefaults -ALPHA_FEATURE_GATES ?= "PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=true&Example=true" +ALPHA_FEATURE_GATES ?= "PlayerAllocationFilter=true&PlayerTracking=true&Example=true" # Build with Windows support WITH_WINDOWS=1 diff --git a/build/includes/sdk.mk b/build/includes/sdk.mk index 17bb9b25df..f220331a1b 100644 --- a/build/includes/sdk.mk +++ b/build/includes/sdk.mk @@ -36,7 +36,7 @@ COMMAND ?= gen SDK_IMAGE_TAG=$(build_sdk_prefix)$(SDK_FOLDER):$(build_sdk_version) DEFAULT_CONFORMANCE_TESTS = ready,allocate,setlabel,setannotation,gameserver,health,shutdown,watch,reserve ALPHA_CONFORMANCE_TESTS = getplayercapacity,setplayercapacity,playerconnect,playerdisconnect,getplayercount,isplayerconnected,getconnectedplayers -# TODO: Move Counter and List tests into ALPHA_CONFORMANCE_TESTS once the they are written for all SDKs +# TODO: Move Counter and List tests into DEFAULT_CONFORMANCE_TESTS once the they are written for all SDKs COUNTS_AND_LISTS_TESTS = getcounter,updatecounter,setcountcounter,setcapacitycounter,getlist,updatelist,addlistvalue,removelistvalue .PHONY: test-sdks test-sdk build-sdks build-sdk gen-all-sdk-grpc gen-sdk-grpc run-all-sdk-command run-sdk-command build-example @@ -168,9 +168,9 @@ run-sdk-conformance-test-node: $(MAKE) run-sdk-conformance-test SDK_FOLDER=node GRPC_PORT=9002 HTTP_PORT=9102 run-sdk-conformance-test-go: - # run without feature flags - $(MAKE) run-sdk-conformance-test SDK_FOLDER=go GRPC_PORT=9001 HTTP_PORT=9101 - # run with feature flags enabled + # run with on-by-default (Beta) feature flags enabled + $(MAKE) run-sdk-conformance-test SDK_FOLDER=go GRPC_PORT=9001 HTTP_PORT=9101 TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) + # run with Alpha and Beta feature flags enabled $(MAKE) run-sdk-conformance-test SDK_FOLDER=go GRPC_PORT=9001 HTTP_PORT=9101 FEATURE_GATES=$(ALPHA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) run-sdk-conformance-test-rust: @@ -184,17 +184,17 @@ run-sdk-conformance-test-rust: DOCKER_RUN_ARGS="$(DOCKER_RUN_ARGS) -e RUN_ASYNC=true" $(MAKE) run-sdk-conformance-test SDK_FOLDER=rust GRPC_PORT=9004 HTTP_PORT=9104 FEATURE_GATES=PlayerTracking=true TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS) run-sdk-conformance-test-csharp: - # run without feature flags - $(MAKE) run-sdk-conformance-test SDK_FOLDER=csharp GRPC_PORT=9005 HTTP_PORT=9105 - # run with feature flags enabled - $(MAKE) run-sdk-conformance-test SDK_FOLDER=csharp GRPC_PORT=9005 HTTP_PORT=9105 FEATURE_GATES=$(ALPHA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) + # run with Beta feature flags enabled + $(MAKE) run-sdk-conformance-test SDK_FOLDER=csharp GRPC_PORT=9005 HTTP_PORT=9105 FEATURE_GATES=$(BETA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) + # run with Alpha feature flags enabled + $(MAKE) run-sdk-conformance-test SDK_FOLDER=csharp GRPC_PORT=9005 HTTP_PORT=9105 FEATURE_GATES=$(ALPHA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS) run-sdk-conformance-test-rest: # (note: the restapi folder doesn't use GRPC_PORT but run-sdk-conformance-no-build defaults it, so we supply a unique value here) - # run without feature flags - $(MAKE) run-sdk-conformance-test SDK_FOLDER=restapi GRPC_PORT=9050 HTTP_PORT=9150 - # run with feature flags enabled - $(MAKE) run-sdk-conformance-test SDK_FOLDER=restapi GRPC_PORT=9050 HTTP_PORT=9150 FEATURE_GATES=$(ALPHA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) + # run with Beta feature flags enabled + $(MAKE) run-sdk-conformance-test SDK_FOLDER=restapi GRPC_PORT=9050 HTTP_PORT=9150 FEATURE_GATES=$(BETA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(COUNTS_AND_LISTS_TESTS) + # run with Alpha feature flags enabled + $(MAKE) run-sdk-conformance-test SDK_FOLDER=restapi GRPC_PORT=9050 HTTP_PORT=9150 FEATURE_GATES=$(ALPHA_FEATURE_GATES) TESTS=$(DEFAULT_CONFORMANCE_TESTS),$(ALPHA_CONFORMANCE_TESTS) $(MAKE) run-sdk-command COMMAND=clean SDK_FOLDER=restapi diff --git a/build/includes/website.mk b/build/includes/website.mk index 3bb6af4858..f28e424bc3 100644 --- a/build/includes/website.mk +++ b/build/includes/website.mk @@ -78,6 +78,7 @@ site-test: # generate site images, if they don't exist site-images: $(site_path)/static/diagrams/gameserver-states.dot.png site-images: $(site_path)/static/diagrams/eviction-decision.dot.png +site-images: ${site_path}/static/diagrams/system-diagram.dot.png site-images: $(site_path)/static/diagrams/gameserver-lifecycle.puml.png site-images: $(site_path)/static/diagrams/gameserver-reserved.puml.png site-images: $(site_path)/static/diagrams/canary-testing.puml.png diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 77bf0fe82a..cee6bcd06b 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -276,7 +276,7 @@ steps: declare -A versionsAndRegions=( [1.27]=us-east1 [1.28]=us-west1 [1.29]=europe-west1 ) # Keep in sync with (the inverse of) pkg/util/runtime/features.go:featureDefaults - featureWithGate="PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=true&DisableResyncOnSDKServer=false&Example=true" + featureWithGate="PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=false&DisableResyncOnSDKServer=false&Example=true" featureWithoutGate="" # Use this if specific feature gates can only be supported on specific Kubernetes versions. diff --git a/install/helm/agones/defaultfeaturegates.yaml b/install/helm/agones/defaultfeaturegates.yaml index 1641eb59f6..3d767ba9f2 100644 --- a/install/helm/agones/defaultfeaturegates.yaml +++ b/install/helm/agones/defaultfeaturegates.yaml @@ -15,15 +15,16 @@ # Default values for feature gates. Keep in sync with pkg/util/runtime/features.go:featureDefaults # Beta features +CountsAndLists: true DisableResyncOnSDKServer: true # Alpha features -CountsAndLists: false GKEAutopilotExtendedDurationPods: false PlayerAllocationFilter: false PlayerTracking: false # Dev features +FeatureAutopilotPassthroughPort: true # Example feature Example: false diff --git a/pkg/apis/agones/v1/gameserver.go b/pkg/apis/agones/v1/gameserver.go index 7b629fcfac..ff944d05e4 100644 --- a/pkg/apis/agones/v1/gameserver.go +++ b/pkg/apis/agones/v1/gameserver.go @@ -123,6 +123,9 @@ const ( // GameServerPodLabel is the label that the name of the GameServer // is set on the Pod the GameServer controls GameServerPodLabel = agones.GroupName + "/gameserver" + // GameServerPortPolicyPodLabel is the label to identify the port policy + // of the pod + GameServerPortPolicyPodLabel = agones.GroupName + "/port" // GameServerContainerAnnotation is the annotation that stores // which container is the container that runs the dedicated game server GameServerContainerAnnotation = agones.GroupName + "/container" diff --git a/pkg/cloudproduct/gke/gke.go b/pkg/cloudproduct/gke/gke.go index 25d0c7921a..a598db0f1f 100644 --- a/pkg/cloudproduct/gke/gke.go +++ b/pkg/cloudproduct/gke/gke.go @@ -155,11 +155,21 @@ func (*gkeAutopilot) ValidateScheduling(ss apis.SchedulingStrategy, fldPath *fie } func (*gkeAutopilot) MutateGameServerPod(gss *agonesv1.GameServerSpec, pod *corev1.Pod) error { + setPassthroughLabel(gss, pod) setPrimaryContainer(pod, gss.Container) podSpecSeccompUnconfined(&pod.Spec) return nil } +// setPassthroughLabel sets the agones.dev/port: "autopilot-passthrough" label to the game server container. +// This will help to back the container port from the allocated port using an objectSelector of this label +// in GameServers that are using Passthrough Port Policy +func setPassthroughLabel(gs *agonesv1.GameServerSpec, pod *corev1.Pod) { + if runtime.FeatureEnabled(runtime.FeatureAutopilotPassthroughPort) && hasPortPolicy(gs, agonesv1.Passthrough) { + pod.ObjectMeta.Labels[agonesv1.GameServerPortPolicyPodLabel] = "autopilot-passthrough" + } +} + // setPrimaryContainer sets the autopilot.gke.io/primary-container annotation to the game server container. // This acts as a hint to Autopilot for which container to add resources to during resource adjustment. // See https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-resource-requests#autopilot-resource-management @@ -223,6 +233,15 @@ func setEvictionNoExtended(ev *agonesv1.Eviction, pod *corev1.Pod) error { return nil } +func hasPortPolicy(gs *agonesv1.GameServerSpec, portPolicy agonesv1.PortPolicy) bool { + for _, p := range gs.Ports { + if p.PortPolicy == portPolicy { + return true + } + } + return false +} + type autopilotPortAllocator struct { minPort int32 maxPort int32 diff --git a/pkg/cloudproduct/gke/gke_test.go b/pkg/cloudproduct/gke/gke_test.go index 622eaae9c3..8b90e49702 100644 --- a/pkg/cloudproduct/gke/gke_test.go +++ b/pkg/cloudproduct/gke/gke_test.go @@ -14,10 +14,12 @@ package gke import ( + "fmt" "testing" "agones.dev/agones/pkg/apis" agonesv1 "agones.dev/agones/pkg/apis/agones/v1" + "agones.dev/agones/pkg/util/runtime" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -222,6 +224,100 @@ func TestPodSeccompUnconfined(t *testing.T) { } } +func TestSetPassthroughLabel(t *testing.T) { + for name, tc := range map[string]struct { + pod *corev1.Pod + wantPod *corev1.Pod + ports []agonesv1.GameServerPort + features string + }{ + "gameserver with with Passthrough port policy adds label to pod": { + features: fmt.Sprintf("%s=true", runtime.FeatureAutopilotPassthroughPort), + + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{}, + }, + }, + ports: []agonesv1.GameServerPort{ + { + Name: "awesome-udp", + PortPolicy: agonesv1.Passthrough, + ContainerPort: 1234, + Protocol: corev1.ProtocolUDP, + }, + }, + wantPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{ + agonesv1.GameServerPortPolicyPodLabel: "autopilot-passthrough", + }, + }, + }, + }, + "gameserver with Static port policy does not add label to pod": { + features: fmt.Sprintf("%s=true", runtime.FeatureAutopilotPassthroughPort), + + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{}, + }, + }, + ports: []agonesv1.GameServerPort{ + { + Name: "awesome-udp", + PortPolicy: agonesv1.Static, + ContainerPort: 1234, + Protocol: corev1.ProtocolUDP, + }, + }, + wantPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{}, + }, + }, + }, + "gameserver, no feature gate, with Passthrough port policy does not add label to pod": { + features: fmt.Sprintf("%s=false", runtime.FeatureAutopilotPassthroughPort), + + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{}, + }, + }, + ports: []agonesv1.GameServerPort{ + { + Name: "awesome-udp", + PortPolicy: agonesv1.Passthrough, + ContainerPort: 1234, + Protocol: corev1.ProtocolUDP, + }, + }, + wantPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + Labels: map[string]string{}, + }, + }, + }, + } { + t.Run(name, func(t *testing.T) { + runtime.FeatureTestMutex.Lock() + defer runtime.FeatureTestMutex.Unlock() + require.NoError(t, runtime.ParseFeatures(tc.features)) + gs := (&autopilotPortAllocator{minPort: 7000, maxPort: 8000}).Allocate(&agonesv1.GameServer{Spec: agonesv1.GameServerSpec{Ports: tc.ports}}) + pod := tc.pod.DeepCopy() + setPassthroughLabel(&gs.Spec, pod) + assert.Equal(t, tc.wantPod, pod) + }) + } +} + func TestSetEvictionNoExtended(t *testing.T) { emptyPodAnd := func(f func(*corev1.Pod)) *corev1.Pod { pod := &corev1.Pod{ diff --git a/pkg/gameserversets/controller_test.go b/pkg/gameserversets/controller_test.go index bb1b09ff2c..c5ccb04b18 100644 --- a/pkg/gameserversets/controller_test.go +++ b/pkg/gameserversets/controller_test.go @@ -340,6 +340,8 @@ func TestComputeStatus(t *testing.T) { Count: 30, Capacity: 55, }, + Counters: map[string]agonesv1.AggregatedCounterStatus{}, + Lists: map[string]agonesv1.AggregatedListStatus{}, } assert.Equal(t, expected, computeStatus(list)) diff --git a/pkg/util/runtime/features.go b/pkg/util/runtime/features.go index 76aca57fa0..486d64ea50 100644 --- a/pkg/util/runtime/features.go +++ b/pkg/util/runtime/features.go @@ -31,16 +31,19 @@ const ( //////////////// // Beta features - //////////////// - // Alpha features - - // FeatureCountsAndLists is a feature flag that enables/disables counts and lists feature + // FeatureCountsAndLists is a feature flag that enables counts and lists feature // (a generic implenetation of the player tracking feature). FeatureCountsAndLists Feature = "CountsAndLists" + //////////////// + // Alpha features + // FeatureDisableResyncOnSDKServer is a feature flag to enable/disable resync on SDK server. FeatureDisableResyncOnSDKServer Feature = "DisableResyncOnSDKServer" + //////////////// + // Alpha features + // FeatureGKEAutopilotExtendedDurationPods enables the use of Extended Duration pods // when Agones is running on Autopilot. Available on 1.28+ only. FeatureGKEAutopilotExtendedDurationPods = "GKEAutopilotExtendedDurationPods" @@ -55,6 +58,9 @@ const ( //////////////// // Dev features + // FeatureAutopilotPassthroughPort is a feature flag that enables/disables Passthrough Port Policy. + FeatureAutopilotPassthroughPort Feature = "PassthroughPortPolicy" + //////////////// // Example feature @@ -83,27 +89,30 @@ var ( // * move from `false` to `true` in `featureDefaults`. // * move from `false` to `true` in install/helm/agones/defaultfeaturegates.yaml // * remove from `ALPHA_FEATURE_GATES` in build/Makefile + // * add to `BETA_FEATURE_GATES` in build/Makefile // * invert in the e2e-runner config in cloudbuild.yaml // * change the value in site/content/en/docs/Guides/feature-stages.md. // * Ensure that the features in each file are organized categorically and alphabetically. // // To promote a feature from beta->GA: // * remove all places consuming the feature gate and fold logic to true - // * consider cleanup - often folding a gate to true allows refactoring + // * consider cleanup - often folding a gate to true allows refactoring // * invert the "new alpha feature" steps above + // * remove from `BETA_FEATURE_GATES` in build/Makefile // // In each of these, keep the feature sorted by descending maturity then alphabetical featureDefaults = map[Feature]bool{ // Beta features + FeatureCountsAndLists: true, FeatureDisableResyncOnSDKServer: true, // Alpha features - FeatureCountsAndLists: false, FeatureGKEAutopilotExtendedDurationPods: false, FeaturePlayerAllocationFilter: false, FeaturePlayerTracking: false, // Dev features + FeatureAutopilotPassthroughPort: true, // Example feature FeatureExample: false, diff --git a/site/content/en/docs/Advanced/system-diagram.md b/site/content/en/docs/Advanced/system-diagram.md new file mode 100644 index 0000000000..24fe2fdfcb --- /dev/null +++ b/site/content/en/docs/Advanced/system-diagram.md @@ -0,0 +1,49 @@ +--- +title: "System Diagram" +date: 2024-04-18 +weight: -100 +description: > + A pictoral overview of the Agones component relationships. +--- + +![System Diagram](../../../diagrams/system-diagram.dot.png) + +# Agones Control Plane + +The Agones Control Plane consists of 4 `Deployments`: +``` +NAME READY UP-TO-DATE AVAILABLE AGE +agones-allocator 3/3 3 3 40d +agones-controller 2/2 2 2 40d +agones-extensions 2/2 2 2 40d +agones-ping 2/2 2 2 40d +``` + +## `agones-allocator` + +`agones-allocator` provides a gRPC/REST service that translates allocation requests into `GameServerAllocations`. See [Allocator Service]({{< relref "allocator-service.md">}}) for more information. + +## `agones-controller` + +`agones-controller` maintains various control loops for all Agones CRDs (`GameServer`, `Fleet`, etc.). A single leader-elected `Pod` of the `Deployment` +is active at any given time (see [High Availability]({{< relref "high-availability-agones.md">}})). + +## `agones-extensions` + +`agones-extensions` is the endpoint for: +* Agones-installed Kubernetes webhooks, which handle defaulting and validation for Agones CRs, +* and the `GameServerAllocation` `APIService`, which handles `GameServer` allocations (either from the Allocator Service or the Kubernetes API). + +## `agones-ping` (not pictured) + +`agones-ping` is a simple ping service for latency testing from your game client - see [Latency Testing]({{< relref "ping-service.md">}}). + +# Agones CRDs + +See [Create a Game Server]({{< relref "create-gameserver.md">}}), [Create a Game Server]({{< relref "create-fleet.md">}}) for examples of Agones CRDs in action, or the [API Reference]({{< ref "/docs/Reference" >}}) for more detail. + +All of the Agones CRDs are controlled and updated by `agones-controller`. `GameServer` is additionally updated by the SDK Sidecar and `agones-extensions` (moving a `GameServer` from [`Ready` to `Allocated`]({{< ref "/docs/Reference/gameserver.md#gameserver-state-diagram" >}}) + +# Game Server Pod + +Also pictured is an example `Pod` owned by a `GameServer`. Game clients typically connect to the Dedicated Game Server directly, or via a proxy like [Quilkin](https://googleforgames.github.io/quilkin/main/book/introduction.html). The game server server interfaces with Agones using the [Client SDK]({{< relref "Client SDKs">}}), which is a thin wrapper around the [SDK gRPC protocol](https://github.com/googleforgames/agones/blob/main/proto/sdk/sdk.proto). The SDK connects to the SDK Sidecar (`sdk-server`) in the same Pod, which handles the SDK business logic for e.g. [health checks]({{< relref "health-checking.md">}}), [Counters and Lists]({{< relref "counters-and-lists.md">}}), etc. \ No newline at end of file diff --git a/site/content/en/docs/Guides/feature-stages.md b/site/content/en/docs/Guides/feature-stages.md index 16650e4165..aa7b4e5688 100644 --- a/site/content/en/docs/Guides/feature-stages.md +++ b/site/content/en/docs/Guides/feature-stages.md @@ -24,6 +24,7 @@ that can be found in the [Helm configuration]({{< ref "/docs/Installation/Instal The current set of `alpha` and `beta` feature gates: +{{% feature expiryVersion="1.41.0" %}} | Feature Name | Gate | Default | Stage | Since | |-----------------------------------------------------------------------------------------------------------------------------|------------------------------------|----------|---------|--------| | [DisableResyncOnSDKServer](https://github.com/googleforgames/agones/issues/3377) | `DisableResyncOnSDKServer` | Enabled | `Beta` | 1.40.0 | @@ -34,7 +35,19 @@ The current set of `alpha` and `beta` feature gates: | Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 | [fleet-updates]: {{% relref "./fleet-updates.md#notifying-gameservers-on-fleet-updatedownscale" %}} +{{% /feature %}} +{{% feature publishVersion="1.41.0" %}} +| Feature Name | Gate | Default | Stage | Since | +|-----------------------------------------------------------------------------------------------------------------------------|------------------------------------|----------|---------|--------| +| [CountsAndLists](https://github.com/googleforgames/agones/issues/2716) | `CountsAndLists` | Enabled | `Beta` | 1.41.0 | +| [DisableResyncOnSDKServer](https://github.com/googleforgames/agones/issues/3377) | `DisableResyncOnSDKServer` | Enabled | `Beta` | 1.40.0 | +| [Support for Extended Duration Pods on GKE Autopilot (*1.28+ only*)](https://github.com/googleforgames/agones/issues/3386) | `GKEAutopilotExtendedDurationPods` | Disabled | `Alpha` | 1.37.0 | +| [GameServer player capacity filtering on GameServerAllocations](https://github.com/googleforgames/agones/issues/1239) | `PlayerAllocationFilter` | Disabled | `Alpha` | 1.14.0 | +| [Player Tracking]({{< ref "/docs/Guides/player-tracking.md" >}}) | `PlayerTracking` | Disabled | `Alpha` | 1.6.0 | +| Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 | +[fleet-updates]: {{% relref "./fleet-updates.md#notifying-gameservers-on-fleet-updatedownscale" %}} +{{% /feature %}} {{< alert title="Note" color="info" >}} If you aren't sure if Feature Flags have been set correctly, have a look at the diff --git a/site/content/en/docs/Installation/Creating Cluster/gke.md b/site/content/en/docs/Installation/Creating Cluster/gke.md index 05b266b68c..86a3da9648 100644 --- a/site/content/en/docs/Installation/Creating Cluster/gke.md +++ b/site/content/en/docs/Installation/Creating Cluster/gke.md @@ -165,7 +165,7 @@ We need a firewall to allow UDP traffic to nodes tagged as `game-server` via por next section. ```bash -gcloud compute firewall-rules create game-server-firewall \ +gcloud compute firewall-rules create gke-agones-game-server-firewall \ --allow udp:7000-8000 \ --target-tags game-server \ --description "Firewall to allow game server udp traffic" @@ -176,6 +176,31 @@ gcloud compute firewall-rules create game-server-firewall \ Create a GKE cluster in which you'll install Agones. You can use [GKE Standard mode](#create-a-standard-mode-cluster-for-agones) or [GKE Autopilot mode](#create-an-autopilot-mode-cluster-for-agones). +You can read more about choosing a [cluster mode above](#choosing-a-gke-cluster-mode). + +### Create an Autopilot mode cluster for Agones + +1. Choose a [Release Channel]({{}}) (Autopilot clusters must be on a Release Channel). + +1. Create the cluster: + + ```bash + gcloud container clusters create-auto [CLUSTER_NAME] \ + --region=[COMPUTE_REGION] \ + --release-channel=[RELEASE_CHANNEL] \ + --autoprovisioning-network-tags=game-server + ``` + +Replace the following: +* `[CLUSTER_NAME]`: The name of your cluster. +* `[COMPUTE_REGION]`: the GCP region to create the cluster in. +* `[RELEASE_CHANNEL]`: one of `rapid`, `regular`, or `stable`, chosen [above](#choosing-a-release-channel-and-optional-version). The default is `regular`. + +Flag explanations: +* `--region`: The compute region [you chose above](#choosing-a-gke-cluster-mode). +* `--release-channel`: The release channel [you chose above](#choosing-a-release-channel-and-optional-version). +* `--autoprovisioning-network-tags`: Defines the tags that will be attached to new nodes in the cluster. This is to grant access through ports via the [firewall created above](#creating-the-firewall). + ### Create a Standard mode cluster for Agones @@ -292,35 +317,6 @@ Flag explanations: * `--machine-type`: The type of machine to use for nodes. Default: `e2-standard-4`. Depending on the needs of your game, you may wish to [have smaller or larger machines](https://cloud.google.com/compute/docs/machine-types). * `--num-nodes`: The number of nodes per cluster zone. For regional clusters, `--num-nodes=1` creates one node in 3 separate zones in the region, giving you faster recovery time in the event of a node failure. -### Create an Autopilot mode cluster for Agones - -{{}} -These installation instructions apply to Agones 1.30+ -{{}} - -1. Choose a [Release Channel]({{}}) (Autopilot clusters must be on a Release Channel). - -1. Create the cluster: - - ```bash - gcloud container clusters create-auto [CLUSTER_NAME] \ - --region=[COMPUTE_REGION] \ - --release-channel=[RELEASE_CHANNEL] \ - --autoprovisioning-network-tags=game-server - ``` - -Replace the following: -* `[CLUSTER_NAME]`: The name of your cluster. -* `[COMPUTE_REGION]`: the GCP region to create the cluster in. -* `[RELEASE_CHANNEL]`: one of `rapid`, `regular`, or `stable`, chosen [above](#choosing-a-release-channel-and-optional-version). The default is `regular`. - -Flag explanations: -* `--region`: The compute region [you chose above](#choosing-a-gke-cluster-mode). -* `--release-channel`: The release channel [you chose above](#choosing-a-release-channel-and-optional-version). -* `--autoprovisioning-network-tags`: Defines the tags that will be attached to new nodes in the cluster. This is to grant access through ports via the [firewall created above](#creating-the-firewall). - - - ## Setting up cluster credentials `gcloud container clusters create` configurates credentials for `kubectl` automatically. If you ever lose those, run: diff --git a/site/layouts/partials/hooks/body-end.html b/site/layouts/partials/hooks/body-end.html index 49462715aa..e1e9c58f01 100644 --- a/site/layouts/partials/hooks/body-end.html +++ b/site/layouts/partials/hooks/body-end.html @@ -1 +1,12 @@ + + + + diff --git a/site/layouts/shortcodes/gs-prerequisites.html b/site/layouts/shortcodes/gs-prerequisites.html index b7207ae871..e02e257498 100644 --- a/site/layouts/shortcodes/gs-prerequisites.html +++ b/site/layouts/shortcodes/gs-prerequisites.html @@ -2,7 +2,7 @@ {{- $test := eq (.Get "link_test") "true" | default true }}

The following prerequisites are required to create a GameServer:

    -
  1. A Kubernetes cluster with the UDP port range 7000-8000 open on each node.
  2. +
  3. A Kubernetes cluster with the UDP port range 7000-8000 open on each node. Creating the firewall.
  4. Agones controller installed in the targeted cluster
  5. kubectl properly configured
  6. Netcat which is already installed on most Linux/macOS distributions, for windows you can use WSL.
  7. diff --git a/site/static/diagrams/allocation-player-capacity.puml b/site/static/diagrams/allocation-player-capacity.puml index e22b8539f5..ade1158e99 100644 --- a/site/static/diagrams/allocation-player-capacity.puml +++ b/site/static/diagrams/allocation-player-capacity.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + 'https://plantuml.com/sequence-diagram actor "Player One" as Player1 diff --git a/site/static/diagrams/allocation-player-capacity.puml.png b/site/static/diagrams/allocation-player-capacity.puml.png index 5242c560f8..0f1110858a 100644 Binary files a/site/static/diagrams/allocation-player-capacity.puml.png and b/site/static/diagrams/allocation-player-capacity.puml.png differ diff --git a/site/static/diagrams/canary-testing.puml b/site/static/diagrams/canary-testing.puml index 633d5ab405..d175c9a529 100644 --- a/site/static/diagrams/canary-testing.puml +++ b/site/static/diagrams/canary-testing.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + 'https://plantuml.com/sequence-diagram participant Matchmaker diff --git a/site/static/diagrams/canary-testing.puml.png b/site/static/diagrams/canary-testing.puml.png index 7d503d99e9..3fd13cc4da 100644 Binary files a/site/static/diagrams/canary-testing.puml.png and b/site/static/diagrams/canary-testing.puml.png differ diff --git a/site/static/diagrams/eviction-decision.dot b/site/static/diagrams/eviction-decision.dot index 00d2a1f0d7..b7b6cb3a8a 100644 --- a/site/static/diagrams/eviction-decision.dot +++ b/site/static/diagrams/eviction-decision.dot @@ -1,3 +1,17 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + digraph { graph [fontname = "helvetica", ordering="out"]; node [fontname = "helvetica"]; diff --git a/site/static/diagrams/gameserver-lifecycle.puml b/site/static/diagrams/gameserver-lifecycle.puml index 28be21598c..c1cd8908b4 100644 --- a/site/static/diagrams/gameserver-lifecycle.puml +++ b/site/static/diagrams/gameserver-lifecycle.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + participant Matchmaker participant "Kubernetes API" as K8sAPI participant Agones diff --git a/site/static/diagrams/gameserver-lifecycle.puml.png b/site/static/diagrams/gameserver-lifecycle.puml.png index c0bbe59052..1a7704f1e9 100644 Binary files a/site/static/diagrams/gameserver-lifecycle.puml.png and b/site/static/diagrams/gameserver-lifecycle.puml.png differ diff --git a/site/static/diagrams/gameserver-reserved.puml b/site/static/diagrams/gameserver-reserved.puml index 0c67045a00..4e30a4277f 100644 --- a/site/static/diagrams/gameserver-reserved.puml +++ b/site/static/diagrams/gameserver-reserved.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + participant Matchmaker participant Agones participant "Game Server\nProcess" as Binary diff --git a/site/static/diagrams/gameserver-reserved.puml.png b/site/static/diagrams/gameserver-reserved.puml.png index 95ab206189..6b1e908228 100644 Binary files a/site/static/diagrams/gameserver-reserved.puml.png and b/site/static/diagrams/gameserver-reserved.puml.png differ diff --git a/site/static/diagrams/gameserver-states.dot b/site/static/diagrams/gameserver-states.dot index 992eb88904..6fc5b726ee 100644 --- a/site/static/diagrams/gameserver-states.dot +++ b/site/static/diagrams/gameserver-states.dot @@ -1,3 +1,17 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + digraph { graph [fontname = "helvetica"]; node [fontname = "helvetica"]; diff --git a/site/static/diagrams/gameserver-states.dot.png b/site/static/diagrams/gameserver-states.dot.png index 52a2a7e412..013ea148d1 100644 Binary files a/site/static/diagrams/gameserver-states.dot.png and b/site/static/diagrams/gameserver-states.dot.png differ diff --git a/site/static/diagrams/high-density.puml b/site/static/diagrams/high-density.puml index 1bdf64842c..017b9f010d 100644 --- a/site/static/diagrams/high-density.puml +++ b/site/static/diagrams/high-density.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + participant Matchmaker participant Agones participant "Game Server\nProcess" as Binary diff --git a/site/static/diagrams/high-density.puml.png b/site/static/diagrams/high-density.puml.png index 96fb3ff913..16a376422d 100644 Binary files a/site/static/diagrams/high-density.puml.png and b/site/static/diagrams/high-density.puml.png differ diff --git a/site/static/diagrams/reusing-gameservers.puml b/site/static/diagrams/reusing-gameservers.puml index 00dfc77ca0..02e6605a5c 100644 --- a/site/static/diagrams/reusing-gameservers.puml +++ b/site/static/diagrams/reusing-gameservers.puml @@ -1,4 +1,20 @@ @startuml +/' +Copyright 2024 Google LLC All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +'/ + participant Matchmaker participant Agones participant "Game Server\nProcess" as Binary diff --git a/site/static/diagrams/reusing-gameservers.puml.png b/site/static/diagrams/reusing-gameservers.puml.png index 3630ffc6a8..83b7f4c145 100644 Binary files a/site/static/diagrams/reusing-gameservers.puml.png and b/site/static/diagrams/reusing-gameservers.puml.png differ diff --git a/site/static/diagrams/system-diagram.dot b/site/static/diagrams/system-diagram.dot new file mode 100644 index 0000000000..155edd8d8a --- /dev/null +++ b/site/static/diagrams/system-diagram.dot @@ -0,0 +1,179 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +digraph { + compound=true + graph [fontname = "helvetica", style="rounded", nodesep=0.2, newrank="true"] + node [fontname = "helvetica", shape="box3d"] + edge [fontname = "helvetica", pad="0.2", penwidth="2"] + + subgraph cluster_invisible_margin0 { + style="invis" + graph[margin=20] + rank="source" + + GameFrontEnd [ label= "game front end" ] + } + + subgraph cluster_invisible_margin1 { + style="invis" + graph[margin=20] + rank="same" + // rank="source" + + subgraph cluster_acp { + label="Agones Control Plane" + graph[margin=4, style="rounded"] + + subgraph cluster_allocator { + label="agones-allocator Deployment"; + rank="same" + + AllocatorN [ label = "agones-allocator\nreplica N", style="filled" ] + Allocator1 [ label = "agones-allocator\nreplica 1", style="filled" ] + } + subgraph cluster_controller { + label="agones-controller Deployment"; + rank="same" + + ControllerSpare [ label = "agones-controller\nspare", style="filled" ] + Controller [ label = "agones-controller\nleader", style="filled" ] + } + subgraph cluster_extensions { + label="agones-extensions Deployment"; + rank="same" + + ExtensionsN [ label = "agones-extensions\nreplica N", style="filled" ] + Extensions1 [ label = "agones-extensions\nreplica 1", style="filled" ] + } + } + } + + GameFrontEnd -> AllocatorN + GameFrontEnd -> Allocator1 + + subgraph cluster_invisible_margin2 { + style="invis" + graph[margin=20] + + subgraph cluster_kcp { + label="Kubernetes Control Plane" + graph[margin=4, style="rounded"] + node[shape="note"] + + subgraph cluster_agones_crds { + label="Agones CRDs" + rank="same" + + subgraph cluster_fleet { + label="Fleet" + + subgraph cluster_gss_2 { + label="GameServerSet 2" + graph[style=rounded] + + GameServer3 [ label = "GameServer\ngame-server-3" ] + } + + subgraph cluster_gss_1 { + label="GameServerSet 1" + graph[style=rounded] + + GameServer2 [ label = "GameServer\ngame-server-2" ] + GameServer1 [ label = "GameServer\ngame-server-1" ] + } + } + } + subgraph cluster_pods { + label="Pods" + rank="same" + + Pod1 [ label = "game-server-1" ] + Pod2 [ label = "game-server-2" ] + Pod3 [ label = "game-server-3" ] + } + GameServer1 -> Pod1 [ style="dotted" ] + GameServer2 -> Pod2 [ style="dotted" ] + GameServer3 -> Pod3 [ style="dotted" ] + } + } + + subgraph cluster_invisible_key { + style="invis" + graph[margin=20, nodesep=1] + + subgraph cluster_key_top { + style="invis" + + k8s_top [ label="", style="invis" ] + gsa_top [ label="", style="invis" ] + sdk_top [ label="", style="invis" ] + control_top [ label="", style="invis" ] + + KubeResource [label="kubernetes\nresource", shape="note" ] + } + + subgraph cluster_key_bottom { + k8s_bottom [label="", style="invis"] + gsa_bottom [ label="", style="invis" ] + sdk_bottom [label="", style="invis"] + control_bottom [label="", style="invis"] + + Container [style="filled"] + } + + KubeResource -> Container [ style="invis" ] + k8s_top -> k8s_bottom [ color="blue", label="K8s" ] + gsa_top -> gsa_bottom [ color="green", label="Allocations" ] + sdk_top -> sdk_bottom [ color="red", label="SDK\ngRPC" ] + control_top -> control_bottom [ style="dotted", label="controls" ] + + } + + subgraph cluster_invisible_margin3 { + style="invis" + graph[margin=0] + rank="sink" + + subgraph cluster_pod { + label="Pod game-server-1 runtime" + graph[margin=4, style="rounded"] + + SDKServer [ label = "sdk-server\nSDK Sidecar", style="filled" ] + GameServerContainer [ label = "dedicated\ngame server", style="filled" ] + GameServerContainer -> SDKServer [ color="red" ] + } + + GameClient [ label="game client" ] + GameClient -> GameServerContainer + + // force position using invisible edges + k8s_bottom -> SDKServer [ style="invis" ] + gsa_bottom -> SDKServer [ style="invis" ] + sdk_bottom -> SDKServer [ style="invis" ] + control_bottom -> SDKServer [ style="invis" ] + Container -> SDKServer[ style="invis" ] + } + + GameServer1 -> Extensions1 [ ltail="cluster_kcp", color="blue" ] + GameServer1 -> ExtensionsN [ ltail="cluster_kcp", color="blue" ] + GameServer1 -> Extensions1 [ ltail="cluster_kcp", color="green", constraint=false ] + GameServer1 -> ExtensionsN [ ltail="cluster_kcp", color="green", constraint=false ] + Controller -> GameServer1 [ lhead="cluster_kcp", color="blue" ] + Allocator1 -> GameServer1 [ lhead="cluster_kcp", color="green" ] + AllocatorN -> GameServer1 [ lhead="cluster_kcp", color="green" ] + SDKServer -> GameServer1 [ color="blue" ] + + Pod1 -> GameServerContainer [ lhead="cluster_pod", style="dotted" ] +} diff --git a/site/static/diagrams/system-diagram.dot.png b/site/static/diagrams/system-diagram.dot.png new file mode 100644 index 0000000000..e6f9134a46 Binary files /dev/null and b/site/static/diagrams/system-diagram.dot.png differ