Dumping ground for working files for Kubernetes.
Talos Linux: v1.13.0
Kubelet: v1.36.0
Metallb: v0.15.3
| README.md | ||
Pi Cluster - Kubernetes on Talos Linux
Prerequisites
talosctlinstalledkubectlinstalledhelminstalled- DNS record for
controlplane.cdb-online.co.ukpointing to VIP10.0.1.11
1. Generate Configuration
Generate secrets only
talosctl gen secrets -o secrets.yaml
Generate full config using secrets
talosctl gen config pi-cluster https://controlplane.cdb-online.co.uk:6443 \
--with-secrets secrets.yaml \
--config-patch @patches/t1-vip-patch.yaml \
--output-dir ./
secrets.yamlcontains your cluster CA, tokens, and keys. Keep this safe and never commit it to git.
2. Validate Config
talosctl validate --config controlplane.yaml --mode metal
talosctl validate --config worker.yaml --mode metal
3. Apply Configuration
Controlplane nodes (one at a time)
talosctl apply-config --nodes 10.0.1.12 --endpoints 10.0.1.12 --file controlplane.yaml
talosctl apply-config --nodes 10.0.1.13 --endpoints 10.0.1.13 --file controlplane.yaml
talosctl apply-config --nodes 10.0.1.14 --endpoints 10.0.1.14 --file controlplane.yaml
Worker nodes
talosctl apply-config --nodes 10.0.1.21 --endpoints 10.0.1.21 --file worker.yaml
talosctl apply-config --nodes 10.0.1.22 --endpoints 10.0.1.22 --file worker.yaml
talosctl apply-config --nodes 10.0.1.23 --endpoints 10.0.1.23 --file worker.yaml
4. Bootstrap etcd
Only run this ONCE on the first controlplane node:
talosctl bootstrap --nodes 10.0.1.12 --endpoints 10.0.1.12
5. Watch Cluster Come Up
talosctl health --nodes 10.0.1.12 --endpoints 10.0.1.12
Wait for VIP 10.0.1.11 to appear before proceeding:
ping 10.0.1.11
6. Export Kubeconfig
One time export
talosctl --nodes controlplane.cdb-online.co.uk \
--endpoints controlplane.cdb-online.co.uk \
kubeconfig ~/.kube/config
Make it permanent - add to ~/.bashrc or ~/.zshrc
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
source ~/.bashrc
Verify kubectl is working
kubectl cluster-info
kubectl get nodes
7. Install MetalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml
Wait for MetalLB to be ready:
kubectl wait --namespace metallb-system \
--for=condition=ready pod \
--selector=app=metallb \
--timeout=90s
Apply IP pool:
kubectl apply -f metallb/metallb.yaml
8. Deploy Applications
# Create namespaces and storage
kubectl apply -f deployments/grav-www-paulcdb-com.yaml
kubectl apply -f deployments/grav-www-cdb-online-co-uk.yaml
kubectl apply -f deployments/grav-www-holyislandarc-club.yaml
kubectl apply -f deployments/vaultwarden.yaml
kubectl apply -f deployments/uptimekuma.yaml
kubectl apply -f deployments/pairdrop.yaml
kubectl apply -f deployments/it-tools.yaml
kubectl apply -f deployments/forgejo.yaml
kubectl apply -f deployments/changedetection.yaml
Watch pods come up:
kubectl get pods -A -w
Check services have IPs:
kubectl get svc -A | grep LoadBalancer
9. Install Monitoring (kube-prometheus-stack)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--values monitoring/kube-prometheus-values.yaml
Watch monitoring come up:
kubectl get pods -n monitoring -w
10. Updating Talos
Bump version in controlplane.yaml and worker.yaml
machine:
install:
image: ghcr.io/siderolabs/installer:v1.14.0
Apply to controlplane nodes one at a time
talosctl apply-config --nodes 10.0.1.12 --endpoints 10.0.1.12 --file controlplane.yaml
# Wait for node to come back before doing the next one
talosctl apply-config --nodes 10.0.1.13 --endpoints 10.0.1.13 --file controlplane.yaml
talosctl apply-config --nodes 10.0.1.14 --endpoints 10.0.1.14 --file controlplane.yaml
Apply to worker nodes
talosctl apply-config --nodes 10.0.1.21 --endpoints 10.0.1.21 --file worker.yaml
talosctl apply-config --nodes 10.0.1.22 --endpoints 10.0.1.22 --file worker.yaml
talosctl apply-config --nodes 10.0.1.23 --endpoints 10.0.1.23 --file worker.yaml
11. Updating Containers
Restart a deployment to pull latest image
kubectl rollout restart deployment <name> -n <namespace>
Apply updated yaml with new version
kubectl apply -f deployments/<name>.yaml
Check rollout status
kubectl rollout status deployment <name> -n <namespace>
12. Using Secrets in Deployments
Create a secret
kubectl create secret generic <name> \
--from-literal=KEY=value \
--namespace <namespace>
Reference in deployment yaml
env:
- name: MY_PASSWORD
valueFrom:
secretKeyRef:
name: <secret-name>
key: KEY
View existing secrets
kubectl get secrets -n <namespace>
kubectl describe secret <name> -n <namespace>
13. Useful Commands
Talos
# Dashboard
talosctl dashboard --nodes 10.0.1.12 --endpoints 10.0.1.12
# Logs
talosctl logs etcd --nodes 10.0.1.12 --endpoints 10.0.1.12
# Service status
talosctl service etcd --nodes 10.0.1.12 --endpoints 10.0.1.12
# Node health
talosctl health --nodes 10.0.1.12 --endpoints 10.0.1.12
Kubernetes
# Get all pods
kubectl get pods -A
# Get all services
kubectl get svc -A
# Describe a pod
kubectl describe pod <pod-name> -n <namespace>
# Pod logs
kubectl logs -n <namespace> -l app=<name>
kubectl logs -n <namespace> -l app=<name> --previous
# Restart deployment
kubectl rollout restart deployment <name> -n <namespace>
# Watch pods
kubectl get pods -A -w
# Get events
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
MetalLB
# Check IP pools
kubectl get ipaddresspools -n metallb-system
# Check advertisements
kubectl get l2advertisements -n metallb-system
# Annotate service with shared IP
kubectl annotate svc <name> -n <namespace> metallb.io/address-pool=metallb-ips --overwrite
kubectl annotate svc <name> -n <namespace> metallb.io/loadBalancerIPs=10.0.1.100 --overwrite
kubectl annotate svc <name> -n <namespace> metallb.io/allow-shared-ip=shared-web --overwrite
Caddy Reverse Proxy Example
www.paulcdb.com {
reverse_proxy 10.0.1.100:8100
}
vault.paulcdb.com {
reverse_proxy 10.0.1.100:8600
}
status.paulcdb.com {
reverse_proxy 10.0.1.100:3001
}
git.paulcdb.com {
reverse_proxy 10.0.1.100:3000
}
drop.paulcdb.com {
reverse_proxy 10.0.1.100:3000
}
File Structure
pi-cluster/
├── README.md
├── secrets.yaml # NEVER COMMIT - add to .gitignore
├── controlplane.yaml
├── worker.yaml
├── patches/
│ └── t1-vip-patch.yaml
├── metallb/
│ └── metallb.yaml
├── monitoring/
│ └── kube-prometheus-values.yaml
└── deployments/
├── grav-www-paulcdb-com.yaml
├── grav-www-cdb-online-co-uk.yaml
├── grav-www-holyislandarc-club.yaml
├── vaultwarden.yaml
├── uptimekuma.yaml
├── pairdrop.yaml
├── it-tools.yaml
├── forgejo.yaml
├── changedetection.yaml
└── spoolman.yaml
Important Notes
- Never commit
secrets.yamlto git — add it to.gitignore - Always apply controlplane updates one node at a time to maintain etcd quorum
- Only run
bootstraponce on initial cluster setup - All services sharing
10.0.1.100must have themetallb.io/allow-shared-ip: shared-webannotation - MetalLB pool name is
metallb-ips - NFS server is at
10.0.1.5
Add secrets.yaml to .gitignore before pushing to Forgejo:
echo "secrets.yaml" >> .gitignore