MCing documentation
This is the documentation site for MCing. MCing is a Kubernetes operator for Minecraft server.
Getting started
Deploying MCing
Basic Installation
-
(Optional) Prepare cert-manager
MCing depends on cert-manager to issue TLS certificate for admission webhooks. If cert-manager is not installed on your cluster, install it as follows:
$ curl -fsLO https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.yaml $ kubectl apply -f cert-manager.yaml -
Apply MCing manifests
$ curl -fsLO https://github.com/kmdkuk/MCing/releases/latest/download/install.yaml $ kubectl apply -f install.yaml
Customizing Controller Settings
To customize the MCing controller, download and edit install.yaml before applying:
$ curl -fsLO https://github.com/kmdkuk/MCing/releases/latest/download/install.yaml
# Edit install.yaml to add/modify controller flags
$ kubectl apply -f install.yaml
Controller Flags
The MCing controller supports the following flags:
| Flag | Default | Description |
|---|---|---|
--metrics-bind-address | :8080 | The address the metric endpoint binds to |
--health-probe-bind-address | :8081 | The address the probe endpoint binds to |
--leader-elect | false | Enable leader election for HA |
--check-interval | 1m | Interval of Minecraft server maintenance checks |
Enabling mc-router (Hostname-based Routing)
mc-router allows multiple Minecraft servers to share a single external IP/port by routing based on hostname.
Add the following flags to the controller deployment:
| Flag | Default | Description |
|---|---|---|
--enable-mc-router | false | Enable mc-router gateway |
--mc-router-default-domain | minecraft.local | Default domain for FQDN generation (<name>.<namespace>.<domain>) |
--mc-router-namespace | mcing-gateway | Namespace for mc-router deployment |
--mc-router-service-type | LoadBalancer | Service type (LoadBalancer or NodePort) |
--mc-router-image | itzg/mc-router:latest | mc-router container image |
Example deployment patch:
spec:
template:
spec:
containers:
- name: manager
args:
- --leader-elect
- --enable-mc-router
- --mc-router-default-domain=mc.example.com
- --mc-router-service-type=LoadBalancer
When mc-router is enabled:
- Each Minecraft server gets a hostname:
<name>.<namespace>.<default-domain>(or customexternalHostname) - Services are created as ClusterIP type and routed through mc-router
- Point your DNS wildcard (
*.mc.example.com) to the mc-router service
Usage
Starting simple server
-
Apply Minecraft Custom Resouce
$ cat <<EOF > minecraft-sample.yaml apiVersion: mcing.kmdkuk.com/v1alpha1 kind: Minecraft metadata: name: minecraft-sample spec: podTemplate: spec: containers: - name: minecraft image: itzg/minecraft-server:java8 env: - name: TYPE value: "SPIGOT" - name: EULA value: "true" serviceTemplate: spec: type: NodePort volumeClaimTemplates: - metadata: name: minecraft-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: standard resources: requests: storage: 1Gi serverPropertiesConfigMapName: mcing-server-props --- apiVersion: v1 kind: ConfigMap metadata: name: mcing-server-props data: motd: "[this is test]A Vanilla Minecraft Server powered by MCing" pvp: "true" difficulty: "hard" EOF $ kubectl apply -f minecraft-sample.yaml # check resources $ kubectl get minecrafts.mcing.kmdkuk.com minecraft-sample NAME AGE minecraft-sample 2m41s $ kubectl get statefulsets.apps mcing-minecraft-sample NAME READY AGE mcing-minecraft-sample 1/1 2m47s $ kubectl get persistentvolumeclaims minecraft-data-minecraft-sample-0 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE minecraft-data-mcing-minecraft-sample-0 Bound pvc-220c9ba1-2395-48ed-a18a-c9d3d7788a6c 1Gi RWO standard 3h58m $ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12m mcing-minecraft-sample NodePort 10.96.232.50 <none> 25565:30088/TCP,25575:30446/UDP 103s mcing-minecraft-sample-headless ClusterIP None <none> 25565/TCP,25575/UDP 103s $ kubectl get configmaps NAME DATA AGE kube-root-ca.crt 1 13m mcing-minecraft-sample 1 2m47s mcing-server-props 3 2m47sWhen you apply Minecraft Custom Resource, several resources will be created.
-
Access the server
You can customize the Service (e.g. change type to LoadBalancer) using
ServiceTemplatein the Minecraft Custom Resource to access the server. Alternatively, you can use port-forward to verify access quickly.kubectl port-forward svc/minecraft-sample 25565:25565
Configuration by ConfigMap
If you edit the ConfigMap specified by .spec.serverPropertiesConfigMapName in the Minecraft resource, it will automatically replace server.properties and then execute the /reload command.
Note: There are some cases where the configuration will not be updated even if you run the /reload command. (In the case of TYPE=SPIGOT, we have confirmed that the configuration is updated automatically.)
The following ConfigMap can be applied to other JSON configuration files.
apiVersion: v1
kind: ConfigMap
metadata:
name: other-props
data:
banned-ips.json: |
[]
banned-players.json: |
[]
whitelist.json: |
[]
ops.json: |
[]
It can be applied by specifying a name, such as otherConfigMapName: other-props.
Warning
Currently, these files are overwritten by the ConfigMap content on every Pod startup. This means any in-game changes (e.g.
/ban,/op) that are not reflected in the ConfigMap will be lost when the Pod restarts. This behavior is a known issue.
RCON Configuration
By default, the controller automatically generates a Secret named <instance-name>-rcon-password containing a random password for RCON.
The password is stored in the key rcon-password.
The controller injects this password into the Minecraft container as the environment variable RCON_PASSWORD.
If you want to use your own password, you can specify an existing Secret name in .spec.rconPasswordSecretName.
apiVersion: mcing.kmdkuk.com/v1alpha1
kind: Minecraft
metadata:
name: minecraft-sample
spec:
rconPasswordSecretName: my-rcon-secret
# ... other fields
The Secret must contain the key rcon-password.
apiVersion: v1
kind: Secret
metadata:
name: my-rcon-secret
stringData:
rcon-password: "your-super-strong-password"
Auto-Pause
MCing supports automatic server pausing when no players are connected, using lazymc. This helps reduce resource usage for idle servers.
Enabling Auto-Pause
apiVersion: mcing.kmdkuk.com/v1alpha1
kind: Minecraft
metadata:
name: minecraft-sample
spec:
autoPause:
enabled: true
timeoutSeconds: 300 # Pause after 5 minutes of inactivity (default)
# ... other fields
How it works
- When enabled, lazymc runs as the main process and proxies connections to the Minecraft server
- The Minecraft server starts when a player connects
- After
timeoutSecondsof no player activity, the server is paused - The server automatically resumes when a new player connects
Note
Auto-pause is enabled by default. Set
autoPause.enabled: falseto disable it.
Operators and Whitelist
MCing can manage operators and whitelist through the Minecraft CR spec.
Operators
spec:
ops:
users:
- player1
- player2
The controller executes /op or /deop commands via RCON to sync the operators list.
Whitelist
spec:
whitelist:
enabled: true
users:
- allowed_player1
- allowed_player2
When whitelist.enabled is true, the controller executes /whitelist on and manages the whitelist via /whitelist add and /whitelist remove commands.
Backup and Download
MCing provides a kubectl plugin for downloading server data.
Installing kubectl-mcing
go install github.com/kmdkuk/mcing/cmd/kubectl-mcing@latest
Or download from GitHub Releases.
Downloading Server Data
kubectl mcing download <minecraft-name> [-o output.tar.gz] [-n namespace]
This command:
- Executes
save-offto disable auto-save - Executes
save-all flushto ensure all data is written - Compresses and downloads the
/datadirectory - Executes
save-onto re-enable auto-save
Excluding Files from Backup
You can exclude files from the backup using the backup.excludes field:
spec:
backup:
excludes:
- "*.jar"
- "logs/*"
- "cache/*"
mc-router (Hostname-based Routing)
When mc-router is enabled on the controller, you can use custom hostnames to access your Minecraft servers.
Using Custom Hostname
spec:
externalHostname: "survival.mc.example.com"
If not specified, the hostname is automatically generated as <name>.<namespace>.<default-domain>.
DNS Configuration
Point a wildcard DNS record to the mc-router service’s external IP:
*.mc.example.com -> <mc-router-external-ip>
Players can then connect using hostnames like survival.mc.example.com:25565.
See Deploy MCing for controller configuration.
Architecture
This document describes the architecture and components used by MCing.
Overview
MCing is a Kubernetes operator that manages Minecraft servers. When you create a Minecraft custom resource, the controller creates and manages the following resources:
graph TD
subgraph cluster ["Kubernetes Cluster"]
subgraph mcing-system ["mcing-system namespace"]
Controller["mcing-controller<br/>(Deployment)"]
end
subgraph user-namespace ["user namespace"]
subgraph STS ["StatefulSet mcing-NAME"]
subgraph Pod ["Pod"]
Init["init: mcing-init"]
MC["minecraft<br/>(user image)"]
Agent["mcing-agent<br/>(sidecar)"]
end
Volumes["Volumes:<br/>minecraft-data PVC<br/>config ConfigMap"]
end
Svc["Service mcing-NAME<br/>:25565 minecraft<br/>:25575 rcon"]
Headless["Service headless<br/>mcing-NAME-headless<br/>For StatefulSet DNS"]
end
subgraph mcing-gateway ["mcing-gateway namespace<br/>(if mc-router enabled)"]
Router["mc-router<br/>(Deployment)"]
end
end
%% Controller creates resources
Controller -->|creates| STS
Controller -->|creates| Svc
Controller -->|creates| Headless
Controller -.->|creates if enabled| Router
%% mc-router routes to services
Router -.->|routes by hostname| Svc
%% StatefulSet uses headless for DNS
STS -.->|serviceName| Headless
%% Styling
style mcing-system fill:#e8f4ea,stroke:#333
style user-namespace fill:#fff,stroke:#333
style mcing-gateway fill:#f0e8f4,stroke:#333
style Controller fill:#2e7d32,color:#fff
style Router fill:#7b1fa2,color:#fff
style STS fill:#1565c0,color:#fff
style Pod fill:#fff,stroke:#1565c0
style Svc fill:#bbdefb,stroke:#1565c0
style Headless fill:#bbdefb,stroke:#1565c0
Components
MCing Controller
The main controller that watches Minecraft custom resources and manages the lifecycle of Minecraft servers.
| Image | Description |
|---|---|
ghcr.io/kmdkuk/mcing-controller | MCing controller |
Pod Containers
Each Minecraft server pod contains the following containers:
| Container | Image | Description |
|---|---|---|
mcing-init | ghcr.io/kmdkuk/mcing-init | Init container that prepares config files |
minecraft | User-specified (e.g., itzg/minecraft-server) | The actual Minecraft server |
mcing-agent | ghcr.io/kmdkuk/mcing-agent | Sidecar for RCON operations and server management |
External Dependencies
| Image | Purpose | Used When |
|---|---|---|
itzg/minecraft-server | Recommended Minecraft server image | User choice |
itzg/mc-router | Hostname-based routing proxy for Minecraft | --enable-mc-router |
timberio/vector (lazymc) | Embedded in mcing-init for auto-pause feature | autoPause.enabled=true |
Features
Auto-Pause (lazymc)
When autoPause.enabled is set to true, MCing uses lazymc to automatically pause the Minecraft server when no players are connected.
How it works:
- The
mcing-initcontainer downloads and configures lazymc - lazymc runs as the main process instead of the Minecraft server directly
- lazymc starts/stops the actual Minecraft server based on player connections
- The server pauses after
timeoutSeconds(default: 300) of inactivity
Configuration:
spec:
autoPause:
enabled: true
timeoutSeconds: 300 # 5 minutes
mc-router (Hostname-based Routing)
When mc-router is enabled, multiple Minecraft servers can share a single external IP address. Players connect using hostnames like server1.minecraft.example.com.
How it works:
- mc-router is deployed in the
mcing-gatewaynamespace - Each Minecraft service gets an annotation with its hostname
- mc-router reads these annotations and routes connections accordingly
- DNS wildcard points to mc-router’s external IP
Architecture with mc-router:
graph TD
Players["Players"]
subgraph Internet
Host1["server1.mc.example.com:25565"]
Host2["server2.mc.example.com:25565"]
end
Router["mc-router (LoadBalancer)<br/>External IP: x.x.x.x:25565"]
subgraph Kubernetes
Server1["server1<br/>(ClusterIP)"]
Server2["server2<br/>(ClusterIP)"]
end
Players --> Host1
Players --> Host2
Host1 --> Router
Host2 --> Router
Router -->|hostname: server1.*| Server1
Router -->|hostname: server2.*| Server2
style Router fill:#7b1fa2,color:#fff
style Server1 fill:#1565c0,color:#fff
style Server2 fill:#1565c0,color:#fff
style Players fill:#fff,stroke:#333
Backup Support
The backup.excludes field allows specifying file patterns to exclude from backups performed via kubectl-mcing download.
spec:
backup:
excludes:
- "*.jar"
- "logs/*"
kubectl-mcing Plugin
The kubectl-mcing plugin provides CLI utilities for managing Minecraft servers:
| Command | Description |
|---|---|
download | Download and compress the server’s data directory |
Example:
kubectl mcing download minecraft-sample -o backup.tar.gz
Ports
| Port | Name | Protocol | Description |
|---|---|---|---|
| 25565 | minecraft | TCP | Minecraft server port |
| 25575 | rcon | TCP | RCON management port |
| 9080 | agent | TCP | mcing-agent gRPC port |
gRPC API (mcing-agent)
The mcing-agent sidecar exposes a gRPC API for server management:
| Method | Description |
|---|---|
Reload | Execute /reload command via RCON |
SyncWhitelist | Sync whitelist with Minecraft CR spec |
SyncOps | Sync operators with Minecraft CR spec |
SaveOff | Disable auto-save (for consistent backups) |
SaveAllFlush | Force save all chunks |
SaveOn | Re-enable auto-save |
See Agent RPC Reference for detailed API documentation.
Custom resources
Minecraft
Custom Resources
Sub Resources
- AutoPause
- Backup
- MinecraftList
- MinecraftSpec
- ObjectMeta
- Ops
- PersistentVolumeClaim
- PodTemplateSpec
- ServiceTemplate
- Whitelist
AutoPause
AutoPause defines the auto-pause configuration for the Minecraft server.
| Field | Description | Scheme | Required |
|---|---|---|---|
| enabled | Enabled enables the auto-pause function. | *bool | false |
| timeoutSeconds | TimeoutSeconds is the time in seconds to wait before pausing the server. Default is 300 seconds. | int | false |
Backup
Backup defines the backup configuration for the Minecraft server.
| Field | Description | Scheme | Required |
|---|---|---|---|
| excludes | Excludes is a list of file patterns to exclude from the backup. | []string | false |
Minecraft
Minecraft is the Schema for the minecrafts API.
| Field | Description | Scheme | Required |
|---|---|---|---|
| metadata | metav1.ObjectMeta | false | |
| spec | MinecraftSpec | false | |
| status | MinecraftStatus | false |
MinecraftList
MinecraftList contains a list of Minecraft.
| Field | Description | Scheme | Required |
|---|---|---|---|
| metadata | metav1.ListMeta | false | |
| items | []Minecraft | true |
MinecraftSpec
MinecraftSpec defines the desired state of Minecraft.
| Field | Description | Scheme | Required |
|---|---|---|---|
| podTemplate | PodTemplate is a Pod template for Minecraft server container. | PodTemplateSpec | true |
| volumeClaimTemplates | PersistentVolumeClaimSpec is a specification of PersistentVolumeClaim for persisting data in minecraft. A claim named "minecraft-data" must be included in the list. | []PersistentVolumeClaim | true |
| serviceTemplate | ServiceTemplate is a Service template. | *ServiceTemplate | false |
| ops | operators on server. exec /op or /deop | Ops | false |
| whitelist | whitelist | Whitelist | false |
| serverPropertiesConfigMapName | ServerPropertiesConfigMapName is a ConfigMap name of server.properties. | *string | false |
| otherConfigMapName | OtherConfigMapName is a ConfigMap name of other configurations file(eg. banned-ips.json, ops.json etc) | *string | false |
| rconPasswordSecretName | RconPasswordSecretName is a Secret name for RCON password. | *string | false |
| autoPause | AutoPause configuration | AutoPause | false |
| backup | Backup configuration | Backup | false |
| externalHostname | ExternalHostname is the custom hostname for mc-router routing. If not set, FQDN will be generated as | *string | false |
ObjectMeta
ObjectMeta is metadata of objects. This is partially copied from metav1.ObjectMeta.
| Field | Description | Scheme | Required |
|---|---|---|---|
| name | Name is the name of the object. | string | false |
| labels | Labels is a map of string keys and values. | map[string]string | false |
| annotations | Annotations is a map of string keys and values. | map[string]string | false |
Ops
Ops represents the ops.json file.
| Field | Description | Scheme | Required |
|---|---|---|---|
| users | user name exec /op or /deop | []string | false |
PersistentVolumeClaim
PersistentVolumeClaim is a user’s request for and claim to a persistent volume. This is slightly modified from corev1.PersistentVolumeClaim.
| Field | Description | Scheme | Required |
|---|---|---|---|
| metadata | Standard object’s metadata. | ObjectMeta | true |
| spec | Spec defines the desired characteristics of a volume requested by a pod author. | corev1.PersistentVolumeClaimSpec | true |
PodTemplateSpec
PodTemplateSpec describes the data a pod should have when created from a template. This is slightly modified from corev1.PodTemplateSpec.
| Field | Description | Scheme | Required |
|---|---|---|---|
| metadata | Standard object’s metadata. The name in this metadata is ignored. | ObjectMeta | false |
| spec | Specification of the desired behavior of the pod. The name of the Minecraft server container in this spec must be minecraft. | corev1.PodSpec | true |
ServiceTemplate
ServiceTemplate define the desired spec and annotations of Service.
| Field | Description | Scheme | Required |
|---|---|---|---|
| metadata | Standard object’s metadata. Only annotations and labels are valid. | ObjectMeta | false |
| spec | Spec is the ServiceSpec | *corev1.ServiceSpec | false |
Whitelist
Whitelist represents the whitelist.json file.
| Field | Description | Scheme | Required |
|---|---|---|---|
| enabled | exec /whitelist on | bool | true |
| users | user name exec /whitelist add or /whitelist remove | []string | false |
Protocol Documentation
Table of Contents
pkg/proto/agentrpc.proto
ReloadRequest
ReloadRequest is the request message to execute /reload via rcon.
ReloadResponse
ReloadResponse is the response message of Reload
SaveAllFlushRequest
SaveAllFlushResponse
SaveOffRequest
SaveOffResponse
SaveOnRequest
SaveOnResponse
SyncOpsRequest
SyncOpsRequest is the request message to exec /op or /deop via rcon
| Field | Type | Label | Description |
|---|---|---|---|
| users | string | repeated |
SyncOpsResponse
SyncOpsResponse is the response message of SyncOps
SyncWhitelistRequest
SyncWhitelistRequest is the request message to exec /whitelist via rcon
SyncWhitelistResponse
SyncWhitelistResponse is the response message of SyncWhitelist
Agent
Agent provides services for MCing.
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| Reload | ReloadRequest | ReloadResponse | |
| SyncWhitelist | SyncWhitelistRequest | SyncWhitelistResponse | |
| SyncOps | SyncOpsRequest | SyncOpsResponse | |
| SaveOff | SaveOffRequest | SaveOffResponse | |
| SaveAllFlush | SaveAllFlushRequest | SaveAllFlushResponse | |
| SaveOn | SaveOnRequest | SaveOnResponse |