feat: add home-assistant-dashboard-conventions skill + update multiple skills
- New: smart-home/home-assistant-dashboard-conventions (Mushroom cards, view tabs, no Bubble Cards) - Updated: rke2, ceph, galera, proxmox, brainstorming, compound-learning, 1password-cli, smart-home-automation skills - New references: ceph-cluster-administration, docker-volume-forensics, ceph-crush-weight, ceph-ec-mixed-size
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
# Traefik LXC → K8s Migration (2026-07-14)
|
||||
|
||||
## CT99999 Inventory (Source)
|
||||
|
||||
- **Location:** proxmox7, VLAN 60, IP `10.0.60.10/24`
|
||||
- **Traefik version:** 3.4.1
|
||||
- **Static config:** `/etc/traefik/traefik.yaml`
|
||||
- **Dynamic config:** `/etc/traefik/conf.d/` (file provider, watch=true)
|
||||
- **TLS:** Let's Encrypt via TLS challenge, `acme.json` at `/etc/traefik/ssl/acme.json`
|
||||
- **Entry Points:** web (:80 → redirect to :443), websecure (:443), traefik (:8080 dashboard)
|
||||
|
||||
## Services on CT99999
|
||||
|
||||
| Router | Host | Backend | Port | Notes |
|
||||
|--------|------|---------|------|-------|
|
||||
| grafana | grafana.familie-schoen.com | 10.0.30.141 | 3000 | CT141 monitoring |
|
||||
| librechat | chat.familie-schoen.com, chat.schoen.eu | 10.0.30.102 | 8080 | LibreChat VM |
|
||||
| seafile_old | seafile.familie-schoen.com | 10.0.30.100 | 8081 | Seafile old |
|
||||
| imkerei | imkerei.familie-schoen.com | 10.0.30.100 | 80 | Catchall forwarder |
|
||||
| immich | immich.familie-schoen.com | 10.0.30.99 | 2283 | Immich |
|
||||
| paperless | dokumente.familie-schoen.com | 10.0.30.101 | 8000 | CT104 paperless |
|
||||
| homeassistant | homeassistant.familie-schoen.com | 10.0.30.10 | 8123 | VM106 HA |
|
||||
| seafile | cloud.familie-schoen.com | 10.0.30.99 | 80 | Seafile |
|
||||
| seadoc | cloud.familie-schoen.com + /sdoc-server | 10.0.30.99 | 8888 | SeaDoc, stripPrefix middleware |
|
||||
| authelia | auth.familie-schoen.com | 192.168.100.11 | 9091 | CT112 authelia |
|
||||
| authelia-admin | auth-admin.familie-schoen.com | 192.168.100.11 | 9092 | CT112 authelia admin |
|
||||
| gitea | git.familie-schoen.com | 10.0.30.105 | 3000 | CT108 (being replaced by K8s) |
|
||||
| catchall-tcp | HostSNI(`*`) passthrough | 10.0.30.100 | 80 | TCP catchall |
|
||||
|
||||
## K8s Traefik (Target)
|
||||
|
||||
- **Type:** DaemonSet `rke2-traefik` in `kube-system`
|
||||
- **Ports:** hostPort 80 + 443 on all 6 nodes (10.0.30.51-53, .61-63)
|
||||
- **IngressClass:** `traefik`
|
||||
- **Existing Ingresses:** argocd-server (argocd ns), gitea (gitea ns)
|
||||
- **Needs:** Let's Encrypt certResolver (not configured by default)
|
||||
|
||||
## HA Failover VIP via Cilium L2 (Implemented 2026-07-14)
|
||||
|
||||
### Architecture
|
||||
|
||||
Instead of pointing the firewall NAT at a single K8s node (SPOF), a
|
||||
`LoadBalancer` Service requests a VIP from the existing Cilium LB IPAM
|
||||
pool. Cilium announces the VIP via ARP on one node; auto-failover to
|
||||
another node on failure (~1-2s).
|
||||
|
||||
```
|
||||
Firewall NAT → 10.0.30.203 (Cilium VIP)
|
||||
↓ L2 Announcement (ARP)
|
||||
[aktiver K8s Node — Traefik DaemonSet]
|
||||
Automatisches Failover bei Node-Ausfall (~1-2s)
|
||||
```
|
||||
|
||||
### Components Deployed
|
||||
|
||||
| Component | File | Purpose |
|
||||
|-----------|------|---------|
|
||||
| `Service` (LoadBalancer) | `clusters/main/proxy/traefik-lb-service.yaml` | VIP `.203`, selects Traefik pods |
|
||||
| `Namespace` | `clusters/main/proxy/namespace.yaml` | Shared proxy namespace |
|
||||
| ArgoCD App | `clusters/main/apps/proxy.yaml` | GitOps for proxy namespace |
|
||||
|
||||
### traefik-lb-service.yaml
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: traefik-lb
|
||||
namespace: kube-system
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: 10.0.30.203
|
||||
selector:
|
||||
app.kubernetes.io/instance: rke2-traefik-kube-system
|
||||
app.kubernetes.io/name: rke2-traefik
|
||||
ports:
|
||||
- name: web
|
||||
port: 80
|
||||
targetPort: web
|
||||
- name: websecure
|
||||
port: 443
|
||||
targetPort: websecure
|
||||
```
|
||||
|
||||
### Why Cilium L2 (not MetalLB/keepalived)
|
||||
|
||||
- Cilium L2 LB IPAM already running (3 services use it: .200, .201, .202)
|
||||
- No additional software needed
|
||||
- Automatic failover — no manual VIP management
|
||||
- Pool: `10.0.30.200–250` (CiliumLoadBalancerIPPool `default-pool`)
|
||||
- L2 policy: `default-l2-policy` announces LB IPs via ARP on `^eth[0-9]+`
|
||||
|
||||
### Verification
|
||||
|
||||
After deploying, tested from mgmt-runner (.124):
|
||||
- `10.0.30.203:80/443` → 404 (no default route — correct)
|
||||
- `git.schoen.codes` via VIP → Gitea 1.26.1 ✅
|
||||
- `argocd` via VIP → ArgoCD UI ✅
|
||||
|
||||
### Firewall Cutover
|
||||
|
||||
Change NAT target: `10.0.60.10` → `10.0.30.203` (one rule, instant cutover).
|
||||
Rollback: revert NAT to `10.0.60.10`. CT99999 stays running throughout.
|
||||
|
||||
## Pattern for External Backends (not in K8s)
|
||||
|
||||
Use `ExternalName` Service + `IngressRoute` CRD:
|
||||
|
||||
```yaml
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: proxy
|
||||
spec:
|
||||
entryPoints:
|
||||
- websecure
|
||||
routes:
|
||||
- match: Host(`grafana.familie-schoen.com`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: grafana-external
|
||||
port: 3000
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: grafana-external
|
||||
namespace: proxy
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: 10.0.30.141
|
||||
```
|
||||
|
||||
## SeaDoc StripPath Middleware
|
||||
|
||||
```yaml
|
||||
middlewares:
|
||||
seadoc-strippath:
|
||||
stripPrefix:
|
||||
prefixes:
|
||||
- /sdoc-server
|
||||
```
|
||||
|
||||
## Accessing CT99999
|
||||
|
||||
```bash
|
||||
# CT99999 is on proxmox7 (10.0.20.70)
|
||||
ssh -i ~/.ssh/id_ed25519_proxmox root@10.0.20.70 "pct exec 99999 -- ..."
|
||||
```
|
||||
|
||||
## Remaining Steps
|
||||
|
||||
1. Add Let's Encrypt certResolver via HelmChartConfig for `rke2-traefik`
|
||||
2. Create IngressRoute + ExternalName Service for each of the 11 external backends
|
||||
3. Handle catchall-TCP (make specific, not HostSNI(`*`) — see pitfall in SKILL.md)
|
||||
4. Cutover firewall NAT: `10.0.60.10` → `10.0.30.203`
|
||||
5. Verify each service, then decommission CT99999 after 1 week
|
||||
|
||||
## Reference
|
||||
|
||||
Full migration plan: `docs/plans/2026-07-14-traefik-ct99999-k8s-migration.md` in iac-homelab repo.
|
||||
Reference in New Issue
Block a user