Skip to content

Commit

Permalink
Quick start to create game server & details spec guide
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyril TOVENA committed Mar 1, 2018
1 parent 09cf3cb commit ce7c685
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 7 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ Documentation and usage guides on how to develop and host dedicated game servers
More documentation forthcoming.

### Quickstarts:
- Create a Game Server (forthcoming)
- [Create a Game Server](./docs/create_gameserver.md)

### Guides
- [Game Server Specification](./docs/gameserver_spec.md)
- Integrating the C++ SDK (forthcoming)
- [GameServer Health Checking](./docs/health_checking.md)

Expand Down
126 changes: 126 additions & 0 deletions docs/create_gameserver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Quickstart Create a Game Server

This guide covers how you can quickly get started using Agones to create GameServers.

## Objectives

- Create a GameServer in kubernetes using Agones custom ressources.
- Get informations about the GameServer such as IP address, port and state.
- Connect to the GameServer.

## Prerequisites

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. Agones controller installed in the targeted cluster
3. kubectl properly configured

>NOTE: Agones required Kubernetes versions 1.9 with role-based access controls (RBAC) and MutatingAdmissionWebhook features activated. To check your version, enter `kubectl version`.
If you don't have a Kubernetes cluster you can follow the [build](../build/README.md#running-a-test-minikube-cluster) instructions to either use [Minikube](https://github.com/kubernetes/minikube) single node cluster or create one in [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/).

To install Agones controller into your Kubernetes cluster follow the [installation instructions](../README.md#Installation).

For the purpose of this guide we're going to use the [simple-udp](../examples/simple-udp/) example as the GameServer container. This example is very simple UDP server written in Go. Don't hesitate to look at the code of this example for more information.

### 1. Create a GameServer

Let's create a GameServer using the following command :

```
kubectl apply -f https://github.com/googlecloudplatform/agones/blob/master/examples/simple-udp/server/gameserver.yaml
```

You should see a successful ouput similar to this :

```
user@computer:~/$ gameserver "simple-udp" created
```

For the full details of the YAML file head to the [GameServer Specification Guide](./gameserver_spec.md)

### 2. Fetch the GameServer Status

Let's wait for the GameServer state to become `Ready`:

```
watch kubectl describe gameserver
```

You should see the `Status.State` changing, as well as, the list of `Events` happening to your Game Server.

```
Name: simple-udp
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"stable.agones.dev/v1alpha1","kind":"GameServer","metadata":{"annotations":{},"name":"simple-udp","namespace":"default"},"spec":{"contain...
API Version: stable.agones.dev/v1alpha1
Kind: GameServer
Metadata:
Cluster Name:
Creation Timestamp: 2018-03-01T20:43:36Z
Finalizers:
stable.agones.dev
Generation: 0
Resource Version: 6238
Self Link: /apis/stable.agones.dev/v1alpha1/namespaces/default/gameservers/simple-udp
UID: 372468b6-1d91-11e8-926e-fa163e0980b0
Spec:
Port Policy: dynamic
Container: simple-udp
Container Port: 7654
Health:
Failure Threshold: 3
Initial Delay Seconds: 5
Period Seconds: 5
Host Port: 7211
Protocol: UDP
Template:
Metadata:
Creation Timestamp: <nil>
Spec:
Containers:
Image: gcr.io/agones-images/udp-server:0.1
Name: simple-udp
Resources:
Status:
Address: 10.130.65.212
Node Name: dev-worker-03
Port: 7211
State: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal PortAllocation 11s gameserver-controller Port allocated
Normal Creating 11s gameserver-controller Pod simple-udp-vwxpt created
Normal Starting 11s gameserver-controller Synced
Normal Ready 4s gameserver-controller Address and Port populated
```


Then retrieve the IP address and the allocated port of your Game Server :

```
kubectl get gs simple-udp -o jsonpath='{.status.address}:{.status.port}'
```

This should ouput your Game Server IP address and port. (eg `10.130.65.208:7936`)

### 3. Connect to the GameServer

You can now communicate with the Game Server :

```
nc -u 10.130.65.208 7936
Hello World !
ACK: Hello World !
EXIT
```

You can also try to send `UNHEALTHY` to change the Game Server state.


## Next Step

If you want to use your own GameServer container make sure you have properly integrated the [Agones SDK](../sdks/).
45 changes: 45 additions & 0 deletions docs/gameserver_spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# GameServer Specification

Like any other kubernetes ressources you describe a GameServer desired state via a specification written in YAML or JSON to the kubernetes API. The Agones controller will then change the actual state to the desired state.

A full GameServer specification is available below and in the [example folder](../examples/gameserver.yml) for reference :

```
apiVersion: "stable.agones.dev/v1alpha1"
kind: GameServer
metadata:
name: "gds-example"
spec:
container: example-server
portPolicy: "static"
containerPort: 7654
hostPort: 7777
protocol: UDP
health:
disabled: false
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
template:
metadata:
labels:
myspeciallabel: myspecialvalue
spec:
containers:
- name: example-server
image: gcr.io/agones/test-server:0.1
imagePullPolicy: Always
```

Since Agones defines a new [Custom Ressources Definition (CRD)](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) we can define a new ressource using the kind `GameServer` with the custom group `stable.agones.dev` and API version `v1alpha1`.

You can use the metadata field to target a specific [namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) but also attach specific [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) and [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) to your ressource. This is a very common pattern in the kubernetes ecosystem.

The `spec` field is the actual GameServer specification and it is composed as follow:

- `container` is the name of container running the GameServer in case you have more than one container defined in the [pod](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/). If you do, this is a mandatory field. For instance this is useful if you want to run a sidecar to ship logs.
- `portPolicy` has two options `dynamic` (default) the system allocates a free hostPort for the gameserver, for game clients to connect to. And `static`, user defines the hostPort that the game client will connect to. Then onus is on the user to ensure that the port is available. When static is the policy specified, `hostPort` is required to be populated.
- `containerPort` the port that is being opened on the game server process, this is required field.
- `protocol` the protocol being used. Defaults to UDP. TCP is the only other option.
- `health` to track the overall healthy state of the GameServer, more information available in the [health check documentation](./health_checking.md).
- `template` the [pod spec template](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#pod-v1-core) to run you GameServer containers, [see](https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/#pod-templates) for more
6 changes: 2 additions & 4 deletions examples/simple-udp/server/gameserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ kind: GameServer
metadata:
name: "simple-udp"
spec:
portPolicy: "static"
portPolicy: "dynamic"
containerPort: 7654
hostPort: 7777
template:
spec:
containers:
- name: simple-udp
image: gcr.io/agones-images/udp-server:0.1
# imagePullPolicy: Always # add for development
image: gcr.io/agones-images/udp-server:0.1
5 changes: 3 additions & 2 deletions examples/simple-udp/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"log"
"net"
"os"
"strings"

"time"

Expand Down Expand Up @@ -66,7 +67,7 @@ func main() {
log.Fatalf("Could not read from udp stream: %v", err)
}

txt := string(b[:n]) // trim the empty bytes
txt := strings.TrimSpace(string(b[:n]))
log.Printf("Received packet from %v: %v", sender.String(), txt)
switch txt {
// shuts down the gameserver
Expand All @@ -87,7 +88,7 @@ func main() {
}

// echo it back
ack := "ACK: " + txt
ack := "ACK: " + txt + "\n"
if _, err = conn.WriteTo([]byte(ack), sender); err != nil {
log.Fatalf("Could not write to udp stream: %v", err)
}
Expand Down

0 comments on commit ce7c685

Please sign in to comment.