feat(gitops): migrate domain to riotpiao.com, add CNPG + Forgejo HA on Redis/Postgres, wire ArgoCD apps — enables cluster rebuild after etcd wipe and unblocks the git-source chicken-egg via standalone Helm-source Applications
This commit is contained in:
+2
-2
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
# ── Cluster Configuration ──────────────────────────────────────────────────────
|
# ── Cluster Configuration ──────────────────────────────────────────────────────
|
||||||
# Base domain for external services (Authentik, MinIO, Forgejo, etc.)
|
# Base domain for external services (Authentik, MinIO, Forgejo, etc.)
|
||||||
# Example: riotpiao.homelab.com
|
# Example: riotpiao.com
|
||||||
CLUSTER_DOMAIN=riotpiao.homelab.com
|
CLUSTER_DOMAIN=riotpiao.com
|
||||||
|
|
||||||
# Internal Kubernetes DNS names (svc.cluster.local)
|
# Internal Kubernetes DNS names (svc.cluster.local)
|
||||||
# Only change these if your cluster domain differs
|
# Only change these if your cluster domain differs
|
||||||
|
|||||||
+5
-5
@@ -83,7 +83,7 @@ Resources: 23
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Requires secrets:**
|
**Requires secrets:**
|
||||||
- `ARGOCD_SERVER`: ArgoCD server URL (https://argocd.riotpiao.homelab.com)
|
- `ARGOCD_SERVER`: ArgoCD server URL (https://argocd.riotpiao.com)
|
||||||
- `ARGOCD_AUTH_TOKEN`: ArgoCD API token (generate via ArgoCD UI)
|
- `ARGOCD_AUTH_TOKEN`: ArgoCD API token (generate via ArgoCD UI)
|
||||||
|
|
||||||
### 3. security-scan.yaml (Optional)
|
### 3. security-scan.yaml (Optional)
|
||||||
@@ -131,7 +131,7 @@ Resources: 23
|
|||||||
```bash
|
```bash
|
||||||
# On runner machine (inside cluster or external)
|
# On runner machine (inside cluster or external)
|
||||||
forgejo-runner register \
|
forgejo-runner register \
|
||||||
--instance https://forgejo.riotpiao.homelab.com \
|
--instance https://forgejo.riotpiao.com \
|
||||||
--token <registration-token> \
|
--token <registration-token> \
|
||||||
--name homelab-runner \
|
--name homelab-runner \
|
||||||
--labels docker
|
--labels docker
|
||||||
@@ -145,7 +145,7 @@ forgejo-runner daemon
|
|||||||
# Go to: Forgejo → Settings → Secrets
|
# Go to: Forgejo → Settings → Secrets
|
||||||
|
|
||||||
# Add:
|
# Add:
|
||||||
ARGOCD_SERVER = https://argocd.riotpiao.homelab.com
|
ARGOCD_SERVER = https://argocd.riotpiao.com
|
||||||
ARGOCD_AUTH_TOKEN = <token> # Generate: argocd account generate-token
|
ARGOCD_AUTH_TOKEN = <token> # Generate: argocd account generate-token
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ kubeval k8s/platform/minio/config.yaml
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check ArgoCD UI
|
# Check ArgoCD UI
|
||||||
# https://argocd.riotpiao.homelab.com → homelab-root
|
# https://argocd.riotpiao.com → homelab-root
|
||||||
|
|
||||||
# Or CLI
|
# Or CLI
|
||||||
argocd app get homelab-root
|
argocd app get homelab-root
|
||||||
@@ -286,7 +286,7 @@ Repository → Actions
|
|||||||
### ArgoCD UI
|
### ArgoCD UI
|
||||||
|
|
||||||
```
|
```
|
||||||
https://argocd.riotpiao.homelab.com
|
https://argocd.riotpiao.com
|
||||||
├─ homelab-root
|
├─ homelab-root
|
||||||
│ ├─ Status: Synced ✓
|
│ ├─ Status: Synced ✓
|
||||||
│ ├─ Health: Healthy ✓
|
│ ├─ Health: Healthy ✓
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/infrastructure # Start with Layer 0
|
path: k8s/infrastructure # Start with Layer 0
|
||||||
destination:
|
destination:
|
||||||
@@ -184,7 +184,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/bootstrap
|
path: k8s/bootstrap
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/infrastructure
|
path: k8s/infrastructure
|
||||||
destination:
|
destination:
|
||||||
@@ -382,7 +382,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/bootstrap
|
path: k8s/bootstrap
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Edit `.env` and fill in cluster configuration. See `.env.example` for all option
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Cluster configuration
|
# Cluster configuration
|
||||||
CLUSTER_DOMAIN=riotpiao.homelab.com # Your cluster domain
|
CLUSTER_DOMAIN=riotpiao.com # Your cluster domain
|
||||||
POSTGRES_HOST=ddb-cluster-rw.ddb.svc.cluster.local
|
POSTGRES_HOST=ddb-cluster-rw.ddb.svc.cluster.local
|
||||||
MINIO_ENDPOINT=minio.storage.svc.cluster.local:9000
|
MINIO_ENDPOINT=minio.storage.svc.cluster.local:9000
|
||||||
KAFKA_BOOTSTRAP=kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092
|
KAFKA_BOOTSTRAP=kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092
|
||||||
@@ -285,15 +285,15 @@ Add to `/etc/hosts` on every client machine (Mac/Linux):
|
|||||||
|
|
||||||
```
|
```
|
||||||
# WireGuard access (remote — via talos-cp-1)
|
# WireGuard access (remote — via talos-cp-1)
|
||||||
10.6.0.1 grafana.riotpiao.homelab.com authentik.riotpiao.homelab.com vault.riotpiao.homelab.com minio.riotpiao.homelab.com prometheus.riotpiao.homelab.com portainer.riotpiao.homelab.com longhorn.riotpiao.homelab.com loki.riotpiao.homelab.com forgejo.riotpiao.homelab.com temporal.riotpiao.homelab.com temporal-grpc.riotpiao.homelab.com kmsvc.riotpiao.homelab.com
|
10.6.0.1 grafana.riotpiao.com authentik.riotpiao.com vault.riotpiao.com minio.riotpiao.com prometheus.riotpiao.com portainer.riotpiao.com longhorn.riotpiao.com loki.riotpiao.com forgejo.riotpiao.com temporal.riotpiao.com temporal-grpc.riotpiao.com kmsvc.riotpiao.com
|
||||||
|
|
||||||
# LAN access (on the home network — use actual LoadBalancer IP from above)
|
# LAN access (on the home network — use actual LoadBalancer IP from above)
|
||||||
192.168.1.160 grafana.riotpiao.homelab.com authentik.riotpiao.homelab.com vault.riotpiao.homelab.com minio.riotpiao.homelab.com prometheus.riotpiao.homelab.com portainer.riotpiao.homelab.com longhorn.riotpiao.homelab.com loki.riotpiao.homelab.com forgejo.riotpiao.homelab.com temporal.riotpiao.homelab.com temporal-grpc.riotpiao.homelab.com kmsvc.riotpiao.homelab.com
|
192.168.1.160 grafana.riotpiao.com authentik.riotpiao.com vault.riotpiao.com minio.riotpiao.com prometheus.riotpiao.com portainer.riotpiao.com longhorn.riotpiao.com loki.riotpiao.com forgejo.riotpiao.com temporal.riotpiao.com temporal-grpc.riotpiao.com kmsvc.riotpiao.com
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** `192.168.1.160` is an example Cilium LB-IPAM assignment. Verify with `kubectl get svc -n ingress-nginx ingress-nginx`.
|
**Note:** `192.168.1.160` is an example Cilium LB-IPAM assignment. Verify with `kubectl get svc -n ingress-nginx ingress-nginx`.
|
||||||
|
|
||||||
**There is no real DNS wildcard for `*.riotpiao.homelab.com`** — every hostname must be added to `/etc/hosts` explicitly (as above) before it resolves. Adding a new Ingress host doesn't make it reachable by itself; add the line too.
|
**There is no real DNS wildcard for `*.riotpiao.com`** — every hostname must be added to `/etc/hosts` explicitly (as above) before it resolves. Adding a new Ingress host doesn't make it reachable by itself; add the line too.
|
||||||
|
|
||||||
### kubectl Context
|
### kubectl Context
|
||||||
|
|
||||||
@@ -310,14 +310,14 @@ Then access services at:
|
|||||||
|
|
||||||
| Service | URL | Credentials |
|
| Service | URL | Credentials |
|
||||||
|---------|-----|-------------|
|
|---------|-----|-------------|
|
||||||
| Grafana | http://grafana.riotpiao.homelab.com | admin / `GRAFANA_ADMIN_PASSWORD` or Authentik SSO |
|
| Grafana | http://grafana.riotpiao.com | admin / `GRAFANA_ADMIN_PASSWORD` or Authentik SSO |
|
||||||
| Authentik | http://authentik.riotpiao.homelab.com | akadmin / see `.env` |
|
| Authentik | http://authentik.riotpiao.com | akadmin / see `.env` |
|
||||||
| Vault | http://vault.riotpiao.homelab.com | root token / see `setup_vault.sh` output |
|
| Vault | http://vault.riotpiao.com | root token / see `setup_vault.sh` output |
|
||||||
| MinIO console | http://minio.riotpiao.homelab.com | `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` |
|
| MinIO console | http://minio.riotpiao.com | `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` |
|
||||||
| Prometheus | http://prometheus.riotpiao.homelab.com | no auth |
|
| Prometheus | http://prometheus.riotpiao.com | no auth |
|
||||||
| Portainer | http://portainer.riotpiao.homelab.com | set on first visit |
|
| Portainer | http://portainer.riotpiao.com | set on first visit |
|
||||||
| Longhorn | http://longhorn.riotpiao.homelab.com | no auth |
|
| Longhorn | http://longhorn.riotpiao.com | no auth |
|
||||||
| Forgejo *(planned)* | https://forgejo.forge.riotpiao.homelab.com | `rock` / `FORGEJO_ADMIN_PASSWORD`, or Authentik SSO |
|
| Forgejo *(planned)* | https://forgejo.forge.riotpiao.com | `rock` / `FORGEJO_ADMIN_PASSWORD`, or Authentik SSO |
|
||||||
| Argo CD *(planned)* | `kubectl port-forward -n argocd svc/argocd-server 8080:443` | Authentik SSO (admins only) |
|
| Argo CD *(planned)* | `kubectl port-forward -n argocd svc/argocd-server 8080:443` | Authentik SSO (admins only) |
|
||||||
|
|
||||||
Grafana → "Homelab" folder has the operator dashboards (sidecar-loaded from `k8s/monitoring/dashboards/`, no restart needed on change):
|
Grafana → "Homelab" folder has the operator dashboards (sidecar-loaded from `k8s/monitoring/dashboards/`, no restart needed on change):
|
||||||
@@ -379,7 +379,7 @@ Authentik is the central OIDC identity provider. Vault stores secrets and delega
|
|||||||
│
|
│
|
||||||
│ OAuth2 / OIDC
|
│ OAuth2 / OIDC
|
||||||
▼
|
▼
|
||||||
Authentik (authentik.riotpiao.homelab.com)
|
Authentik (authentik.riotpiao.com)
|
||||||
├── grafana app → Grafana OIDC login (group → Admin/Viewer role)
|
├── grafana app → Grafana OIDC login (group → Admin/Viewer role)
|
||||||
├── minio app → MinIO OIDC login (group → readwrite/readonly policy)
|
├── minio app → MinIO OIDC login (group → readwrite/readonly policy)
|
||||||
├── vault-browser → Vault UI OIDC login / `vault login -method=oidc`
|
├── vault-browser → Vault UI OIDC login / `vault login -method=oidc`
|
||||||
@@ -387,7 +387,7 @@ Authentik is the central OIDC identity provider. Vault stores secrets and delega
|
|||||||
│
|
│
|
||||||
│ JWKS endpoint for JWT validation
|
│ JWKS endpoint for JWT validation
|
||||||
▼
|
▼
|
||||||
HashiCorp Vault (vault.riotpiao.homelab.com)
|
HashiCorp Vault (vault.riotpiao.com)
|
||||||
├── auth/jwt — core-cli authenticates with device code JWT
|
├── auth/jwt — core-cli authenticates with device code JWT
|
||||||
├── auth/oidc — browser/UI login via Authentik
|
├── auth/oidc — browser/UI login via Authentik
|
||||||
└── secret/ — KV v2: mcp/*, cluster/*, cloud/*
|
└── secret/ — KV v2: mcp/*, cluster/*, cloud/*
|
||||||
@@ -402,8 +402,8 @@ core put cluster/DUCKDNS_TOKEN DUCKDNS_TOKEN="abc" # field name = var
|
|||||||
**One-time IAM setup (after `helmfile apply`):**
|
**One-time IAM setup (after `helmfile apply`):**
|
||||||
```bash
|
```bash
|
||||||
# 1. Provision OIDC apps and groups in Authentik
|
# 1. Provision OIDC apps and groups in Authentik
|
||||||
GRAFANA_URL=http://grafana.riotpiao.homelab.com \
|
GRAFANA_URL=http://grafana.riotpiao.com \
|
||||||
MINIO_URL=http://minio.riotpiao.homelab.com \
|
MINIO_URL=http://minio.riotpiao.com \
|
||||||
python3 k8s/talos-iam/provision_oidc.py
|
python3 k8s/talos-iam/provision_oidc.py
|
||||||
|
|
||||||
# 2. Init Vault, wire JWT + OIDC auth, seed secrets
|
# 2. Init Vault, wire JWT + OIDC auth, seed secrets
|
||||||
@@ -487,7 +487,7 @@ Pods / Talos journal (both nodes)
|
|||||||
│
|
│
|
||||||
Grafana (logging ns) queries Loki + Prometheus via dashboards
|
Grafana (logging ns) queries Loki + Prometheus via dashboards
|
||||||
│
|
│
|
||||||
Nginx Ingress → grafana.riotpiao.homelab.com browser access
|
Nginx Ingress → grafana.riotpiao.com browser access
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example Applications & Workloads
|
## Example Applications & Workloads
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
# Cluster Recovery Plan
|
||||||
|
|
||||||
|
**Context:** Control-plane node (`talos-cp-1`, 192.168.1.213) had a corrupted machine CA in `terraform.tfvars`, causing a "broken key size" TLS error. During troubleshooting, an `apply-config` run with `install.wipe: true` (before the fix) wiped the OS/etcd disk (`sda`). Longhorn storage disks (`sdb`/`sdc`/`sdd`, ~1.26TB) were NOT touched and still hold data. etcd has since been re-bootstrapped fresh and empty; kube-apiserver/controller-manager/scheduler are running; node is `NotReady` (no CNI yet).
|
||||||
|
|
||||||
|
## Phase 1 — Get CNI up (blocks everything else)
|
||||||
|
|
||||||
|
Cluster config has `cni: name: none` (Cilium installs via Helm, not Talos-managed). Install via Helm, using KubePrism (already enabled, port 7445) as the API endpoint:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm repo add cilium https://helm.cilium.io/
|
||||||
|
helm repo update
|
||||||
|
helm install cilium cilium/cilium --namespace kube-system \
|
||||||
|
--set ipam.mode=kubernetes \
|
||||||
|
--set kubeProxyReplacement=true \
|
||||||
|
--set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \
|
||||||
|
--set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \
|
||||||
|
--set cgroup.autoMount.enabled=false \
|
||||||
|
--set cgroup.hostRoot=/sys/fs/cgroup \
|
||||||
|
--set k8sServiceHost=localhost \
|
||||||
|
--set k8sServicePort=7445
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify: node flips to `Ready`, `cilium status` reports OK.
|
||||||
|
|
||||||
|
## Phase 2 — Bootstrap ArgoCD (app-of-apps)
|
||||||
|
|
||||||
|
If ArgoCD's own manifests + root Application live in git (`k8s/argocd/`), recovery is a 3-step process:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create namespace argocd
|
||||||
|
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||||
|
# wait for argocd-server to be Ready
|
||||||
|
kubectl apply -f k8s/argocd/root-app.yaml # app-of-apps entrypoint
|
||||||
|
```
|
||||||
|
|
||||||
|
Everything downstream (Longhorn CRDs, ingress, cert-manager, workloads) reconciles automatically from git once the root app syncs.
|
||||||
|
|
||||||
|
## Phase 3 — Longhorn volume salvage (manual, per-volume, do after Longhorn CRDs reinstall)
|
||||||
|
|
||||||
|
Replica data survived on disk; CRDs (PVC↔PV↔Volume mappings) did not. Official supported recovery path: "Export a Volume from a Single Replica."
|
||||||
|
|
||||||
|
1. Confirm disk path via `longhorn-disk.cfg` (already confirmed: `/var/lib/longhorn-disk{1,2,3}`)
|
||||||
|
2. Locate `replicas/<volume-name>/` directories, read `volume.meta` for size
|
||||||
|
3. Launch a temporary `longhornio/longhorn-engine` container against the replica directory to expose it as a block device
|
||||||
|
4. Mount and copy data out manually, per volume
|
||||||
|
|
||||||
|
Not automatic — budget real time, one volume at a time.
|
||||||
|
|
||||||
|
## Phase 4 — WireGuard / router path
|
||||||
|
|
||||||
|
DuckDNS (`riotpiao.duckdns.org`) resolves correctly to current public IP (`24.114.42.68`, confirmed via Google + Cloudflare DNS). Tunnel fails to connect from **off-LAN** — needs router-side verification:
|
||||||
|
- Confirm port-forward rule is **UDP 51820 → 192.168.1.213:51820** exactly
|
||||||
|
- If double-NAT, forward must be on the outermost internet-facing router
|
||||||
|
- Confirm with ISP whether you're behind CGNAT (silently blocks all inbound forwarding)
|
||||||
|
|
||||||
|
**Separately — LAN-side symptom:** tunnel also fails to connect **from the same LAN** as the server, via the public DDNS hostname. Root cause: **NAT hairpin/loopback not supported by the router** — traffic leaves the LAN, tries to loop back in via the public IP, and gets dropped. This is a router limitation, not a WireGuard/Shadowrocket bug.
|
||||||
|
|
||||||
|
Fixes, in order of robustness:
|
||||||
|
1. Enable NAT hairpinning/loopback in router settings, if supported
|
||||||
|
2. Split-DNS: resolve the DDNS hostname to the LAN IP (`192.168.1.213`) for LAN clients only, via a local resolver (Pi-hole/dnsmasq/router DNS)
|
||||||
|
3. Quick workaround: manually point the Shadowrocket WireGuard peer endpoint at `192.168.1.213:51820` while on LAN; switch back to the DDNS hostname when away
|
||||||
|
|
||||||
|
## Phase 5 — Redeploy DuckDNS updater
|
||||||
|
|
||||||
|
The cluster wipe likely took out any in-cluster DuckDNS-refresh CronJob. Redeploy via GitOps once ArgoCD is back — standard pattern: a `CronJob` running `curl "https://www.duckdns.org/update?domains=riotpiao&token=...&ip="` every few minutes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Recommended order:** Phase 1 (Cilium) → Phase 2 (ArgoCD) → Phase 4 (router/WireGuard, parallel) → Phase 5 (DuckDNS cron) → Phase 3 (Longhorn salvage, lowest urgency).
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [How to Install Cilium on Talos Linux Step by Step](https://oneuptime.com/blog/post/2026-03-03-install-cilium-on-talos-linux-step-by-step/view)
|
||||||
|
- [Deploy Cilium CNI - Sidero Documentation](https://docs.siderolabs.com/kubernetes-guides/cni/deploying-cilium)
|
||||||
|
- [Cluster Bootstrapping - Argo CD](https://argo-cd.readthedocs.io/en/latest/operator-manual/cluster-bootstrapping/)
|
||||||
|
- [How to Bootstrap an Entire Cluster with ArgoCD App-of-Apps](https://oneuptime.com/blog/post/2026-02-26-argocd-bootstrap-cluster-app-of-apps/view)
|
||||||
|
- [Restoring Data from an Orphaned Replica Directory - Longhorn KB](https://longhorn.io/kb/restoring-data-from-an-orphaned-replica-directory/)
|
||||||
|
- [Port Forwarding for WireGuard](https://portforward.com/wireguard/)
|
||||||
|
- [Guide Wireguard-portforwarding - SNBForums](https://www.snbforums.com/threads/guide-wireguard-portforwarding.89737/)
|
||||||
|
- [Help with hairpin NAT for wireguard on ubuntu server - Ubiquiti Community](https://community.ui.com/questions/Help-with-hairpin-NAT-for-wireguard-on-ubuntu-server/12d4cbe7-f1f5-448d-9d77-ea8226c18f16)
|
||||||
|
- [Wireguard VPN on Pi4 - cannot connect client - Raspberry Pi Forums](https://forums.raspberrypi.com/viewtopic.php?t=339692)
|
||||||
@@ -209,7 +209,7 @@ core iam list-apps
|
|||||||
#### Create New Application
|
#### Create New Application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.homelab.com/callback"
|
core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.com/callback"
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns client ID and secret (save immediately).
|
Returns client ID and secret (save immediately).
|
||||||
@@ -331,13 +331,13 @@ core get cluster/iam/roles/admin --key roles
|
|||||||
export REGISTRY_TOKEN=$(core get cluster/iam/agents/ci-bot --key token)
|
export REGISTRY_TOKEN=$(core get cluster/iam/agents/ci-bot --key token)
|
||||||
|
|
||||||
# 2. Authenticate docker/podman to Forgejo registry
|
# 2. Authenticate docker/podman to Forgejo registry
|
||||||
docker login forgejo.riotpiao.homelab.com \
|
docker login forgejo.riotpiao.com \
|
||||||
--username ci-bot \
|
--username ci-bot \
|
||||||
--password "$REGISTRY_TOKEN"
|
--password "$REGISTRY_TOKEN"
|
||||||
|
|
||||||
# 3. Tag and push image
|
# 3. Tag and push image
|
||||||
docker tag myapp:latest forgejo.riotpiao.homelab.com/rock/myapp:latest
|
docker tag myapp:latest forgejo.riotpiao.com/rock/myapp:latest
|
||||||
docker push forgejo.riotpiao.homelab.com/rock/myapp:latest
|
docker push forgejo.riotpiao.com/rock/myapp:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
**Pull images in runner (automatic):**
|
**Pull images in runner (automatic):**
|
||||||
@@ -345,7 +345,7 @@ docker push forgejo.riotpiao.homelab.com/rock/myapp:latest
|
|||||||
```bash
|
```bash
|
||||||
# Inside .forgejo/workflows/*.yml, runner pulls via K8s ServiceAccount
|
# Inside .forgejo/workflows/*.yml, runner pulls via K8s ServiceAccount
|
||||||
# No explicit login needed — imagePullSecrets injected by runner pod
|
# No explicit login needed — imagePullSecrets injected by runner pod
|
||||||
image: forgejo.riotpiao.homelab.com/rock/myapp:latest
|
image: forgejo.riotpiao.com/rock/myapp:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
**Runner pod setup:**
|
**Runner pod setup:**
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Trust the homelab-ca CA for pulling from the Forgejo container registry.
|
# Trust the homelab-ca CA for pulling from the Forgejo container registry.
|
||||||
# Without this, containerd fails: x509 certificate signed by unknown authority
|
# Without this, containerd fails: x509 certificate signed by unknown authority
|
||||||
# (nginx terminates forgejo.riotpiao.homelab.com TLS with a homelab-ca cert).
|
# (nginx terminates forgejo.riotpiao.com TLS with a homelab-ca cert).
|
||||||
# Apply: talosctl -n <node> patch mc --patch @cluster-config/patches/forgejo-registry-ca.yaml
|
# Apply: talosctl -n <node> patch mc --patch @cluster-config/patches/forgejo-registry-ca.yaml
|
||||||
machine:
|
machine:
|
||||||
registries:
|
registries:
|
||||||
config:
|
config:
|
||||||
forgejo.riotpiao.homelab.com:
|
forgejo.riotpiao.com:
|
||||||
tls:
|
tls:
|
||||||
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJiVENDQVJTZ0F3SUJBZ0lVYTBVaGs3Rm81d3BiWjZsRzVEWWJUVkFic1k4d0NnWUlLb1pJemowRUF3SXcKRlRFVE1CRUdBMVVFQXhNS2FHOXRaV3hoWWkxallUQWVGdzB5TmpBM01UQXdORFF3TXpaYUZ3MHpOakEzTURjdwpORFF3TXpaYU1CVXhFekFSQmdOVkJBTVRDbWh2YldWc1lXSXRZMkV3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPClBRTUJCd05DQUFTc1pNU2piUWI0YzNiUk00MjMxVEVrRXVLTnFLUUhaaW5uYnUzbWZGbStRc0wweTF3cjg1Uk0KUWJ6ZEZ2N01JZmN4REpMbHFqQTY1bEJ6TE9pdHRZZHRvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUVmcGJQL3FnYWsxaXUvQzdaQi9uZk5zc0hpd3dDZ1lJCktvWkl6ajBFQXdJRFJ3QXdSQUlnR2ltdnJiWU1xZjhGYThCeTBBM0M1ak1VL0d3dGU0NHgzOU4rRDRyaTJ1a0MKSUNkOEtIQXhhV0s2ZkVJcEFYZGdUQ1FxQmFiZjVZUDdhQzNDVzkzYkNsTjIKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJiVENDQVJTZ0F3SUJBZ0lVYTBVaGs3Rm81d3BiWjZsRzVEWWJUVkFic1k4d0NnWUlLb1pJemowRUF3SXcKRlRFVE1CRUdBMVVFQXhNS2FHOXRaV3hoWWkxallUQWVGdzB5TmpBM01UQXdORFF3TXpaYUZ3MHpOakEzTURjdwpORFF3TXpaYU1CVXhFekFSQmdOVkJBTVRDbWh2YldWc1lXSXRZMkV3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPClBRTUJCd05DQUFTc1pNU2piUWI0YzNiUk00MjMxVEVrRXVLTnFLUUhaaW5uYnUzbWZGbStRc0wweTF3cjg1Uk0KUWJ6ZEZ2N01JZmN4REpMbHFqQTY1bEJ6TE9pdHRZZHRvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUVmcGJQL3FnYWsxaXUvQzdaQi9uZk5zc0hpd3dDZ1lJCktvWkl6ajBFQXdJRFJ3QXdSQUlnR2ltdnJiWU1xZjhGYThCeTBBM0M1ak1VL0d3dGU0NHgzOU4rRDRyaTJ1a0MKSUNkOEtIQXhhV0s2ZkVJcEFYZGdUQ1FxQmFiZjVZUDdhQzNDVzkzYkNsTjIKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: cloudflared
|
||||||
|
namespace: cloudflared
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: cloudflared
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: cloudflared
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cloudflared
|
||||||
|
image: cloudflare/cloudflared:latest
|
||||||
|
args:
|
||||||
|
- tunnel
|
||||||
|
- --no-autoupdate
|
||||||
|
- run
|
||||||
|
- --token
|
||||||
|
- $(TUNNEL_TOKEN)
|
||||||
|
env:
|
||||||
|
- name: TUNNEL_TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cloudflared-token
|
||||||
|
key: token
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 128Mi
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: cloudflared
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
@@ -9,17 +9,17 @@ Build for `linux/amd64`:
|
|||||||
```bash
|
```bash
|
||||||
cd homelab
|
cd homelab
|
||||||
docker buildx build --platform linux/amd64 \
|
docker buildx build --platform linux/amd64 \
|
||||||
-t forgejo.riotpiao.homelab.com/rock/claude-terminal:latest \
|
-t forgejo.riotpiao.com/rock/claude-terminal:latest \
|
||||||
-f k8s/dev-tools/Dockerfile \
|
-f k8s/dev-tools/Dockerfile \
|
||||||
k8s/dev-tools
|
k8s/dev-tools
|
||||||
|
|
||||||
# Log in to Forgejo registry
|
# Log in to Forgejo registry
|
||||||
docker login forgejo.riotpiao.homelab.com \
|
docker login forgejo.riotpiao.com \
|
||||||
--username ci-bot \
|
--username ci-bot \
|
||||||
--password "$(talos get cluster/iam/agents/ci-bot --key token)"
|
--password "$(talos get cluster/iam/agents/ci-bot --key token)"
|
||||||
|
|
||||||
# Push
|
# Push
|
||||||
docker push forgejo.riotpiao.homelab.com/rock/claude-terminal:latest
|
docker push forgejo.riotpiao.com/rock/claude-terminal:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use the provided build script:
|
Or use the provided build script:
|
||||||
@@ -36,7 +36,7 @@ Update `values.yaml` if needed, then deploy via helmfile:
|
|||||||
helmfile apply -l name=claude-terminal
|
helmfile apply -l name=claude-terminal
|
||||||
```
|
```
|
||||||
|
|
||||||
Access the terminal at: **https://claude.riotpiao.homelab.com**
|
Access the terminal at: **https://claude.riotpiao.com**
|
||||||
|
|
||||||
## Persistent Storage
|
## Persistent Storage
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
REGISTRY="forgejo.riotpiao.homelab.com"
|
REGISTRY="forgejo.riotpiao.com"
|
||||||
IMAGE_NAME="rock/claude-terminal"
|
IMAGE_NAME="rock/claude-terminal"
|
||||||
TAG="latest"
|
TAG="latest"
|
||||||
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ ingress:
|
|||||||
annotations:
|
annotations:
|
||||||
cert-manager.io/cluster-issuer: homelab-ca
|
cert-manager.io/cluster-issuer: homelab-ca
|
||||||
hosts:
|
hosts:
|
||||||
- host: claude.riotpiao.homelab.com
|
- host: claude.riotpiao.com
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
tls:
|
tls:
|
||||||
- secretName: claude-terminal-tls
|
- secretName: claude-terminal-tls
|
||||||
hosts:
|
hosts:
|
||||||
- claude.riotpiao.homelab.com
|
- claude.riotpiao.com
|
||||||
|
|
||||||
persistence:
|
persistence:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
namespace: duckdns
|
resources:
|
||||||
resources: []
|
- duckdns-corn.yaml
|
||||||
# DuckDNS deployed via Helm chart or CronJob
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
# The homelab-ca secret above only reaches the runner/register/dind containers.
|
# The homelab-ca secret above only reaches the runner/register/dind containers.
|
||||||
# It does NOT reach the per-job containers DinD spawns (e.g. golangci-lint,
|
# It does NOT reach the per-job containers DinD spawns (e.g. golangci-lint,
|
||||||
# node:22-bookworm) — those are fresh sibling containers with their own trust
|
# node:22-bookworm) — those are fresh sibling containers with their own trust
|
||||||
# store. Without this, any git/curl/apk call to forgejo.riotpiao.homelab.com
|
# store. Without this, any git/curl/apk call to forgejo.riotpiao.com
|
||||||
# from inside a job fails with "SSL certificate problem: unable to get local
|
# from inside a job fails with "SSL certificate problem: unable to get local
|
||||||
# issuer certificate". Build a merged bundle (public roots + homelab CA) and
|
# issuer certificate". Build a merged bundle (public roots + homelab CA) and
|
||||||
# bind-mount it over /etc/ssl/certs/ca-certificates.crt in every job
|
# bind-mount it over /etc/ssl/certs/ca-certificates.crt in every job
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
# IMPORTANT: source the CA from the live cluster secret, NOT from
|
# IMPORTANT: source the CA from the live cluster secret, NOT from
|
||||||
# k8s/forge/pki/ca.crt — that repo file is a stale CA from before the
|
# k8s/forge/pki/ca.crt — that repo file is a stale CA from before the
|
||||||
# "unified certificate" migration (different key, fails verification
|
# "unified certificate" migration (different key, fails verification
|
||||||
# against the cert actually served by forgejo.riotpiao.homelab.com). The
|
# against the cert actually served by forgejo.riotpiao.com). The
|
||||||
# org-wide CA that signs the live ingress cert lives in
|
# org-wide CA that signs the live ingress cert lives in
|
||||||
# cert-manager/homelab-ca-secret, and cicd/homelab-ca above is already
|
# cert-manager/homelab-ca-secret, and cicd/homelab-ca above is already
|
||||||
# synced from it.
|
# synced from it.
|
||||||
@@ -220,7 +220,7 @@ spec:
|
|||||||
- |
|
- |
|
||||||
test -f /data/.runner && echo "already registered, skipping" && exit 0
|
test -f /data/.runner && echo "already registered, skipping" && exit 0
|
||||||
forgejo-runner register --no-interactive \
|
forgejo-runner register --no-interactive \
|
||||||
--instance https://forgejo.riotpiao.homelab.com \
|
--instance https://forgejo.riotpiao.com \
|
||||||
--token "$RUNNER_TOKEN" \
|
--token "$RUNNER_TOKEN" \
|
||||||
--name talos-runner \
|
--name talos-runner \
|
||||||
--labels "docker:docker://node:22-bookworm"
|
--labels "docker:docker://node:22-bookworm"
|
||||||
@@ -407,7 +407,7 @@ spec:
|
|||||||
- to:
|
- to:
|
||||||
- podSelector: {}
|
- podSelector: {}
|
||||||
# ingress-nginx (the runner talks to Forgejo via its public hostname,
|
# ingress-nginx (the runner talks to Forgejo via its public hostname,
|
||||||
# https://forgejo.riotpiao.homelab.com, which resolves to the ingress
|
# https://forgejo.riotpiao.com, which resolves to the ingress
|
||||||
# controller's ClusterIP — a different namespace on the pod network)
|
# controller's ClusterIP — a different namespace on the pod network)
|
||||||
- to:
|
- to:
|
||||||
- namespaceSelector:
|
- namespaceSelector:
|
||||||
|
|||||||
@@ -16,3 +16,4 @@ resources:
|
|||||||
- shadowsocks/
|
- shadowsocks/
|
||||||
- dev-tools/
|
- dev-tools/
|
||||||
- duckdns/
|
- duckdns/
|
||||||
|
- cloudflared/
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: kmsvc
|
project: kmsvc
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/charts/kafka-cluster
|
path: k8s/charts/kafka-cluster
|
||||||
helm:
|
helm:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: kmsvc
|
project: kmsvc
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/charts/queue-crd
|
path: k8s/charts/queue-crd
|
||||||
helm:
|
helm:
|
||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||||
image:
|
image:
|
||||||
repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service-queue-operator
|
repository: forgejo.riotpiao.com/rock/kafka-management-service-queue-operator
|
||||||
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
||||||
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
||||||
tag: latest
|
tag: latest
|
||||||
|
|||||||
@@ -8,25 +8,25 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: kmsvc
|
project: kmsvc
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/charts/management-service
|
path: k8s/charts/management-service
|
||||||
helm:
|
helm:
|
||||||
values: |
|
values: |
|
||||||
namespace: sqs
|
namespace: sqs
|
||||||
image:
|
image:
|
||||||
repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service
|
repository: forgejo.riotpiao.com/rock/kafka-management-service
|
||||||
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
||||||
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
||||||
tag: latest
|
tag: latest
|
||||||
env:
|
env:
|
||||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
host: kmsvc.riotpiao.homelab.com
|
host: kmsvc.riotpiao.com
|
||||||
clusterIssuer: homelab-ca
|
clusterIssuer: homelab-ca
|
||||||
destination:
|
destination:
|
||||||
server: https://kubernetes.default.svc
|
server: https://kubernetes.default.svc
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
description: Kafka Management Service (design.md) -- Strimzi/Kafka, Redis, queue-operator, message-plane server
|
description: Kafka Management Service (design.md) -- Strimzi/Kafka, Redis, queue-operator, message-plane server
|
||||||
sourceRepos:
|
sourceRepos:
|
||||||
- https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
- https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||||
- https://strimzi.io/charts/
|
- https://strimzi.io/charts/
|
||||||
- https://charts.bitnami.com/bitnami
|
- https://charts.bitnami.com/bitnami
|
||||||
destinations:
|
destinations:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: kmsvc
|
project: kmsvc
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/argocd/apps
|
path: k8s/argocd/apps
|
||||||
directory:
|
directory:
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ ingress:
|
|||||||
enabled: true
|
enabled: true
|
||||||
className: nginx
|
className: nginx
|
||||||
clusterIssuer: homelab-ca
|
clusterIssuer: homelab-ca
|
||||||
host: kmsvc.riotpiao.homelab.com
|
host: kmsvc.riotpiao.com
|
||||||
tlsSecretName: kmsvc-tls
|
tlsSecretName: kmsvc-tls
|
||||||
# kmsvc-cli connects via gRPC directly to --server/KMSVC_SERVER (default
|
# kmsvc-cli connects via gRPC directly to --server/KMSVC_SERVER (default
|
||||||
# kmsvc.riotpiao.homelab.com:443, see kmsvc-cli's README), so raw gRPC needs an
|
# kmsvc.riotpiao.com:443, see kmsvc-cli's README), so raw gRPC needs an
|
||||||
# external path too — scoped to the gRPC service's own path prefix on the
|
# external path too — scoped to the gRPC service's own path prefix on the
|
||||||
# same host/port, rather than opening the whole host to gRPC passthrough.
|
# same host/port, rather than opening the whole host to gRPC passthrough.
|
||||||
grpcEnabled: true
|
grpcEnabled: true
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ redis:
|
|||||||
|
|
||||||
managementService:
|
managementService:
|
||||||
ingress:
|
ingress:
|
||||||
host: kmsvc.riotpiao.homelab.com
|
host: kmsvc.riotpiao.com
|
||||||
clusterIssuer: homelab-ca
|
clusterIssuer: homelab-ca
|
||||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ worker-production-5f8b4c... 1/1 Running 0 10s
|
|||||||
### Step 5: Verify Worker Connected to Temporal Namespace
|
### Step 5: Verify Worker Connected to Temporal Namespace
|
||||||
Check Temporal UI for namespace "production":
|
Check Temporal UI for namespace "production":
|
||||||
```bash
|
```bash
|
||||||
open https://temporal.riotpiao.homelab.com/namespaces/production/task-queues
|
open https://temporal.riotpiao.com/namespaces/production/task-queues
|
||||||
```
|
```
|
||||||
|
|
||||||
Look for all task queues with worker count > 0:
|
Look for all task queues with worker count > 0:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Browser → Ingress (TLS) → oauth2-proxy (OIDC check) → temporal-web (intern
|
|||||||
✅ Authentik OIDC provider `temporal` already exists with:
|
✅ Authentik OIDC provider `temporal` already exists with:
|
||||||
- Client ID: `temporal`
|
- Client ID: `temporal`
|
||||||
- Client Secret: stored in Kubernetes secret `temporal-oidc` (key: `clientSecret`)
|
- Client Secret: stored in Kubernetes secret `temporal-oidc` (key: `clientSecret`)
|
||||||
- Redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback`
|
- Redirect URI: `https://temporal.riotpiao.com/oauth2/callback`
|
||||||
|
|
||||||
## Secrets
|
## Secrets
|
||||||
|
|
||||||
@@ -85,14 +85,14 @@ kubectl get ingress -n temporal
|
|||||||
Expected:
|
Expected:
|
||||||
```
|
```
|
||||||
NAME CLASS HOSTS ADDRESS PORTS AGE
|
NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||||
temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s
|
temporal nginx temporal.riotpiao.com ... 80, 443 10s
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Test Access
|
### Step 3: Test Access
|
||||||
|
|
||||||
1. **Open Temporal UI (unauthenticated):**
|
1. **Open Temporal UI (unauthenticated):**
|
||||||
```bash
|
```bash
|
||||||
open https://temporal.riotpiao.homelab.com
|
open https://temporal.riotpiao.com
|
||||||
```
|
```
|
||||||
|
|
||||||
Expected: Redirects to Authentik login page
|
Expected: Redirects to Authentik login page
|
||||||
@@ -100,12 +100,12 @@ temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s
|
|||||||
2. **Login with Authentik credentials**
|
2. **Login with Authentik credentials**
|
||||||
- Username/email
|
- Username/email
|
||||||
- Password
|
- Password
|
||||||
- Should redirect back to `temporal.riotpiao.homelab.com` and display UI
|
- Should redirect back to `temporal.riotpiao.com` and display UI
|
||||||
|
|
||||||
3. **Verify auth:**
|
3. **Verify auth:**
|
||||||
```bash
|
```bash
|
||||||
# Check for oauth2_proxy cookie
|
# Check for oauth2_proxy cookie
|
||||||
curl -v https://temporal.riotpiao.homelab.com 2>&1 | grep -i cookie
|
curl -v https://temporal.riotpiao.com 2>&1 | grep -i cookie
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Check oauth2-proxy logs:**
|
4. **Check oauth2-proxy logs:**
|
||||||
@@ -127,7 +127,7 @@ redirect_uri_mismatch: The redirect_uri does not match the one registered in Aut
|
|||||||
```
|
```
|
||||||
|
|
||||||
Fix:
|
Fix:
|
||||||
- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback`
|
- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.com/oauth2/callback`
|
||||||
- Ensure HTTPS (not HTTP)
|
- Ensure HTTPS (not HTTP)
|
||||||
|
|
||||||
### Missing secret
|
### Missing secret
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs
|
path: k8s/sqs
|
||||||
directory:
|
directory:
|
||||||
@@ -35,7 +35,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs
|
path: k8s/sqs
|
||||||
directory:
|
directory:
|
||||||
@@ -60,7 +60,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/monitoring
|
path: k8s/monitoring
|
||||||
directory:
|
directory:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/argocd/root
|
path: k8s/argocd/root
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/talos-iam
|
path: k8s/talos-iam
|
||||||
directory:
|
directory:
|
||||||
@@ -33,7 +33,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/logging
|
path: k8s/logging
|
||||||
directory:
|
directory:
|
||||||
@@ -45,29 +45,30 @@ spec:
|
|||||||
automated:
|
automated:
|
||||||
prune: true
|
prune: true
|
||||||
selfHeal: true
|
selfHeal: true
|
||||||
---
|
# cloudnative-pg: managed separately via k8s/argocd/apps/cnpg-operator.yaml
|
||||||
apiVersion: argoproj.io/v1alpha1
|
# (Helm-source Application, avoids the git chicken-egg for the operator itself)
|
||||||
kind: Application
|
# apiVersion: argoproj.io/v1alpha1
|
||||||
metadata:
|
# kind: Application
|
||||||
name: cloudnative-pg
|
# metadata:
|
||||||
namespace: argocd
|
# name: cloudnative-pg
|
||||||
annotations:
|
# namespace: argocd
|
||||||
argocd.argoproj.io/sync-wave: "1"
|
# annotations:
|
||||||
spec:
|
# argocd.argoproj.io/sync-wave: "1"
|
||||||
project: homelab
|
# spec:
|
||||||
source:
|
# project: homelab
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
# source:
|
||||||
targetRevision: main
|
# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
path: k8s/ddb
|
# targetRevision: main
|
||||||
directory:
|
# path: k8s/ddb
|
||||||
recurse: false
|
# directory:
|
||||||
destination:
|
# recurse: false
|
||||||
server: https://kubernetes.default.svc
|
# destination:
|
||||||
namespace: ddb
|
# server: https://kubernetes.default.svc
|
||||||
syncPolicy:
|
# namespace: ddb
|
||||||
automated:
|
# syncPolicy:
|
||||||
prune: true
|
# automated:
|
||||||
selfHeal: true
|
# prune: true
|
||||||
|
# selfHeal: true
|
||||||
---
|
---
|
||||||
apiVersion: argoproj.io/v1alpha1
|
apiVersion: argoproj.io/v1alpha1
|
||||||
kind: Application
|
kind: Application
|
||||||
@@ -79,7 +80,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/talos-iam
|
path: k8s/talos-iam
|
||||||
directory:
|
directory:
|
||||||
@@ -101,7 +102,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/temporal
|
path: k8s/temporal
|
||||||
directory:
|
directory:
|
||||||
@@ -124,7 +125,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs
|
path: k8s/sqs
|
||||||
directory:
|
directory:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs
|
path: k8s/sqs
|
||||||
directory:
|
directory:
|
||||||
@@ -31,7 +31,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs
|
path: k8s/sqs
|
||||||
directory:
|
directory:
|
||||||
@@ -54,7 +54,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/logging
|
path: k8s/logging
|
||||||
directory:
|
directory:
|
||||||
@@ -77,7 +77,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/logging
|
path: k8s/logging
|
||||||
directory:
|
directory:
|
||||||
@@ -89,26 +89,27 @@ spec:
|
|||||||
automated:
|
automated:
|
||||||
prune: true
|
prune: true
|
||||||
selfHeal: true
|
selfHeal: true
|
||||||
---
|
# forgejo: managed separately via k8s/argocd/apps/forgejo.yaml
|
||||||
apiVersion: argoproj.io/v1alpha1
|
# (Helm-source Application with inlined values, avoids the git chicken-egg)
|
||||||
kind: Application
|
# apiVersion: argoproj.io/v1alpha1
|
||||||
metadata:
|
# kind: Application
|
||||||
name: forgejo
|
# metadata:
|
||||||
namespace: argocd
|
# name: forgejo
|
||||||
annotations:
|
# namespace: argocd
|
||||||
argocd.argoproj.io/sync-wave: "2"
|
# annotations:
|
||||||
spec:
|
# argocd.argoproj.io/sync-wave: "2"
|
||||||
project: homelab
|
# spec:
|
||||||
source:
|
# project: homelab
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
# source:
|
||||||
targetRevision: main
|
# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
path: k8s/talos-ci-cd
|
# targetRevision: main
|
||||||
directory:
|
# path: k8s/talos-ci-cd
|
||||||
recurse: false
|
# directory:
|
||||||
destination:
|
# recurse: false
|
||||||
server: https://kubernetes.default.svc
|
# destination:
|
||||||
namespace: cicd
|
# server: https://kubernetes.default.svc
|
||||||
syncPolicy:
|
# namespace: cicd
|
||||||
automated:
|
# syncPolicy:
|
||||||
prune: true
|
# automated:
|
||||||
selfHeal: true
|
# prune: true
|
||||||
|
# selfHeal: true
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/talos-ci-cd
|
path: k8s/talos-ci-cd
|
||||||
directory:
|
directory:
|
||||||
@@ -31,7 +31,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/portainer
|
path: k8s/portainer
|
||||||
directory:
|
directory:
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: cnpg-operator
|
||||||
|
namespace: argocd
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "0"
|
||||||
|
spec:
|
||||||
|
project: homelab
|
||||||
|
source:
|
||||||
|
repoURL: https://cloudnative-pg.github.io/charts
|
||||||
|
chart: cloudnative-pg
|
||||||
|
targetRevision: "*"
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: ddb
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: forgejo
|
||||||
|
namespace: argocd
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "7"
|
||||||
|
# Must sync after cnpg-operator (wave 0) and the ddb-cluster/forgejo-database
|
||||||
|
# (wave 6, k8s/data) — Forgejo's DB connection depends on both existing first.
|
||||||
|
spec:
|
||||||
|
project: homelab
|
||||||
|
source:
|
||||||
|
repoURL: https://dl.gitea.com/charts/
|
||||||
|
chart: gitea
|
||||||
|
targetRevision: "~10"
|
||||||
|
helm:
|
||||||
|
# Mirrors k8s/security/ci-cd/forgejo-values.yaml inline — avoids the
|
||||||
|
# git-repo chicken-egg (Forgejo can't source its own values from a repo
|
||||||
|
# it hosts). Keep both files in sync when editing either one.
|
||||||
|
valuesObject:
|
||||||
|
image:
|
||||||
|
repository: codeberg.org/forgejo/forgejo
|
||||||
|
tag: "13"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
gitea:
|
||||||
|
admin:
|
||||||
|
username: rock
|
||||||
|
email: [email protected]
|
||||||
|
config:
|
||||||
|
server:
|
||||||
|
PROTOCOL: http
|
||||||
|
DOMAIN: forgejo.riotpiao.com
|
||||||
|
ROOT_URL: https://forgejo.riotpiao.com/
|
||||||
|
HTTP_PORT: 3000
|
||||||
|
START_SSH_SERVER: true
|
||||||
|
SSH_DOMAIN: forgejo.riotpiao.com
|
||||||
|
SSH_PORT: 2222
|
||||||
|
SSH_LISTEN_PORT: 2222
|
||||||
|
database:
|
||||||
|
DB_TYPE: postgres
|
||||||
|
HOST: ddb-cluster-rw.ddb.svc:5432
|
||||||
|
NAME: forgejo
|
||||||
|
USER: app
|
||||||
|
repository:
|
||||||
|
ROOT: /data/git
|
||||||
|
actions:
|
||||||
|
ENABLED: true
|
||||||
|
packages:
|
||||||
|
ENABLED: true
|
||||||
|
metrics:
|
||||||
|
ENABLED: true
|
||||||
|
service:
|
||||||
|
DISABLE_REGISTRATION: true
|
||||||
|
oauth2:
|
||||||
|
ENABLED: true
|
||||||
|
PROVIDER: openidconnect
|
||||||
|
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||||
|
CLIENT_ID: forgejo
|
||||||
|
AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||||
|
cache:
|
||||||
|
ADAPTER: redis
|
||||||
|
HOST: "redis://forgejo-redis.cicd.svc:6379/0"
|
||||||
|
session:
|
||||||
|
PROVIDER: redis
|
||||||
|
PROVIDER_CONFIG: "redis://forgejo-redis.cicd.svc:6379/1"
|
||||||
|
queue:
|
||||||
|
TYPE: redis
|
||||||
|
CONN_STR: "redis://forgejo-redis.cicd.svc:6379/2"
|
||||||
|
metrics:
|
||||||
|
enabled: true
|
||||||
|
serviceMonitor:
|
||||||
|
enabled: false
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
storageClass: longhorn
|
||||||
|
size: 20Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
replicaCount: 2
|
||||||
|
deployment:
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
env:
|
||||||
|
- name: SSL_CERT_DIR
|
||||||
|
value: /homelab-ca
|
||||||
|
- name: GITEA__database__PASSWD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ddb-cluster-app
|
||||||
|
key: password
|
||||||
|
podAnnotations:
|
||||||
|
configmap.reloader.stakater.com/reload: "homelab-ca"
|
||||||
|
service:
|
||||||
|
http:
|
||||||
|
type: LoadBalancer
|
||||||
|
port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
annotations:
|
||||||
|
io.cilium/lb-ipam-ips: "192.168.1.165"
|
||||||
|
io.cilium/lb-ipam-sharing-key: "forgejo"
|
||||||
|
ssh:
|
||||||
|
type: LoadBalancer
|
||||||
|
port: 2222
|
||||||
|
targetPort: 2222
|
||||||
|
annotations:
|
||||||
|
io.cilium/lb-ipam-ips: "192.168.1.165"
|
||||||
|
io.cilium/lb-ipam-sharing-key: "forgejo"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 250m
|
||||||
|
memory: 512Mi
|
||||||
|
limits:
|
||||||
|
cpu: "1"
|
||||||
|
memory: 1Gi
|
||||||
|
tolerations:
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
extraVolumes:
|
||||||
|
- name: homelab-ca
|
||||||
|
configMap:
|
||||||
|
name: homelab-ca
|
||||||
|
extraVolumeMounts:
|
||||||
|
- name: homelab-ca
|
||||||
|
mountPath: /homelab-ca
|
||||||
|
readOnly: true
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
postgresql:
|
||||||
|
enabled: false
|
||||||
|
postgresql-ha:
|
||||||
|
enabled: false
|
||||||
|
mysql:
|
||||||
|
enabled: false
|
||||||
|
redis-cluster:
|
||||||
|
enabled: false
|
||||||
|
act_runner:
|
||||||
|
enabled: false
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: cicd
|
||||||
|
syncPolicy:
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
# NO automated sync — Forgejo is what CI uses to push commits; auto-sync
|
||||||
|
# would let a bad CI commit break the system CI depends on. Manual only.
|
||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/infrastructure
|
path: k8s/infrastructure
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/bootstrap
|
path: k8s/bootstrap
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/platform
|
path: k8s/platform
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/security
|
path: k8s/security
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/applications
|
path: k8s/applications
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/data
|
path: k8s/data
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ spec:
|
|||||||
purge: false
|
purge: false
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration
|
MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration
|
||||||
MINIO_IDENTITY_OPENID_CLIENT_ID: minio
|
MINIO_IDENTITY_OPENID_CLIENT_ID: minio
|
||||||
MINIO_IDENTITY_OPENID_CLIENT_SECRET: 9d2867fe08c3bf7fedd7e32bbaf4456fce3b0aaf788966d7559e1955947b0219
|
MINIO_IDENTITY_OPENID_CLIENT_SECRET: 9d2867fe08c3bf7fedd7e32bbaf4456fce3b0aaf788966d7559e1955947b0219
|
||||||
MINIO_IDENTITY_OPENID_CLAIM_NAME: policy
|
MINIO_IDENTITY_OPENID_CLAIM_NAME: policy
|
||||||
MINIO_IDENTITY_OPENID_SCOPES: openid,profile,email,minio
|
MINIO_IDENTITY_OPENID_SCOPES: openid,profile,email,minio
|
||||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.homelab.com/oauth_callback
|
MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.com/oauth_callback
|
||||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME: Authentik
|
MINIO_IDENTITY_OPENID_DISPLAY_NAME: Authentik
|
||||||
|
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs/charts/kafka-cluster
|
path: k8s/sqs/charts/kafka-cluster
|
||||||
helm:
|
helm:
|
||||||
@@ -117,7 +117,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs/charts/queue-crd
|
path: k8s/sqs/charts/queue-crd
|
||||||
helm:
|
helm:
|
||||||
@@ -146,7 +146,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/sqs/charts/management-service
|
path: k8s/sqs/charts/management-service
|
||||||
helm:
|
helm:
|
||||||
@@ -155,11 +155,11 @@ spec:
|
|||||||
env:
|
env:
|
||||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
host: kmsvc.riotpiao.homelab.com
|
host: kmsvc.riotpiao.com
|
||||||
clusterIssuer: homelab-ca
|
clusterIssuer: homelab-ca
|
||||||
destination:
|
destination:
|
||||||
server: https://kubernetes.default.svc
|
server: https://kubernetes.default.svc
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
helm:
|
helm:
|
||||||
valueFiles:
|
valueFiles:
|
||||||
- k8s/monitoring/prometheus-values.yaml
|
- k8s/monitoring/prometheus-values.yaml
|
||||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/hooks/phase2
|
path: k8s/hooks/phase2
|
||||||
destination:
|
destination:
|
||||||
@@ -47,7 +47,7 @@ spec:
|
|||||||
helm:
|
helm:
|
||||||
valueFiles:
|
valueFiles:
|
||||||
- k8s/ddb/cnpg-values.yaml
|
- k8s/ddb/cnpg-values.yaml
|
||||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/hooks/phase2
|
path: k8s/hooks/phase2
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: homelab
|
project: homelab
|
||||||
sources:
|
sources:
|
||||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/talos-ci-cd/charts/forgejo-runner
|
path: k8s/talos-ci-cd/charts/forgejo-runner
|
||||||
helm:
|
helm:
|
||||||
valueFiles:
|
valueFiles:
|
||||||
- values.yaml
|
- values.yaml
|
||||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/hooks/phase2
|
path: k8s/hooks/phase2
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ spec:
|
|||||||
valueFiles:
|
valueFiles:
|
||||||
- k8s/talos-iam/authentik-values.yaml
|
- k8s/talos-iam/authentik-values.yaml
|
||||||
- k8s/talos-iam/authentik-secrets.enc.yaml
|
- k8s/talos-iam/authentik-secrets.enc.yaml
|
||||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: k8s/hooks/phase3
|
path: k8s/hooks/phase3
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# k8s/argocd/projects/homelab-project.yaml
|
||||||
|
# AppProject referenced by every Application manifest under k8s/argocd/apps/
|
||||||
|
# (project: homelab) — was never committed, so 00-homelab-root.yaml and all
|
||||||
|
# layer/wave/phase apps fail admission with "application references project
|
||||||
|
# 'homelab' which does not exist" until this exists.
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: AppProject
|
||||||
|
metadata:
|
||||||
|
name: homelab
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
description: Homelab GitOps — single-repo, in-cluster destinations only
|
||||||
|
sourceRepos:
|
||||||
|
- https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||||
|
- https://cloudnative-pg.github.io/charts
|
||||||
|
- https://dl.gitea.com/charts/
|
||||||
|
destinations:
|
||||||
|
- server: https://kubernetes.default.svc
|
||||||
|
namespace: "*"
|
||||||
|
clusterResourceWhitelist:
|
||||||
|
- group: "*"
|
||||||
|
kind: "*"
|
||||||
|
namespaceResourceWhitelist:
|
||||||
|
- group: "*"
|
||||||
|
kind: "*"
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml
|
||||||
|
# Let's Encrypt ClusterIssuers for *.riotpiao.com, DNS-01 via Cloudflare
|
||||||
|
# (wildcard certs require DNS-01 — HTTP-01 can't prove ownership of a wildcard name).
|
||||||
|
#
|
||||||
|
# Prereq (apply manually, not in git — token is a secret):
|
||||||
|
# kubectl create secret generic cloudflare-api-token-secret \
|
||||||
|
# --namespace cert-manager \
|
||||||
|
# --from-literal=api-token=<CLOUDFLARE_API_TOKEN>
|
||||||
|
# Token scope: Zone:DNS:Edit for the riotpiao.com zone.
|
||||||
|
#
|
||||||
|
# Start with letsencrypt-staging to validate the solver, then point
|
||||||
|
# Certificate.issuerRef at letsencrypt-prod once staging issues cleanly.
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-staging
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
email: [email protected]
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-staging-account-key
|
||||||
|
solvers:
|
||||||
|
- dns01:
|
||||||
|
cloudflare:
|
||||||
|
apiTokenSecretRef:
|
||||||
|
name: cloudflare-api-token-secret
|
||||||
|
key: api-token
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
email: [email protected]
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-prod-account-key
|
||||||
|
solvers:
|
||||||
|
- dns01:
|
||||||
|
cloudflare:
|
||||||
|
apiTokenSecretRef:
|
||||||
|
name: cloudflare-api-token-secret
|
||||||
|
key: api-token
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
# Why this is needed:
|
# Why this is needed:
|
||||||
# Grafana v10+ does OIDC auto-discovery by fetching
|
# Grafana v10+ does OIDC auto-discovery by fetching
|
||||||
# /.well-known/openid-configuration from Authentik. When Grafana reaches
|
# /.well-known/openid-configuration from Authentik. When Grafana reaches
|
||||||
# Authentik via the external hostname (authentik.riotpiao.homelab.com), the
|
# Authentik via the external hostname (authentik.riotpiao.com), the
|
||||||
# HTTP Host header is preserved and Authentik returns external URLs in the
|
# HTTP Host header is preserved and Authentik returns external URLs in the
|
||||||
# discovery response. Without this rewrite, the hostname doesn't resolve
|
# discovery response. Without this rewrite, the hostname doesn't resolve
|
||||||
# inside the cluster and Grafana falls back to the internal service DNS,
|
# inside the cluster and Grafana falls back to the internal service DNS,
|
||||||
@@ -30,29 +30,33 @@ data:
|
|||||||
}
|
}
|
||||||
prometheus :9153
|
prometheus :9153
|
||||||
|
|
||||||
|
# VPN Access: Map api-server.cluster.local to cluster API IP
|
||||||
|
# Allows secure cluster access via WireGuard tunnel (Shadowrocket/Talos)
|
||||||
|
rewrite name api-server.cluster.local kubernetes.default.svc.cluster.local
|
||||||
|
|
||||||
# Forgejo: route through nginx ingress like every other host below. nginx
|
# Forgejo: route through nginx ingress like every other host below. nginx
|
||||||
# terminates TLS (wildcard-tls) on :443 and routes both /v2/ (container
|
# terminates TLS (wildcard-tls) on :443 and routes both /v2/ (container
|
||||||
# registry) and web/git to forgejo-gitea-http:3000.
|
# registry) and web/git to forgejo-gitea-http:3000.
|
||||||
# Do NOT point this at forgejo-gitea-http directly: that service only serves
|
# Do NOT point this at forgejo-gitea-http directly: that service only serves
|
||||||
# port 3000, so containerd image pulls (which use https/:443) get
|
# port 3000, so containerd image pulls (which use https/:443) get
|
||||||
# `dial tcp <clusterIP>:443: i/o timeout`. SSH stays on its own LB service.
|
# `dial tcp <clusterIP>:443: i/o timeout`. SSH stays on its own LB service.
|
||||||
rewrite name forgejo.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name forgejo.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
|
|
||||||
# Rewrite homelab hostnames to the nginx ingress controller so in-cluster pods
|
# Rewrite homelab hostnames to the nginx ingress controller so in-cluster pods
|
||||||
# hit nginx TLS termination (cert-manager cert) and preserve the Host header.
|
# hit nginx TLS termination (cert-manager cert) and preserve the Host header.
|
||||||
# Routing through nginx — not directly to the backend service — is critical:
|
# Routing through nginx — not directly to the backend service — is critical:
|
||||||
# direct rewrites to the backend bypass nginx TLS and expose each app's own
|
# direct rewrites to the backend bypass nginx TLS and expose each app's own
|
||||||
# self-signed cert, which nothing in the cluster trusts.
|
# self-signed cert, which nothing in the cluster trusts.
|
||||||
rewrite name authentik.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name authentik.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name grafana.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name grafana.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name minio.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name minio.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name minio-api.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name minio-api.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name argocd.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name argocd.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name vault.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name vault.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name loki.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name loki.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name prometheus.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name prometheus.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name portainer.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name portainer.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
rewrite name longhorn.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
rewrite name longhorn.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||||
|
|
||||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||||
pods insecure
|
pods insecure
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# k8s/ingress/ingress.yaml
|
# k8s/ingress/ingress.yaml
|
||||||
# Ingress rules for all homelab services.
|
# Ingress rules for all homelab services.
|
||||||
# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.homelab.com)
|
# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.com)
|
||||||
# as its default-ssl-certificate. No per-rule tls: blocks or cert-manager annotations
|
# as its default-ssl-certificate. No per-rule tls: blocks or cert-manager annotations
|
||||||
# are needed — cert-manager manages one cert, nginx uses it for all hosts.
|
# are needed — cert-manager manages one cert, nginx uses it for all hosts.
|
||||||
#
|
#
|
||||||
# DNS: *.riotpiao.homelab.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN).
|
# DNS: *.riotpiao.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN).
|
||||||
|
|
||||||
# ── Grafana ───────────────────────────────────────────────────────────────────
|
# ── Grafana ───────────────────────────────────────────────────────────────────
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
@@ -17,7 +17,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: grafana.riotpiao.homelab.com
|
- host: grafana.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -38,7 +38,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: loki.riotpiao.homelab.com
|
- host: loki.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -62,7 +62,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: authentik.riotpiao.homelab.com
|
- host: authentik.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -85,7 +85,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: vault.riotpiao.homelab.com
|
- host: vault.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -113,7 +113,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: minio.riotpiao.homelab.com
|
- host: minio.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -138,7 +138,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: minio-api.riotpiao.homelab.com
|
- host: minio-api.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -159,7 +159,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: prometheus.riotpiao.homelab.com
|
- host: prometheus.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -183,7 +183,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: portainer.riotpiao.homelab.com
|
- host: portainer.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -210,7 +210,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: forgejo.riotpiao.homelab.com
|
- host: forgejo.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -238,7 +238,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: argocd.riotpiao.homelab.com
|
- host: argocd.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -259,7 +259,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: longhorn.riotpiao.homelab.com
|
- host: longhorn.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -285,7 +285,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: temporal.riotpiao.homelab.com
|
- host: temporal.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -307,7 +307,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: kmsvc.riotpiao.homelab.com
|
- host: kmsvc.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
# k8s/ingress/nginx-values.yaml
|
# k8s/ingress/nginx-values.yaml
|
||||||
# Nginx Ingress Controller — bare-metal homelab config.
|
# Nginx Ingress Controller — bare-metal homelab config.
|
||||||
# LoadBalancer service with Cilium LB-IPAM assigns fixed IP (192.168.1.160).
|
# LoadBalancer service with Cilium LB-IPAM assigns fixed IP (192.168.1.160).
|
||||||
# Access services at https://grafana.riotpiao.homelab.com (80/443 via LoadBalancer).
|
# Access services at https://grafana.riotpiao.com (80/443 via LoadBalancer).
|
||||||
|
|
||||||
controller:
|
controller:
|
||||||
kind: DaemonSet
|
kind: DaemonSet
|
||||||
|
|
||||||
# Single wildcard cert served for every *.riotpiao.homelab.com host.
|
# Single wildcard cert served for every *.riotpiao.com host (Let's Encrypt,
|
||||||
# Applied by the ingress-nginx presync hook (wildcard-cert.yaml) before nginx starts.
|
# see ../ingress/riotpiao-com-cert.yaml + ../cert-manager/letsencrypt-issuer.yaml).
|
||||||
# nginx hot-reloads when cert-manager renews homelab-tls — no restart needed.
|
# nginx hot-reloads when cert-manager renews riotpiao-com-tls — no restart needed.
|
||||||
extraArgs:
|
extraArgs:
|
||||||
default-ssl-certificate: "ingress-nginx/homelab-tls"
|
default-ssl-certificate: "ingress-nginx/riotpiao-com-tls"
|
||||||
|
|
||||||
hostPort:
|
hostPort:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -19,7 +19,7 @@ controller:
|
|||||||
https: 443
|
https: 443
|
||||||
|
|
||||||
# TCP proxy: forward port 2222 on every node → Forgejo SSH service.
|
# TCP proxy: forward port 2222 on every node → Forgejo SSH service.
|
||||||
# This lets `git clone [email protected].homelab.com:repo` work via the
|
# This lets `git clone [email protected]:repo` work via the
|
||||||
# same hostname as HTTPS without a separate LoadBalancer IP for SSH.
|
# same hostname as HTTPS without a separate LoadBalancer IP for SSH.
|
||||||
tcp:
|
tcp:
|
||||||
2222: "cicd/forgejo-gitea-ssh:2222"
|
2222: "cicd/forgejo-gitea-ssh:2222"
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# k8s/bootstrap/ingress/riotpiao-com-cert.yaml
|
||||||
|
# Public wildcard cert for *.riotpiao.com, signed by Let's Encrypt (DNS-01 via
|
||||||
|
# Cloudflare, see ../cert-manager/letsencrypt-issuer.yaml). Distinct from
|
||||||
|
# homelab-tls (self-signed homelab-ca, internal *.riotpiao.com) —
|
||||||
|
# reference riotpiao-com-tls explicitly on ingresses that expose riotpiao.com
|
||||||
|
# hosts to the internet; it is not nginx's default-ssl-certificate.
|
||||||
|
#
|
||||||
|
# issuerRef starts on letsencrypt-staging. Switch to letsencrypt-prod once the
|
||||||
|
# staging cert issues cleanly, then delete this Certificate's Secret to force
|
||||||
|
# a re-issue against prod (staging certs aren't browser-trusted).
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: riotpiao-com-tls
|
||||||
|
namespace: ingress-nginx
|
||||||
|
spec:
|
||||||
|
secretName: riotpiao-com-tls
|
||||||
|
dnsNames:
|
||||||
|
- "*.riotpiao.com"
|
||||||
|
- "riotpiao.com"
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-staging
|
||||||
|
kind: ClusterIssuer
|
||||||
|
duration: 2160h # 90 days (LE max)
|
||||||
|
renewBefore: 720h # renew 30 days before expiry
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# k8s/ingress/wildcard-cert.yaml
|
|
||||||
# Single wildcard TLS certificate for all *.riotpiao.homelab.com services.
|
|
||||||
# Lives in the ingress-nginx namespace and is set as nginx's default-ssl-certificate,
|
|
||||||
# so every ingress host gets it automatically — no per-service TLS blocks needed.
|
|
||||||
#
|
|
||||||
# Renewal: cert-manager auto-renews 30 days before expiry (renewBefore: 720h).
|
|
||||||
# nginx detects the secret update via its K8s watch and hot-reloads — no pod restart.
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: homelab-tls
|
|
||||||
namespace: ingress-nginx
|
|
||||||
spec:
|
|
||||||
secretName: homelab-tls
|
|
||||||
dnsNames:
|
|
||||||
- "*.riotpiao.homelab.com"
|
|
||||||
- "riotpiao.homelab.com"
|
|
||||||
issuerRef:
|
|
||||||
name: homelab-ca
|
|
||||||
kind: ClusterIssuer
|
|
||||||
duration: 8760h # 1 year
|
|
||||||
renewBefore: 720h # renew 30 days before expiry
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: postgresql.cnpg.io/v1
|
||||||
|
kind: Database
|
||||||
|
metadata:
|
||||||
|
name: forgejo
|
||||||
|
namespace: ddb
|
||||||
|
spec:
|
||||||
|
name: forgejo
|
||||||
|
owner: app
|
||||||
|
cluster:
|
||||||
|
name: ddb-cluster
|
||||||
@@ -13,3 +13,4 @@ resources:
|
|||||||
- ddb-cluster.yaml
|
- ddb-cluster.yaml
|
||||||
- schemas.yaml
|
- schemas.yaml
|
||||||
- db-init-job.yaml
|
- db-init-job.yaml
|
||||||
|
- forgejo-database.yaml
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ spec:
|
|||||||
# Environment variables — OIDC config
|
# Environment variables — OIDC config
|
||||||
env:
|
env:
|
||||||
- name: MINIO_IDENTITY_OPENID_CONFIG_URL
|
- name: MINIO_IDENTITY_OPENID_CONFIG_URL
|
||||||
value: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration"
|
value: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration"
|
||||||
- name: MINIO_IDENTITY_OPENID_CLIENT_ID
|
- name: MINIO_IDENTITY_OPENID_CLIENT_ID
|
||||||
value: "minio"
|
value: "minio"
|
||||||
- name: MINIO_IDENTITY_OPENID_CLIENT_SECRET
|
- name: MINIO_IDENTITY_OPENID_CLIENT_SECRET
|
||||||
@@ -124,7 +124,7 @@ spec:
|
|||||||
- name: MINIO_IDENTITY_OPENID_SCOPES
|
- name: MINIO_IDENTITY_OPENID_SCOPES
|
||||||
value: "openid,profile,email,minio"
|
value: "openid,profile,email,minio"
|
||||||
- name: MINIO_IDENTITY_OPENID_REDIRECT_URI
|
- name: MINIO_IDENTITY_OPENID_REDIRECT_URI
|
||||||
value: "https://minio.riotpiao.homelab.com/oauth_callback"
|
value: "https://minio.riotpiao.com/oauth_callback"
|
||||||
- name: MINIO_IDENTITY_OPENID_DISPLAY_NAME
|
- name: MINIO_IDENTITY_OPENID_DISPLAY_NAME
|
||||||
value: "Authentik"
|
value: "Authentik"
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ envFrom:
|
|||||||
name: minio-oidc
|
name: minio-oidc
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration"
|
MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration"
|
||||||
MINIO_IDENTITY_OPENID_CLIENT_ID: "minio"
|
MINIO_IDENTITY_OPENID_CLIENT_ID: "minio"
|
||||||
MINIO_IDENTITY_OPENID_CLAIM_NAME: "policy"
|
MINIO_IDENTITY_OPENID_CLAIM_NAME: "policy"
|
||||||
MINIO_IDENTITY_OPENID_SCOPES: "openid,profile,email,minio"
|
MINIO_IDENTITY_OPENID_SCOPES: "openid,profile,email,minio"
|
||||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.homelab.com/oauth_callback"
|
MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.com/oauth_callback"
|
||||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME: "Authentik"
|
MINIO_IDENTITY_OPENID_DISPLAY_NAME: "Authentik"
|
||||||
|
|
||||||
podAnnotations:
|
podAnnotations:
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ persistence:
|
|||||||
# ── Grafana config ────────────────────────────────────────────────────────────
|
# ── Grafana config ────────────────────────────────────────────────────────────
|
||||||
grafana.ini:
|
grafana.ini:
|
||||||
server:
|
server:
|
||||||
root_url: https://grafana.riotpiao.homelab.com
|
root_url: https://grafana.riotpiao.com
|
||||||
|
|
||||||
# No anonymous read access — every user must log in via Authentik SSO.
|
# No anonymous read access — every user must log in via Authentik SSO.
|
||||||
auth.anonymous:
|
auth.anonymous:
|
||||||
@@ -70,9 +70,9 @@ grafana.ini:
|
|||||||
allow_sign_up: true
|
allow_sign_up: true
|
||||||
client_id: grafana
|
client_id: grafana
|
||||||
scopes: openid email profile
|
scopes: openid email profile
|
||||||
auth_url: https://authentik.riotpiao.homelab.com/application/o/authorize/
|
auth_url: https://authentik.riotpiao.com/application/o/authorize/
|
||||||
token_url: https://authentik.riotpiao.homelab.com/application/o/token/
|
token_url: https://authentik.riotpiao.com/application/o/token/
|
||||||
api_url: https://authentik.riotpiao.homelab.com/application/o/userinfo/
|
api_url: https://authentik.riotpiao.com/application/o/userinfo/
|
||||||
role_attribute_path: "contains(groups[*], 'grafana-admins') && 'Admin' || 'Viewer'"
|
role_attribute_path: "contains(groups[*], 'grafana-admins') && 'Admin' || 'Viewer'"
|
||||||
use_pkce: false
|
use_pkce: false
|
||||||
use_refresh_token: false
|
use_refresh_token: false
|
||||||
@@ -154,7 +154,7 @@ tolerations:
|
|||||||
operator: Exists
|
operator: Exists
|
||||||
effect: NoSchedule
|
effect: NoSchedule
|
||||||
|
|
||||||
# ClusterIP only — access via ingress (grafana.riotpiao.homelab.com) or port-forward.
|
# ClusterIP only — access via ingress (grafana.riotpiao.com) or port-forward.
|
||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
port: 80
|
port: 80
|
||||||
|
|||||||
@@ -40,27 +40,27 @@ serviceMonitor:
|
|||||||
module: http_2xx
|
module: http_2xx
|
||||||
targets:
|
targets:
|
||||||
- name: grafana
|
- name: grafana
|
||||||
url: https://grafana.riotpiao.homelab.com/
|
url: https://grafana.riotpiao.com/
|
||||||
- name: loki
|
- name: loki
|
||||||
url: https://loki.riotpiao.homelab.com/ready
|
url: https://loki.riotpiao.com/ready
|
||||||
- name: authentik
|
- name: authentik
|
||||||
url: https://authentik.riotpiao.homelab.com/-/health/ready/
|
url: https://authentik.riotpiao.com/-/health/ready/
|
||||||
- name: vault
|
- name: vault
|
||||||
url: https://vault.riotpiao.homelab.com/v1/sys/health
|
url: https://vault.riotpiao.com/v1/sys/health
|
||||||
- name: minio-console
|
- name: minio-console
|
||||||
url: https://minio.riotpiao.homelab.com/
|
url: https://minio.riotpiao.com/
|
||||||
- name: minio-api
|
- name: minio-api
|
||||||
url: https://minio-api.riotpiao.homelab.com/minio/health/live
|
url: https://minio-api.riotpiao.com/minio/health/live
|
||||||
- name: prometheus
|
- name: prometheus
|
||||||
url: https://prometheus.riotpiao.homelab.com/-/healthy
|
url: https://prometheus.riotpiao.com/-/healthy
|
||||||
- name: portainer
|
- name: portainer
|
||||||
url: https://portainer.riotpiao.homelab.com/
|
url: https://portainer.riotpiao.com/
|
||||||
- name: forgejo
|
- name: forgejo
|
||||||
url: https://forgejo.riotpiao.homelab.com/api/healthz
|
url: https://forgejo.riotpiao.com/api/healthz
|
||||||
- name: argocd
|
- name: argocd
|
||||||
url: https://argocd.riotpiao.homelab.com/healthz
|
url: https://argocd.riotpiao.com/healthz
|
||||||
- name: longhorn
|
- name: longhorn
|
||||||
url: https://longhorn.riotpiao.homelab.com/
|
url: https://longhorn.riotpiao.com/
|
||||||
|
|
||||||
prometheusRule:
|
prometheusRule:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Deployed via helmfile (name=argocd) so it sits alongside Authentik, MinIO, etc.
|
# Deployed via helmfile (name=argocd) so it sits alongside Authentik, MinIO, etc.
|
||||||
#
|
#
|
||||||
# UI is exposed via the cluster Ingress (k8s/ingress/ingress.yaml,
|
# UI is exposed via the cluster Ingress (k8s/ingress/ingress.yaml,
|
||||||
# argocd.riotpiao.homelab.com) over the WireGuard/LAN-only nginx ingress —
|
# argocd.riotpiao.com) over the WireGuard/LAN-only nginx ingress —
|
||||||
# never as a LoadBalancer, since argocd-server holds cluster-admin
|
# never as a LoadBalancer, since argocd-server holds cluster-admin
|
||||||
# credentials and that Ingress isn't reachable from the WAN.
|
# credentials and that Ingress isn't reachable from the WAN.
|
||||||
#
|
#
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
# CA trust for Forgejo repo clones injected into argocd-tls-certs-cm by postsync hook.
|
# CA trust for Forgejo repo clones injected into argocd-tls-certs-cm by postsync hook.
|
||||||
|
|
||||||
global:
|
global:
|
||||||
domain: argocd.riotpiao.homelab.com
|
domain: argocd.riotpiao.com
|
||||||
|
|
||||||
configs:
|
configs:
|
||||||
params:
|
params:
|
||||||
@@ -23,10 +23,10 @@ configs:
|
|||||||
# Authentik (provision_oidc.py argocd_url) exactly — ArgoCD builds its
|
# Authentik (provision_oidc.py argocd_url) exactly — ArgoCD builds its
|
||||||
# OIDC redirect_uri as "{url}/auth/callback", so any mismatch here is
|
# OIDC redirect_uri as "{url}/auth/callback", so any mismatch here is
|
||||||
# what Authentik's "Invalid redirect URL" error means.
|
# what Authentik's "Invalid redirect URL" error means.
|
||||||
url: "https://argocd.riotpiao.homelab.com"
|
url: "https://argocd.riotpiao.com"
|
||||||
oidc.config: |
|
oidc.config: |
|
||||||
name: Authentik
|
name: Authentik
|
||||||
issuer: https://authentik.riotpiao.homelab.com/application/o/argocd/
|
issuer: https://authentik.riotpiao.com/application/o/argocd/
|
||||||
clientID: $oidc-secret:client-id
|
clientID: $oidc-secret:client-id
|
||||||
clientSecret: $oidc-secret:client-secret
|
clientSecret: $oidc-secret:client-secret
|
||||||
requestedScopes: [openid, profile, email, groups]
|
requestedScopes: [openid, profile, email, groups]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ runner:
|
|||||||
tag: "6" # pin exact release before apply
|
tag: "6" # pin exact release before apply
|
||||||
name: talos-runner
|
name: talos-runner
|
||||||
labels: "docker:docker://node:22-bookworm"
|
labels: "docker:docker://node:22-bookworm"
|
||||||
forgejoUrl: https://forgejo.riotpiao.homelab.com
|
forgejoUrl: https://forgejo.riotpiao.com
|
||||||
# tokenSecret: name of the K8s Secret that holds the runner registration token
|
# tokenSecret: name of the K8s Secret that holds the runner registration token
|
||||||
# created automatically by the helmfile presync hook (see helmfile.yaml.gotmpl)
|
# created automatically by the helmfile presync hook (see helmfile.yaml.gotmpl)
|
||||||
tokenSecret: runner-token
|
tokenSecret: runner-token
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: api
|
- name: api
|
||||||
# CI bumps this tag on every push to main (ci.yml step "bump deploy repo")
|
# CI bumps this tag on every push to main (ci.yml step "bump deploy repo")
|
||||||
image: forgejo.riotpiao.homelab.com/rock/api:latest
|
image: forgejo.riotpiao.com/rock/api:latest
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: api
|
path: api
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: argocd
|
path: argocd
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
source:
|
||||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||||
targetRevision: main
|
targetRevision: main
|
||||||
path: forge
|
path: forge
|
||||||
destination:
|
destination:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
# ── 2. Build + push OCI image ───────────────────────────────────────────
|
# ── 2. Build + push OCI image ───────────────────────────────────────────
|
||||||
- name: build and push image
|
- name: build and push image
|
||||||
env:
|
env:
|
||||||
REGISTRY: forgejo.forge.riotpiao.homelab.com
|
REGISTRY: forgejo.forge.riotpiao.com
|
||||||
OWNER: rock
|
OWNER: rock
|
||||||
run: |
|
run: |
|
||||||
REPO_NAME=${{ github.event.repository.name }}
|
REPO_NAME=${{ github.event.repository.name }}
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
# Argo CD notices the commit and rolls out the new image.
|
# Argo CD notices the commit and rolls out the new image.
|
||||||
- name: bump deploy repo
|
- name: bump deploy repo
|
||||||
env:
|
env:
|
||||||
REGISTRY: forgejo.forge.riotpiao.homelab.com
|
REGISTRY: forgejo.forge.riotpiao.com
|
||||||
OWNER: rock
|
OWNER: rock
|
||||||
run: |
|
run: |
|
||||||
git clone \
|
git clone \
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
|
|
||||||
git -C /tmp/deploy \
|
git -C /tmp/deploy \
|
||||||
-c user.name="ci-bot" \
|
-c user.name="ci-bot" \
|
||||||
-c user.email="[email protected].homelab.com" \
|
-c user.email="[email protected]" \
|
||||||
commit -am "${REPO_NAME}: deploy ${TAG}"
|
commit -am "${REPO_NAME}: deploy ${TAG}"
|
||||||
|
|
||||||
git -C /tmp/deploy push
|
git -C /tmp/deploy push
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: forgejo-redis
|
||||||
|
namespace: cicd
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: forgejo-redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: forgejo-redis
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: redis:7-alpine
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 128Mi
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: forgejo-redis
|
||||||
|
namespace: cicd
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: forgejo-redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
# k8s/talos-ci-cd/forgejo-values.yaml
|
# k8s/security/ci-cd/forgejo-values.yaml
|
||||||
# Forgejo deployed via the gitea-charts/gitea Helm chart with image override.
|
# Forgejo deployed via the gitea-charts/gitea Helm chart with image override,
|
||||||
# Admin password injected via helmfile --set (FORGEJO_ADMIN_PASSWORD in .env).
|
# as an ArgoCD Application with an inline Helm source (k8s/argocd/apps/forgejo.yaml).
|
||||||
# Runner is managed by a separate helmfile release (charts/forgejo-runner/).
|
# Admin password set via --set at install time (FORGEJO_ADMIN_PASSWORD in .env).
|
||||||
|
# DB: CNPG (k8s/data/ddb-cluster.yaml + forgejo-database.yaml), not SQLite.
|
||||||
|
# Cache/session/queue: dedicated Redis (forgejo-redis.yaml), not in-memory —
|
||||||
|
# required once replicaCount > 1, since in-memory state isn't shared across pods.
|
||||||
#
|
#
|
||||||
# Chart docs: https://gitea.com/gitea/helm-chart
|
# Chart docs: https://gitea.com/gitea/helm-chart
|
||||||
|
|
||||||
@@ -21,16 +24,18 @@ gitea:
|
|||||||
config:
|
config:
|
||||||
server:
|
server:
|
||||||
PROTOCOL: http # nginx ingress handles TLS; pod serves plain HTTP
|
PROTOCOL: http # nginx ingress handles TLS; pod serves plain HTTP
|
||||||
DOMAIN: forgejo.riotpiao.homelab.com
|
DOMAIN: forgejo.riotpiao.com
|
||||||
ROOT_URL: https://forgejo.riotpiao.homelab.com/
|
ROOT_URL: https://forgejo.riotpiao.com/
|
||||||
HTTP_PORT: 3000
|
HTTP_PORT: 3000
|
||||||
START_SSH_SERVER: true
|
START_SSH_SERVER: true
|
||||||
SSH_DOMAIN: forgejo.riotpiao.homelab.com
|
SSH_DOMAIN: forgejo.riotpiao.com
|
||||||
SSH_PORT: 2222
|
SSH_PORT: 2222
|
||||||
SSH_LISTEN_PORT: 2222
|
SSH_LISTEN_PORT: 2222
|
||||||
database:
|
database:
|
||||||
DB_TYPE: sqlite3
|
DB_TYPE: postgres
|
||||||
PATH: /data/forgejo.db
|
HOST: ddb-cluster-rw.ddb.svc:5432
|
||||||
|
NAME: forgejo
|
||||||
|
USER: app
|
||||||
repository:
|
repository:
|
||||||
ROOT: /data/git
|
ROOT: /data/git
|
||||||
actions:
|
actions:
|
||||||
@@ -44,37 +49,49 @@ gitea:
|
|||||||
oauth2:
|
oauth2:
|
||||||
ENABLED: true
|
ENABLED: true
|
||||||
PROVIDER: openidconnect
|
PROVIDER: openidconnect
|
||||||
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration
|
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||||
CLIENT_ID: forgejo
|
CLIENT_ID: forgejo
|
||||||
AUTO_DISCOVER_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration
|
AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||||
cache:
|
cache:
|
||||||
ADAPTER: memory # no Redis — single-replica SQLite setup
|
ADAPTER: redis
|
||||||
|
HOST: redis://forgejo-redis.cicd.svc:6379/0
|
||||||
session:
|
session:
|
||||||
PROVIDER: memory
|
PROVIDER: redis
|
||||||
|
PROVIDER_CONFIG: redis://forgejo-redis.cicd.svc:6379/1
|
||||||
queue:
|
queue:
|
||||||
TYPE: channel # in-memory queue; no file lock, no LevelDB contention on rollout
|
TYPE: redis
|
||||||
|
CONN_STR: redis://forgejo-redis.cicd.svc:6379/2
|
||||||
|
|
||||||
metrics:
|
metrics:
|
||||||
enabled: true
|
enabled: true
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
enabled: true # kube-prometheus-stack discovers ServiceMonitors cluster-wide
|
enabled: true # kube-prometheus-stack discovers ServiceMonitors cluster-wide
|
||||||
|
|
||||||
# ── Persistence (Longhorn RWO — SQLite lives here) ────────────────────────────
|
# ── Persistence (Longhorn RWX — git repo data shared across replicas) ────────
|
||||||
persistence:
|
persistence:
|
||||||
enabled: true
|
enabled: true
|
||||||
storageClass: longhorn
|
storageClass: longhorn
|
||||||
size: 20Gi
|
size: 20Gi
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteOnce
|
- ReadWriteMany
|
||||||
|
|
||||||
|
# ── Replicas ──────────────────────────────────────────────────────────────────
|
||||||
|
# Postgres (CNPG) + Redis (session/cache/queue) + RWX storage means replicas
|
||||||
|
# no longer need to serialize on a single pod like the old SQLite setup did.
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
# ── Deployment strategy ────────────────────────────────────────────────────────
|
# ── Deployment strategy ────────────────────────────────────────────────────────
|
||||||
# RWO PVC + SQLite: old pod must terminate before new one mounts the volume.
|
|
||||||
deployment:
|
deployment:
|
||||||
strategy:
|
strategy:
|
||||||
type: Recreate
|
type: RollingUpdate
|
||||||
env:
|
env:
|
||||||
- name: SSL_CERT_DIR
|
- name: SSL_CERT_DIR
|
||||||
value: /homelab-ca
|
value: /homelab-ca
|
||||||
|
- name: GITEA__database__PASSWD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ddb-cluster-app
|
||||||
|
key: password
|
||||||
|
|
||||||
# ── Cert / CA auto-reload ─────────────────────────────────────────────────────
|
# ── Cert / CA auto-reload ─────────────────────────────────────────────────────
|
||||||
# nginx serves the wildcard-tls cert — Forgejo itself never reads a TLS secret.
|
# nginx serves the wildcard-tls cert — Forgejo itself never reads a TLS secret.
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
namespace: ci-cd
|
namespace: ci-cd
|
||||||
resources: []
|
resources:
|
||||||
# Helm charts (forgejo-runner) deployed via ArgoCD Helm source
|
- forgejo-redis.yaml
|
||||||
|
# Helm charts (forgejo, forgejo-runner) deployed via standalone ArgoCD
|
||||||
|
# Applications with Helm sources (k8s/argocd/apps/forgejo.yaml) — not through
|
||||||
|
# this kustomization, since layer-4-security syncs from Forgejo's own repo
|
||||||
|
# (chicken-egg: Forgejo can't be the source of truth for deploying itself).
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 0. Source your env (Authentik bootstrap token + Vault addr)
|
# 0. Source your env (Authentik bootstrap token + Vault addr)
|
||||||
set -a && source ~/.authentik/.env && set +a
|
set -a && source ~/.authentik/.env && set +a
|
||||||
VAULT_ADDR="http://vault.riotpiao.homelab.com"
|
VAULT_ADDR="http://vault.riotpiao.com"
|
||||||
AUTHENTIK_URL="http://authentik.riotpiao.homelab.com"
|
AUTHENTIK_URL="http://authentik.riotpiao.com"
|
||||||
|
|
||||||
# 1. Fetch the real client_id + client_secret from Authentik
|
# 1. Fetch the real client_id + client_secret from Authentik
|
||||||
PROVIDER_PK=$(curl -s \
|
PROVIDER_PK=$(curl -s \
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ cd /Users/rockliang/workplace/homelab
|
|||||||
python3 k8s/talos-iam/register_oauth_app.py \
|
python3 k8s/talos-iam/register_oauth_app.py \
|
||||||
--service-name my-app \
|
--service-name my-app \
|
||||||
--namespace my-namespace \
|
--namespace my-namespace \
|
||||||
--redirect-uri "https://my-app.riotpiao.homelab.com/oauth2/callback" \
|
--redirect-uri "https://my-app.riotpiao.com/oauth2/callback" \
|
||||||
--service-name-in-vault "MY_SERVICE" \
|
--service-name-in-vault "MY_SERVICE" \
|
||||||
--vault-jwt-policy "shell-secrets"
|
--vault-jwt-policy "shell-secrets"
|
||||||
```
|
```
|
||||||
@@ -127,7 +127,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 &
|
|||||||
- **Name:** `yourservice`
|
- **Name:** `yourservice`
|
||||||
- **Client ID:** `yourservice` (or custom)
|
- **Client ID:** `yourservice` (or custom)
|
||||||
- **Client Secret:** (paste from `$CLIENT_SECRET` above)
|
- **Client Secret:** (paste from `$CLIENT_SECRET` above)
|
||||||
- **Redirect URIs:** `https://your-app.riotpiao.homelab.com/oauth2/callback` (or your app's callback URL)
|
- **Redirect URIs:** `https://your-app.riotpiao.com/oauth2/callback` (or your app's callback URL)
|
||||||
- **Sub Mode:** `Hashed User ID`
|
- **Sub Mode:** `Hashed User ID`
|
||||||
- **Include claims in ID Token:** ✓ Enabled
|
- **Include claims in ID Token:** ✓ Enabled
|
||||||
- **Grant Types:** `Authorization Code`, `Refresh Token`
|
- **Grant Types:** `Authorization Code`, `Refresh Token`
|
||||||
@@ -143,7 +143,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 &
|
|||||||
- **Name:** `Your App Display Name`
|
- **Name:** `Your App Display Name`
|
||||||
- **Slug:** `yourservice` (must match provider slug)
|
- **Slug:** `yourservice` (must match provider slug)
|
||||||
- **Provider:** (select the provider created above)
|
- **Provider:** (select the provider created above)
|
||||||
- **Meta Launch URL:** `https://your-app.riotpiao.homelab.com` (optional, for app launcher)
|
- **Meta Launch URL:** `https://your-app.riotpiao.com` (optional, for app launcher)
|
||||||
|
|
||||||
3. **Save**
|
3. **Save**
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ OIDC_CLIENT_ID=yourservice
|
|||||||
OIDC_CLIENT_SECRET=$CLIENT_SECRET
|
OIDC_CLIENT_SECRET=$CLIENT_SECRET
|
||||||
|
|
||||||
# Redirect URI (must match what you configured in step 2)
|
# Redirect URI (must match what you configured in step 2)
|
||||||
OIDC_REDIRECT_URI=https://your-app.riotpiao.homelab.com/oauth2/callback
|
OIDC_REDIRECT_URI=https://your-app.riotpiao.com/oauth2/callback
|
||||||
|
|
||||||
# Optionally, token validation endpoint
|
# Optionally, token validation endpoint
|
||||||
OIDC_TOKEN_URL=http://authentik-server.iam.svc.cluster.local/application/o/yourservice/token/
|
OIDC_TOKEN_URL=http://authentik-server.iam.svc.cluster.local/application/o/yourservice/token/
|
||||||
@@ -179,7 +179,7 @@ talos put cluster/YOURSERVICE_OIDC_CLIENT_SECRET YOURSERVICE_OIDC_CLIENT_SECRET=
|
|||||||
talos put cluster/yourservice-oidc \
|
talos put cluster/yourservice-oidc \
|
||||||
client_id=yourservice \
|
client_id=yourservice \
|
||||||
issuer_url="http://authentik-server.iam.svc.cluster.local/application/o/yourservice/" \
|
issuer_url="http://authentik-server.iam.svc.cluster.local/application/o/yourservice/" \
|
||||||
callback_uri="https://your-app.riotpiao.homelab.com/oauth2/callback"
|
callback_uri="https://your-app.riotpiao.com/oauth2/callback"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 5: Mount Credentials in Your Service
|
### Step 5: Mount Credentials in Your Service
|
||||||
@@ -378,7 +378,7 @@ kubectl get secret yourservice-oidc -n your-namespace -o jsonpath='{.data}' | ba
|
|||||||
vault read auth/jwt/role/yourservice
|
vault read auth/jwt/role/yourservice
|
||||||
|
|
||||||
# 5. Test OAuth login (requires port-forward to your app)
|
# 5. Test OAuth login (requires port-forward to your app)
|
||||||
# Open http://your-app.riotpiao.homelab.com/login
|
# Open http://your-app.riotpiao.com/login
|
||||||
# Should redirect to Authentik, then back to your app
|
# Should redirect to Authentik, then back to your app
|
||||||
|
|
||||||
# 6. Test JWT auth to Vault (if applicable)
|
# 6. Test JWT auth to Vault (if applicable)
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ The homelab provides **automated OAuth registration** for new services via `regi
|
|||||||
python3 k8s/talos-iam/register_oauth_app.py \
|
python3 k8s/talos-iam/register_oauth_app.py \
|
||||||
--service-name my-service \
|
--service-name my-service \
|
||||||
--namespace my-ns \
|
--namespace my-ns \
|
||||||
--redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \
|
--redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \
|
||||||
--service-name-in-vault MY_SERVICE \
|
--service-name-in-vault MY_SERVICE \
|
||||||
--vault-jwt-policy shell-secrets \
|
--vault-jwt-policy shell-secrets \
|
||||||
--add-group my-service-admins
|
--add-group my-service-admins
|
||||||
@@ -254,7 +254,7 @@ export DASHBOARD_OIDC_CLIENT_SECRET
|
|||||||
python3 k8s/talos-iam/register_oauth_app.py \
|
python3 k8s/talos-iam/register_oauth_app.py \
|
||||||
--service-name dashboard-service \
|
--service-name dashboard-service \
|
||||||
--namespace apps \
|
--namespace apps \
|
||||||
--redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \
|
--redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \
|
||||||
--service-name-in-vault DASHBOARD \
|
--service-name-in-vault DASHBOARD \
|
||||||
--vault-jwt-policy shell-secrets \
|
--vault-jwt-policy shell-secrets \
|
||||||
--add-group dashboard-admins \
|
--add-group dashboard-admins \
|
||||||
@@ -282,7 +282,7 @@ kubectl get secret my-service-oidc -n my-ns -o yaml
|
|||||||
vault read auth/jwt/role/my-service
|
vault read auth/jwt/role/my-service
|
||||||
|
|
||||||
# Test OAuth login
|
# Test OAuth login
|
||||||
# Browser: https://my-service.riotpiao.homelab.com/login
|
# Browser: https://my-service.riotpiao.com/login
|
||||||
# Should redirect to Authentik → back to service with session
|
# Should redirect to Authentik → back to service with session
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ authentik:
|
|||||||
# Must match what the browser sees — if it returns an internal svc URL,
|
# Must match what the browser sees — if it returns an internal svc URL,
|
||||||
# the browser's redirect after login will fail (can't reach svc DNS externally).
|
# the browser's redirect after login will fail (can't reach svc DNS externally).
|
||||||
# HTTP (not HTTPS) because the Authentik ingress has no TLS cert configured.
|
# HTTP (not HTTPS) because the Authentik ingress has no TLS cert configured.
|
||||||
host: "https://authentik.riotpiao.homelab.com"
|
host: "https://authentik.riotpiao.com"
|
||||||
|
|
||||||
error_reporting:
|
error_reporting:
|
||||||
enabled: false # do not phone home to Sentry
|
enabled: false # do not phone home to Sentry
|
||||||
@@ -103,7 +103,7 @@ _caEnv: &caEnv
|
|||||||
# ── Authentik server (UI + API) ───────────────────────────────────────────────
|
# ── Authentik server (UI + API) ───────────────────────────────────────────────
|
||||||
# Handles all browser traffic: login flows, admin UI, OAuth2 authorize/token endpoints.
|
# Handles all browser traffic: login flows, admin UI, OAuth2 authorize/token endpoints.
|
||||||
# NodePort 32172 is a fallback for direct node access during troubleshooting;
|
# NodePort 32172 is a fallback for direct node access during troubleshooting;
|
||||||
# normal access is via nginx ingress (authentik.riotpiao.homelab.com → svc:80).
|
# normal access is via nginx ingress (authentik.riotpiao.com → svc:80).
|
||||||
# Recreate: single replica + RWO-adjacent state — avoids split-brain on redeploy.
|
# Recreate: single replica + RWO-adjacent state — avoids split-brain on redeploy.
|
||||||
server:
|
server:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
@@ -221,5 +221,5 @@ redis:
|
|||||||
operator: Exists
|
operator: Exists
|
||||||
architecture: standalone
|
architecture: standalone
|
||||||
|
|
||||||
# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.homelab.com).
|
# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.com).
|
||||||
# For direct access during bootstrap: kubectl -n iam port-forward svc/authentik-server 7000:80
|
# For direct access during bootstrap: kubectl -n iam port-forward svc/authentik-server 7000:80
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ To use this example:
|
|||||||
python3 register_oauth_app.py \\
|
python3 register_oauth_app.py \\
|
||||||
--service-name dashboard-service \\
|
--service-name dashboard-service \\
|
||||||
--namespace apps \\
|
--namespace apps \\
|
||||||
--redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \\
|
--redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \\
|
||||||
--service-name-in-vault DASHBOARD \\
|
--service-name-in-vault DASHBOARD \\
|
||||||
--vault-jwt-policy shell-secrets \\
|
--vault-jwt-policy shell-secrets \\
|
||||||
--add-group dashboard-admins \\
|
--add-group dashboard-admins \\
|
||||||
@@ -34,7 +34,7 @@ To use this example:
|
|||||||
http://localhost:7000/api/v3/core/applications/?slug=dashboard-service | jq .
|
http://localhost:7000/api/v3/core/applications/?slug=dashboard-service | jq .
|
||||||
|
|
||||||
# 5. Test OAuth callback (requires app running)
|
# 5. Test OAuth callback (requires app running)
|
||||||
# Browser: http://dashboard.riotpiao.homelab.com/login
|
# Browser: http://dashboard.riotpiao.com/login
|
||||||
# Should redirect to Authentik → back to dashboard with session
|
# Should redirect to Authentik → back to dashboard with session
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ def example_dashboard_service():
|
|||||||
"register_oauth_app.py",
|
"register_oauth_app.py",
|
||||||
"--service-name", "dashboard-service",
|
"--service-name", "dashboard-service",
|
||||||
"--namespace", "apps",
|
"--namespace", "apps",
|
||||||
"--redirect-uri", "https://dashboard.riotpiao.homelab.com/oauth2/callback",
|
"--redirect-uri", "https://dashboard.riotpiao.com/oauth2/callback",
|
||||||
"--service-name-in-vault", "DASHBOARD",
|
"--service-name-in-vault", "DASHBOARD",
|
||||||
"--vault-jwt-policy", "shell-secrets",
|
"--vault-jwt-policy", "shell-secrets",
|
||||||
"--add-group", "dashboard-admins",
|
"--add-group", "dashboard-admins",
|
||||||
@@ -122,7 +122,7 @@ def verify_example():
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
print("✅ Test OAuth redirect (requires app running):")
|
print("✅ Test OAuth redirect (requires app running):")
|
||||||
print(" curl -L https://dashboard.riotpiao.homelab.com/login")
|
print(" curl -L https://dashboard.riotpiao.com/login")
|
||||||
print(" # Should redirect to Authentik, then back to dashboard")
|
print(" # Should redirect to Authentik, then back to dashboard")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Usage:
|
|||||||
python3 register_oauth_app.py \\
|
python3 register_oauth_app.py \\
|
||||||
--service-name my-service \\
|
--service-name my-service \\
|
||||||
--namespace my-ns \\
|
--namespace my-ns \\
|
||||||
--redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \\
|
--redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \\
|
||||||
[--service-name-in-vault MY_SERVICE] \\
|
[--service-name-in-vault MY_SERVICE] \\
|
||||||
[--vault-jwt-policy shell-secrets]
|
[--vault-jwt-policy shell-secrets]
|
||||||
|
|
||||||
@@ -28,13 +28,13 @@ Examples:
|
|||||||
python3 register_oauth_app.py \\
|
python3 register_oauth_app.py \\
|
||||||
--service-name myapp \\
|
--service-name myapp \\
|
||||||
--namespace apps \\
|
--namespace apps \\
|
||||||
--redirect-uri "https://myapp.riotpiao.homelab.com/callback"
|
--redirect-uri "https://myapp.riotpiao.com/callback"
|
||||||
|
|
||||||
# Advanced: full service with Vault JWT auth
|
# Advanced: full service with Vault JWT auth
|
||||||
python3 register_oauth_app.py \\
|
python3 register_oauth_app.py \\
|
||||||
--service-name myservice \\
|
--service-name myservice \\
|
||||||
--namespace my-namespace \\
|
--namespace my-namespace \\
|
||||||
--redirect-uri "https://myservice.riotpiao.homelab.com/oauth2/callback" \\
|
--redirect-uri "https://myservice.riotpiao.com/oauth2/callback" \\
|
||||||
--service-name-in-vault MYSERVICE \\
|
--service-name-in-vault MYSERVICE \\
|
||||||
--vault-jwt-policy shell-secrets \\
|
--vault-jwt-policy shell-secrets \\
|
||||||
--add-group myservice-admins \\
|
--add-group myservice-admins \\
|
||||||
@@ -328,7 +328,7 @@ def main() -> None:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--redirect-uri",
|
"--redirect-uri",
|
||||||
required=True,
|
required=True,
|
||||||
help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.homelab.com/callback)"
|
help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.com/callback)"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--service-name-in-vault",
|
"--service-name-in-vault",
|
||||||
@@ -420,7 +420,7 @@ def main() -> None:
|
|||||||
display_name=service_name.replace("-", " ").title(),
|
display_name=service_name.replace("-", " ").title(),
|
||||||
slug=service_name,
|
slug=service_name,
|
||||||
provider_pk=provider_pk,
|
provider_pk=provider_pk,
|
||||||
launch_url=f"https://{service_name}.riotpiao.homelab.com"
|
launch_url=f"https://{service_name}.riotpiao.com"
|
||||||
)
|
)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ _vault_browser_payload=$(jq -n \
|
|||||||
invalidation_flow: $inval_flow,
|
invalidation_flow: $inval_flow,
|
||||||
signing_key: $signing_key,
|
signing_key: $signing_key,
|
||||||
redirect_uris: [
|
redirect_uris: [
|
||||||
{"matching_mode": "strict", "url": "http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback"},
|
{"matching_mode": "strict", "url": "http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback"},
|
||||||
{"matching_mode": "strict", "url": "http://localhost:8250/oidc/callback"}
|
{"matching_mode": "strict", "url": "http://localhost:8250/oidc/callback"}
|
||||||
]
|
]
|
||||||
}')
|
}')
|
||||||
@@ -465,7 +465,7 @@ step oidc_enable "Enabling OIDC auth method for browser login..."
|
|||||||
vault auth enable oidc 2>/dev/null || echo "OIDC auth already enabled."
|
vault auth enable oidc 2>/dev/null || echo "OIDC auth already enabled."
|
||||||
|
|
||||||
vault write auth/oidc/config \
|
vault write auth/oidc/config \
|
||||||
oidc_discovery_url="http://authentik.riotpiao.homelab.com/application/o/vault-browser/" \
|
oidc_discovery_url="http://authentik.riotpiao.com/application/o/vault-browser/" \
|
||||||
oidc_client_id="vault-browser" \
|
oidc_client_id="vault-browser" \
|
||||||
oidc_client_secret="${VAULT_BROWSER_CLIENT_SECRET}" \
|
oidc_client_secret="${VAULT_BROWSER_CLIENT_SECRET}" \
|
||||||
default_role="homelab"
|
default_role="homelab"
|
||||||
@@ -475,7 +475,7 @@ vault write auth/oidc/config \
|
|||||||
vault write auth/oidc/role/homelab \
|
vault write auth/oidc/role/homelab \
|
||||||
role_type=oidc \
|
role_type=oidc \
|
||||||
bound_audiences="vault-browser" \
|
bound_audiences="vault-browser" \
|
||||||
allowed_redirect_uris="http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \
|
allowed_redirect_uris="http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \
|
||||||
user_claim="sub" \
|
user_claim="sub" \
|
||||||
oidc_scopes="openid,profile,email" \
|
oidc_scopes="openid,profile,email" \
|
||||||
token_policies="shell-secrets,cluster-admin" \
|
token_policies="shell-secrets,cluster-admin" \
|
||||||
@@ -483,8 +483,8 @@ vault write auth/oidc/role/homelab \
|
|||||||
token_max_ttl=12h
|
token_max_ttl=12h
|
||||||
|
|
||||||
echo "OIDC auth configured."
|
echo "OIDC auth configured."
|
||||||
echo " Browser login: http://vault.riotpiao.homelab.com → sign in with Authentik"
|
echo " Browser login: http://vault.riotpiao.com → sign in with Authentik"
|
||||||
echo " CLI login: VAULT_ADDR=http://vault.riotpiao.homelab.com vault login -method=oidc"
|
echo " CLI login: VAULT_ADDR=http://vault.riotpiao.com vault login -method=oidc"
|
||||||
|
|
||||||
# ── 14. Seed initial secrets ──────────────────────────────────────────────────
|
# ── 14. Seed initial secrets ──────────────────────────────────────────────────
|
||||||
step seed_secrets "Seeding initial secrets from environment (accessible after OIDC login)..."
|
step seed_secrets "Seeding initial secrets from environment (accessible after OIDC login)..."
|
||||||
@@ -519,8 +519,8 @@ echo "==> Vault bootstrap complete."
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Next steps:"
|
echo "Next steps:"
|
||||||
echo " 1. Move ${UNSEAL_KEYS_FILE} OFFLINE (USB / password manager)."
|
echo " 1. Move ${UNSEAL_KEYS_FILE} OFFLINE (USB / password manager)."
|
||||||
echo " 2. Browser login: open http://vault.riotpiao.homelab.com → choose OIDC → sign in with Authentik"
|
echo " 2. Browser login: open http://vault.riotpiao.com → choose OIDC → sign in with Authentik"
|
||||||
echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.homelab.com"
|
echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.com"
|
||||||
echo " vault login -method=oidc"
|
echo " vault login -method=oidc"
|
||||||
echo " 4. Read MinIO credentials from Vault after login:"
|
echo " 4. Read MinIO credentials from Vault after login:"
|
||||||
echo " vault kv get secret/cluster/minio"
|
echo " vault kv get secret/cluster/minio"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# once after first install to initialize and store the keys).
|
# once after first install to initialize and store the keys).
|
||||||
|
|
||||||
# ── Global ────────────────────────────────────────────────────────────────────
|
# ── Global ────────────────────────────────────────────────────────────────────
|
||||||
# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.homelab.com)
|
# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.com)
|
||||||
# or at port-forward. In-cluster traffic to Vault is plain HTTP; this is acceptable
|
# or at port-forward. In-cluster traffic to Vault is plain HTTP; this is acceptable
|
||||||
# because all clients are on the pod network (not crossing node boundaries).
|
# because all clients are on the pod network (not crossing node boundaries).
|
||||||
global:
|
global:
|
||||||
@@ -137,7 +137,7 @@ server:
|
|||||||
|
|
||||||
# ── Service ─────────────────────────────────────────────────────────────────
|
# ── Service ─────────────────────────────────────────────────────────────────
|
||||||
# NodePort 32171 — fallback for direct node access during bootstrap before
|
# NodePort 32171 — fallback for direct node access during bootstrap before
|
||||||
# the ingress is up. Normal access is via nginx ingress (vault.riotpiao.homelab.com).
|
# the ingress is up. Normal access is via nginx ingress (vault.riotpiao.com).
|
||||||
service:
|
service:
|
||||||
type: NodePort
|
type: NodePort
|
||||||
port: 8200
|
port: 8200
|
||||||
@@ -155,7 +155,7 @@ server:
|
|||||||
# ── UI ────────────────────────────────────────────────────────────────────────
|
# ── UI ────────────────────────────────────────────────────────────────────────
|
||||||
# Vault's web UI is used for the OIDC browser login flow (Vault as an OIDC
|
# Vault's web UI is used for the OIDC browser login flow (Vault as an OIDC
|
||||||
# provider, if configured) and for manual operator inspection.
|
# provider, if configured) and for manual operator inspection.
|
||||||
# Accessible at http://vault.riotpiao.homelab.com or via port-forward.
|
# Accessible at http://vault.riotpiao.com or via port-forward.
|
||||||
ui:
|
ui:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Authentik Federated OIDC & SSO
|
# Authentik Federated OIDC & SSO
|
||||||
|
|
||||||
**Provider:** `https://authentik.riotpiao.homelab.com`
|
**Provider:** `https://authentik.riotpiao.com`
|
||||||
**OIDC Issuer:** `https://authentik.riotpiao.homelab.com/application/o/talos-federation/`
|
**OIDC Issuer:** `https://authentik.riotpiao.com/application/o/talos-federation/`
|
||||||
**Namespace:** `iam`
|
**Namespace:** `iam`
|
||||||
|
|
||||||
## When to Use
|
## When to Use
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
**1. Login to Authentik console:**
|
**1. Login to Authentik console:**
|
||||||
```bash
|
```bash
|
||||||
# Browser: https://authentik.riotpiao.homelab.com
|
# Browser: https://authentik.riotpiao.com
|
||||||
# Default user: akadmin
|
# Default user: akadmin
|
||||||
# Password: AUTHENTIK_BOOTSTRAP_PASSWORD (from .env)
|
# Password: AUTHENTIK_BOOTSTRAP_PASSWORD (from .env)
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ Authentik console → Users → Create
|
|||||||
|
|
||||||
**3. User logs into Grafana:**
|
**3. User logs into Grafana:**
|
||||||
```
|
```
|
||||||
https://grafana.riotpiao.homelab.com
|
https://grafana.riotpiao.com
|
||||||
→ Sign in with Authentik (auto-redirects to OIDC provider)
|
→ Sign in with Authentik (auto-redirects to OIDC provider)
|
||||||
→ Approve access
|
→ Approve access
|
||||||
→ Logged in as alice (group determines role: Admin or Viewer)
|
→ Logged in as alice (group determines role: Admin or Viewer)
|
||||||
@@ -44,8 +44,8 @@ https://grafana.riotpiao.homelab.com
|
|||||||
| Key | Value |
|
| Key | Value |
|
||||||
|-----|-------|
|
|-----|-------|
|
||||||
| OIDC provider | `talos-federation` (federated) |
|
| OIDC provider | `talos-federation` (federated) |
|
||||||
| OIDC issuer | `https://authentik.riotpiao.homelab.com/application/o/talos-federation/` |
|
| OIDC issuer | `https://authentik.riotpiao.com/application/o/talos-federation/` |
|
||||||
| JWKS endpoint | `https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration` |
|
| JWKS endpoint | `https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration` |
|
||||||
| Database | PostgreSQL (ddb namespace, authentik user) |
|
| Database | PostgreSQL (ddb namespace, authentik user) |
|
||||||
| Backups | WAL archived to MinIO |
|
| Backups | WAL archived to MinIO |
|
||||||
|
|
||||||
@@ -60,9 +60,9 @@ grafana:
|
|||||||
name: Authentik
|
name: Authentik
|
||||||
client_id: grafana
|
client_id: grafana
|
||||||
client_secret: $GRAFANA_OIDC_CLIENT_SECRET # from Vault
|
client_secret: $GRAFANA_OIDC_CLIENT_SECRET # from Vault
|
||||||
auth_url: https://authentik.riotpiao.homelab.com/application/o/authorize/
|
auth_url: https://authentik.riotpiao.com/application/o/authorize/
|
||||||
token_url: https://authentik.riotpiao.homelab.com/application/o/token/
|
token_url: https://authentik.riotpiao.com/application/o/token/
|
||||||
api_url: https://authentik.riotpiao.homelab.com/application/o/userinfo/
|
api_url: https://authentik.riotpiao.com/application/o/userinfo/
|
||||||
scopes: openid profile email groups
|
scopes: openid profile email groups
|
||||||
use_pkce: true
|
use_pkce: true
|
||||||
```
|
```
|
||||||
@@ -75,8 +75,8 @@ minio:
|
|||||||
provider: authentik
|
provider: authentik
|
||||||
client_id: minio
|
client_id: minio
|
||||||
client_secret: $MINIO_OIDC_CLIENT_SECRET
|
client_secret: $MINIO_OIDC_CLIENT_SECRET
|
||||||
redirect_uri: https://minio.riotpiao.homelab.com/oauth_callback
|
redirect_uri: https://minio.riotpiao.com/oauth_callback
|
||||||
config_url: https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration
|
config_url: https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration
|
||||||
policy_mappings:
|
policy_mappings:
|
||||||
- group: homelab-admins → consoleAdmin
|
- group: homelab-admins → consoleAdmin
|
||||||
- group: homelab-devops → readwrite
|
- group: homelab-devops → readwrite
|
||||||
@@ -99,7 +99,7 @@ core get cluster/ANTHROPIC_API_KEY --key ANTHROPIC_API_KEY
|
|||||||
```go
|
```go
|
||||||
import "github.com/coreos/go-oidc/v3/oidc"
|
import "github.com/coreos/go-oidc/v3/oidc"
|
||||||
|
|
||||||
provider, _ := oidc.NewProvider(ctx, "https://authentik.riotpiao.homelab.com/application/o/talos-federation/")
|
provider, _ := oidc.NewProvider(ctx, "https://authentik.riotpiao.com/application/o/talos-federation/")
|
||||||
|
|
||||||
verifier := provider.Verifier(&oidc.Config{ClientID: "my-app"})
|
verifier := provider.Verifier(&oidc.Config{ClientID: "my-app"})
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ Authentik console → Users → alice → Edit
|
|||||||
|
|
||||||
## Monitoring
|
## Monitoring
|
||||||
|
|
||||||
**Authentik dashboard:** https://authentik.riotpiao.homelab.com/api/v3/admin/dashboards
|
**Authentik dashboard:** https://authentik.riotpiao.com/api/v3/admin/dashboards
|
||||||
|
|
||||||
**Key metrics:**
|
**Key metrics:**
|
||||||
- Login attempts (success/failure)
|
- Login attempts (success/failure)
|
||||||
@@ -151,7 +151,7 @@ Authentik console → Users → alice → Edit
|
|||||||
```bash
|
```bash
|
||||||
# Check redirect URI matches
|
# Check redirect URI matches
|
||||||
# Authentik console → Applications → grafana → Edit
|
# Authentik console → Applications → grafana → Edit
|
||||||
# Verify Redirect URI = https://grafana.riotpiao.homelab.com/login/generic_oauth
|
# Verify Redirect URI = https://grafana.riotpiao.com/login/generic_oauth
|
||||||
|
|
||||||
# Check OIDC provider is running
|
# Check OIDC provider is running
|
||||||
k get pods -n iam -l app=authentik
|
k get pods -n iam -l app=authentik
|
||||||
@@ -174,7 +174,7 @@ core secrets login
|
|||||||
**Vault can't validate JWT:**
|
**Vault can't validate JWT:**
|
||||||
```bash
|
```bash
|
||||||
# Verify JWKS endpoint is accessible
|
# Verify JWKS endpoint is accessible
|
||||||
curl https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration
|
curl https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration
|
||||||
|
|
||||||
# Restart Vault to refresh JWKS cache
|
# Restart Vault to refresh JWKS cache
|
||||||
k rollout restart -n iam deployment/vault
|
k rollout restart -n iam deployment/vault
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# CI/CD Pipeline (Forgejo + Argo CD)
|
# CI/CD Pipeline (Forgejo + Argo CD)
|
||||||
|
|
||||||
**Git Forge:** `https://forgejo.riotpiao.homelab.com`
|
**Git Forge:** `https://forgejo.riotpiao.com`
|
||||||
**Deployments:** `https://argocd.riotpiao.homelab.com` (or `kubectl port-forward`)
|
**Deployments:** `https://argocd.riotpiao.com` (or `kubectl port-forward`)
|
||||||
**Namespaces:** `cicd`, `forge`
|
**Namespaces:** `cicd`, `forge`
|
||||||
|
|
||||||
## When to Use
|
## When to Use
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
**1. Clone a repo from Forgejo:**
|
**1. Clone a repo from Forgejo:**
|
||||||
```bash
|
```bash
|
||||||
git clone https://forgejo.riotpiao.homelab.com/rock/source.git
|
git clone https://forgejo.riotpiao.com/rock/source.git
|
||||||
cd source
|
cd source
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -33,10 +33,10 @@ jobs:
|
|||||||
- run: npm test
|
- run: npm test
|
||||||
- run: docker build -t myapp:latest .
|
- run: docker build -t myapp:latest .
|
||||||
- run: |
|
- run: |
|
||||||
docker login forgejo.riotpiao.homelab.com \
|
docker login forgejo.riotpiao.com \
|
||||||
-u ci-bot \
|
-u ci-bot \
|
||||||
-p ${{ secrets.CI_BOT_TOKEN }}
|
-p ${{ secrets.CI_BOT_TOKEN }}
|
||||||
docker push forgejo.riotpiao.homelab.com/rock/myapp:latest
|
docker push forgejo.riotpiao.com/rock/myapp:latest
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git add .forgejo/workflows/ci.yml
|
git add .forgejo/workflows/ci.yml
|
||||||
@@ -47,11 +47,11 @@ git push
|
|||||||
**3. Trigger deployment:**
|
**3. Trigger deployment:**
|
||||||
```bash
|
```bash
|
||||||
# Update deployment repo (rock/deploy)
|
# Update deployment repo (rock/deploy)
|
||||||
git clone https://forgejo.riotpiao.homelab.com/rock/deploy.git
|
git clone https://forgejo.riotpiao.com/rock/deploy.git
|
||||||
cd deploy
|
cd deploy
|
||||||
|
|
||||||
# Update image tag
|
# Update image tag
|
||||||
sed -i 's|forgejo.riotpiao.homelab.com/rock/myapp:.*|forgejo.riotpiao.homelab.com/rock/myapp:abc123|' k8s/deployment.yaml
|
sed -i 's|forgejo.riotpiao.com/rock/myapp:.*|forgejo.riotpiao.com/rock/myapp:abc123|' k8s/deployment.yaml
|
||||||
|
|
||||||
git add k8s/deployment.yaml
|
git add k8s/deployment.yaml
|
||||||
git commit -m "deploy: bump myapp to abc123"
|
git commit -m "deploy: bump myapp to abc123"
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- run: docker build -t myapp:${{ github.sha }} .
|
- run: docker build -t myapp:${{ github.sha }} .
|
||||||
- run: docker push forgejo.riotpiao.homelab.com/rock/myapp:${{ github.sha }}
|
- run: docker push forgejo.riotpiao.com/rock/myapp:${{ github.sha }}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Available variables:**
|
**Available variables:**
|
||||||
@@ -109,10 +109,10 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo
|
|||||||
```yaml
|
```yaml
|
||||||
- run: |
|
- run: |
|
||||||
echo "${{ secrets.CI_BOT_TOKEN }}" | docker login \
|
echo "${{ secrets.CI_BOT_TOKEN }}" | docker login \
|
||||||
forgejo.riotpiao.homelab.com \
|
forgejo.riotpiao.com \
|
||||||
-u ci-bot \
|
-u ci-bot \
|
||||||
--password-stdin
|
--password-stdin
|
||||||
docker push forgejo.riotpiao.homelab.com/rock/myapp:latest
|
docker push forgejo.riotpiao.com/rock/myapp:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
**API token (for pushing commits):**
|
**API token (for pushing commits):**
|
||||||
@@ -121,7 +121,7 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo
|
|||||||
git config user.name "ci-bot"
|
git config user.name "ci-bot"
|
||||||
git config user.email "ci-bot@homelab"
|
git config user.email "ci-bot@homelab"
|
||||||
git commit --allow-empty -m "bump: version"
|
git commit --allow-empty -m "bump: version"
|
||||||
git push https://ci-bot:${{ secrets.CI_BOT_TOKEN }}@forgejo.riotpiao.homelab.com/rock/deploy.git main
|
git push https://ci-bot:${{ secrets.CI_BOT_TOKEN }}@forgejo.riotpiao.com/rock/deploy.git main
|
||||||
```
|
```
|
||||||
|
|
||||||
**Vault secrets (via talos CLI):**
|
**Vault secrets (via talos CLI):**
|
||||||
@@ -135,7 +135,7 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo
|
|||||||
**Create app (one-time):**
|
**Create app (one-time):**
|
||||||
```bash
|
```bash
|
||||||
argocd app create story-crater \
|
argocd app create story-crater \
|
||||||
--repo https://forgejo.riotpiao.homelab.com/rock/deploy.git \
|
--repo https://forgejo.riotpiao.com/rock/deploy.git \
|
||||||
--path k8s/ \
|
--path k8s/ \
|
||||||
--dest-server https://kubernetes.default.svc \
|
--dest-server https://kubernetes.default.svc \
|
||||||
--dest-namespace story-crater-backend \
|
--dest-namespace story-crater-backend \
|
||||||
@@ -148,7 +148,7 @@ argocd app create story-crater \
|
|||||||
argocd app get story-crater
|
argocd app get story-crater
|
||||||
argocd app logs story-crater
|
argocd app logs story-crater
|
||||||
|
|
||||||
# UI: https://argocd.riotpiao.homelab.com
|
# UI: https://argocd.riotpiao.com
|
||||||
# Login: Authentik SSO (homelab-admins group only)
|
# Login: Authentik SSO (homelab-admins group only)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Standardized procedures for troubleshooting, developing, deploying, and operatin
|
|||||||
- Verify scrape: `kubectl get servicemonitor -A | grep <name>` and check Prometheus Targets UI for green status.
|
- Verify scrape: `kubectl get servicemonitor -A | grep <name>` and check Prometheus Targets UI for green status.
|
||||||
|
|
||||||
9. **If OIDC/IAM-gated (admin UI, restricted API):**
|
9. **If OIDC/IAM-gated (admin UI, restricted API):**
|
||||||
- Create app in Authentik: `core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.homelab.com/callback"`.
|
- Create app in Authentik: `core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.com/callback"`.
|
||||||
- Bind app to group: `core iam bind-app my-service <group>` (e.g., `grafana-admins` for admin-only UI).
|
- Bind app to group: `core iam bind-app my-service <group>` (e.g., `grafana-admins` for admin-only UI).
|
||||||
- Retrieve credentials: `core iam describe-app my-service` (client ID, client secret).
|
- Retrieve credentials: `core iam describe-app my-service` (client ID, client secret).
|
||||||
- Deploy secret: `kubectl create secret generic <service>-oidc --from-literal=client-id=<ID> --from-literal=client-secret=<SECRET> -n <namespace>`.
|
- Deploy secret: `kubectl create secret generic <service>-oidc --from-literal=client-id=<ID> --from-literal=client-secret=<SECRET> -n <namespace>`.
|
||||||
@@ -117,7 +117,7 @@ Standardized procedures for troubleshooting, developing, deploying, and operatin
|
|||||||
10. **Verify service is live.**
|
10. **Verify service is live.**
|
||||||
- Pods: `kubectl get pods -n <namespace> -o wide` (all Running, 1/1 Ready).
|
- Pods: `kubectl get pods -n <namespace> -o wide` (all Running, 1/1 Ready).
|
||||||
- Metrics (if applicable): `kubectl get servicemonitor -A | grep <name>` and visit Prometheus Targets or Grafana dashboard.
|
- Metrics (if applicable): `kubectl get servicemonitor -A | grep <name>` and visit Prometheus Targets or Grafana dashboard.
|
||||||
- Endpoint: If publicly routed via Ingress, verify `/etc/hosts` entry (10.6.0.1 for WireGuard, 192.168.1.160 for LAN) and `curl https://my-service.riotpiao.homelab.com/health` (or equivalent health endpoint).
|
- Endpoint: If publicly routed via Ingress, verify `/etc/hosts` entry (10.6.0.1 for WireGuard, 192.168.1.160 for LAN) and `curl https://my-service.riotpiao.com/health` (or equivalent health endpoint).
|
||||||
- Logs: `kubectl logs -n <namespace> <pod>` (no errors).
|
- Logs: `kubectl logs -n <namespace> <pod>` (no errors).
|
||||||
|
|
||||||
### Definition of Done (Per Service)
|
### Definition of Done (Per Service)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ k exec -n ddb pod/ddb-cluster-0 -- psql -U postgres -c "SELECT * FROM pg_stat_re
|
|||||||
- **MinIO credentials:** Use Secret volumes, never `--env` flag (exposes in `kubectl describe`)
|
- **MinIO credentials:** Use Secret volumes, never `--env` flag (exposes in `kubectl describe`)
|
||||||
- **Temporal namespace registration:** never manually `temporal operator namespace create` for a namespace a Queue's `temporal.io/namespace` label references — `queue-operator` registers it automatically. See `~/workplace/kmsvc-manage/CLAUDE.md` ("Temporal Namespace Registration") for the full rule and why.
|
- **Temporal namespace registration:** never manually `temporal operator namespace create` for a namespace a Queue's `temporal.io/namespace` label references — `queue-operator` registers it automatically. See `~/workplace/kmsvc-manage/CLAUDE.md` ("Temporal Namespace Registration") for the full rule and why.
|
||||||
- **kubectl hangs / connection refused:** you're probably off-LAN. `kubectl config use-context admin@homelab-cluster-1` (WireGuard path, `10.6.0.1:6443`) — the default context (`admin@homelab-cluster`, `192.168.1.213:6443`) only works on-LAN. See README.md "kubectl Context".
|
- **kubectl hangs / connection refused:** you're probably off-LAN. `kubectl config use-context admin@homelab-cluster-1` (WireGuard path, `10.6.0.1:6443`) — the default context (`admin@homelab-cluster`, `192.168.1.213:6443`) only works on-LAN. See README.md "kubectl Context".
|
||||||
- **No wildcard DNS:** `*.riotpiao.homelab.com` isn't a real DNS zone — every hostname is a manual `/etc/hosts` line (`10.6.0.1` for WireGuard, the Cilium LB-IPAM IP for LAN). Adding an Ingress `host:` rule doesn't make it resolvable; you must also add the `/etc/hosts` line, on every client machine that needs it.
|
- **No wildcard DNS:** `*.riotpiao.com` isn't a real DNS zone — every hostname is a manual `/etc/hosts` line (`10.6.0.1` for WireGuard, the Cilium LB-IPAM IP for LAN). Adding an Ingress `host:` rule doesn't make it resolvable; you must also add the `/etc/hosts` line, on every client machine that needs it.
|
||||||
- **gRPC through nginx ingress:** add `nginx.ingress.kubernetes.io/backend-protocol: "GRPC"` to proxy h2c to a plaintext-gRPC backend (see `temporal-grpc` Ingress in `k8s/ingress/ingress.yaml`). TLS still terminates at nginx via the wildcard cert — clients need `--tls`, not client certs.
|
- **gRPC through nginx ingress:** add `nginx.ingress.kubernetes.io/backend-protocol: "GRPC"` to proxy h2c to a plaintext-gRPC backend (see `temporal-grpc` Ingress in `k8s/ingress/ingress.yaml`). TLS still terminates at nginx via the wildcard cert — clients need `--tls`, not client certs.
|
||||||
- **Soft podAntiAffinity doesn't rebalance existing pods.** `preferredDuringSchedulingIgnoredDuringExecution` only applies at scheduling time — pods that landed on the same node before the constraint existed (or before other nodes were `Ready`) stay there forever. Fixing the affinity config in values.yaml/CRD only affects *future* pod creation; existing skew needs `kubectl delete pod <name>` (one at a time, verify healthy before the next) to force a reschedule under the now-correct constraint. Hit this with Cassandra, the Kafka `KafkaNodePool`, and CNPG's `ddb-cluster` all stacking onto `talos-cp-1`.
|
- **Soft podAntiAffinity doesn't rebalance existing pods.** `preferredDuringSchedulingIgnoredDuringExecution` only applies at scheduling time — pods that landed on the same node before the constraint existed (or before other nodes were `Ready`) stay there forever. Fixing the affinity config in values.yaml/CRD only affects *future* pod creation; existing skew needs `kubectl delete pod <name>` (one at a time, verify healthy before the next) to force a reschedule under the now-correct constraint. Hit this with Cassandra, the Kafka `KafkaNodePool`, and CNPG's `ddb-cluster` all stacking onto `talos-cp-1`.
|
||||||
- **Cassandra/StatefulSet pod deleted+recreated with no PVC (ephemeral storage) can crash-loop on rejoin:** `Other bootstrapping/leaving/moving nodes detected` or `A node required to move the data consistently is down (/<old-ip>)` — the ring still holds a stale gossip entry for the deleted pod's old IP. Fix: `kubectl exec <a live cassandra pod> -- nodetool assassinate <stale-ip>` from a healthy node, then let the crash-looping pod's next restart retry.
|
- **Cassandra/StatefulSet pod deleted+recreated with no PVC (ephemeral storage) can crash-loop on rejoin:** `Other bootstrapping/leaving/moving nodes detected` or `A node required to move the data consistently is down (/<old-ip>)` — the ring still holds a stale gossip entry for the deleted pod's old IP. Fix: `kubectl exec <a live cassandra pod> -- nodetool assassinate <stale-ip>` from a healthy node, then let the crash-looping pod's next restart retry.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# MinIO S3-Compatible Object Storage
|
# MinIO S3-Compatible Object Storage
|
||||||
|
|
||||||
**Endpoint:** `https://minio.riotpiao.homelab.com` (console)
|
**Endpoint:** `https://minio.riotpiao.com` (console)
|
||||||
**API:** `minio.storage.svc.cluster.local:9000` (cluster-internal)
|
**API:** `minio.storage.svc.cluster.local:9000` (cluster-internal)
|
||||||
**Namespace:** `storage`
|
**Namespace:** `storage`
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
**1. Access MinIO console:**
|
**1. Access MinIO console:**
|
||||||
```bash
|
```bash
|
||||||
# Via browser: https://minio.riotpiao.homelab.com
|
# Via browser: https://minio.riotpiao.com
|
||||||
# Credentials: MINIO_ROOT_USER / MINIO_ROOT_PASSWORD (from .env)
|
# Credentials: MINIO_ROOT_USER / MINIO_ROOT_PASSWORD (from .env)
|
||||||
|
|
||||||
# Or port-forward
|
# Or port-forward
|
||||||
@@ -29,7 +29,7 @@ export AWS_ACCESS_KEY_ID=$MINIO_ROOT_USER
|
|||||||
export AWS_SECRET_ACCESS_KEY=$MINIO_ROOT_PASSWORD
|
export AWS_SECRET_ACCESS_KEY=$MINIO_ROOT_PASSWORD
|
||||||
|
|
||||||
aws s3 mb s3://my-bucket \
|
aws s3 mb s3://my-bucket \
|
||||||
--endpoint-url https://minio.riotpiao.homelab.com \
|
--endpoint-url https://minio.riotpiao.com \
|
||||||
--region homelab
|
--region homelab
|
||||||
|
|
||||||
# Or via console UI: Click "Create Bucket"
|
# Or via console UI: Click "Create Bucket"
|
||||||
@@ -126,8 +126,8 @@ aws s3 ls --endpoint-url http://$MINIO_ENDPOINT --use-path-style
|
|||||||
|
|
||||||
**External access (HTTPS via Ingress):**
|
**External access (HTTPS via Ingress):**
|
||||||
```bash
|
```bash
|
||||||
# Console: https://minio.riotpiao.homelab.com (port 9001)
|
# Console: https://minio.riotpiao.com (port 9001)
|
||||||
# API: Use AWS CLI with --endpoint-url https://minio.riotpiao.homelab.com:9000
|
# API: Use AWS CLI with --endpoint-url https://minio.riotpiao.com:9000
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Monitoring: Prometheus, Grafana & Loki
|
# Monitoring: Prometheus, Grafana & Loki
|
||||||
|
|
||||||
**Prometheus:** `prometheus-kube-prom-prometheus.monitoring.svc.cluster.local:9090`
|
**Prometheus:** `prometheus-kube-prom-prometheus.monitoring.svc.cluster.local:9090`
|
||||||
**Grafana:** `https://grafana.riotpiao.homelab.com`
|
**Grafana:** `https://grafana.riotpiao.com`
|
||||||
**Loki:** `loki.logging.svc.cluster.local:3100`
|
**Loki:** `loki.logging.svc.cluster.local:3100`
|
||||||
**Namespaces:** `monitoring`, `logging`
|
**Namespaces:** `monitoring`, `logging`
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
**1. Access Grafana:**
|
**1. Access Grafana:**
|
||||||
```bash
|
```bash
|
||||||
# Browser: https://grafana.riotpiao.homelab.com
|
# Browser: https://grafana.riotpiao.com
|
||||||
# Login: admin / GRAFANA_ADMIN_PASSWORD (from .env)
|
# Login: admin / GRAFANA_ADMIN_PASSWORD (from .env)
|
||||||
# Or via Authentik SSO
|
# Or via Authentik SSO
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ spec:
|
|||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- myapp.riotpiao.homelab.com
|
- myapp.riotpiao.com
|
||||||
secretName: myapp-tls
|
secretName: myapp-tls
|
||||||
rules:
|
rules:
|
||||||
- host: myapp.riotpiao.homelab.com
|
- host: myapp.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -54,10 +54,10 @@ kubectl get certificate -n myapp-ns
|
|||||||
**3. Test from client:**
|
**3. Test from client:**
|
||||||
```bash
|
```bash
|
||||||
# Add to /etc/hosts (or use WireGuard)
|
# Add to /etc/hosts (or use WireGuard)
|
||||||
192.168.1.160 myapp.riotpiao.homelab.com
|
192.168.1.160 myapp.riotpiao.com
|
||||||
|
|
||||||
# Access
|
# Access
|
||||||
curl https://myapp.riotpiao.homelab.com
|
curl https://myapp.riotpiao.com
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
@@ -83,10 +83,10 @@ spec:
|
|||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- api.riotpiao.homelab.com
|
- api.riotpiao.com
|
||||||
secretName: api-tls
|
secretName: api-tls
|
||||||
rules:
|
rules:
|
||||||
- host: api.riotpiao.homelab.com
|
- host: api.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /users
|
- path: /users
|
||||||
@@ -130,7 +130,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
- host: protected.riotpiao.homelab.com
|
- host: protected.riotpiao.com
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -146,8 +146,8 @@ spec:
|
|||||||
```yaml
|
```yaml
|
||||||
# k8s/coredns/coredns-configmap.yaml
|
# k8s/coredns/coredns-configmap.yaml
|
||||||
# Rewrite:
|
# Rewrite:
|
||||||
# - grafana.riotpiao.homelab.com → grafana.logging (cluster-internal)
|
# - grafana.riotpiao.com → grafana.logging (cluster-internal)
|
||||||
# - prometheus.riotpiao.homelab.com → prometheus-kube-prom-prometheus.monitoring
|
# - prometheus.riotpiao.com → prometheus-kube-prom-prometheus.monitoring
|
||||||
#
|
#
|
||||||
# Allows pods to use external URLs but resolve to internal Services
|
# Allows pods to use external URLs but resolve to internal Services
|
||||||
```
|
```
|
||||||
@@ -184,9 +184,9 @@ spec:
|
|||||||
secretName: myapp-tls
|
secretName: myapp-tls
|
||||||
duration: 2160h # 90 days
|
duration: 2160h # 90 days
|
||||||
renewBefore: 360h # renew 15 days before expiry
|
renewBefore: 360h # renew 15 days before expiry
|
||||||
commonName: myapp.riotpiao.homelab.com
|
commonName: myapp.riotpiao.com
|
||||||
dnsNames:
|
dnsNames:
|
||||||
- myapp.riotpiao.homelab.com
|
- myapp.riotpiao.com
|
||||||
issuerRef:
|
issuerRef:
|
||||||
name: homelab-ca
|
name: homelab-ca
|
||||||
kind: ClusterIssuer
|
kind: ClusterIssuer
|
||||||
@@ -229,7 +229,7 @@ nslookup grafana # if in logging namespace
|
|||||||
make pf-grafana # localhost:3000 → grafana.logging:3000
|
make pf-grafana # localhost:3000 → grafana.logging:3000
|
||||||
|
|
||||||
# Option 3: Add to /etc/hosts (on home network)
|
# Option 3: Add to /etc/hosts (on home network)
|
||||||
192.168.1.160 grafana.riotpiao.homelab.com
|
192.168.1.160 grafana.riotpiao.com
|
||||||
```
|
```
|
||||||
|
|
||||||
## Monitoring
|
## Monitoring
|
||||||
@@ -308,7 +308,7 @@ k get secret -n myapp-ns myapp-tls -o jsonpath='{.data.tls\.crt}' | base64 -d |
|
|||||||
|
|
||||||
# If cert is self-signed (homelab-ca), add to client's trusted roots
|
# If cert is self-signed (homelab-ca), add to client's trusted roots
|
||||||
# Or bypass cert verification (dev only):
|
# Or bypass cert verification (dev only):
|
||||||
curl -k https://myapp.riotpiao.homelab.com
|
curl -k https://myapp.riotpiao.com
|
||||||
```
|
```
|
||||||
|
|
||||||
See `/TROUBLESHOOTING.md` for full incident guide.
|
See `/TROUBLESHOOTING.md` for full incident guide.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# SQS-like Message Queue Service (kmsvc)
|
# SQS-like Message Queue Service (kmsvc)
|
||||||
|
|
||||||
**Endpoint:** `https://kmsvc.riotpiao.homelab.com` (REST + gRPC-Gateway)
|
**Endpoint:** `https://kmsvc.riotpiao.com` (REST + gRPC-Gateway)
|
||||||
**Internal:** `kmsvc-management-service.sqs.svc.cluster.local:8080`
|
**Internal:** `kmsvc-management-service.sqs.svc.cluster.local:8080`
|
||||||
**Namespace:** `sqs`
|
**Namespace:** `sqs`
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ EOF
|
|||||||
|
|
||||||
**2. Send message:**
|
**2. Send message:**
|
||||||
```bash
|
```bash
|
||||||
curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages \
|
curl -X POST https://kmsvc.riotpiao.com/v1/queues/orders/messages \
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
-H "Authorization: Bearer $JWT_TOKEN" \
|
||||||
-d '{
|
-d '{
|
||||||
"body": "{\"order_id\":123,\"total\":99.99}",
|
"body": "{\"order_id\":123,\"total\":99.99}",
|
||||||
@@ -41,7 +41,7 @@ curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages \
|
|||||||
|
|
||||||
**3. Receive message:**
|
**3. Receive message:**
|
||||||
```bash
|
```bash
|
||||||
curl "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages?max_number_of_messages=10&wait_time_seconds=20" \
|
curl "https://kmsvc.riotpiao.com/v1/queues/orders/messages?max_number_of_messages=10&wait_time_seconds=20" \
|
||||||
-H "Authorization: Bearer $JWT_TOKEN"
|
-H "Authorization: Bearer $JWT_TOKEN"
|
||||||
|
|
||||||
# Response:
|
# Response:
|
||||||
@@ -60,7 +60,7 @@ curl "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages?max_number_of
|
|||||||
|
|
||||||
**4. Acknowledge (delete) message:**
|
**4. Acknowledge (delete) message:**
|
||||||
```bash
|
```bash
|
||||||
curl -X DELETE "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages/$receipt_handle" \
|
curl -X DELETE "https://kmsvc.riotpiao.com/v1/queues/orders/messages/$receipt_handle" \
|
||||||
-H "Authorization: Bearer $JWT_TOKEN"
|
-H "Authorization: Bearer $JWT_TOKEN"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ curl -X DELETE "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages/$re
|
|||||||
**Batch processing:**
|
**Batch processing:**
|
||||||
```bash
|
```bash
|
||||||
for i in {1..100}; do
|
for i in {1..100}; do
|
||||||
curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/jobs/messages \
|
curl -X POST https://kmsvc.riotpiao.com/v1/queues/jobs/messages \
|
||||||
-H "Authorization: Bearer $JWT_TOKEN" \
|
-H "Authorization: Bearer $JWT_TOKEN" \
|
||||||
-d "{\"body\":\"task-$i\"}" &
|
-d "{\"body\":\"task-$i\"}" &
|
||||||
done
|
done
|
||||||
@@ -148,7 +148,7 @@ core secrets login
|
|||||||
|
|
||||||
# Use token
|
# Use token
|
||||||
export JWT_TOKEN=$(core get cluster/kmsvc/jwt-token --key jwt-token)
|
export JWT_TOKEN=$(core get cluster/kmsvc/jwt-token --key jwt-token)
|
||||||
curl -H "Authorization: Bearer $JWT_TOKEN" https://kmsvc.riotpiao.homelab.com/v1/queues
|
curl -H "Authorization: Bearer $JWT_TOKEN" https://kmsvc.riotpiao.com/v1/queues
|
||||||
```
|
```
|
||||||
|
|
||||||
## Integration Example
|
## Integration Example
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Vault: Secret Management & JWT Auth
|
# Vault: Secret Management & JWT Auth
|
||||||
|
|
||||||
**Vault:** `https://vault.riotpiao.homelab.com`
|
**Vault:** `https://vault.riotpiao.com`
|
||||||
**Internal:** `vault.iam.svc.cluster.local:8200`
|
**Internal:** `vault.iam.svc.cluster.local:8200`
|
||||||
**Namespace:** `iam`
|
**Namespace:** `iam`
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
**1. Login to Vault:**
|
**1. Login to Vault:**
|
||||||
```bash
|
```bash
|
||||||
# Browser: https://vault.riotpiao.homelab.com
|
# Browser: https://vault.riotpiao.com
|
||||||
# Auth method: OIDC → "Sign in with Authentik" (federated)
|
# Auth method: OIDC → "Sign in with Authentik" (federated)
|
||||||
# Or: Device code → core secrets login (CLI)
|
# Or: Device code → core secrets login (CLI)
|
||||||
|
|
||||||
|
|||||||
+79
-77
@@ -1,15 +1,15 @@
|
|||||||
# Generate Talos machine configurations
|
# Generate Talos machine configurations
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
pod_cidr = var.cluster_config.pod_subnets[0]
|
pod_cidr = var.cluster_config.pod_subnets[0]
|
||||||
service_cidr = var.cluster_config.service_subnets[0]
|
service_cidr = var.cluster_config.service_subnets[0]
|
||||||
controlplane_ip = var.cluster_config.controlplane_ip
|
controlplane_ip = var.cluster_config.controlplane_ip
|
||||||
cluster_dns_ip = "10.96.0.10"
|
cluster_dns_ip = "10.96.0.10"
|
||||||
kubelet_image = "ghcr.io/siderolabs/kubelet:${var.kubernetes_version}"
|
kubelet_image = "ghcr.io/siderolabs/kubelet:${var.kubernetes_version}"
|
||||||
kube_apiserver_img = "registry.k8s.io/kube-apiserver:${var.kubernetes_version}"
|
kube_apiserver_img = "registry.k8s.io/kube-apiserver:${var.kubernetes_version}"
|
||||||
controller_mgr_img = "registry.k8s.io/kube-controller-manager:${var.kubernetes_version}"
|
controller_mgr_img = "registry.k8s.io/kube-controller-manager:${var.kubernetes_version}"
|
||||||
kube_proxy_img = "registry.k8s.io/kube-proxy:${var.kubernetes_version}"
|
kube_proxy_img = "registry.k8s.io/kube-proxy:${var.kubernetes_version}"
|
||||||
scheduler_img = "registry.k8s.io/kube-scheduler:${var.kubernetes_version}"
|
scheduler_img = "registry.k8s.io/kube-scheduler:${var.kubernetes_version}"
|
||||||
|
|
||||||
factory_image = "factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${var.talos_version}"
|
factory_image = "factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${var.talos_version}"
|
||||||
}
|
}
|
||||||
@@ -19,58 +19,59 @@ resource "local_file" "controlplane_config" {
|
|||||||
filename = "${path.module}/../cluster-config/controlplane.yaml"
|
filename = "${path.module}/../cluster-config/controlplane.yaml"
|
||||||
|
|
||||||
content = templatefile("${path.module}/templates/controlplane.tftpl", {
|
content = templatefile("${path.module}/templates/controlplane.tftpl", {
|
||||||
version = "v1alpha1"
|
version = "v1alpha1"
|
||||||
hostname = var.controlplane_config.hostname
|
hostname = var.controlplane_config.hostname
|
||||||
token = var.machine_token
|
token = var.machine_token
|
||||||
ca_crt = var.machine_ca_crt
|
ca_crt = var.machine_ca_crt
|
||||||
ca_key = var.machine_ca_key
|
ca_key = var.machine_ca_key
|
||||||
lan_ip = var.controlplane_config.lan_ip
|
lan_ip = var.controlplane_config.lan_ip
|
||||||
lan_subnet = var.controlplane_config.lan_subnet
|
lan_subnet = var.controlplane_config.lan_subnet
|
||||||
lan_gateway = var.controlplane_config.lan_gateway
|
lan_gateway = var.controlplane_config.lan_gateway
|
||||||
wg0_ip = var.controlplane_config.wg0_ip
|
wg0_ip = var.controlplane_config.wg0_ip
|
||||||
wg0_subnet = var.controlplane_config.wg0_subnet
|
wg0_subnet = var.controlplane_config.wg0_subnet
|
||||||
wg0_port = var.controlplane_config.wg0_port
|
wg0_port = var.controlplane_config.wg0_port
|
||||||
wg0_private_key = var.controlplane_config.wg0_private_key
|
wg0_private_key = var.controlplane_config.wg0_private_key
|
||||||
wg0_peers = var.controlplane_config.wg0_peers
|
wg0_peers = var.controlplane_config.wg0_peers
|
||||||
wg1_ip = var.controlplane_config.wg1_ip
|
wg1_ip = var.controlplane_config.wg1_ip
|
||||||
wg1_subnet = var.controlplane_config.wg1_subnet
|
wg1_subnet = var.controlplane_config.wg1_subnet
|
||||||
wg1_port = var.controlplane_config.wg1_port
|
wg1_port = var.controlplane_config.wg1_port
|
||||||
wg1_private_key = var.controlplane_config.wg1_private_key
|
wg1_private_key = var.controlplane_config.wg1_private_key
|
||||||
wg1_peers = var.controlplane_config.wg1_peers
|
wg1_peers = var.controlplane_config.wg1_peers
|
||||||
kubelet_image = local.kubelet_image
|
kubelet_image = local.kubelet_image
|
||||||
cluster_dns_ip = local.cluster_dns_ip
|
cluster_dns_ip = local.cluster_dns_ip
|
||||||
install_disk = var.controlplane_config.install_disk
|
install_disk = var.controlplane_config.install_disk
|
||||||
factory_image = local.factory_image
|
factory_image = local.factory_image
|
||||||
longhorn_disks = var.controlplane_config.longhorn_disks
|
talos_version = var.talos_version
|
||||||
dns_servers = var.cluster_config.dns_servers
|
longhorn_disks = var.controlplane_config.longhorn_disks
|
||||||
forgejo_registry_ip = var.forgejo_registry_ip
|
dns_servers = var.cluster_config.dns_servers
|
||||||
forgejo_hostname = var.forgejo_hostname
|
forgejo_registry_ip = var.forgejo_registry_ip
|
||||||
|
forgejo_hostname = var.forgejo_hostname
|
||||||
|
|
||||||
# Cluster config
|
# Cluster config
|
||||||
cluster_id = var.cluster_id
|
cluster_id = var.cluster_id
|
||||||
cluster_secret = var.cluster_secret
|
cluster_secret = var.cluster_secret
|
||||||
controlplane_ip = local.controlplane_ip
|
controlplane_ip = local.controlplane_ip
|
||||||
cluster_name = var.cluster_name
|
cluster_name = var.cluster_name
|
||||||
pod_subnets = var.cluster_config.pod_subnets
|
pod_subnets = var.cluster_config.pod_subnets
|
||||||
service_subnets = var.cluster_config.service_subnets
|
service_subnets = var.cluster_config.service_subnets
|
||||||
dns_domain = var.cluster_config.dns_domain
|
dns_domain = var.cluster_config.dns_domain
|
||||||
bootstrap_token = var.bootstrap_token
|
bootstrap_token = var.bootstrap_token
|
||||||
|
|
||||||
# Kubernetes certs
|
# Kubernetes certs
|
||||||
kubernetes_ca_crt = var.kubernetes_ca_crt
|
kubernetes_ca_crt = var.kubernetes_ca_crt
|
||||||
kubernetes_ca_key = var.kubernetes_ca_key
|
kubernetes_ca_key = var.kubernetes_ca_key
|
||||||
etcd_ca_crt = var.etcd_ca_crt
|
etcd_ca_crt = var.etcd_ca_crt
|
||||||
etcd_ca_key = var.etcd_ca_key
|
etcd_ca_key = var.etcd_ca_key
|
||||||
aggregator_ca_crt = var.aggregator_ca_crt
|
aggregator_ca_crt = var.aggregator_ca_crt
|
||||||
aggregator_ca_key = var.aggregator_ca_key
|
aggregator_ca_key = var.aggregator_ca_key
|
||||||
service_account_key = var.service_account_key
|
service_account_key = var.service_account_key
|
||||||
secretbox_encryption_secret = var.secretbox_encryption_secret
|
secretbox_encryption_secret = var.secretbox_encryption_secret
|
||||||
|
|
||||||
# Component images
|
# Component images
|
||||||
kube_apiserver_img = local.kube_apiserver_img
|
kube_apiserver_img = local.kube_apiserver_img
|
||||||
controller_mgr_img = local.controller_mgr_img
|
controller_mgr_img = local.controller_mgr_img
|
||||||
kube_proxy_img = local.kube_proxy_img
|
kube_proxy_img = local.kube_proxy_img
|
||||||
scheduler_img = local.scheduler_img
|
scheduler_img = local.scheduler_img
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,34 +82,35 @@ resource "local_file" "worker_configs" {
|
|||||||
filename = "${path.module}/../cluster-config/${each.key}.yaml"
|
filename = "${path.module}/../cluster-config/${each.key}.yaml"
|
||||||
|
|
||||||
content = templatefile("${path.module}/templates/worker.tftpl", {
|
content = templatefile("${path.module}/templates/worker.tftpl", {
|
||||||
version = "v1alpha1"
|
version = "v1alpha1"
|
||||||
hostname = each.value.hostname
|
hostname = each.value.hostname
|
||||||
token = var.machine_token
|
token = var.machine_token
|
||||||
ca_crt = var.machine_ca_crt
|
ca_crt = var.machine_ca_crt
|
||||||
lan_ip = each.value.lan_ip
|
lan_ip = each.value.lan_ip
|
||||||
lan_subnet = each.value.lan_subnet
|
lan_subnet = each.value.lan_subnet
|
||||||
lan_gateway = each.value.lan_gateway
|
lan_gateway = each.value.lan_gateway
|
||||||
kubelet_image = local.kubelet_image
|
kubelet_image = local.kubelet_image
|
||||||
cluster_dns_ip = local.cluster_dns_ip
|
cluster_dns_ip = local.cluster_dns_ip
|
||||||
install_disk = each.value.install_disk
|
install_disk = each.value.install_disk
|
||||||
factory_image = local.factory_image
|
factory_image = local.factory_image
|
||||||
node_labels = each.value.node_labels
|
talos_version = var.talos_version
|
||||||
|
node_labels = each.value.node_labels
|
||||||
|
|
||||||
# Cluster config
|
# Cluster config
|
||||||
cluster_id = var.cluster_id
|
cluster_id = var.cluster_id
|
||||||
cluster_secret = var.cluster_secret
|
cluster_secret = var.cluster_secret
|
||||||
controlplane_ip = local.controlplane_ip
|
controlplane_ip = local.controlplane_ip
|
||||||
cluster_name = var.cluster_name
|
cluster_name = var.cluster_name
|
||||||
pod_subnets = var.cluster_config.pod_subnets
|
pod_subnets = var.cluster_config.pod_subnets
|
||||||
service_subnets = var.cluster_config.service_subnets
|
service_subnets = var.cluster_config.service_subnets
|
||||||
dns_domain = var.cluster_config.dns_domain
|
dns_domain = var.cluster_config.dns_domain
|
||||||
bootstrap_token = var.bootstrap_token
|
bootstrap_token = var.bootstrap_token
|
||||||
|
|
||||||
# Kubernetes certs
|
# Kubernetes certs
|
||||||
kubernetes_ca_crt = var.kubernetes_ca_crt
|
kubernetes_ca_crt = var.kubernetes_ca_crt
|
||||||
|
|
||||||
# Component images
|
# Component images
|
||||||
kube_proxy_img = local.kube_proxy_img
|
kube_proxy_img = local.kube_proxy_img
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ machine:
|
|||||||
install:
|
install:
|
||||||
disk: ${install_disk}
|
disk: ${install_disk}
|
||||||
image: factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${talos_version}
|
image: factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${talos_version}
|
||||||
wipe: true
|
wipe: false
|
||||||
grubUseUKICmdline: true
|
grubUseUKICmdline: true
|
||||||
disks:
|
disks:
|
||||||
%{ for disk in longhorn_disks ~}
|
%{ for disk in longhorn_disks ~}
|
||||||
|
|||||||
+21
-21
@@ -102,28 +102,28 @@ variable "secretbox_encryption_secret" {
|
|||||||
|
|
||||||
variable "controlplane_config" {
|
variable "controlplane_config" {
|
||||||
type = object({
|
type = object({
|
||||||
hostname = string
|
hostname = string
|
||||||
lan_ip = string
|
lan_ip = string
|
||||||
lan_subnet = string
|
lan_subnet = string
|
||||||
lan_gateway = string
|
lan_gateway = string
|
||||||
wg0_ip = string
|
wg0_ip = string
|
||||||
wg0_subnet = string
|
wg0_subnet = string
|
||||||
wg0_port = number
|
wg0_port = number
|
||||||
wg0_peers = list(object({
|
wg0_peers = list(object({
|
||||||
public_key = string
|
public_key = string
|
||||||
allowed_ips = list(string)
|
allowed_ips = list(string)
|
||||||
}))
|
}))
|
||||||
wg1_ip = string
|
wg1_ip = string
|
||||||
wg1_subnet = string
|
wg1_subnet = string
|
||||||
wg1_port = number
|
wg1_port = number
|
||||||
wg1_peers = list(object({
|
wg1_peers = list(object({
|
||||||
public_key = string
|
public_key = string
|
||||||
allowed_ips = list(string)
|
allowed_ips = list(string)
|
||||||
persistent_keepalive_secs = number
|
persistent_keepalive_secs = number
|
||||||
}))
|
}))
|
||||||
wg0_private_key = string
|
wg0_private_key = string
|
||||||
wg1_private_key = string
|
wg1_private_key = string
|
||||||
install_disk = string
|
install_disk = string
|
||||||
longhorn_disks = list(object({
|
longhorn_disks = list(object({
|
||||||
device = string
|
device = string
|
||||||
mountpoint = string
|
mountpoint = string
|
||||||
@@ -134,12 +134,12 @@ variable "controlplane_config" {
|
|||||||
|
|
||||||
variable "worker_configs" {
|
variable "worker_configs" {
|
||||||
type = map(object({
|
type = map(object({
|
||||||
hostname = string
|
hostname = string
|
||||||
lan_ip = string
|
lan_ip = string
|
||||||
lan_subnet = string
|
lan_subnet = string
|
||||||
lan_gateway = string
|
lan_gateway = string
|
||||||
install_disk = string
|
install_disk = string
|
||||||
node_labels = map(string)
|
node_labels = map(string)
|
||||||
}))
|
}))
|
||||||
description = "Worker machine configurations"
|
description = "Worker machine configurations"
|
||||||
}
|
}
|
||||||
@@ -163,6 +163,6 @@ variable "forgejo_registry_ip" {
|
|||||||
|
|
||||||
variable "forgejo_hostname" {
|
variable "forgejo_hostname" {
|
||||||
type = string
|
type = string
|
||||||
default = "forgejo.riotpiao.homelab.com"
|
default = "forgejo.riotpiao.com"
|
||||||
description = "Forgejo external hostname"
|
description = "Forgejo external hostname"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user