feat(sandbox-env): opt-in HPA, PDB and 502-retry EnvoyFilter for the preview gateway#4285
feat(sandbox-env): opt-in HPA, PDB and 502-retry EnvoyFilter for the preview gateway#4285nicacioliveira wants to merge 2 commits into
Conversation
…preview gateway The Istio-generated preview gateway Deployment runs a single fixed replica with no HPA/PDB, and Istio's default retry policy does not retry upstream 502s — which is what the sandbox daemon returns while the dev server inside a sandbox is booting/restarting. Chart 0.10.0 adds three opt-in, default-off knobs under previewGateway: - autoscaling: HPA targeting the generated <previewName>-istio Deployment (controller never manages replicas, so no conflict) - pdb: PDB over the generated pods (blocks voluntary evictions of the only preview ingress) - retries: EnvoyFilter retrying GET-only 502s with backoff, hard-scoped to this gateway's workloadSelector (namespace + gateway-name label); render is rejected in istio-system where root-namespace semantics would widen the selector cluster-wide, and when gatewayClassName is not istio No behavior change for existing consumers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 6 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="deploy/helm/sandbox-env/templates/sandbox-preview-hpa.yaml">
<violation number="1" location="deploy/helm/sandbox-env/templates/sandbox-preview-hpa.yaml:12">
P2: Autoscaling can silently be ineffective when `previewGateway.gatewayClassName` is not `istio`, because the HPA target Deployment name is fixed to `-istio`. Consider gating `previewGateway.autoscaling.enabled` to Istio (validation) or deriving the target from the selected gateway controller instead of hard-coding the suffix.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| apiVersion: autoscaling/v2 | ||
| kind: HorizontalPodAutoscaler | ||
| metadata: | ||
| name: {{ $previewName }}-istio |
There was a problem hiding this comment.
P2: Autoscaling can silently be ineffective when previewGateway.gatewayClassName is not istio, because the HPA target Deployment name is fixed to -istio. Consider gating previewGateway.autoscaling.enabled to Istio (validation) or deriving the target from the selected gateway controller instead of hard-coding the suffix.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At deploy/helm/sandbox-env/templates/sandbox-preview-hpa.yaml, line 12:
<comment>Autoscaling can silently be ineffective when `previewGateway.gatewayClassName` is not `istio`, because the HPA target Deployment name is fixed to `-istio`. Consider gating `previewGateway.autoscaling.enabled` to Istio (validation) or deriving the target from the selected gateway controller instead of hard-coding the suffix.</comment>
<file context>
@@ -0,0 +1,30 @@
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ $previewName }}-istio
+ namespace: {{ .Values.previewGateway.namespace }}
+ labels:
</file context>
There was a problem hiding this comment.
Fixed — extended the existing retries-only validation to all three knobs: autoscaling/pdb/retries.enabled=true each fail at template time when gatewayClassName != istio. PDB had the same issue (the gateway.networking.k8s.io/gateway-name pod label is also Istio's controller convention), so it's gated too. Deriving the generated Deployment name per controller isn't worth it here — every other controller has different generated-workload conventions, and the chart's data path (per-claim HTTPRoutes minted by mesh) is only exercised against Istio anyway.
There was a problem hiding this comment.
Thanks — the Istio-specific boundary is clear, and the PDB/gateway-name detail is useful. The original autoscaling point still stands, but the broader contract is that these preview-gateway resilience knobs should be gated together to Istio-only conventions.
Thanks for the feedback! I've saved this as a new learning to improve future reviews.
…yClassName=istio The HPA targets the generated Deployment by its Istio-specific name and the PDB selects pods by the label Istio's controller stamps — under another gatewayClass both would render but silently bind to nothing. Extend the retries-only validation to all three knobs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Context
The preview gateway (Gateway API + Istio auto-deploy) runs as a single fixed replica with no HPA or PDB. Investigation on eks-serverless showed:
response_flags="-": the sandbox daemon itself answers 502 while the dev server inside the sandbox is booting/restarting. Istio's default retry policy does not retry an upstream that answered 502.Changes (chart
sandbox-env0.9.0 → 0.10.0, all opt-in, default-off)previewGateway.autoscaling— HPA targeting the Istio-generated<previewName>-istioDeployment. This is the documented pattern for auto-deployed gateways: the controller never managesreplicas, so the HPA owns replica count without conflict. Defaults: min 1 / max 3 / 80% CPU.previewGateway.pdb— PDB (minAvailable: 1) over the generated pods, selected by thegateway.networking.k8s.io/gateway-namelabel. Blocks voluntary evictions (Karpenter consolidation/drift) of the only preview ingress. Does not cover spot interruptions — raiseminReplicasto 2 for that.previewGateway.retries— EnvoyFilter adding a retry policy for the preview data path:connect-failure,refused-stream,reset+ upstream 502 only (503 is the daemon's auto-refreshing "Connecting…" page — retrying it would just delay it)retriable_request_headerson:method— no body buffering, no replayed mutationsScoping / blast radius
The EnvoyFilter
workloadSelectoris hard-coded to this gateway'sgateway-namelabel and lands in the gateway's namespace — double barrier (namespace + label). It cannot apply to any other gateway (e.g.deco-gateway-istioinistio-system, which serves sites). Template-time validations reject:retries.enabled=truewithnamespace=istio-system(root-namespace EnvoyFilter selects workloads cluster-wide)retries.enabled=truewith a non-IstiogatewayClassNameretries.enabled=truewhen the EnvoyFilter CRD is absentTesting
helm lintcleanhelm templateverified: default values render zero new resources; all three knobs enabled render HPA/PDB/EnvoyFilter correctly scoped; all three validation guards fail with clear messagesv1alpha3and coupled to Envoy route internals — smoke-test on stg after Istio upgrades (noted in the template)Rollout
Consumed via
deco-apps-cd(studio-sandbox-{stg,prod}): follow-up PR bumpstargetRevisionto 0.10.0 and enables retries+PDB on stg first, prod after validation.🤖 Generated with Claude Code
Summary by cubic
Adds opt-in HPA, PDB, and a GET-only 502 retry policy to the preview gateway to improve resilience and cut transient 502s during sandbox restarts. Bumps the
sandbox-envchart to 0.10.0; defaults keep current behavior.New Features
previewGateway.autoscaling— HPA for the Istio-generated<previewName>-istioDeployment (min 1 / max 3 / 80% CPU). Validated to requiregatewayClassName=istio.previewGateway.pdb— PDB (minAvailable: 1) for the generated gateway pods to block voluntary evictions. Validated to requiregatewayClassName=istio.previewGateway.retries— EnvoyFilter that retries GETs on connection errors and 502s (2 attempts with backoff), scoped by namespace andgateway-namelabel. Validations: requiregatewayClassName=istio, EnvoyFilter CRD present, and namespace notistio-system.Migration
previewGateway.autoscaling.enabled=true,previewGateway.pdb.enabled=true,previewGateway.retries.enabled=true.previewGateway.autoscaling.minReplicas=2.istio-systemnamespace.Written for commit 0691f0e. Summary will update on new commits.