k8s-mgmt-pod/k8s
2026-06-23 15:29:06 +02:00
..
deployment.yaml Update entrypoint.sh to prevent failure on missing password entry and modify deployment.yaml to use latest image tag with Always pull policy 2026-06-23 15:29:06 +02:00
kustomization.yaml initial commit 2026-06-23 15:06:17 +02:00
namespace.yaml initial commit 2026-06-23 15:06:17 +02:00
networkpolicy.yaml initial commit 2026-06-23 15:06:17 +02:00
rbac.yaml initial commit 2026-06-23 15:06:17 +02:00
README.md initial commit 2026-06-23 15:06:17 +02:00
secret.yaml.example initial commit 2026-06-23 15:06:17 +02:00
service.yaml initial commit 2026-06-23 15:06:17 +02:00
serviceaccount.yaml initial commit 2026-06-23 15:06:17 +02:00

Kubernetes deployment

These manifests deploy k8s-mgmt-pod as a single-replica bastion deployment inside its own namespace.

Before you apply

  1. Build and publish the image.
  2. Replace the placeholder image in deployment.yaml with a pinned tag or digest.
  3. Create the real k8s-mgmt-pod-auth Secret instead of applying secret.yaml.example.

Create the Secret

Public-key path:

kubectl -n k8s-mgmt-pod create secret generic k8s-mgmt-pod-auth \
  --from-literal=ADMIN_SSH_PUBKEY="$(cat ~/.ssh/id_ed25519.pub)" \
  --from-literal=USER_SSH_PUBKEY="$(cat ~/.ssh/id_ed25519.pub)" \
  --from-literal=ADMIN_PASSWORD='' \
  --from-literal=USER_PASSWORD=''

Password path:

kubectl -n k8s-mgmt-pod create secret generic k8s-mgmt-pod-auth \
  --from-literal=ADMIN_SSH_PUBKEY='' \
  --from-literal=USER_SSH_PUBKEY='' \
  --from-literal=ADMIN_PASSWORD='change-this-admin-password' \
  --from-literal=USER_PASSWORD='change-this-user-password'

Mixed key-plus-password path:

kubectl -n k8s-mgmt-pod create secret generic k8s-mgmt-pod-auth \
  --from-literal=ADMIN_SSH_PUBKEY="$(cat ~/.ssh/id_ed25519.pub)" \
  --from-literal=USER_SSH_PUBKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexample user@example" \
  --from-literal=ADMIN_PASSWORD='change-this-admin-password' \
  --from-literal=USER_PASSWORD='change-this-user-password'

With that configuration, both admin and user can authenticate with either their SSH key or their password.

Resolution order is per user:

  1. If a public key is supplied, key-based login is enabled.
  2. If a password is also supplied, password login is enabled too.
  3. If only a public key is supplied, password login is locked for that user.
  4. If neither is supplied, the container generates and logs a random password for that user.

Apply

kubectl apply -k k8s/

If you prefer individual files, apply namespace.yaml, serviceaccount.yaml, rbac.yaml, deployment.yaml, service.yaml, and networkpolicy.yaml after creating the real Secret.

Safe local access

Port-forward the service instead of exposing it externally by default:

kubectl -n k8s-mgmt-pod port-forward svc/k8s-mgmt-pod 2222:22 3000:3000

Then connect with:

ssh admin@localhost -p 2222

Or open http://localhost:3000/ssh in a browser.

RBAC note

The included Role is the most security-sensitive part of this deployment. It is namespace-scoped and avoids cluster-admin, but it still grants broad read/write access to common namespaced resources so lfk remains usable as a management tool. In particular, access to secrets, pods/exec, and workload mutation verbs may be too broad for your environment and should be reduced wherever possible.

Bastion note

This pod is a privileged operational entry point into the cluster. Treat it like a bastion: restrict who can reach it, monitor access, rotate credentials, and avoid using it as a general-purpose workstation.