Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MCing documentation

This is the documentation site for MCing. MCing is a Kubernetes operator for Minecraft server.

Getting started

  1. Install cert-manager and apply MCing manifests

Deploying MCing

Basic Installation

  1. (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
    
  2. 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:

FlagDefaultDescription
--metrics-bind-address:8080The address the metric endpoint binds to
--health-probe-bind-address:8081The address the probe endpoint binds to
--leader-electfalseEnable leader election for HA
--check-interval1mInterval 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:

FlagDefaultDescription
--enable-mc-routerfalseEnable mc-router gateway
--mc-router-default-domainminecraft.localDefault domain for FQDN generation (<name>.<namespace>.<domain>)
--mc-router-namespacemcing-gatewayNamespace for mc-router deployment
--mc-router-service-typeLoadBalancerService type (LoadBalancer or NodePort)
--mc-router-imageitzg/mc-router:latestmc-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 custom externalHostname)
  • 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

  1. 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      2m47s
    

    When you apply Minecraft Custom Resource, several resources will be created.

  2. Access the server

    You can customize the Service (e.g. change type to LoadBalancer) using ServiceTemplate in 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

  1. When enabled, lazymc runs as the main process and proxies connections to the Minecraft server
  2. The Minecraft server starts when a player connects
  3. After timeoutSeconds of no player activity, the server is paused
  4. The server automatically resumes when a new player connects

Note

Auto-pause is enabled by default. Set autoPause.enabled: false to 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:

  1. Executes save-off to disable auto-save
  2. Executes save-all flush to ensure all data is written
  3. Compresses and downloads the /data directory
  4. Executes save-on to 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.

ImageDescription
ghcr.io/kmdkuk/mcing-controllerMCing controller

Pod Containers

Each Minecraft server pod contains the following containers:

ContainerImageDescription
mcing-initghcr.io/kmdkuk/mcing-initInit container that prepares config files
minecraftUser-specified (e.g., itzg/minecraft-server)The actual Minecraft server
mcing-agentghcr.io/kmdkuk/mcing-agentSidecar for RCON operations and server management

External Dependencies

ImagePurposeUsed When
itzg/minecraft-serverRecommended Minecraft server imageUser choice
itzg/mc-routerHostname-based routing proxy for Minecraft--enable-mc-router
timberio/vector (lazymc)Embedded in mcing-init for auto-pause featureautoPause.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:

  1. The mcing-init container downloads and configures lazymc
  2. lazymc runs as the main process instead of the Minecraft server directly
  3. lazymc starts/stops the actual Minecraft server based on player connections
  4. 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:

  1. mc-router is deployed in the mcing-gateway namespace
  2. Each Minecraft service gets an annotation with its hostname
  3. mc-router reads these annotations and routes connections accordingly
  4. 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:

CommandDescription
downloadDownload and compress the server’s data directory

Example:

kubectl mcing download minecraft-sample -o backup.tar.gz

Ports

PortNameProtocolDescription
25565minecraftTCPMinecraft server port
25575rconTCPRCON management port
9080agentTCPmcing-agent gRPC port

gRPC API (mcing-agent)

The mcing-agent sidecar exposes a gRPC API for server management:

MethodDescription
ReloadExecute /reload command via RCON
SyncWhitelistSync whitelist with Minecraft CR spec
SyncOpsSync operators with Minecraft CR spec
SaveOffDisable auto-save (for consistent backups)
SaveAllFlushForce save all chunks
SaveOnRe-enable auto-save

See Agent RPC Reference for detailed API documentation.

Custom resources

Minecraft

Custom Resources

Sub Resources

AutoPause

AutoPause defines the auto-pause configuration for the Minecraft server.

FieldDescriptionSchemeRequired
enabledEnabled enables the auto-pause function.*boolfalse
timeoutSecondsTimeoutSeconds is the time in seconds to wait before pausing the server. Default is 300 seconds.intfalse

Back to Custom Resources

Backup

Backup defines the backup configuration for the Minecraft server.

FieldDescriptionSchemeRequired
excludesExcludes is a list of file patterns to exclude from the backup.[]stringfalse

