-
Notifications
You must be signed in to change notification settings - Fork 386
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
Add ExternalIPPool API and update Egress API for failover support #2236
Conversation
c59fc68
to
26b76b6
Compare
Codecov Report
@@ Coverage Diff @@
## main #2236 +/- ##
===========================================
- Coverage 61.95% 40.25% -21.70%
===========================================
Files 276 273 -3
Lines 21178 20506 -672
===========================================
- Hits 13120 8255 -4865
- Misses 6699 11094 +4395
+ Partials 1359 1157 -202
Flags with carried forward coverage won't be shown. Click here to find out more.
|
/test-all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A question on whether we always enable Node assignment or not.
type ExternalIPPoolSpec struct { | ||
// The IP ranges of this IP pool, e.g. 10.10.0.0/24, 10.10.10.2-10.10.10.20, 10.10.10.30-10.10.10.30. | ||
IPRanges []IPRange `json:"ipRanges"` | ||
// The Nodes that the external IPs can be assigned to. If empty, it means all Nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is nil, do you think we can say it means auto-assignement is not enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel it wouldn't be very useful in practice. It seems if users want to manage the egress IPs themselves, providing an ExternalIPPool here and associate it with the Egresses is not as convenient as just specifying the IP in Egress directly. Some benefits when using nil to represent all Nodes in my mind:
- For a cluster that all nodes are in same subnet, it's more convinient to use nil to select all Nodes as the Egress Nodes. I don't know a typical expression that selects all Nodes without adding labels to them. (unless using
NotIn
andDoesNotExist
with some meaningless key/value) - Have a clear boundary between enabling assignment/failover and disabling it by the externalIPPool field.
- Keep backwards-compatible with the previous static Egresses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you said make sense to me. But do you think it is a convention to use empty selector (but not nil) to express selecting all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that it's quite unusual for a nil selector to mean "select all". Is there an example in the K8s API of such behavior? On the other hand, it seems that empty (but not nil) to select all is fairly common. My preference if we do not think there will be other mechanisms / fields for selection would be to make this field not optional, with empty meaning "select all" (like the PodSelector
field in the NetworkPolicy Spec). As Jianjun mentioned in the meeting, if we plan to have other selector fields (potentially mutually-exclusive), that's potentially a different story...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do go with a pointer, Jianjun's proposal kind of makes sense to me (disabling auto-assignment for nil
): the user is responsible for assigning IP addresses to Nodes, but doesn't have to manage individual IPs for different Egress resources? Still, if we don't need other selectors in the future and this is not an actual use case, a non optional field makes more sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed the difference between nil and empty, thought they are same somehow. Yes, what you suggested makes sense. Empty is more common to to represent selecting All. I have made the field mandatory in the latest patch. If we have other fields to select Nodes in the future, I think changing a mandatory field to optional is compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think last time we discussed changing from mandatory to optional is not a compatible change. But anyway if we see no use case to make it optional, we can keep the current design (otherwise maybe change back to a pointer, but validating it cannot be nil?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also believe that changing from mandatory to optional is not considered a compatible changes, since it can break older clients which read ExternalIPPoolSpec
resources created by a newer client? https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md#on-compatibility
Given that this is an alpha API, maybe we should go with what makes the most sense right now, which I would say is making the field mandatory (current proposal).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, was considering the server side storage only. Agree we should keep what makes the most sense right now when we don't have clear idea about how to extend it.
pkg/apis/crd/v1alpha2/types.go
Outdated
// ExternalIPPool specifies the IP Pool that the EgressIP should be allocated from. | ||
// If it's set, the allocated EgressIP will be assigned to a Node specified by the Pool and it will failover to | ||
// another Node if the assigned Node becomes unavailable. | ||
// If it's set with EgressIP, the EgressIP must be in the IP Pool. | ||
ExternalIPPool string `json:"externalIPPool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have an EgressStatus
to report which IP has been assigned (e.g. for troubleshooting) to the Egress resource?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assigned IP will be set to the above EgressIP field. Does it make sense to you? This is similar to Service ClusterIP. It can be specified manually or assigned by server, the field is kept in Spec
for unification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, for troubleshooting and visibility, there is a plan to add a nodeName
field to status
after the major function is done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. If we want to get fancy, we can even add a status to the EgressIPPool to report the number of allocated vs free IPs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion, will create an issue to track it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jianjuns and @antoninbas for the suggestions.
pkg/apis/crd/v1alpha2/types.go
Outdated
// ExternalIPPool specifies the IP Pool that the EgressIP should be allocated from. | ||
// If it's set, the allocated EgressIP will be assigned to a Node specified by the Pool and it will failover to | ||
// another Node if the assigned Node becomes unavailable. | ||
// If it's set with EgressIP, the EgressIP must be in the IP Pool. | ||
ExternalIPPool string `json:"externalIPPool"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assigned IP will be set to the above EgressIP field. Does it make sense to you? This is similar to Service ClusterIP. It can be specified manually or assigned by server, the field is kept in Spec
for unification.
type ExternalIPPoolSpec struct { | ||
// The IP ranges of this IP pool, e.g. 10.10.0.0/24, 10.10.10.2-10.10.10.20, 10.10.10.30-10.10.10.30. | ||
IPRanges []IPRange `json:"ipRanges"` | ||
// The Nodes that the external IPs can be assigned to. If empty, it means all Nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed the difference between nil and empty, thought they are same somehow. Yes, what you suggested makes sense. Empty is more common to to represent selecting All. I have made the field mandatory in the latest patch. If we have other fields to select Nodes in the future, I think changing a mandatory field to optional is compatible.
type ExternalIPPoolSpec struct { | ||
// The IP ranges of this IP pool, e.g. 10.10.0.0/24, 10.10.10.2-10.10.10.20, 10.10.10.30-10.10.10.30. | ||
IPRanges []IPRange `json:"ipRanges"` | ||
// The Nodes that the external IPs can be assigned to. If empty, it means all Nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think last time we discussed changing from mandatory to optional is not a compatible change. But anyway if we see no use case to make it optional, we can keep the current design (otherwise maybe change back to a pointer, but validating it cannot be nil?).
pkg/apis/crd/v1alpha2/types.go
Outdated
// +genclient:noStatus | ||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
|
||
// ExternalIPPool defines one or multiple IP sets that can be used in external network. For instance, the IPs can be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"in the external network"?
or "in external networks"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
type ExternalIPPoolSpec struct { | ||
// The IP ranges of this IP pool, e.g. 10.10.0.0/24, 10.10.10.2-10.10.10.20, 10.10.10.30-10.10.10.30. | ||
IPRanges []IPRange `json:"ipRanges"` | ||
// The Nodes that the external IPs can be assigned to. If empty, it means all Nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also believe that changing from mandatory to optional is not considered a compatible changes, since it can break older clients which read ExternalIPPoolSpec
resources created by a newer client? https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md#on-compatibility
Given that this is an alpha API, maybe we should go with what makes the most sense right now, which I would say is making the field mandatory (current proposal).
1. Add ExternalIPPool CRD which defines one or multiple IP sets that can be used in external network, and the Nodes that can hold the IPs. 2. Add an optional field "externalIPPool" to Egress spec which specifies the IP Pool that the EgressIP should be allocated from. Signed-off-by: Quan Tian <qtian@vmware.com>
/test-all |
/test-networkpolicy |
Add ExternalIPPool CRD which defines one or multiple IP sets that can
be used in external network, and the Nodes that can hold the IPs.
Add an optional field "externalIPPool" to Egress spec which specifies
the IP Pool that the EgressIP should be allocated from.
Signed-off-by: Quan Tian qtian@vmware.com
For #2128