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

Mixed protocol support for Services with type=LoadBalancer #94028

Merged
merged 2 commits into from Nov 13, 2020

Conversation

janosi
Copy link
Contributor

@janosi janosi commented Aug 15, 2020

What type of PR is this?
/kind feature
/kind api-change

What this PR does / why we need it:
This PR implements the following KEP: kubernetes/enhancements@4ccf8f5

It enables the usage of different protocol values in the same LoadBalancer Service.
It extends the Service's Status definition so cloud provider implementations can include more details about the status of the cloud load balancer into that.

KEP issue: kubernetes/enhancements#1435

Which issue(s) this PR fixes:
Fixes #23880

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

The usage of mixed protocol values in the same LoadBalancer Service is possible if the new feature gate MixedProtocolLBService is enabled.
"action required"
The feature gate is disabled by default. The user has to enable it for the API Server.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

- [KEP]: https://github.com/kubernetes/enhancements/commit/4ccf8f53d9ffa4ffdb98afecfc5eb0ed4f5550f3

@k8s-ci-robot k8s-ci-robot added release-note-action-required Denotes a PR that introduces potentially breaking changes that require user action. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/feature Categorizes issue or PR as related to a new feature. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 15, 2020
@k8s-ci-robot
Copy link
Contributor

Hi @janosi. Thanks for your PR.

I'm waiting for a kubernetes 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. Regular contributors should join the org to skip this step.

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.

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/test-infra repository.

@k8s-ci-robot k8s-ci-robot added sig/apps Categorizes an issue or PR as relevant to SIG Apps. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Aug 15, 2020
@janosi janosi changed the title WIP Mixed protocol support for Services with type=LoadBalancer Mixed protocol support for Services with type=LoadBalancer Aug 15, 2020
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 15, 2020
@fejta-bot
Copy link

This PR may require API review.

If so, when the changes are ready, complete the pre-review checklist and request an API review.

Status of requested reviews is tracked in the API Review project.

@janosi
Copy link
Contributor Author

janosi commented Aug 16, 2020

/label api-review

@k8s-ci-robot k8s-ci-robot added the api-review Categorizes an issue or PR as actively needing an API review. label Aug 16, 2020
@janosi
Copy link
Contributor Author

janosi commented Aug 16, 2020

/assign @thockin

@pontiyaraja
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 17, 2020

//Current service state
// +optional
Conditions []ServiceCondition
Copy link
Member

Choose a reason for hiding this comment

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

The KEP says: "Our feature does not introduce new values or new fields"

am not saying that adding a field is wrong, but it is not part of the committed KEP. I re-read the discussion on the KEP and we agreed to this in theory, but it was never updated

Copy link
Member

Choose a reason for hiding this comment

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

We should use metav1.Condition from staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but it is not part of the committed KEP. I re-read the discussion on the KEP and we agreed to this in theory, but it was never updated

Hmmm, we have in the KEP the following:

In order to provide a way for the CPI to indicate port statuses to the user we would add the following new portStatus list of port statuses to Service.status.loadBalancer.ingress, so the CPI can indicate the status of the LB. Also we add a conditions list of conditions to the Service.status.loadBalancer, with the first official condition LoadBalancerMixedProtocolNotSupported defined.

And then there is the specification of these fields, too.

Am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, should I remove this API change (ServiceStatus) from this PR? I put it in here, as it is part of the KEP.

Copy link
Member

Choose a reason for hiding this comment

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

You are right, I guess I skimmed too fast. Sorry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, I started using metav1.Condition there instead of ServiceConditions, but as I can see, bazel-test fails due to that https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/94028/pull-kubernetes-bazel-test/1296919306033958912

Copy link
Member

Choose a reason for hiding this comment

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

So, I started using metav1.Condition there instead of ServiceConditions, but as I can see, bazel-test fails due to that https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/94028/pull-kubernetes-bazel-test/1296919306033958912

