LCMD db logoLCMD[db]

Kubernetes Setup

Guide for kubectl access and cluster deployment

Prerequisites

  1. kubectl installed locally
  2. SSH access to lcmd-app.epfl.ch
  3. Connected to EPFL network (or VPN)

kubectl Access

cd infrastructure/ansible
ansible-playbook playbooks/setup_kubectl.yml

Manual Setup

# 1. SSH tunnel (keep open)
ssh -L 6443:localhost:6443 root@lcmd-app.epfl.ch

# 2. Configure kubectl
kubectl config set-cluster lcmd-cluster --server=https://localhost:6443
kubectl config set-credentials lcmd-cluster --token=<node-token>
kubectl config set-context lcmd-cluster --cluster=lcmd-cluster --user=lcmd-cluster
kubectl config use-context lcmd-cluster

Get the token from the server:

ssh root@lcmd-app.epfl.ch "cat /var/lib/rancher/k3s/server/node-token"

Secrets Management

We use SOPS + age for secret encryption. Secrets are stored encrypted in Git and decrypted by ArgoCD at deploy time.

Decrypting Secrets

# Set up age key (get from 1Password)
mkdir -p ~/.config/sops/age
echo "AGE-SECRET-KEY-..." > ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt

# Decrypt and edit
cd infrastructure/kubernetes/app/overlays/prod
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops secrets.enc.yaml

Adding New Secrets

# Edit the plaintext file
vim secrets.yaml

# Encrypt
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops --encrypt secrets.yaml > secrets.enc.yaml

# Commit only the encrypted version
git add secrets.enc.yaml

Never commit secrets.yaml (unencrypted). It's in .gitignore.

Recreating the Cluster

Provision the server

cd infrastructure/ansible
ansible-playbook playbooks/setup_server.yml
ansible-playbook playbooks/setup_k3s.yml

Configure storage

Point local-path provisioner at /data:

kubectl apply -k infrastructure/kubernetes/storage/
kubectl rollout restart deployment/local-path-provisioner -n kube-system

Install core components

# Sealed Secrets controller
kubectl apply -k infrastructure/kubernetes/sealed-secrets/

# ArgoCD + Image Updater + Applications
kubectl create namespace argocd
kubectl apply -k infrastructure/kubernetes/argocd/

Configure the ArgoCD SOPS key

kubectl create secret generic sops-age-key \
  --namespace argocd \
  --from-literal=keys.txt="AGE-SECRET-KEY-..."
kubectl rollout restart deployment/argocd-repo-server -n argocd

Verify

kubectl -n argocd get applications
kubectl -n prod get pods

# ArgoCD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# → https://localhost:8080

# Admin password
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

Resource Allocation

Optimized for 4-core, 8GB RAM VPS:

ComponentCPU ReqCPU LimitMem ReqMem Limit
Backend200m1000m512Mi1Gi
Frontend150m500m256Mi512Mi
PostgreSQL100m500m256Mi1Gi
MinIO100m500m256Mi512Mi
Docs100m200m128Mi256Mi

Troubleshooting

# Check pod status
kubectl -n prod get pods
kubectl -n prod describe pod <pod-name>
kubectl -n prod logs <pod-name>

# Check ArgoCD sync status
kubectl -n argocd get applications
kubectl -n argocd describe application lcmd-app

# Verify secrets decryption
kubectl -n prod get secrets

On this page