Merge pull request #62497 from MrHohn/endpoint-controller-headless-ports

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Fix a bug that headless service without ports fails to have endpoint created.

**What this PR does / why we need it**:
Follow up of https://github.com/kubernetes/kubernetes/pull/47250. Headless service without ports fails to have corresponding endpoint created because endpoint controller deliberately attaches a dummy endpointPort with portNum=0, which will fail API validation check. Error as below:
```
endpoints_controller.go:375] Error syncing endpoints for service "default/XXX": Endpoints "XXX" is invalid: subsets[0].ports[0].port: Invalid value: 0: must be between 1 and 65535, inclusive
```

This PR makes endpoint controller not attach the dummy endpointPort for headless service.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #55158, fixes #62440 

**Special notes for your reviewer**:
cc @xiangpengzhao 

**Release note**:

```release-note
Fix a bug that headless service without ports fails to have endpoint created.
```
This commit is contained in:
Kubernetes Submit Queue 2018-04-29 07:45:02 -07:00 committed by GitHub
commit dfba1c1f2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 8 deletions

View File

@ -454,8 +454,8 @@ func (e *EndpointController) syncService(key string) error {
// Allow headless service not to have ports.
if len(service.Spec.Ports) == 0 {
if service.Spec.ClusterIP == api.ClusterIPNone {
epp := v1.EndpointPort{Port: 0, Protocol: v1.ProtocolTCP}
subsets, totalReadyEps, totalNotReadyEps = addEndpointSubset(subsets, pod, epa, epp, tolerateUnreadyEndpoints)
subsets, totalReadyEps, totalNotReadyEps = addEndpointSubset(subsets, pod, epa, nil, tolerateUnreadyEndpoints)
// No need to repack subsets for headless service without ports.
}
} else {
for i := range service.Spec.Ports {
@ -470,14 +470,14 @@ func (e *EndpointController) syncService(key string) error {
}
var readyEps, notReadyEps int
epp := v1.EndpointPort{Name: portName, Port: int32(portNum), Protocol: portProto}
epp := &v1.EndpointPort{Name: portName, Port: int32(portNum), Protocol: portProto}
subsets, readyEps, notReadyEps = addEndpointSubset(subsets, pod, epa, epp, tolerateUnreadyEndpoints)
totalReadyEps = totalReadyEps + readyEps
totalNotReadyEps = totalNotReadyEps + notReadyEps
}
subsets = endpoints.RepackSubsets(subsets)
}
}
subsets = endpoints.RepackSubsets(subsets)
// See if there's actually an update here.
currentEndpoints, err := e.endpointsLister.Endpoints(service.Namespace).Get(service.Name)
@ -561,20 +561,24 @@ func (e *EndpointController) checkLeftoverEndpoints() {
}
func addEndpointSubset(subsets []v1.EndpointSubset, pod *v1.Pod, epa v1.EndpointAddress,
epp v1.EndpointPort, tolerateUnreadyEndpoints bool) ([]v1.EndpointSubset, int, int) {
epp *v1.EndpointPort, tolerateUnreadyEndpoints bool) ([]v1.EndpointSubset, int, int) {
var readyEps int = 0
var notReadyEps int = 0
ports := []v1.EndpointPort{}
if epp != nil {
ports = append(ports, *epp)
}
if tolerateUnreadyEndpoints || podutil.IsPodReady(pod) {
subsets = append(subsets, v1.EndpointSubset{
Addresses: []v1.EndpointAddress{epa},
Ports: []v1.EndpointPort{epp},
Ports: ports,
})
readyEps++
} else if shouldPodBeInEndpoints(pod) {
glog.V(5).Infof("Pod is out of service: %s/%s", pod.Namespace, pod.Name)
subsets = append(subsets, v1.EndpointSubset{
NotReadyAddresses: []v1.EndpointAddress{epa},
Ports: []v1.EndpointPort{epp},
Ports: ports,
})
notReadyEps++
}

View File

@ -753,7 +753,7 @@ func TestSyncEndpointsHeadlessService(t *testing.T) {
},
Subsets: []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", NodeName: &emptyNodeName, TargetRef: &v1.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}},
Ports: []v1.EndpointPort{{Port: 0, Protocol: "TCP"}},
Ports: []v1.EndpointPort{},
}},
})
endpointsHandler.ValidateRequestCount(t, 1)