Merge pull request #25284 from bprashanth/service_unready

Automatic merge from submit-queue

Add a service annotation that allows endpoints for unready pods

See https://github.com/kubernetes/kubernetes/issues/25283 for context 
@smarterclayton @thockin yes?

<!-- Reviewable:start -->
---
This change is [<img src="http://reviewable.k8s.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](http://reviewable.k8s.io/reviews/kubernetes/kubernetes/25284)
<!-- Reviewable:end -->
This commit is contained in:
k8s-merge-robot
2016-05-12 12:05:27 -07:00
4 changed files with 83 additions and 2 deletions

View File

@@ -20,6 +20,7 @@ package endpoint
import (
"reflect"
"strconv"
"time"
"encoding/json"
@@ -53,6 +54,14 @@ const (
// We must avoid syncing service until the pod store has synced. If it hasn't synced, to
// avoid a hot loop, we'll wait this long between checks.
PodStoreSyncedPollPeriod = 100 * time.Millisecond
// An annotation on the Service denoting if the endpoints controller should
// go ahead and create endpoints for unready pods. This annotation is
// currently only used by PetSets, where we need the pet to be DNS
// resolvable during initialization. In this situation we create a headless
// service just for the PetSet, and clients shouldn't be using this Service
// for anything so unready endpoints don't matter.
TolerateUnreadyEndpointsAnnotation = "service.alpha.kubernetes.io/tolerate-unready-endpoints"
)
var (
@@ -356,6 +365,16 @@ func (e *EndpointController) syncService(key string) {
subsets := []api.EndpointSubset{}
podHostNames := map[string]endpoints.HostRecord{}
var tolerateUnreadyEndpoints bool
if v, ok := service.Annotations[TolerateUnreadyEndpointsAnnotation]; ok {
b, err := strconv.ParseBool(v)
if err == nil {
tolerateUnreadyEndpoints = b
} else {
glog.Errorf("Failed to parse annotation %v: %v", TolerateUnreadyEndpointsAnnotation, err)
}
}
for i := range pods.Items {
pod := &pods.Items[i]
@@ -401,7 +420,7 @@ func (e *EndpointController) syncService(key string) {
epa.Hostname = hostname
}
if api.IsPodReady(pod) {
if tolerateUnreadyEndpoints || api.IsPodReady(pod) {
subsets = append(subsets, api.EndpointSubset{
Addresses: []api.EndpointAddress{epa},
Ports: []api.EndpointPort{epp},

View File

@@ -254,6 +254,9 @@ func (f *fakePetClient) setHealthy(index int) error {
}
f.pets[index].pod.Status.Phase = api.PodRunning
f.pets[index].pod.Annotations[PetSetInitAnnotation] = "true"
f.pets[index].pod.Status.Conditions = []api.PodCondition{
{Type: api.PodReady, Status: api.ConditionTrue},
}
return nil
}

View File

@@ -299,7 +299,7 @@ func (d *defaultPetHealthChecker) isHealthy(pod *api.Pod) bool {
if err != nil {
return false
}
return b
return b && api.IsPodReady(pod)
}
// isDying returns true if the pod has a non-nil deletion timestamp. Since the