Skip to content

Commit 5fbda60

Browse files
authored
Merge pull request kubernetes#82077 from deads2k/poststart
add ability to pre-configure poststarthooks for apiservers
2 parents 90f4871 + f14f4c9 commit 5fbda60

File tree

7 files changed

+88
-39
lines changed

7 files changed

+88
-39
lines changed

cmd/kube-apiserver/app/aggregator.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ func createAggregatorConfig(
6464
// make a shallow copy to let us twiddle a few things
6565
// most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the aggregator
6666
genericConfig := kubeAPIServerConfig
67+
genericConfig.PostStartHooks = map[string]genericapiserver.PostStartHookConfigEntry{}
68+
genericConfig.RESTOptionsGetter = nil
6769

6870
// override genericConfig.AdmissionControl with kube-aggregator's scheme,
6971
// because aggregator apiserver should use its own scheme to convert its own resources.

cmd/kube-apiserver/app/apiextensions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func createAPIExtensionsConfig(
4848
// make a shallow copy to let us twiddle a few things
4949
// most of the config actually remains the same. We only need to mess with a couple items related to the particulars of the apiextensions
5050
genericConfig := kubeAPIServerConfig
51+
genericConfig.PostStartHooks = map[string]genericapiserver.PostStartHookConfigEntry{}
52+
genericConfig.RESTOptionsGetter = nil
5153

5254
// override genericConfig.AdmissionControl with apiextensions' scheme,
5355
// because apiextentions apiserver should use its own scheme to convert resources.

cmd/kube-apiserver/app/server.go

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
168168
return nil, err
169169
}
170170

171-
kubeAPIServerConfig, insecureServingInfo, serviceResolver, pluginInitializer, admissionPostStartHook, err := CreateKubeAPIServerConfig(completedOptions, nodeTunneler, proxyTransport)
171+
kubeAPIServerConfig, insecureServingInfo, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(completedOptions, nodeTunneler, proxyTransport)
172172
if err != nil {
173173
return nil, err
174174
}
@@ -184,7 +184,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
184184
return nil, err
185185
}
186186

187-
kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer, admissionPostStartHook)
187+
kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer)
188188
if err != nil {
189189
return nil, err
190190
}
@@ -211,14 +211,12 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan
211211
}
212212

213213
// CreateKubeAPIServer creates and wires a workable kube-apiserver
214-
func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, delegateAPIServer genericapiserver.DelegationTarget, admissionPostStartHook genericapiserver.PostStartHookFunc) (*master.Master, error) {
214+
func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, delegateAPIServer genericapiserver.DelegationTarget) (*master.Master, error) {
215215
kubeAPIServer, err := kubeAPIServerConfig.Complete().New(delegateAPIServer)
216216
if err != nil {
217217
return nil, err
218218
}
219219

220-
kubeAPIServer.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-admission-initializer", admissionPostStartHook)
221-
222220
return kubeAPIServer, nil
223221
}
224222

@@ -273,25 +271,20 @@ func CreateKubeAPIServerConfig(
273271
nodeTunneler tunneler.Tunneler,
274272
proxyTransport *http.Transport,
275273
) (
276-
config *master.Config,
277-
insecureServingInfo *genericapiserver.DeprecatedInsecureServingInfo,
278-
serviceResolver aggregatorapiserver.ServiceResolver,
279-
pluginInitializers []admission.PluginInitializer,
280-
admissionPostStartHook genericapiserver.PostStartHookFunc,
281-
lastErr error,
274+
*master.Config,
275+
*genericapiserver.DeprecatedInsecureServingInfo,
276+
aggregatorapiserver.ServiceResolver,
277+
[]admission.PluginInitializer,
278+
error,
282279
) {
283-
var genericConfig *genericapiserver.Config
284-
var storageFactory *serverstorage.DefaultStorageFactory
285-
var versionedInformers clientgoinformers.SharedInformerFactory
286-
genericConfig, versionedInformers, insecureServingInfo, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, lastErr = buildGenericConfig(s.ServerRunOptions, proxyTransport)
287-
if lastErr != nil {
288-
return
280+
genericConfig, versionedInformers, insecureServingInfo, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, err := buildGenericConfig(s.ServerRunOptions, proxyTransport)
281+
if err != nil {
282+
return nil, nil, nil, nil, err
289283
}
290284

291285
if _, port, err := net.SplitHostPort(s.Etcd.StorageConfig.Transport.ServerList[0]); err == nil && port != "0" && len(port) != 0 {
292286
if err := utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval, preflight.EtcdConnection{ServerList: s.Etcd.StorageConfig.Transport.ServerList}.CheckEtcdServers); err != nil {
293-
lastErr = fmt.Errorf("error waiting for etcd connection: %v", err)
294-
return
287+
return nil, nil, nil, nil, fmt.Errorf("error waiting for etcd connection: %v", err)
295288
}
296289
}
297290

@@ -306,31 +299,31 @@ func CreateKubeAPIServerConfig(
306299
PerConnectionBandwidthLimitBytesPerSec: s.MaxConnectionBytesPerSec,
307300
})
308301

