Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change kube hairpin configuration settings and defaults #2417

Merged

Conversation

juanluisvaladas
Copy link
Contributor

Description

Enable hairpin for kube-router by default

We agreed that the most logical decision was to enable hairpin by default. The old configuration doesn't reflect our real needs, for this reason we decided to deprecate the old configuration and add a new configuration. This commit handles all these details.

Also I spotted a bug related to reconciling, since I noticed it in one of the files which I spotted and it's just a one liner I slipped the commit in this PR.

Fixes #1953

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

How Has This Been Tested?

  • Manual test
  • Auto test added

Checklist:

  • My code follows the style guidelines of this project
  • My commit messages are signed-off
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

@juanluisvaladas
Copy link
Contributor Author

@hercherf @mtb-xt since you commented on #1953 I'd like your feedback as well please.

Copy link
Member

@twz123 twz123 left a comment

Choose a reason for hiding this comment

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

We should probably implement json.Unmarshaller for KubeRouter, now that we have a default which doesn't equal the zero value of its type.

pkg/apis/k0s.k0sproject.io/v1beta1/kuberouter.go Outdated Show resolved Hide resolved
pkg/apis/k0s.k0sproject.io/v1beta1/kuberouter.go Outdated Show resolved Hide resolved
@@ -70,6 +71,27 @@ func (k *KubeRouter) Init(_ context.Context) error { return nil }
// Stop no-op as nothing running
func (k *KubeRouter) Stop() error { return nil }

func getHairpinConfig(cfg *kubeRouterConfig, krc *v1beta1.KubeRouter) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe a better name this applyHairpinConfig, since this is not idempotently getting something, but updating the cfg in place.

@mtb-xt
Copy link

mtb-xt commented Nov 17, 2022

There was an edge case about the CNI config - if it was already generated, then activating hairpin mode in k0s won't update the CNI config.
If someone now creates the cluster with hairpin mode disabled, but then decides to enable it - it won't be updated as well.
I realize this is a rare scenario now it's enabled by default, but do we want to do anything about it or not?

if [ ! -f /etc/cni/net.d/10-kuberouter.conflist ]; then
<- because of this check, if there is a CNI config present, it won't be touched.

@juanluisvaladas
Copy link
Contributor Author

Having one field accepting multiple types breaks dynamic configuration because of kubernetes-sigs/controller-tools#735

I'm currently waiting for controller-manager people to give me the OK to start implementing this so in the meantime I'll put this on hold. If the proposed change wouldn't be accepted then we'll have to consider a strategy different than using the same field to accept multiple types.

@juanluisvaladas
Copy link
Contributor Author

juanluisvaladas commented Dec 13, 2022

@jnummelin @twz123 I don't think I can achieve this even by patching the CRD manually.

The CRDs with IntOrString work because the porperties of the schema include the field x-kubernetes-int-or-string. The apiserver schema validation explictly skips some validations for IntOrString, so we cannot modify this.

I've tried to workaround this in many ways but I don't think it's actually possible. The only option that I see here would be adding x-kubernetes-preserve-unknown-fields to the KubeRouter struct and removing the HairpinMode field of the CRD but then this adds some additional problems in validation...

I see the following options:
1- Issue a new version of the clusterconfigs CRD including a new version v1beta2 in which the hairpinMode is a string. This is probably the best one.
2- Add a new field with a different name and deprecate HairpinMode, which isn't great because hairpinMode is the best name.
3- Allowing unknown fields and removing the field from the CRD, which brings issues with the validation.

@twz123
Copy link
Member

twz123 commented Dec 14, 2022

I would vote for option 2 (new field with a different name). This is what this PR initially aimed at, and it's a fair compromise compared to the alternatives. Introducing a new API version for this seems like a quite heavy thing to do. Maybe it's better to accumulate some changes over time and then issue a new API version that contains more improvements than just this one. Allowing unknown fields OTOH seems to me like removing a safety net for very little gain.

I didn't know that IntOrString was such a custom thing. Otherwise I wouldn't have brought it up as an example 🙈.

@juanluisvaladas juanluisvaladas changed the title Change kube hairpin configuration settings and defaults Change kube hairpin configuration settings and defaults [DO NOT REVIEW DOING NASTY STUFF WITH REFLOG RIGHT NOW] Dec 14, 2022
@juanluisvaladas juanluisvaladas force-pushed the change-kube-hairpin branch 3 times, most recently from de5eeae to d0756a2 Compare December 14, 2022 22:14
@juanluisvaladas
Copy link
Contributor Author

I would vote for option 2 (new field with a different name).

And there is a big advantage that it's already implemented, I just had to go through the reflog :) and patch some little thing.

@juanluisvaladas juanluisvaladas changed the title Change kube hairpin configuration settings and defaults [DO NOT REVIEW DOING NASTY STUFF WITH REFLOG RIGHT NOW] Change kube hairpin configuration settings and defaults Dec 14, 2022
pkg/apis/k0s.k0sproject.io/v1beta1/kuberouter.go Outdated Show resolved Hide resolved
// Activate Hairpin Mode (allow a Pod behind a Service to communicate to its own ClusterIP:Port)
HairpinMode bool `json:"hairpinMode"`
// Admits three values: "enabled" enables it globaly, "allowed" allows but services must be annotated explictly and "disabled"
Hairpin Hairpin `json:"hairpin"`
Copy link
Member

Choose a reason for hiding this comment

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

Worth mentioning the default value here as well.

Suggested change
Hairpin Hairpin `json:"hairpin"`
// Defaults to "Enabled".
// +kubebuilder:default=Enabled
Hairpin Hairpin `json:"hairpin"`

Copy link
Member

Choose a reason for hiding this comment

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

The kubebuilder default hint is still missing. But that's a purely cosmetic thing...

docs/configuration.md Outdated Show resolved Hide resolved
pkg/apis/k0s.k0sproject.io/v1beta1/kuberouter.go Outdated Show resolved Hide resolved
@juanluisvaladas
Copy link
Contributor Author

@twz123 I addressed everything and I also changed the table in docs/configuration.md. Apparently I didn´t find the latest version if the reflog and there were a couple things missing even if the code was working as expected.

I went file by file and I believe everything is good now.

twz123
twz123 previously approved these changes Dec 15, 2022
// Activate Hairpin Mode (allow a Pod behind a Service to communicate to its own ClusterIP:Port)
HairpinMode bool `json:"hairpinMode"`
// Admits three values: "enabled" enables it globaly, "allowed" allows but services must be annotated explictly and "disabled"
Hairpin Hairpin `json:"hairpin"`
Copy link
Member

Choose a reason for hiding this comment

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

The kubebuilder default hint is still missing. But that's a purely cosmetic thing...

We agreed that the most logical decision was to enable hairpin by
default. The old configuration doesn't reflect our real needs, for this
reason we decided to deprecate the old configuration and add a new
configuration. This commit handles all these details.

Fixes k0sproject#1953

Co-authored-by: Tom Wieczorek <twz123@users.noreply.github.com>
Signed-off-by: Juan Luis de Sousa-Valadas Castaño <jvaladas@mirantis.com>
@juanluisvaladas
Copy link
Contributor Author

Oh sorry I missed that one. That's added now.

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.

Should k0s enable hairpin-mode by default for kube-router?
4 participants