Back to Custom Resources

Minecraft

Minecraft is the Schema for the minecrafts API.

FieldDescriptionSchemeRequired
metadatametav1.ObjectMetafalse
specMinecraftSpecfalse
statusMinecraftStatusfalse

Back to Custom Resources

MinecraftList

MinecraftList contains a list of Minecraft.

FieldDescriptionSchemeRequired
metadatametav1.ListMetafalse
items[]Minecrafttrue

Back to Custom Resources

MinecraftSpec

MinecraftSpec defines the desired state of Minecraft.

FieldDescriptionSchemeRequired
podTemplatePodTemplate is a Pod template for Minecraft server container.PodTemplateSpectrue
volumeClaimTemplatesPersistentVolumeClaimSpec is a specification of PersistentVolumeClaim for persisting data in minecraft. A claim named "minecraft-data" must be included in the list.[]PersistentVolumeClaimtrue
serviceTemplateServiceTemplate is a Service template.*ServiceTemplatefalse
opsoperators on server. exec /op or /deopOpsfalse
whitelistwhitelistWhitelistfalse
serverPropertiesConfigMapNameServerPropertiesConfigMapName is a ConfigMap name of server.properties.*stringfalse
otherConfigMapNameOtherConfigMapName is a ConfigMap name of other configurations file(eg. banned-ips.json, ops.json etc)*stringfalse
rconPasswordSecretNameRconPasswordSecretName is a Secret name for RCON password.*stringfalse
autoPauseAutoPause configurationAutoPausefalse
backupBackup configurationBackupfalse
externalHostnameExternalHostname is the custom hostname for mc-router routing. If not set, FQDN will be generated as ... Only used when mc-router is enabled on the controller.*stringfalse

Back to Custom Resources

ObjectMeta

ObjectMeta is metadata of objects. This is partially copied from metav1.ObjectMeta.

FieldDescriptionSchemeRequired
nameName is the name of the object.stringfalse
labelsLabels is a map of string keys and values.map[string]stringfalse
annotationsAnnotations is a map of string keys and values.map[string]stringfalse

Back to Custom Resources

Ops

Ops represents the ops.json file.

FieldDescriptionSchemeRequired
usersuser name exec /op or /deop[]stringfalse

Back to Custom Resources

PersistentVolumeClaim

PersistentVolumeClaim is a user’s request for and claim to a persistent volume. This is slightly modified from corev1.PersistentVolumeClaim.

FieldDescriptionSchemeRequired
metadataStandard object’s metadata.ObjectMetatrue
specSpec defines the desired characteristics of a volume requested by a pod author.corev1.PersistentVolumeClaimSpectrue

Back to Custom Resources

PodTemplateSpec

PodTemplateSpec describes the data a pod should have when created from a template. This is slightly modified from corev1.PodTemplateSpec.

FieldDescriptionSchemeRequired
metadataStandard object’s metadata. The name in this metadata is ignored.ObjectMetafalse
specSpecification of the desired behavior of the pod. The name of the Minecraft server container in this spec must be minecraft.corev1.PodSpectrue

Back to Custom Resources

ServiceTemplate

ServiceTemplate define the desired spec and annotations of Service.

FieldDescriptionSchemeRequired
metadataStandard object’s metadata. Only annotations and labels are valid.ObjectMetafalse
specSpec is the ServiceSpec*corev1.ServiceSpecfalse

Back to Custom Resources

Whitelist

Whitelist represents the whitelist.json file.

FieldDescriptionSchemeRequired
enabledexec /whitelist onbooltrue
usersuser name exec /whitelist add or /whitelist remove[]stringfalse

Back to Custom Resources

Protocol Documentation

Table of Contents

Top

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

FieldTypeLabelDescription
usersstringrepeated

SyncOpsResponse

SyncOpsResponse is the response message of SyncOps

SyncWhitelistRequest

SyncWhitelistRequest is the request message to exec /whitelist via rcon

FieldTypeLabelDescription
enabledbool
usersstringrepeated

SyncWhitelistResponse

SyncWhitelistResponse is the response message of SyncWhitelist

Agent

Agent provides services for MCing.

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)