309-
serviceIPRange, apiServerServiceIP, lastErr := master.ServiceIPRange(s.PrimaryServiceClusterIPRange)
310-
if lastErr != nil {
311-
return
302+
serviceIPRange, apiServerServiceIP, err := master.ServiceIPRange(s.PrimaryServiceClusterIPRange)
303+
if err != nil {
304+
return nil, nil, nil, nil, err
312305
}
313306

314307
// defaults to empty range and ip
315308
var secondaryServiceIPRange net.IPNet
316309
// process secondary range only if provided by user
317310
if s.SecondaryServiceClusterIPRange.IP != nil {
318-
secondaryServiceIPRange, _, lastErr = master.ServiceIPRange(s.SecondaryServiceClusterIPRange)
319-
if lastErr != nil {
320-
return
311+
secondaryServiceIPRange, _, err = master.ServiceIPRange(s.SecondaryServiceClusterIPRange)
312+
if err != nil {
313+
return nil, nil, nil, nil, err
321314
}
322315
}
323316

324-
clientCA, lastErr := readCAorNil(s.Authentication.ClientCert.ClientCA)
325-
if lastErr != nil {
326-
return
317+
clientCA, err := readCAorNil(s.Authentication.ClientCert.ClientCA)
318+
if err != nil {
319+
return nil, nil, nil, nil, err
327320
}
328-
requestHeaderProxyCA, lastErr := readCAorNil(s.Authentication.RequestHeader.ClientCAFile)
329-
if lastErr != nil {
330-
return
321+
requestHeaderProxyCA, err := readCAorNil(s.Authentication.RequestHeader.ClientCAFile)
322+
if err != nil {
323+
return nil, nil, nil, nil, err
331324
}
332325

333-
config = &master.Config{
326+
config := &master.Config{
334327
GenericConfig: genericConfig,
335328
ExtraConfig: master.ExtraConfig{
336329
ClientCARegistrationHook: master.ClientCARegistrationHook{
@@ -369,6 +362,9 @@ func CreateKubeAPIServerConfig(
369362
VersionedInformers: versionedInformers,
370363
},
371364
}
365+
if err := config.GenericConfig.AddPostStartHook("start-kube-apiserver-admission-initializer", admissionPostStartHook); err != nil {
366+
return nil, nil, nil, nil, err
367+
}
372368

373369
if nodeTunneler != nil {
374370
// Use the nodeTunneler's dialer to connect to the kubelet
@@ -379,7 +375,7 @@ func CreateKubeAPIServerConfig(
379375
config.ExtraConfig.KubeletClientConfig.Lookup = config.GenericConfig.EgressSelector.Lookup
380376
}
381377

382-
return
378+
return config, insecureServingInfo, serviceResolver, pluginInitializers, nil
383379
}
384380

385381
// BuildGenericConfig takes the master server options and produces the genericapiserver.Config associated with it

staging/src/k8s.io/apiserver/pkg/server/config.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"net"
2424
"net/http"
2525
goruntime "runtime"
26+
"runtime/debug"
2627
"sort"
2728
"strconv"
2829
"strings"
@@ -116,6 +117,8 @@ type Config struct {
116117
EnableMetrics bool
117118

118119
DisabledPostStartHooks sets.String
120+
// done values in this values for this map are ignored.
121+
PostStartHooks map[string]PostStartHookConfigEntry
119122

120123
// Version will enable the /version endpoint if non-nil
121124
Version *version.Info
@@ -282,6 +285,7 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
282285
HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup),
283286
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
284287
DisabledPostStartHooks: sets.NewString(),
288+
PostStartHooks: map[string]PostStartHookConfigEntry{},
285289
HealthzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...),
286290
ReadyzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...),
287291
LivezChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...),
@@ -389,6 +393,36 @@ func (c *Config) AddHealthChecks(healthChecks ...healthz.HealthChecker) {
389393
}
390394
}
391395

396+
// AddPostStartHook allows you to add a PostStartHook that will later be added to the server itself in a New call.
397+
// Name conflicts will cause an error.
398+
func (c *Config) AddPostStartHook(name string, hook PostStartHookFunc) error {
399+
if len(name) == 0 {
400+
return fmt.Errorf("missing name")
401+
}
402+
if hook == nil {
403+
return fmt.Errorf("hook func may not be nil: %q", name)
404+
}
405+
if c.DisabledPostStartHooks.Has(name) {
406+
klog.V(1).Infof("skipping %q because it was explicitly disabled", name)
407+
return nil
408+
}
409+
410+
if postStartHook, exists := c.PostStartHooks[name]; exists {
411+
// this is programmer error, but it can be hard to debug
412+
return fmt.Errorf("unable to add %q because it was already registered by: %s", name, postStartHook.originatingStack)
413+
}
414+
c.PostStartHooks[name] = PostStartHookConfigEntry{hook: hook, originatingStack: string(debug.Stack())}
415+
416+
return nil
417+
}
418+
419+
// AddPostStartHookOrDie allows you to add a PostStartHook, but dies on failure.
420+
func (c *Config) AddPostStartHookOrDie(name string, hook PostStartHookFunc) {
421+
if err := c.AddPostStartHook(name, hook); err != nil {
422+
klog.Fatalf("Error registering PostStartHook %q: %v", name, err)
423+
}
424+
}
425+
392426
// Complete fills in any fields not set that are required to have valid data and can be derived
393427
// from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
394428
func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig {
@@ -550,6 +584,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
550584
}
551585
}
552586

587+
// first add poststarthooks from delegated targets
553588
for k, v := range delegationTarget.PostStartHooks() {
554589
s.postStartHooks[k] = v
555590
}
@@ -558,6 +593,13 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
558593
s.preShutdownHooks[k] = v
559594
}
560595

596+
// add poststarthooks that were preconfigured. Using the add method will give us an error if the same name has already been registered.
597+
for name, preconfiguredPostStartHook := range c.PostStartHooks {
598+
if err := s.AddPostStartHook(name, preconfiguredPostStartHook.hook); err != nil {
599+
return nil, err
600+
}
601+
}
602+
561603
genericApiServerHookName := "generic-apiserver-start-informers"
562604
if c.SharedInformerFactory != nil && !s.isPostStartHookRegistered(genericApiServerHookName) {
563605
err := s.AddPostStartHook(genericApiServerHookName, func(context PostStartHookContext) error {
@@ -611,7 +653,6 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
611653
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
612654
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
613655
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
614-
handler = genericapifilters.WithCacheControl(handler)
615656
handler = genericfilters.WithPanicRecovery(handler)
616657
return handler
617658
}

staging/src/k8s.io/apiserver/pkg/server/hooks.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ type postStartHookEntry struct {
6666
done chan struct{}
6767
}
6868

69+
type PostStartHookConfigEntry struct {
70+
hook PostStartHookFunc
71+
// originatingStack holds the stack that registered postStartHooks. This allows us to show a more helpful message
72+
// for duplicate registration.
73+
originatingStack string
74+
}
75+
6976
type preShutdownHookEntry struct {
7077
hook PreShutdownHookFunc
7178
}
@@ -76,9 +83,10 @@ func (s *GenericAPIServer) AddPostStartHook(name string, hook PostStartHookFunc)
7683
return fmt.Errorf("missing name")
7784
}
7885
if hook == nil {
79-
return nil
86+
return fmt.Errorf("hook func may not be nil: %q", name)
8087
}
8188
if s.disabledPostStartHooks.Has(name) {
89+
klog.V(1).Infof("skipping %q because it was explicitly disabled", name)
8290
return nil
8391
}
8492

test/integration/examples/apiserver_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func TestAggregatedAPIServer(t *testing.T) {
118118
if err != nil {
119119
t.Fatal(err)
120120
}
121-
kubeAPIServerConfig, _, _, _, admissionPostStartHook, err := app.CreateKubeAPIServerConfig(completedOptions, tunneler, proxyTransport)
121+
kubeAPIServerConfig, _, _, _, err := app.CreateKubeAPIServerConfig(completedOptions, tunneler, proxyTransport)
122122
if err != nil {
123123
t.Fatal(err)
124124
}
@@ -129,7 +129,7 @@ func TestAggregatedAPIServer(t *testing.T) {
129129
kubeAPIServerClientConfig.ServerName = ""
130130
kubeClientConfigValue.Store(kubeAPIServerClientConfig)
131131

132-
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate(), admissionPostStartHook)
132+
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate())
133133
if err != nil {
134134
t.Fatal(err)
135135
}

test/integration/framework/test_server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ func StartTestServer(t *testing.T, stopCh <-chan struct{}, setup TestServerSetup
113113
if err != nil {
114114
t.Fatal(err)
115115
}
116-
kubeAPIServerConfig, _, _, _, admissionPostStartHook, err := app.CreateKubeAPIServerConfig(completedOptions, tunneler, proxyTransport)
116+
kubeAPIServerConfig, _, _, _, err := app.CreateKubeAPIServerConfig(completedOptions, tunneler, proxyTransport)
117117
if err != nil {
118118
t.Fatal(err)
119119
}
120120

121121
if setup.ModifyServerConfig != nil {
122122
setup.ModifyServerConfig(kubeAPIServerConfig)
123123
}
124-
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate(), admissionPostStartHook)
124+
kubeAPIServer, err := app.CreateKubeAPIServer(kubeAPIServerConfig, genericapiserver.NewEmptyDelegate())
125125
if err != nil {
126126
t.Fatal(err)
127127
}

0 commit comments

Comments
 (0)