Repository navigation
feat(redis): add affinity configuration - #2665
Kostiantyn Astakhov (kastakhov) wants to merge 1 commit into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces the ability to define Kubernetes affinity rules for Redis and Sentinel pods within the Redis application configuration. By exposing these settings, users can now exert finer control over pod placement within their clusters, improving workload distribution and scheduling requirements. The changes include necessary updates to the API types, Helm chart values, schema definitions, and the underlying resource templates. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces Kubernetes affinity configuration for Redis and Sentinel pods by updating the Go API types, Helm templates, JSON schema, and documentation. The review feedback suggests marking the affinity parameter as optional in the values.yaml documentation to ensure consistency and proper Go type generation. Additionally, it is recommended to refine the Helm templates to avoid rendering empty affinity blocks in the resulting manifests, as the current default values in values.yaml cause the templates to always evaluate as true.
| ## @field {object} [redis] - Affinity rules for Redis pods. | ||
| ## @field {object} [sentinel] - Affinity rules for Sentinel pods. | ||
|
|
||
| ## @param {Affinity} affinity - Kubernetes affinity configuration for Redis and Sentinel pods. |
There was a problem hiding this comment.
To maintain consistency with other optional fields like resources, the affinity parameter should be marked as optional in the documentation. This will also ensure that the generated Go type in api/apps/v1alpha1/redis/types.go includes the omitempty JSON tag when you run make generate.
## @param {Affinity} [affinity] - Kubernetes affinity configuration for Redis and Sentinel pods.There was a problem hiding this comment.
code updated
| {{- with .Values.affinity.sentinel }} | ||
| affinity: {{- toYaml . | nindent 6 }} | ||
| {{- end }} |
There was a problem hiding this comment.
Since affinity.sentinel defaults to {} in values.yaml, this with block will always evaluate to true and render affinity: {} in the resulting manifest. While valid Kubernetes YAML, it adds unnecessary noise. Consider checking if the object is empty before rendering, or removing the default empty objects from values.yaml if they are not strictly required for the dashboard UI.
|
This PR has had no activity for 60 days and was marked |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Same feature as your rabbitmq PR and the same verified good news: the affinity does reach the pods (RedisFailover.spec.redis.affinity and spec.sentinel.affinity both exist in the vendored operator CRD, and rendering the branch puts the values at those paths), and the generated artifacts genuinely regenerate byte for byte, so the bot comments claiming they were hand-edited are wrong.
Three things to fix here that do not apply to the rabbitmq one.
The template crashes on an explicit null. helm template --set affinity=null fails with nil pointer evaluating interface {}.sentinel, because packages/apps/redis/templates/redisfailover.yaml:29 does {{- with .Values.affinity.sentinel }} and dereferences the parent before testing it. The rabbitmq chart is immune because its with sits on the parent itself. (.Values.affinity).sentinel fixes it. I agree this is hard to reach through the Application path, since the CRD's own typing should reject an explicit null, but it is one character of parentheses and the failure mode is a render crash.
The fields should be *RawExtension rather than the value form, which is what your rabbitmq PR already does. omitempty is a no-op on a struct, so as written this always emits affinity with two nulls inside instead of omitting it. Your other PR has the right spelling; matching it here also lines this up with the third affinity PR, where I have asked for the same change.
api/apps/v1alpha1/redis/types.go:50 exports a type named Affinity that is not the Kubernetes corev1.Affinity but a two-field wrapper holding the redis and sentinel rules. In a module that gets published and imported by tenants, that name will be read as the Kubernetes one every time. Something like AffinitySpec, or a name mentioning the split, would avoid the collision.
As on the other PR: no Signed-off-by on the commits, which is a hard merge gate, and a mechanical conflict with main that a rebase plus the package's make generate should clear. The field descriptions would also benefit from naming the expected shape, since preserve-unknown-fields gives the dashboard nothing else to show.
On ordering, so you are not blocked by the queue: several other open PRs touch this chart's values.yaml, but every overlap is in artifacts that regenerate deterministically, so it is merge ordering rather than a conflict of intent. Whichever lands first, the rest rebase and regenerate.
And the same note as the other one: lifecycle/stale puts this on a close timer, so it needs a nudge if you still want it.
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
One more thing worth knowing about this field, which I checked in the operator's source and which belongs in the field description rather than in the code.
The operator does not merge what you pass with its own scheduling rules. Its helper returns the user-supplied affinity verbatim when one is set, and only when none is set does it synthesize a soft pod anti-affinity, weight 100 on kubernetes.io/hostname, that spreads the replicas across nodes.
So a user who sets this field only to express a node preference, which is the most common reason to reach for affinity at all, silently loses replica spreading on what is meant to be a highly available service. Nothing warns them, and the symptom only appears when a node goes down and takes more than one replica with it.
Documenting that in the field description is enough, ideally with the concrete advice that anyone setting this should include a podAntiAffinity themselves unless they specifically want replicas co-located. The rabbitmq PR has no equivalent trap, since that operator passes a nil straight through and adds no default of its own, which is another reason the two field descriptions should not simply be copies of each other.
d8e3d65 to
f48939a
Compare
|
Hi Aleksei Sviridkin (@lexfrei), I updated PR and addressed your concerns |
f48939a to
83244b0
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Kostiantyn Astakhov (@kastakhov) NOT LGTM. Everything from my July reviews is fixed. What is left is a rebase and a test.
The conflict with main is only in the generated packages/system/redis-rd/cozyrds/redis.yaml. Rebase and rerun make generate in packages/apps/redis with cozyvalues-gen v1.7.0, which is what CI uses. On my trial merge that regenerates the RD with affinity in the schema and in keysOrder, and the other generated files come out identical to what git merges on its own. The render is right: spec.redis.affinity and spec.sentinel.affinity get the values, and the default, affinity: null and affinity.redis: null render no affinity key, so the operator keeps its own default spreading.
Since your last push, main added helm-unittest tests for this chart in packages/apps/redis/tests/, and none of them covers affinity. I pointed the redis block at (.Values.affinity).sentinel and all 48 tests still passed, so swapped or dropped wiring would ship unnoticed. One small test file is enough: defaults render no affinity under either spec.redis or spec.sentinel, and each value lands only under its own component.
CI on this head tells nothing yet. The August runs failed before any job started because the branch could not be merged, and E2E Tests never ran. They will run after the rebase.
|
Kostiantyn Astakhov (@kastakhov) my change request from 2026-09-29 is still open and there has been no activity here since August. Is this still something you want to finish? If there is no activity in the next two weeks, the stale bot will close it; reopening later is always fine. |
|
I'd like to close this PR instead as I don't have time to play catch-up with your changes. |
|
I will rebase the code one more time in this and in the sibling PR this week, hope this time it will be checked not after another 2 months. |
83244b0 to
8723462
Compare
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Kostiantyn Astakhov (@kastakhov) LGTM. The rebase and affinity tests address my previous change request. I ran the 71 chart tests and checked separate Redis and Sentinel settings, including null values and TLS. Swapping either component's input makes the new test fail.
Functional CI has not run on this head; the passing checks only cover metadata.
Please link a Terraform provider follow-up in the downstream checklist; its schema and mappings do not expose the new affinity fields yet.
Signed-off-by: kastakhov <[email protected]> Assisted-by: LLM
8723462 to
b2e5791
Compare
What this PR does
Adds independent Kubernetes affinity configuration for Redis and Sentinel pods through
RedisFailover.spec.redis.affinityandspec.sentinel.affinity. Empty or null rules preserve operator defaults. Configured rules replace default soft pod anti-affinity; includepodAntiAffinitywhen replica spreading is required.Validation
make generateremains blocked by the pinned code-generator parser rejecting Go 1.27'smath/rand/v2generic method. Affected API deepcopy generation passes separately with controller-gen v0.16.4.make showwas unavailable becausecozyhris not installed; offline Helm rendering passed.Screenshots
Not applicable; no UI changes.
Downstream repositories
Release note