chatted in slack, but for posterity, looks like metav1.Condition types should be added to

// These types are registered in external versions, and therefore include json tags,
// but are also registered in internal versions (or referenced from internal types),
// so we explicitly allow tags for them
var typesAllowedTags = map[reflect.Type]bool{
reflect.TypeOf(intstr.IntOrString{}): true,
reflect.TypeOf(metav1.Time{}): true,
reflect.TypeOf(metav1.MicroTime{}): true,
reflect.TypeOf(metav1.Duration{}): true,
reflect.TypeOf(metav1.TypeMeta{}): true,
reflect.TypeOf(metav1.ListMeta{}): true,
reflect.TypeOf(metav1.ObjectMeta{}): true,
reflect.TypeOf(metav1.OwnerReference{}): true,
reflect.TypeOf(metav1.LabelSelector{}): true,
reflect.TypeOf(metav1.GetOptions{}): true,
reflect.TypeOf(metav1.ExportOptions{}): true,
reflect.TypeOf(metav1.ListOptions{}): true,
reflect.TypeOf(metav1.DeleteOptions{}): true,
reflect.TypeOf(metav1.GroupVersionKind{}): true,
reflect.TypeOf(metav1.GroupVersionResource{}): true,
reflect.TypeOf(metav1.Status{}): true,
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@liggitt Thank you for your help. Indeed, it is OK now.

@@ -3508,6 +3512,14 @@ type LoadBalancerIngress struct {
// (typically AWS load-balancers)
// +optional
Hostname string

//The list has one entry per service port in the manifest
Copy link
Member

Choose a reason for hiding this comment

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

nit: comments want a " " between // and text

Copy link
Member

Choose a reason for hiding this comment

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

Godoc style starts with the field name

Copy link
Member

Choose a reason for hiding this comment

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

We need to tighten the spec. This field is optional, but if it is provided, there must be one entry per service port, mapped by port number and protocol (avoid the word "manifest, tooooo vague).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the comment here.


//The list has one entry per service port in the manifest
// +optional
PortStatuses []PortStatus
Copy link
Member

Choose a reason for hiding this comment

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

name "ports"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

// +optional
PortStatuses []PortStatus

//A human readable message indicating details about the condition of the load-balancer.
Copy link
Member

Choose a reason for hiding this comment

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

Is human-readable what we want here? We have conditions and ports which have messages - what is THIS for that isn't better in one of those?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I just wonder how I should interpret all caps here).
Well, this is the part of the agreed and accepted KEP. Which has been reviewed and accepted by people much better in K8s API design than I.
Of course things change and I am OK to remove it from here. Just like the whole API implementation as said above.

Copy link
Member

Choose a reason for hiding this comment

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

/KEPs are not written in stone, and API reviews can tweak the exact structure. I am asking what this particular field is for that is not already covered by the other messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the original purpose was to have a "message" on this level, too. I.e. we have a condition with a message on Service level, we have a message on portstatus level, but no message on LB level, in the middle.
Though, I just removed it.


// PortStatus represents the condition of a service port condition
type PortStatus struct {
Port int32
Copy link
Member

Choose a reason for hiding this comment

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

comments on all these

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, please check.

pkg/apis/core/types.go Outdated Show resolved Hide resolved
var protocol api.Protocol = "init"
for _, port := range service.Spec.Ports {
if protocol == "init" {
if port.Protocol == "" {
Copy link
Member

Choose a reason for hiding this comment

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

You should not need to handle "" - that will be defaulted

Copy link
Member

Choose a reason for hiding this comment

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

This whole thing should be as easy as:

protos := map[string]bool{}
for _, port := range service.Spec.Ports {
    protos[string(port.Protocol)] = true
}
return len(protos) > 1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Replaced my code with this one.

@@ -4232,18 +4232,12 @@ func ValidateService(service *core.Service, allowAppProtocol bool) field.ErrorLi

if service.Spec.Type == core.ServiceTypeLoadBalancer {
Copy link
Member

Choose a reason for hiding this comment

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

I think this whole block can go away - the same check (supportedPortProtocols.Has) exists in validateServicePort() already. Please double-check that I am not missing something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed. Service ports are checked before this place for any Service. Removed this one here.

@@ -3971,6 +3977,15 @@ type LoadBalancerIngress struct {
// (typically AWS load-balancers)
// +optional
Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`

//The list has one entry per service port in the manifest
// +listType=map
Copy link
Member

Choose a reason for hiding this comment

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

Why not atomic? Do we really need to patch individual records? The key for the map is multi-field, which is unpleasant

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To tell the truth, it was more like a guess. Modified to atomic.

Port int32 `json:"port" protobuf:"varint,1,opt,name=port"`
// The IP protocol for this port. Supports "TCP", "UDP", and "SCTP".
// Default is TCP.
// +optional
Copy link
Member

Choose a reason for hiding this comment

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

If this is optional with a default, you need to write the rule in defaults.go to set it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made it required. As you commented above port + protocol should be the key.

@janosi
Copy link
Contributor Author

janosi commented Nov 13, 2020

FWIW regarding squash, you can set thetide/merge-method-squash and let the bots handle it for you, if the goal is a complete squash. Just make sure your first commit message is good :)

Good to know. Thank you! :)

@thockin
Copy link
Member

thockin commented Nov 13, 2020

/retest

Laszlo Janosi added 2 commits November 13, 2020 17:31
KEP: https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/20200103-mixed-protocol-lb.md
Add new feature gate to control the support of mixed protocols in Services with type=LoadBalancer
Add new fields to the ServiceStatus
  Add Ports to the LoadBalancerIngress, so cloud provider implementations can report the status of the requested load balanc
er ports
  Add ServiceCondition to the ServiceStatus so Service controllers can indicate the conditions of the Service
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 13, 2020
@janosi
Copy link
Contributor Author

janosi commented Nov 13, 2020

@thockin new rebase was required

@thockin
Copy link
Member

thockin commented Nov 13, 2020

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 13, 2020
@janosi
Copy link
Contributor Author

janosi commented Nov 13, 2020

/retest

1 similar comment
@janosi
Copy link
Contributor Author

janosi commented Nov 13, 2020

/retest

@k8s-ci-robot k8s-ci-robot merged commit c970a46 into kubernetes:master Nov 13, 2020
@janosi janosi deleted the mixedprotocollb branch November 13, 2020 21:23
@janosi
Copy link
Contributor Author

janosi commented Nov 13, 2020

@andrewsykim @thockin @kikisdeliveryservice @liggitt Thank you all for your help!

@zimmertr
Copy link

Thanks everyone for this!

hidetatz pushed a commit to hidetatz/kubernetes that referenced this pull request Jan 12, 2021
…s#94028)

* Mixed protocol support for Services with type=LoadBalancer

KEP: https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/20200103-mixed-protocol-lb.md
Add new feature gate to control the support of mixed protocols in Services with type=LoadBalancer
Add new fields to the ServiceStatus
  Add Ports to the LoadBalancerIngress, so cloud provider implementations can report the status of the requested load balanc
er ports
  Add ServiceCondition to the ServiceStatus so Service controllers can indicate the conditions of the Service

* regenerate conflicting stuff
@liggitt liggitt added this to Backlog in API Reviews Feb 16, 2021
@liggitt liggitt moved this from Backlog to API review completed, 1.20 in API Reviews Feb 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-review Categorizes an issue or PR as actively needing an API review. approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note-action-required Denotes a PR that introduces potentially breaking changes that require user action. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/apps Categorizes an issue or PR as relevant to SIG Apps. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges.
Projects
Status: API review completed, 1.20
Development

Successfully merging this pull request may close these issues.

Support mixed protocols in service.type=loadbalancer
10 participants