Skip to content

Make Service IP family configurable via the Pulp CR (ipv6-only + dual-stack) - #1700

Open
josephtate wants to merge 1 commit into
pulp:mainfrom
josephtate:ipv6-config-support
Open

josephtate wants to merge 1 commit into
pulp:mainfrom
josephtate:ipv6-config-support

Conversation

@josephtate

@josephtate josephtate commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Make the IP family of the Services the operator creates for pulp-api, pulp-content, the database, and otel configurable via the Pulp CR, enabling both IPv6-only and genuine dual-stack deployments.

Every one of these Services hardcoded IPFamilies: ["IPv4"] and IPFamilyPolicy: SingleStack, with no way to change it short of hand-patching the operator. pulp-web and the redis Service never set these fields at all, inheriting the cluster's default IP family instead.

Adds spec.ip_family_policy and spec.ip_families to the Pulp CRD, mirroring corev1.ServiceSpec's own fields exactly (SingleStack, PreferDualStack, RequireDualStack; ["IPv4"], ["IPv6"], or both in priority order). Both default to today's behavior when unset, so this is non-breaking for existing CRs.

  • settings.IPFamilyPolicy()/IPFamilies() helpers resolve the CR value (or the default), wired into the four Services that hardcoded the old values
  • ip_families is validated: x-kubernetes-list-type=set and MaxItems=2 stop duplicates/over-long lists at the API server; a precheck rejects unrecognized string values with a clear message
  • A non-blocking warning (surfaced via a Kubernetes Event) fires if spec.ipv6_disabled=true conflicts with ip_families including IPv6 -- that combination would route IPv6 traffic to a pod that's only listening on IPv4
  • Documents that changing these fields on an already-reconciled Pulp CR isn't a supported workflow: the API server only allows a live Service to go from SingleStack to a dual-stack policy, not between address families

Verified against real kind clusters (single-stack IPv6-only, and genuinely dual-stack with both --service-cluster-ip-range families configured), not just unit tests:

  • ip_families: ["IPv6"] on a single-stack IPv6-only cluster: Services get real IPv6 ClusterIPs, confirmed independently addressable (HTTP:200 via a direct curl from a separate pod against the live ClusterIP).
  • ip_family_policy: PreferDualStack, ip_families: ["IPv4","IPv6"] on a dual-stack cluster: the same Service gets both an IPv4 and an IPv6 ClusterIP simultaneously, both independently reachable (HTTP:200 via each). This is the capability Let the K8S cluster decide on ipFamily usage #1651 cannot provide -- see below.

Relation to #1699 (a freshened-up #1651, by @macwinnie): that PR takes a simpler approach -- just drop the hardcoded values entirely and let the cluster default them, the same way pulp-web/redis already behave. It's sufficient to fix #1380 on a single-stack IPv6-only cluster (verified), but on a dual-stack cluster it still defaults to IPv4-only, since Kubernetes defaults an unspecified Service to its primary configured family rather than to dual-stack. This PR is for anyone who wants deliberate control -- most notably genuine dual-stack support, which #1699 cannot provide at all.

Both approaches fix the same underlying bug and are offered as alternatives for maintainers to evaluate; this is not meant to supersede #1699.

AI disclosure

Per the AI policy: the code, tests, docs, and this description were written with Hermes Agent running claude-sonnet-5-5 (Anthropic). The commit carries an Assisted By: label. I reviewed the code and this description and can explain the change.

closes #1380

@openshift-ci
openshift-ci Bot requested review from dkliban and ipanova November 5, 2026 19:38
@openshift-ci

openshift-ci Bot commented Nov 5, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: josephtate
Once this PR has been reviewed and has the lgtm label, please assign git-hyagi for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci

openshift-ci Bot commented Nov 5, 2026

Copy link
Copy Markdown

Hi @josephtate. Thanks for your PR.

I'm waiting for a pulp member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Every Service the operator creates (pulp-api, pulp-content, database,
otel) hardcoded IPFamilies: ["IPv4"] and IPFamilyPolicy: SingleStack,
with no way to change it short of hand-patching the operator. pulp-web
and the redis Service never set these fields at all, inheriting the
cluster's default IP family instead.

Add spec.ip_family_policy and spec.ip_families to the Pulp CRD,
mirroring corev1.ServiceSpec's own fields exactly (SingleStack,
PreferDualStack, RequireDualStack; ["IPv4"], ["IPv6"], or both in
priority order), enabling IPv6-only and dual-stack deployments that
were previously impossible. Both default to today's behavior when
unset.

* Add settings.IPFamilyPolicy()/IPFamilies() helpers and wire them into
  the four Services that hardcoded the old values
* Validate ip_families: x-kubernetes-list-type=set and MaxItems=2 stop
  duplicates/over-long lists; a new precheck rejects unrecognized values
* Warn via a Kubernetes Event when ipv6_disabled=true conflicts with
  ip_families including IPv6 (app would listen on IPv4 only, but the
  Service would route IPv6 traffic to it)
* Document that changing these fields on an already-reconciled Pulp CR
  is unsupported: Kubernetes only allows a live Service to go from
  SingleStack to dual-stack, not between address families
* Run `make generate manifests bundle`; add a CHANGES/ fragment

This is one of two possible approaches to the problem. pulp#1651 took the
simpler route of just dropping the hardcoded IPv4/SingleStack values
entirely and letting the cluster default apply (matching how pulp-web
and the redis Service already behave) rather than adding an explicit
CR-level switch; see that PR, freshened up in a companion branch, for
comparison.

closes pulp#1380

Assisted By: Hermes Agent (claude-sonnet-5-5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Operator won't start services in single-stack IPv6 EKS

1 participant