Add naas-portal Helm chart for K8s deployment #232

Merged
admin merged 1 commits from naas-portal-k8s into main 2026-02-24 16:51:36 +01:00
Owner

Phase 21: Migrate PaaS portal from Docker to K8s with Helm chart, Ingress, TLS, RBAC.

Phase 21: Migrate PaaS portal from Docker to K8s with Helm chart, Ingress, TLS, RBAC.
claude added 1 commit 2026-02-24 16:51:35 +01:00
Add naas-portal Helm chart for K8s deployment
All checks were successful
AI Review / AI Code Review (pull_request) Successful in 2s
PR Checks / Validate & Security Scan (pull_request) Successful in 12s
455250ee79
Migrate PaaS portal from Docker control-plane to K8s with:
- Dedicated Helm chart (Deployment, Service, Ingress, PVC, RBAC, NetworkPolicy)
- Domain: georgepaas.duckdns.org with TLS via cert-manager
- In-cluster ServiceAccount bound to naas-manager ClusterRole
- Longhorn PVC for SQLite persistence
- ArgoCD auto-sync application
admin approved these changes 2026-02-24 16:51:35 +01:00
admin merged commit 046bdac3f0 into main 2026-02-24 16:51:36 +01:00
admin deleted branch naas-portal-k8s 2026-02-24 16:51:37 +01:00
Author
Owner

AI Code Review

Review: naas-portal K8s Migration

Strengths

  • Security: Pod Security Standards compliant (non-root, no privileges, seccomp, capabilities dropped)
  • RBAC: Proper ServiceAccount + ClusterRoleBinding to naas-manager
  • NetworkPolicy: Ingress/egress explicit, covers DNS/API/Gitea/HTTPS
  • Probes: Liveness + readiness configured
  • Storage: PVC with Longhorn

🔴 Critical Issues

1. Missing secret creation

  • Deployment references naas-portal-secrets with 5 keys (gitea-token, gitea-admin-token, keycloak-client-secret, keycloak-admin-password, secret-key)
  • No Secret resource in chart or sealing strategy
  • Action: Add templates/secret.yaml OR document manual creation + external-secrets/Kyverno sealing requirement

2. Replica count = 1

  • Single point of failure; node failure = downtime
  • Recommend: replicaCount: 2 + PodDisruptionBudget

3. Missing TopologySpreadConstraints

  • With 2+ replicas, should spread across nodes
  • Add to deployment.spec.template.spec:
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: naas-portal

🟡 Minor Issues

4. Ingress port mismatch

  • Service exposes port: 80, Deployment containerPort: 8080
  • Ingress routes to port: 80 (correct)
  • OK, but inconsistent naming (service port name should match probes)

5. Resource requests may be tight

  • FastAPI + React frontend: 128Mi baseline could cause OOMKill under load
  • Consider: Increase request to 256Mi, limit to 768Mi

6. PVC not auto-mounted

  • PVC created but no guarantee binding before pod starts (storageClass may lack volumeBindingMode: WaitForFirstConsumer)
  • Document: Ensure longhorn storage class is properly configured

7. Missing HPA

  • Single replica can't autoscale
  • Add: HorizontalPodAutoscaler (e.g., 2-4 replicas on 70% CPU)

8. KEYCLOAK_ADMIN_PASSWORD in env

  • Highly sensitive, should NOT be in env vars—use Secret only
  • Fix: Remove from env section in values.yaml; ensure Deployment pulls from Secret only

📋 Recommendations (non-blocking)

  • Add PodDisruptionBudget (minAvailable: 1)
  • Document pre-deployment: kubectl create secret generic naas-portal-secrets -n prod --from-literal=gitea-token=...
  • Add ResourceQuota to prod namespace
  • Consider ConfigMap for non-sensitive env vars (GITEA_URL, KEYCLOAK_URL, etc.)

Status: ⚠️ Request Changes — Secret handling + HPA + topology spread required before merge.


Automated review by Claude Haiku | advisory, does not block merge

## AI Code Review ## Review: naas-portal K8s Migration ### ✅ Strengths - **Security:** Pod Security Standards compliant (non-root, no privileges, seccomp, capabilities dropped) - **RBAC:** Proper ServiceAccount + ClusterRoleBinding to naas-manager - **NetworkPolicy:** Ingress/egress explicit, covers DNS/API/Gitea/HTTPS - **Probes:** Liveness + readiness configured - **Storage:** PVC with Longhorn --- ### 🔴 Critical Issues **1. Missing secret creation** - Deployment references `naas-portal-secrets` with 5 keys (gitea-token, gitea-admin-token, keycloak-client-secret, keycloak-admin-password, secret-key) - No Secret resource in chart or sealing strategy - **Action:** Add `templates/secret.yaml` OR document manual creation + external-secrets/Kyverno sealing requirement **2. Replica count = 1** - Single point of failure; node failure = downtime - **Recommend:** `replicaCount: 2` + PodDisruptionBudget **3. Missing TopologySpreadConstraints** - With 2+ replicas, should spread across nodes - **Add to deployment.spec.template.spec:** ```yaml topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: naas-portal ``` --- ### 🟡 Minor Issues **4. Ingress port mismatch** - Service exposes `port: 80`, Deployment `containerPort: 8080` - Ingress routes to `port: 80` (correct) - OK, but inconsistent naming (service port name should match probes) **5. Resource requests may be tight** - FastAPI + React frontend: 128Mi baseline could cause OOMKill under load - **Consider:** Increase request to `256Mi`, limit to `768Mi` **6. PVC not auto-mounted** - PVC created but no guarantee binding before pod starts (storageClass may lack `volumeBindingMode: WaitForFirstConsumer`) - **Document:** Ensure `longhorn` storage class is properly configured **7. Missing HPA** - Single replica can't autoscale - **Add:** HorizontalPodAutoscaler (e.g., 2-4 replicas on 70% CPU) **8. KEYCLOAK_ADMIN_PASSWORD in env** - Highly sensitive, should NOT be in env vars—use Secret only - **Fix:** Remove from `env` section in values.yaml; ensure Deployment pulls from Secret only --- ### 📋 Recommendations (non-blocking) - Add `PodDisruptionBudget` (minAvailable: 1) - Document pre-deployment: `kubectl create secret generic naas-portal-secrets -n prod --from-literal=gitea-token=... ` - Add ResourceQuota to `prod` namespace - Consider ConfigMap for non-sensitive env vars (GITEA_URL, KEYCLOAK_URL, etc.) --- **Status:** ⚠️ **Request Changes** — Secret handling + HPA + topology spread required before merge. --- _Automated review by Claude Haiku | advisory, does not block merge_
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: claude/k8s-apps#232
No description provided.