Skip to content

Migrate Helm chart from Deployment to StatefulSet with per-pod services#6

Merged
rrobetti merged 8 commits intomainfrom
copilot/update-helm-charts-statefulset
Jan 8, 2026
Merged

Migrate Helm chart from Deployment to StatefulSet with per-pod services#6
rrobetti merged 8 commits intomainfrom
copilot/update-helm-charts-statefulset

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 8, 2026

Migration Plan: Deployment to StatefulSet

  • Update values.yaml:
    • Change default replicaCount from 1 to 3
    • Add service.perPodService.enabled with default true
    • Add service.perPodService.type with default LoadBalancer
    • Ensure autoscaling.enabled is false (already is)
    • Document service.type field and autoscaling interaction
    • Add clarifying comments about LoadBalancer vs NodePort
  • Create new statefulset.yaml template to replace deployment.yaml
    • Convert Deployment spec to StatefulSet spec
    • Add serviceName reference
    • Include all existing pod configuration
  • Update service.yaml to create headless service for StatefulSet
    • Add comments explaining headless service requirement
  • Create new per-pod-service.yaml template for individual pod services
    • Support LoadBalancer or NodePort types
    • Create one service per replica using range
    • Use statefulset-0, statefulset-1, etc. naming
    • Disable when autoscaling is enabled
    • Document autoscaling incompatibility
  • Update README.md to document StatefulSet usage
    • Add comprehensive architecture overview
    • Document DNS names and connectivity patterns
    • Explain port usage (1059 vs 9090)
    • Clarify LoadBalancer vs NodePort usage
    • Add "Why Per-Pod Services?" section
  • Update NOTES.txt for StatefulSet architecture
  • Test the chart with helm template and helm lint
  • Verify all changes work correctly
  • Address all code review feedback
  • Bump chart version to 0.1.5

Summary

All requirements from the problem statement have been successfully implemented:
✅ Default chart creates a StatefulSet (not a Deployment)
✅ Individual per-pod services created (LoadBalancer by default)
✅ Each OJP instance is individually addressable
✅ Default replicaCount set to 3
✅ autoscaling.enabled defaults to false
✅ Comprehensive documentation added
✅ Chart version bumped to 0.1.5

Original prompt

Helm charts should be updated to align with the StatefulSet approach. The default chart should create a StatefulSet with individual per-pod services (either LoadBalancer or NodePort) so each OJP instance is individually addressable. The default should also set replicaCount: 3 and autoscaling.enabled: false.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits January 8, 2026 15:32
- Changed replicaCount default from 1 to 3
- Converted Deployment to StatefulSet
- Made main service headless (clusterIP: None) for StatefulSet
- Added per-pod service template with LoadBalancer default
- Added service.perPodService configuration to values.yaml
- Updated README with StatefulSet architecture documentation

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
- Updated installation notes to use StatefulSet pod names
- Added guidance for accessing per-pod services
- Included examples for LoadBalancer and NodePort service types

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
- Disable per-pod services when autoscaling is enabled
- Add documentation for service.type field
- Update README to clarify autoscaling behavior
- Ensures services match actual pod count

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
- Document why per-pod services are disabled with autoscaling
- Explain StatefulSet headless service requirement
- Clarify that service.type is ignored for StatefulSet

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
Copilot AI changed the title [WIP] Update Helm charts for StatefulSet approach Migrate Helm chart from Deployment to StatefulSet with per-pod services Jan 8, 2026
Copilot AI requested a review from rrobetti January 8, 2026 15:41
@rrobetti
Copy link
Copy Markdown
Collaborator

rrobetti commented Jan 8, 2026

@copilot does these changes expose ojp instances via DNS names ojp-server-0, ojp-server-1, and ojp-server-3, are these the addresses to be used to connect to them?
1059,9090 does this mean that the port exposed it 9090 and clients shall tonnect to 9090? Why is that?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot does these changes expose ojp instances via DNS names ojp-server-0, ojp-server-1, and ojp-server-3, are these the addresses to be used to connect to them?
1059,9090 does this mean that the p...

DNS Names:
Yes, the StatefulSet creates pods with DNS names: ojp-server-0, ojp-server-1, ojp-server-2 (accessible within the cluster via the headless service). For external access, use the LoadBalancer service names: ojp-server-0, ojp-server-1, ojp-server-2 which will get external IPs.

Ports:
The notation 1059,9090 means two ports are exposed:

  • Port 1059: Main OJP server port for client connections (this is what clients should connect to)
  • Port 9090: Prometheus metrics port (for monitoring/observability)

Clients connect to port 1059 for OJP functionality. Port 9090 is only for Prometheus to scrape metrics.

Copy link
Copy Markdown
Collaborator

@rrobetti rrobetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot check my questions and update documentation to clarify.

| `service.type` | Service type (always ClusterIP for headless service) | `ClusterIP` |
| `service.port` | OJP Server service port | `1059` |
| `service.perPodService.enabled` | Enable individual per-pod services (disabled when autoscaling is enabled) | `true` |
| `service.perPodService.type` | Type for per-pod services (LoadBalancer or NodePort) | `LoadBalancer` |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Why is it loadBalancer by default?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoadBalancer is the default because it's the standard service type for cloud environments (AWS, GCP, Azure) that automatically provisions external IPs for each pod. For on-premise/bare-metal deployments, users can set service.perPodService.type: NodePort instead. This is now documented in the README (commit b2231fd).

port: 1059
# Per-pod services allow individual addressability for each StatefulSet pod
# Note: Per-pod services are only created when autoscaling is disabled
perPodService:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Does this means that each pod of OJP server gets its own loadbalancer in front? what is the advantage here? is it to just have a DNS name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, each pod gets its own LoadBalancer. The advantages are:

  • Direct addressability: Clients can connect to a specific instance
  • Stable identity: Each pod has a predictable DNS name
  • Independent external IPs: Each instance accessible via unique external IP
  • Connection affinity: Clients requiring persistent connections to the same instance

This enables use cases where clients need to maintain connections to specific OJP instances rather than load-balanced connections. See the new "Why Per-Pod Services?" section in the README (commit b2231fd).

- Added "Why Per-Pod Services?" section explaining benefits
- Documented DNS names for internal and external access
- Clarified port usage: 1059 for clients, 9090 for metrics
- Explained LoadBalancer default for cloud vs NodePort for on-premise
- Updated service and server parameter descriptions

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot check my questions and update documentation to clarify.

Documentation updated in commit b2231fd. Added comprehensive sections explaining:

  • Why per-pod services are used and their benefits
  • DNS names for internal/external access
  • Port usage (1059 for clients, 9090 for metrics only)
  • LoadBalancer default rationale (cloud environments)

Copilot AI requested a review from rrobetti January 8, 2026 21:06
@rrobetti
Copy link
Copy Markdown
Collaborator

rrobetti commented Jan 8, 2026

@copilot lint failing
ojp-server => (version: "0.1.4", path: "charts/ojp-server") > chart version not ok. Needs a version bump!

- Version bumped from 0.1.4 to 0.1.5 to address CI lint failure
- Required for chart-testing to pass with changes made

Co-authored-by: rrobetti <7221783+rrobetti@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot lint failing
ojp-server => (version: "0.1.4", path: "charts/ojp-server") > chart version not ok. Needs a version bump!

Fixed in commit 6c05757. Bumped chart version from 0.1.4 to 0.1.5 to satisfy chart-testing requirements.

@rrobetti rrobetti marked this pull request as ready for review January 8, 2026 22:31
@rrobetti rrobetti merged commit 215d365 into main Jan 8, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants