I’ve had two itzg/minecraft-bedrock-server containers running on a single node using docker-compose for a while now, but I wanted to move them to microk8s.
I wanted to have them announce themselves to the LAN so that the consoles could see them. This requires them to have a MACVLAN interface on the host’s network.
This was “easy” to do with docker, I had a systemd service that also created the “magic” MACVLAN network and the compose file attached the containers to it.
These are not complete files, only the relevant parts.
# /etc/systemd/system/docker-compose-minecraft.service
[Service]
ExecStartPre=-/snap/bin/docker network create -d macvlan -o parent=enp4s0 --subnet 192.168.1.0/24 --ip-range 192.168.1.128/27 --gateway 192.168.1.1 magic
ExecStart=/snap/bin/docker compose up --abort-on-container-exit
# docker-compose.yaml
networks:
magic:
external: true
services:
minecraft:
image: itzg/minecraft-bedrock-server
networks:
- magic
Converting this to kubernetes was not as straightforward as I had hoped. Mainly because working out what the magic JSON CNI configuration is was not obvious. I had to read the Multus CNI documentation and the MACVLAN CNI documentation. Still, only needed an arbitrary example to fill in the gaps.
Helpfully, there is also a helm chart for itzg/minecraft-bedrock-server, so I didn’t have to write a deployment myself. So, exploiting helm’s sub-chart dependency mechanism, I created a custom chart that creates the MACVLAN and assigns it to the minecraft server(s).
# Chart.yaml
apiVersion: v2
name: Minecraft
description: Minecraft
type: application
version: 0.0.0
appVersion: "0.0"
dependencies:
- name: minecraft-bedrock
version: 2.8.4
repository: https://itzg.github.io/minecraft-server-charts/
# values.yaml
minecraft-bedrock:
podAnnotations:
k8s.v1.cni.cncf.io/networks: macvlan
# templates/macvlan.yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: macvlan
spec:
config: |
{
"cniVersion": "0.3.1",
"plugins": [
{
"cniVersion": "0.3.1",
"type": "macvlan",
"master": "enp4s0",
"mode": "bridge",
"ipam": {
"type": "host-local",
"ranges": [
[
{
"subnet": "192.168.1.0/24",
"gateway": "192.168.1.1",
"rangeStart": "192.168.1.129",
"rangeEnd": "192.168.1.159"
}
]
]
}
}
]
}
Assuming one has already microk8s enable multus
, the above files can be used to create a helm chart that will create
the MACVLAN network and deploy the minecraft server(s) to it. I suspect that master
and mode
are redundant.
Crucially, the Multus CNI configuration wraps the actual CNI MACVLAN plugin configuration.
Every example I found online used the MACVLAN CNI configuration (without the Multus wrapper) and also specified the
routes
and dns
options. When spefifying the routes
option all traffic fails inside the pod. Apparently because it
is the same subnet as the host’s network and routing is confused.