Quake III Arena, Kubernetes (k3s) and Raspberry Pi

Approx. transl. : it would seem that until recently the combination of the title seemed to be an impossible madness. The world does not stand still, and this madness has become not only possible, but even really simple to implement. Confirmation read below in translation of the corresponding instruction from Johan Siebens - cloud architect from Belgium.







Yesterday I saw this tweet from Chris Campbell in my feed:





Oh, memories ... Quake III Arena is one of my all-time favorite first person shooters.



I've spent (and lost) a lot of time in the past playing this fast-paced game with friends and enemies. Now, thanks to the QuakeKube project from Capital One Tech , the world of containers and Kubernetes is open to it.



QuakeKube is a Kubernetes version of QuakeJS . To do this, a dedicated Quake 3 server is launched in the corresponding deployment , to which clients connect via QuakeJS in the browser.


Of course, I was eager to try this project, especially after seeing the following in the documentation:



Container images are cross-compiled with Docker Buildx and can run on hardware with a variety of architectures and operating systems. Currently available versions for linux/amd64



and linux/arm64



.


ARM64 support! Class, so I can run Quake on one of my Raspberry Pi! (Note translation: later in the article we will consider the option of installing k3s on the Raspberry Pi, and if you are interested in regular [vanilla] Kubernetes, we wrote about this recently .)



Well, let's shoot!



Most of the work has already been done by other enthusiasts, so with the right tools and a plan, it will only take a few minutes to launch the game.



Requirements



  • Raspberry Pi running Ubuntu 20.04 with ARM64 support
  • k3sup



    - lightweight utility for automatic installation and configuration of k3s on any local or remote virtual machine;
  • arkade



    - a simple CLI in Golang with strictly defined flags, allowing you to easily and easily install charts and applications in the cluster;
  • kubectl



    ;
  • DigitalOcean account and API token.


Installation and configuration



First of all, install k3s



on a Raspberry Pi with an ARM64-compatible operating system like Ubuntu 20.04:



$ k3sup install --ip 192.168.0.52 --user ubuntu --k3s-extra-args '--no-deploy servicelb --no-deploy traefik'
      
      





After installing k3s on the Raspberry Pi, k3sup also downloads the required file kubeconfig



to the current working directory. Configure kubectl



to use this config:



$ export KUBECONFIG=$(pwd)/kubeconfig
      
      





Now arcade



install the inlets-operator with:



$ arkade install inlets-operator --provider digitalocean --token-file ~/do-api-token
      
      





The inlets-operator will create a so-called inlets exit-node on DigitalOcean, i.e. will provide a public IP address for the k3s private cluster LoadBalancer services.



The OSS version of inlets will suffice for this, since clients connect to the server via QuakeJS in a browser with websockets. If you need support for TLS, etc., I recommend paying attention to the PRO version.



Finally, grab the QuakeKube YAML file from the project's GitHub repository and edit it accordingly. The service should be replaced with LoadBalancer (instead of NodePort). You can also customize the parameters of the game itself as you wish.



Example YAML configuration for QuakeKube:



apiVersion: apps/v1
kind: Deployment
metadata:
  name: quakejs
spec:
  selector:
    matchLabels:
      run: quakejs
  replicas: 1
  template:
    metadata:
      labels:
        run: quakejs
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '8080'
    spec:
      containers:
      - command:
        - q3
        - server
        - --config=/config/config.yaml
        - --content-server=http://localhost:9090
        - --agree-eula
        image: docker.io/criticalstack/quake:v1.0.5
        name: server
        ports:
        - containerPort: 8080
        readinessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 5
        volumeMounts:
        - name: quake3-server-config
          mountPath: /config
        - name: quake3-content
          mountPath: /assets
      - command:
        - q3
        - content
        - --seed-content-url=http://content.quakejs.com
        image: docker.io/criticalstack/quake:v1.0.5
        name: content-server
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: quake3-content
          mountPath: /assets
      volumes:
        - name: quake3-server-config
          configMap:
            name: quake3-server-config
        - name: quake3-content
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: quakejs
spec:
  type: LoadBalancer
  selector:
    run: quakejs
  ports:
    - port: 80
      targetPort: 8080
      name: http
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: quake3-server-config
data:
  config.yaml: |
    fragLimit: 25
    timeLimit: 15m
    bot:
      minPlayers: 3
    game:
      motd: "Welcome to Critical Stack"
      type: FreeForAll
      forceRespawn: false
      inactivity: 10m
      quadFactor: 3
      weaponRespawn: 3
    server:
      hostname: "quakekube"
      maxClients: 12
      password: "changeme"
    commands:
      - addbot sarge 2
    maps:
    - name: q3dm7
      type: FreeForAll
      timeLimit: 10m
    - name: q3dm17
      type: FreeForAll
    - name: q3wctf1
      type: CaptureTheFlag
      captureLimit: 8
    - name: q3tourney2
      type: Tournament
    - name: q3wctf3
      type: CaptureTheFlag
      captureLimit: 8
    - name: ztn3tourney1
      type: Tournament
      
      





Running



Apply this manifest to your k3s cluster:




$ kubectl apply -f example.yaml 
deployment.apps/quakejs created
service/quakejs created
configmap/quake3-server-config created
      
      





Wait until all pods become running , and inlets-operator creates its own exit-node:




$ kubectl get pods,service
NAME                                         READY   STATUS    RESTARTS   AGE
pod/inlets-operator-76fb794578-s2fg4         1/1     Running   0          147m
pod/quakejs-tunnel-client-6f7c986dfc-mdt5w   1/1     Running   0          50s
pod/quakejs-786cc496b-g7b7n                  2/2     Running   0          80s

NAME                 TYPE           CLUSTER-IP    EXTERNAL-IP                       PORT(S)        AGE
service/kubernetes   ClusterIP      10.43.0.1     <none>                            443/TCP        152m
service/quakejs      LoadBalancer   10.43.46.33   143.110.174.204,143.110.174.204   80:32116/TCP   80s
      
      





And that's it! Launch your favorite browser, download the application and start shooting in all directions!





useful links





PS from translator



You can see / try a demo of QuakeJS in action here .



Read also on our blog:






All Articles