Custom Kubernetes controller for automating external DNS on Minecraft GameServers
Explore the docs »
View Example
·
Report Bug
·
Request Feature
Custom Kubernetes controller for automating external DNS records for Agones Minecraft GameServers using third-party DNS providers
You need a running GKE cluster running with Agones resources and controllers installed
- GKE
gcloud container clusters create minecraft --cluster-version=1.18 \
--tags=mc \
--scopes=gke-default,"https://www.googleapis.com/auth/ndev.clouddns.readwrite" \ # GKE scope needed for Cloud DNS
--node-labels=agones-mc/<DOMAIN_NAME> \ # Replace with the domain for the zone that the controller will manage
--num-nodes=2 \
--no-enable-autoupgrade \
--machine-type=n2-standard-4gcloud config set container/cluster minecraft
gcloud container clusters get-credentials minecraftgcloud compute firewall-rules create mc-server-firewall \
--allow tcp:7000-8000 \
--target-tags mc \
--description "Firewall rule to allow mc server tcp traffic"- Agones
kubectl create namespace agones-system
kubectl apply -f https://raw.githubusercontent.com/googleforgames/agones/release-1.13.0/install/yaml/install.yamlkubectl apply
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-mc-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-mc-dns
rules:
- apiGroups: ['agones.dev']
resources: ['gameservers']
verbs: ['get', 'watch', 'list', 'update']
- apiGroups: ['']
resources: ['nodes']
verbs: ['get', 'watch', 'list', 'update']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: agones-mc-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: agones-mc-dns
subjects:
- kind: ServiceAccount
name: agones-mc-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: agones-mc-dns-controller
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: agones-mc-dns-controller
template:
metadata:
labels:
app: agones-mc-dns-controller
spec:
serviceAccountName: agones-mc-dns
containers:
- name: agones-mc-dns-controller
image: saulmaldonado/agones-mc-dns-controller
args:
- --zone=<MANAGED_ZONE> # Replace with name of DNS managed zone
imagePullPolicy: Always docker run -it --rm --name agones-mc-dns-controller \
-v $HOME/.kube/config:/root/.kube/config \ # Passes kubeconfig to container
-v $HOME/.config/gcloud/:/root/.config/gcloud/ \ # Passes gcloud credentials to container
-e HOME=/root \ # Needed for google oauth authentication
saulmaldonado/agones-mc-dns-controller \
--gcp-project=$(GCP_PROJECT) \ # Replace with GCP project ID
--zone=$(MANAGED_ZONE) # Replace with Managed DNS zoneThis controller takes advantage of dynamic host port allocation that Agones provisions for GameServers. Instead of creating external DNS records for Kubernetes services and ingresses, DNS A and SRV are created to point to GameServer host nodes and the their GameServer ports.
To provision an A record for Nodes, they need to have agones-mc/domain label that contains the domain of the zone that the controller is managing. This will indicate to the controller that the Node needs an A record.
Labeling existing Nodes can be done using kubectl:
kubectl label node/<NODE_NAME> agones-mc/domain=<DOMAIN>All Nodes that you intend to host GameServers one should have this label.
A new annotation with agones-mc/externalDNS will contain the new A record that points to the Node IP.
Example:
| Node Name | domain label | Resulting A Record |
|---|---|---|
gke-minecraft-default-pool-79cd0803-42d7 |
example.com |
gke-minecraft-default-pool-79cd0803-42d7.example.com |
To provision an SRV record for GameServers, they need to contain an agones-mc/domain annotation that contains the domain for the controller's Managed Zone. This will indicate to the controller that the GameServer needs a SRV record.
template:
metadata:
annotations:
agones-mc/domain: <DOMAIN_NAME> # Domain name of the managed zone
# agones-mc/externalDNS: <GAMESERVER_NAME>.<DOMAIN_NAME> # Will be added by the controller
spec:
containers:
- name: mc-server
image: itzg/minecraft-server # Minecraft server image
imagePullPolicy: Always
env: # Full list of ENV variables at https://github.com/itzg/docker-minecraft-server
- name: EULA
value: 'TRUE'
- name: mc-monitor
image: saulmaldonado/agones-mc-monitor # Agones monitor sidecar
imagePullPolicy: AlwaysOnce the pod has been created, a new SRV will be generated with the format _minecraft._tcp.<GAMESERVER_NAME>.<DOMAIN>. that points to the A record of the host Node 0 0 <PORT> <HOST_A_RECORD>.
A new annotation agones-mc/externalDNS will then be added to the GameServer containing the URL from which players can connect to.
| GameServer Name | Port | domain annotation | Node A Record |
Resulting SRV Record |
Minecraft Server URL |
|---|---|---|---|---|---|
mc-server-cfwd7 |
7908 | agones-mc/domain: example.com |
gke-minecraft-default-pool-79cd0803-42d7.example.com. |
_minecraft._tcp.mc-server-cfwd7.example.com 0 0 7908 gke-minecraft-default-pool-79cd0803-42d7.example.com. |
mc-server-cfwd7.example.com |
docker run -it --rm --name agones-mc-dns-controller \
-v $HOME/.kube/config:/root/.kube/config \ # Passes kubeconfig to container
-v $HOME/.config/gcloud/:/root/.config/gcloud/ \ # Passes gcloud credentials to container
-e HOME=/root \ # Needed for google oauth authentication
saulmaldonado/agones-mc-dns-controller \
--gcp-project=$(GCP_PROJECT) \ # Replace with GCP project ID
--zone=$(MANAGED_ZONE) # Replace with Managed DNS zoneFlags:
--gcp-project string
GCP project id
--kubeconfig string
Paths to a kubeconfig. Only required if out-of-cluster.
--zone string
DNS zone that the controller will manage
See the open issues for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Clone the Project
- Create your Feature or Fix Branch (
git checkout -b (feat|fix)/AmazingFeatureOrFix) - Commit your Changes (
git commit -m 'Add some AmazingFeatureOrFix') - Push to the Branch (
git push origin (feat|fix)/AmazingFeature) - Open a Pull Request
-
Clone the repo
git clone https://github.com/saulmaldonado/agones-minecraft.git
-
Build
make go-build
-
Clone the repo
git clone https://github.com/saulmaldonado/agones-minecraft.git
-
Build
docker build -t <hub-user>/agones-mc-dns-controller:latest ./controller
-
Push to Docker repo
docker push <hub-user>/agones-mc-dns-controller:latest
Distributed under the MIT License. See LICENSE for more information.
- 🐱 Github: @saulmaldonado
- 🤝 LinkedIn: @saulmaldonado4
- 🐦 Twitter: @saul_mal
- 💻 Website: saulmaldonado.com
Give a ⭐️ if this project helped you!