Send traffic to the arm64 pods from one Service - #241
Merged
Conversation
koikonom
force-pushed
the
arm64_shared_service
branch
from
September 1, 2026 08:15
7c08ce8 to
68e0d05
Compare
koikonom
marked this pull request as draft
September 1, 2026 08:40
Collaborator
Author
|
Don't review yet. I want to figure out a clean migration path that does not involve deleting deployments (hence causing downtime). |
The arm64 variant has its own `app.kubernetes.io/name`, so the chart made a second Service for it. The HTTPRoute backs only the amd64 Service, so the arm64 pods never received traffic. Every pod template now carries `app.kubernetes.io/component`, which holds the workload name and is the same for all architectures. When arm64 is enabled, the Service and the PodDisruptionBudget select that label, so one Service reaches the pods of both architectures and the load balancer sends traffic to both. When arm64 is off, the selector does not change. No Deployment selector changes, so no workload is recreated. The label is added before it is selected, so an environment that enables arm64 later gets no interval without endpoints. Bump the chart first, then enable arm64. In one sync the amd64 pods would still roll to get the label while the selector already moved.
koikonom
force-pushed
the
arm64_shared_service
branch
from
September 1, 2026 09:39
68e0d05 to
3e493e1
Compare
koikonom
marked this pull request as ready for review
September 1, 2026 11:18
mikeh-lago
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #240.
The problem
#240 gave the arm64 variant its own
app.kubernetes.io/name, for examplelago-api-arm64, so the chart rendered a second Service for it. The HTTPRoutebacks
lago-rails.fullname, which is the amd64 Service, so the arm64 pods werenever a target of the load balancer.
On
lago-dev-us-1the arm64 API pod is Ready and answers/readywith 200, butits only endpoint is the unused
main-lago-api-arm64Service. Its logs holdkubelet probes and nothing else.
The change
Every pod template now carries
app.kubernetes.io/component, which holds theworkload name (
lago-api) and is the same for all architectures. The Serviceand the PodDisruptionBudget select it when arm64 is enabled:
global.architectures.arm64.enabledfalse{name, instance}— no change from todaytrue{instance, component}— matches the pods of both architecturesDeployment selectors keep a name for each architecture, so each one matches only
its own pods:
lago-apiname=lago-api, instance=lagolago-api-arm64name=lago-api-arm64, instance=lagoTraffic distribution stays with the NLB and the gateway. Because one Service
holds the pods of both architectures, the share of each follows the endpoint
count, so it tracks the replica count of each Deployment with no weights to
maintain.
No workload is recreated
spec.selectorof a Deployment is immutable. No Deployment selector changeshere, so nothing has to be deleted, in any environment, including the arm64
Deployments that
lago-dev-us-1already runs.Each Deployment matches only its own pods, so an HPA collects the metrics of one
architecture. This matters: the
lago-apiHPA in both production clustersscales on
Resource:cpuandResource:memory.Order of the rollout
Bump the chart first. Enable arm64 in a later sync.
The label is added whether arm64 is on or off, so by the time an environment
enables arm64, its amd64 pods already carry the label and the selector finds
them at once. In one sync the amd64 pods would still roll to get the label while
the selector had already moved, which empties the endpoint list for the length
of the rollout.
Verification
Rendered against the real values of
lago-staging-eu-1— the five value filesfrom
lago-infrastructureandlago-deployatorigin/main, and the inlinevaluesObjectof the Argo app. Compared with the published 0.13.0 chart, thecomplete diff is one label on 14 Deployments:
46 objects before, 46 after. No Service selector change, no PDB selector change,
and no arm64 object, because staging does not enable arm64.
With arm64 enabled, the Service and the PDB move to
{instance, component}andboth Deployments keep their own name selector.
task test:unitgives 200 passed and 0 failed over 10 charts.task lintpasses.
Note for a local render
helm dependency buildin this repository vendors a nestedlago-configinlago-rails, which the published charts do not have. A localhelm templatethen stops with
global.database.uri value is required. Render the publishedchart, or give the values of the secret.
🤖 Generated with Claude Code