No description
  • Go 82%
  • Makefile 16%
  • Dockerfile 1.4%
  • Shell 0.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Noah Feldt e448721a17 add ssh
2026-09-27 20:50:02 +02:00
.devcontainer add ssh 2026-09-27 20:50:02 +02:00
.forgejo/workflows fix runner v1 2026-08-17 21:21:47 +02:00
.github/workflows Inital Commit 2026-08-17 21:02:56 +02:00
api/v1alpha1 add ssh 2026-09-27 20:50:02 +02:00
cmd add ssh 2026-09-27 20:50:02 +02:00
config add ssh 2026-09-27 20:50:02 +02:00
hack Inital Commit 2026-08-17 21:02:56 +02:00
internal add ssh 2026-09-27 20:50:02 +02:00
test Inital Commit 2026-08-17 21:02:56 +02:00
.dockerignore Inital Commit 2026-08-17 21:02:56 +02:00
.gitignore add ssh 2026-09-27 20:50:02 +02:00
.golangci.yml Inital Commit 2026-08-17 21:02:56 +02:00
Dockerfile add ssh 2026-09-27 20:50:02 +02:00
go.mod add ssh 2026-09-27 20:50:02 +02:00
go.sum add ssh 2026-09-27 20:50:02 +02:00
Makefile add ssh 2026-09-27 20:50:02 +02:00
PROJECT Inital Commit 2026-08-17 21:02:56 +02:00
README.md add ssh 2026-09-27 20:50:02 +02:00

minecraftinator

// TODO(user): Add simple overview of use/purpose

Description

// TODO(user): An in-depth paragraph about your project and overview of use

Getting Started

Prerequisites

  • go version v1.26.0+
  • docker version 17.03+.
  • kubectl version v1.11.3+.
  • Access to a Kubernetes v1.11.3+ cluster.

To Deploy on the cluster

Build and push your image to the location specified by IMG:

make docker-build docker-push IMG=<some-registry>/minecraftinator:tag

NOTE: This image ought to be published in the personal registry you specified. And it is required to have access to pull the image from the working environment. Make sure you have the proper permission to the registry if the above commands don’t work.

Install the CRDs into the cluster:

make install

Deploy the Manager to the cluster with the image specified by IMG:

make deploy IMG=<some-registry>/minecraftinator:tag

NOTE: If you encounter RBAC errors, you may need to grant yourself cluster-admin privileges or be logged in as admin.

Create instances of your solution You can apply the samples (examples) from the config/sample:

kubectl apply -k config/samples/

NOTE: Ensure that the samples has default values to test it out.

To Uninstall

Delete the instances (CRs) from the cluster:

kubectl delete -k config/samples/

Delete the APIs(CRDs) from the cluster:

make uninstall

UnDeploy the controller from the cluster:

make undeploy

Project Distribution

Following the options to release and provide this solution to the users.

By providing a bundle with all YAML files

  1. Build the installer for the image built and published in the registry:
make build-installer IMG=<some-registry>/minecraftinator:tag

NOTE: The makefile target mentioned above generates an 'install.yaml' file in the dist directory. This file contains all the resources built with Kustomize, which are necessary to install this project without its dependencies.

  1. Using the installer

Users can just run 'kubectl apply -f ' to install the project, i.e.:

kubectl apply -f https://raw.githubusercontent.com/<org>/minecraftinator/<tag or branch>/dist/install.yaml

By providing a Helm Chart

  1. Build the chart using the optional helm plugin
operator-sdk edit --plugins=helm/v1-alpha
  1. See that a chart was generated under 'dist/chart', and users can obtain this solution from there.

NOTE: If you change the project, you need to update the Helm Chart using the same command above to sync the latest changes. Furthermore, if you create webhooks, you need to use the above command with the '--force' flag and manually ensure that any custom configuration previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' is manually re-applied afterwards.

Contributing

// TODO(user): Add detailed information on how you would like others to contribute to this project

NOTE: Run make help for more information on all potential make targets

More information can be found via the Kubebuilder Documentation

License

Copyright 2026.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Minecraft console over SSH

The optional SSH gateway is a separate deployment with one shared LoadBalancer Service (minecraftinator-ssh) for all servers and namespaces. The operator continues to manage Minecraft resources independently; the gateway has read-only Kubernetes permissions and routes authorized commands to each server's private RCON port. Adding a MinecraftServer does not create another SSH Service.

Each login selects one MinecraftServer using <namespace>.<resource-name> as the SSH username. Add the user's public key to that resource:

spec:
  sshAuthorizedKeys:
    - "ssh-ed25519 AAAA... user@laptop"

Use complete public keys, without authorized_keys options or certificates. An empty list disables access. Every authorized key grants full Minecraft command access, including stop, op, and world administration. Authorization is checked again before each command, so removing a key revokes existing sessions too.

Create a persistent SSH host key once, and store it in a Kubernetes Secret:

kubectl create namespace minecraftinator-system --dry-run=client -o yaml | kubectl apply -f -
ssh-keygen -t ed25519 -N '' -f ./ssh_host_ed25519_key
kubectl -n minecraftinator-system create secret generic minecraftinator-ssh-host-key \
  --from-file=ssh_host_ed25519_key=./ssh_host_ed25519_key
ssh-keygen -lf ./ssh_host_ed25519_key.pub

Keep the private key out of source control. Retain the Secret across deployments so that users see a stable SSH host identity. Verify the host fingerprint above when connecting for the first time.

Build and push the controller image as described above, set its reference, and apply the SSH overlay (in place of make deploy):

(cd config/ssh && ../../bin/kustomize edit set image controller=<registry>/minecraftinator:<tag>)
bin/kustomize build config/ssh | kubectl apply -f -
kubectl -n minecraftinator-system get service minecraftinator-ssh

Connect to that Service's external IP or hostname:

ssh -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample <ssh-host>
# minecraft> list
# minecraft> say Hello from SSH
# minecraft> exit

# Single commands also work:
ssh -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample <ssh-host> 'list'

For a local Kind cluster without a LoadBalancer implementation, forward the SSH Service to your machine, then use port 22222:

kubectl -n minecraftinator-system port-forward service/minecraftinator-ssh 22222:22
# In another terminal:
ssh -p 22222 -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample 127.0.0.1

Allow at least 4 GiB RAM for the container VM when running Kind and Minecraft locally; a 2 GiB VM ran out of memory during the integration test.

All users connect to the same <ssh-host>:22; only their username and authorized key change. For example, these consoles share the same endpoint:

ssh -l games.survival <ssh-host>
ssh -l games.creative <ssh-host>
ssh -l another-namespace.survival <ssh-host>

Minecraft game Services are unchanged and remain separate from this SSH endpoint. The proxy does not expose a raw RCON port or require client-side RCON software.

The gateway forwards commands to the selected server's private RCON port and reads its password from the existing <resource-name>-rcon Secret. Users do not need Kubernetes credentials or the RCON password. SSH encrypts the client-to-gateway connection; the RCON hop stays inside the cluster and is not encrypted. Allow the gateway to reach Minecraft pods on TCP 25575 when using NetworkPolicies. The public Minecraft Service continues to expose only the game port.

The console provides command responses, not a live server-log stream. exit or Ctrl-D disconnects. OS shells, SFTP and SSH port forwarding are disabled. A failed command is never retried automatically because it may already have executed.

For local development:

go run ./cmd/gateway --ssh-bind-address=:2222 \
  --ssh-host-key=/path/to/ssh_host_ed25519_key

The gateway needs Kubernetes credentials and network access to Minecraft pod IPs. The operator binary does not accept SSH connections.

To migrate from an older deployment that served SSH inside the operator, apply the updated config/ssh overlay with an image containing both binaries. The existing Service name, SSH host-key Secret, usernames, and authorized keys stay the same; existing SSH sessions disconnect during the rollout.