Also updates gateway-config-secret.enc.yaml with the same port fixes.
NOTE: This file is currently in plaintext and should be encrypted with SOPS:
export SOPS_AGE_RECIPIENTS=age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
sops --encrypt k8s/gateway-config-secret.enc.yaml
As mentioned in the repo structure, this should be encrypted before merge
to avoid exposing internal infrastructure details (service DNS names,
upstream addresses, auth configuration) in the git history.
NetworkPolicy allows gateway→iam only on ports 9000/9443, but config
used port 80 for JWKS fetch and token endpoints. This caused
'operation not permitted' errors and JWKS refresh failures.
Affects:
- auth.jwksUrl: uses port 9000 (Authentik HTTP)
- auth.tokenUrl: uses port 9000 for token exchange
- iam adapter upstream: routes to port 9000
Fixes: Gateway unable to validate JWT tokens, all chat/inference requests
returned 401 with 'token is unverifiable' error.
Route `qwen2.5:3b-instruct` to `qwen-cpu.llm-serving:80` (CPU on cp-2) instead of `ornith-predictor` (GPU on worker-1).
Companion to homelab GPU rebalance PR.
MinIO ClusterIP service listens on port 80 (targetPort 9000).
Config had port 9000 which caused 30s timeout then 502 — gateway
connected to service port 9000 which doesn't exist on the ClusterIP.
Changes:
- configmap.yaml: S3 upstream :9000 → :80
- gateway-config-secret.enc.yaml: same
- network-policy.yaml: add port 80 egress to storage namespace
Verified: S3 adapter now reaches MinIO (403 AccessDenied = auth issue,
not connectivity).
- Add internal/tracing package with OTel tracer initialization
- HTTP middleware for server-side tracing (request/response attributes)
- Transport wrapper for client-side upstream call tracing
- Update proxy to use tracing transport
- Add OTEL_* env vars to k8s deployment
Traces flow: api-gateway -> otel-collector -> tempo -> grafana
Enable Poimen orchestrator and worker pods to reach the LLM API gateway
in the api namespace.
The api-gateway NetworkPolicy was only allowing traffic from:
- ingress-nginx (external ingress)
- monitoring (Prometheus scraping)
Added new ingress rule to allow:
- poimen namespace (orchestrator-job and worker pods)
- Port 8080 (api-gateway service port)
This fixes the DNS resolution error where orchestrator pods couldn't
reach http://api-gateway.api:8080/health from within the cluster.
Managed via ArgoCD in homelab/k8s/argocd/apps/55-api-gateway.yaml
which syncs from this repo's k8s/ directory.
Per homelab/project-usage/jwt-auth-rollout.md, temporal-frontend (port 7233)
is gRPC-specific for workers/SDKs. External HTTP access is unresolved design.
Disabled until gRPC ingress is added. Keeps only: sqs, memory, s3, iam.
Adapters defined in config.yaml alongside routes and models.
Parsed by existing config loader, populated into registry at startup.
Removed: client-go deps, REST loader, informer, nginx proxy,
CiliumNetworkPolicy, apis/gateway/v1/ (duplicate types).
Kept: merged CI pipeline, imagePullPolicy Always, CA certs in Dockerfile.
- Dockerfile: multi-stage, distroless nonroot, CGO_ENABLED=0 static, commit
SHA stamped via VERSION build arg.
- .forgejo/workflows/ci.yaml: Forgejo reads .forgejo/, not .github/, and the
runner declares only the "docker" label. Verify job on every push; image
build and push gated to main.
- Drop .github/workflows/ci.yml — this remote is Forgejo, so it never ran.
- deployment.yaml: image from the Forgejo registry, forgejo-registry pull
secret, runAsUser 65532 to match distroless nonroot.
- kustomization.yaml: pin the tag in one place. Promoting a build is a
one-line newTag bump, never :latest.
Baseline for the Kong replacement on api.riotpiao.com. Brings the working
tree under version control for the first time: gateway source, the task
board that drives the agent runs, test fixtures, and K8s manifests.
Anchor the gateway ignore rule to the repo root. Unanchored, "gateway"
also matched the cmd/gateway/ source directory, so the program entrypoint
was excluded from every commit.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>