Skip to content

Commit

Permalink
better early termination of reachability check
Browse files Browse the repository at this point in the history
Signed-off-by: everettraven <[email protected]>
  • Loading branch information
everettraven committed Dec 12, 2024
1 parent 2ed95e1 commit 61014ac
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 18 deletions.
30 changes: 17 additions & 13 deletions openshift-kube-apiserver/openshiftkubeapiserver/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,10 @@ func OpenShiftKubeAPIServerConfigPatch(genericConfig *genericapiserver.Config, k
// END HANDLER CHAIN

openshiftAPIServiceReachabilityCheck := newOpenshiftAPIServiceReachabilityCheck(genericConfig.PublicAddress)
oauthAPIServiceReachabilityCheck := newOAuthPIServiceReachabilityCheck(genericConfig.PublicAddress)
genericConfig.ReadyzChecks = append(genericConfig.ReadyzChecks, openshiftAPIServiceReachabilityCheck, oauthAPIServiceReachabilityCheck)

genericConfig.AddPostStartHookOrDie("openshift.io-startkubeinformers", func(context genericapiserver.PostStartHookContext) error {
go openshiftInformers.Start(context.StopCh)
return nil
})
genericConfig.AddPostStartHookOrDie("openshift.io-openshift-apiserver-reachable", func(context genericapiserver.PostStartHookContext) error {
go openshiftAPIServiceReachabilityCheck.checkForConnection(context)
return nil
})
genericConfig.AddPostStartHookOrDie("openshift.io-oauth-apiserver-reachable", func(context genericapiserver.PostStartHookContext) error {
oauthAPIServiceTerminationCondition := func() (bool, string) {
authnCache := authncache.NewAuthnCache(openshiftInformers.OpenshiftConfigInformers.Config().V1().Authentications())
err := wait.PollImmediate(1*time.Second, 10*time.Second, func() (bool, error) {
err := wait.PollImmediate(1*time.Second, 30*time.Second, func() (bool, error) {
return authnCache.HasSynced(), nil
})
if err == nil {
Expand All @@ -132,11 +122,25 @@ func OpenShiftKubeAPIServerConfigPatch(genericConfig *genericapiserver.Config, k
if auth.Spec.Type == configv1.AuthenticationTypeOIDC {
// skip the oauthAPIServiceReachabilityCheck if OIDC
// has been configured since the oauth apiserver will be down.
return nil
return true, "authentication type is OIDC, meaning no oauth-apiserver is deployed. Skipping oauth-apiserver availability check"
}
}
}
return false, ""
}
oauthAPIServiceReachabilityCheck := newOAuthAPIServiceReachabilityCheck(genericConfig.PublicAddress, oauthAPIServiceTerminationCondition)

genericConfig.ReadyzChecks = append(genericConfig.ReadyzChecks, openshiftAPIServiceReachabilityCheck, oauthAPIServiceReachabilityCheck)

genericConfig.AddPostStartHookOrDie("openshift.io-startkubeinformers", func(context genericapiserver.PostStartHookContext) error {
go openshiftInformers.Start(context.StopCh)
return nil
})
genericConfig.AddPostStartHookOrDie("openshift.io-openshift-apiserver-reachable", func(context genericapiserver.PostStartHookContext) error {
go openshiftAPIServiceReachabilityCheck.checkForConnection(context)
return nil
})
genericConfig.AddPostStartHookOrDie("openshift.io-oauth-apiserver-reachable", func(context genericapiserver.PostStartHookContext) error {
go oauthAPIServiceReachabilityCheck.checkForConnection(context)
return nil
})
Expand Down
26 changes: 21 additions & 5 deletions openshift-kube-apiserver/openshiftkubeapiserver/sdn_readyz_wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,28 @@ import (
)

func newOpenshiftAPIServiceReachabilityCheck(ipForKubernetesDefaultService net.IP) *aggregatedAPIServiceAvailabilityCheck {
return newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService, "openshift-apiserver", "api")
return newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService, "openshift-apiserver", "api", nil)
}

func newOAuthPIServiceReachabilityCheck(ipForKubernetesDefaultService net.IP) *aggregatedAPIServiceAvailabilityCheck {
return newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService, "openshift-oauth-apiserver", "api")
func newOAuthAPIServiceReachabilityCheck(ipForKubernetesDefaultService net.IP, terminationCondition terminationConditionFunc) *aggregatedAPIServiceAvailabilityCheck {
return newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService, "openshift-oauth-apiserver", "api", terminationCondition)
}

// if the API service is not found, then this check returns quickly.
// if the API service is not found or the termination condition is met, then this check returns quickly.
// if the endpoint is not accessible within 60 seconds, we report ready no matter what
// otherwise, wait for up to 60 seconds to be able to reach the apiserver
func newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService net.IP, namespace, service string) *aggregatedAPIServiceAvailabilityCheck {
func newAggregatedAPIServiceReachabilityCheck(ipForKubernetesDefaultService net.IP, namespace, service string, terminationCondition terminationConditionFunc) *aggregatedAPIServiceAvailabilityCheck {
return &aggregatedAPIServiceAvailabilityCheck{
done: make(chan struct{}),
ipForKubernetesDefaultService: ipForKubernetesDefaultService,
namespace: namespace,
serviceName: service,
terminationCondition: terminationCondition,
}
}

type terminationConditionFunc func() (bool, string)

type aggregatedAPIServiceAvailabilityCheck struct {
// done indicates that this check is complete (success or failure) and the check should return true
done chan struct{}
Expand All @@ -50,6 +53,11 @@ type aggregatedAPIServiceAvailabilityCheck struct {
namespace string
// serviceName is used to get a list of endpoints to directly dial
serviceName string

// terminationCondition is used to determine if conditions are met
// to terminate the availability check early. If the conditions are met,
// it is expected that true and a message is returned to be logged.
terminationCondition terminationConditionFunc
}

func (c *aggregatedAPIServiceAvailabilityCheck) Name() string {
Expand All @@ -75,6 +83,14 @@ func (c *aggregatedAPIServiceAvailabilityCheck) checkForConnection(context gener
close(waitUntilCh) // this stops the endpoint check
close(c.done) // once this method is done, the ready check should return true
}()

if c.terminationCondition != nil {
if ok, msg := c.terminationCondition(); ok {
klog.V(2).Infof("%s early termination condition met: %s", c.Name(), msg)
return
}
}

start := time.Now()

kubeClient, err := kubernetes.NewForConfig(context.LoopbackClientConfig)
Expand Down

0 comments on commit 61014ac

Please sign in to comment.