mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 22:05:59 +00:00
compensate for raft/cache delay in namespace admission
This commit is contained in:
parent
d323fed024
commit
2b569eeea0
@ -21,6 +21,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/cache"
|
"k8s.io/kubernetes/pkg/client/cache"
|
||||||
@ -38,6 +39,12 @@ const (
|
|||||||
PluginName = "NamespaceLifecycle"
|
PluginName = "NamespaceLifecycle"
|
||||||
// how long a namespace stays in the force live lookup cache before expiration.
|
// how long a namespace stays in the force live lookup cache before expiration.
|
||||||
forceLiveLookupTTL = 30 * time.Second
|
forceLiveLookupTTL = 30 * time.Second
|
||||||
|
// how long to wait for a missing namespace before re-checking the cache (and then doing a live lookup)
|
||||||
|
// this accomplishes two things:
|
||||||
|
// 1. It allows a watch-fed cache time to observe a namespace creation event
|
||||||
|
// 2. It allows time for a namespace creation to distribute to members of a storage cluster,
|
||||||
|
// so the live lookup has a better chance of succeeding even if it isn't performed against the leader.
|
||||||
|
missingNamespaceWait = 50 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -113,6 +120,19 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
|
|||||||
return errors.NewInternalError(err)
|
return errors.NewInternalError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !exists && a.GetOperation() == admission.Create {
|
||||||
|
// give the cache time to observe the namespace before rejecting a create.
|
||||||
|
// this helps when creating a namespace and immediately creating objects within it.
|
||||||
|
time.Sleep(missingNamespaceWait)
|
||||||
|
namespaceObj, exists, err = l.namespaceInformer.GetStore().Get(key)
|
||||||
|
if err != nil {
|
||||||
|
return errors.NewInternalError(err)
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
glog.V(4).Infof("found %s in cache after waiting", a.GetNamespace())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// forceLiveLookup if true will skip looking at local cache state and instead always make a live call to server.
|
// forceLiveLookup if true will skip looking at local cache state and instead always make a live call to server.
|
||||||
forceLiveLookup := false
|
forceLiveLookup := false
|
||||||
lruItemObj, ok := l.forceLiveLookupCache.Get(a.GetNamespace())
|
lruItemObj, ok := l.forceLiveLookupCache.Get(a.GetNamespace())
|
||||||
@ -123,7 +143,7 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
|
|||||||
|
|
||||||
// refuse to operate on non-existent namespaces
|
// refuse to operate on non-existent namespaces
|
||||||
if !exists || forceLiveLookup {
|
if !exists || forceLiveLookup {
|
||||||
// in case of latency in our caches, make a call direct to storage to verify that it truly exists or not
|
// as a last resort, make a call directly to storage
|
||||||
namespaceObj, err = l.client.Core().Namespaces().Get(a.GetNamespace())
|
namespaceObj, err = l.client.Core().Namespaces().Get(a.GetNamespace())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
@ -131,6 +151,7 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
|
|||||||
}
|
}
|
||||||
return errors.NewInternalError(err)
|
return errors.NewInternalError(err)
|
||||||
}
|
}
|
||||||
|
glog.V(4).Infof("found %s via storage lookup", a.GetNamespace())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that we're not trying to create objects in terminating namespaces
|
// ensure that we're not trying to create objects in terminating namespaces
|
||||||
|
Loading…
Reference in New Issue
Block a user