Skip to content

Commit

Permalink
Merge pull request #78458 from logicalhan/readiness
Browse files Browse the repository at this point in the history
Add readyz endpoint to apiserver, modify poststarthooks health checking behavior
  • Loading branch information
k8s-ci-robot committed Jun 17, 2019
2 parents 35e8a70 + 54dcf5c commit ae3c44d
Show file tree
Hide file tree
Showing 15 changed files with 334 additions and 20 deletions.
1 change: 1 addition & 0 deletions cmd/kube-apiserver/app/testing/BUILD
Expand Up @@ -17,6 +17,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
Expand Down
11 changes: 10 additions & 1 deletion cmd/kube-apiserver/app/testing/testserver.go
Expand Up @@ -25,12 +25,13 @@ import (
"runtime"
"time"

pflag "github.com/spf13/pflag"
"github.com/spf13/pflag"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/registry/generic/registry"
"k8s.io/apiserver/pkg/server/healthz"
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
Expand All @@ -45,6 +46,8 @@ type TearDownFunc func()
type TestServerInstanceOptions struct {
// DisableStorageCleanup Disable the automatic storage cleanup
DisableStorageCleanup bool
// Injected health
InjectedHealthzChecker healthz.HealthzChecker
}

// TestServer return values supplied by kube-test-ApiServer
Expand Down Expand Up @@ -144,6 +147,12 @@ func StartTestServer(t Logger, instanceOptions *TestServerInstanceOptions, custo
t.Logf("runtime-config=%v", completedOptions.APIEnablement.RuntimeConfig)
t.Logf("Starting kube-apiserver on port %d...", s.SecureServing.BindPort)
server, err := app.CreateServerChain(completedOptions, stopCh)

if instanceOptions.InjectedHealthzChecker != nil {
t.Logf("Adding health check with delay %v %v", s.GenericServerRunOptions.MaxStartupSequenceDuration, instanceOptions.InjectedHealthzChecker.Name())
server.AddDelayedHealthzChecks(s.GenericServerRunOptions.MaxStartupSequenceDuration, instanceOptions.InjectedHealthzChecker)
}

if err != nil {
return result, fmt.Errorf("failed to create server chain: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
Expand Up @@ -198,7 +198,7 @@ func ClusterRoles() []rbacv1.ClusterRole {
ObjectMeta: metav1.ObjectMeta{Name: "system:discovery"},
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get").URLs(
"/healthz", "/version", "/version/",
"/readyz", "/healthz", "/version", "/version/",
"/openapi", "/openapi/*",
"/api", "/api/*",
"/apis", "/apis/*",
Expand All @@ -218,7 +218,7 @@ func ClusterRoles() []rbacv1.ClusterRole {
ObjectMeta: metav1.ObjectMeta{Name: "system:public-info-viewer"},
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get").URLs(
"/healthz", "/version", "/version/",
"/readyz", "/healthz", "/version", "/version/",
).RuleOrDie(),
},
},
Expand Down
Expand Up @@ -535,6 +535,7 @@ items:
- /healthz
- /openapi
- /openapi/*
- /readyz
- /version
- /version/
verbs:
Expand Down Expand Up @@ -1156,6 +1157,7 @@ items:
rules:
- nonResourceURLs:
- /healthz
- /readyz
- /version
- /version/
verbs:
Expand Down
3 changes: 3 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/server/BUILD
Expand Up @@ -12,13 +12,15 @@ go_test(
"config_selfclient_test.go",
"config_test.go",
"genericapiserver_test.go",
"healthz_test.go",
],
embed = [":go_default_library"],
deps = [
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
Expand Down Expand Up @@ -66,6 +68,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
Expand Down
24 changes: 20 additions & 4 deletions staging/src/k8s.io/apiserver/pkg/server/config.go
Expand Up @@ -32,11 +32,11 @@ import (
jsonpatch "github.com/evanphx/json-patch"
"github.com/go-openapi/spec"
"github.com/pborman/uuid"
"k8s.io/klog"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/clock"
"k8s.io/apimachinery/pkg/util/sets"
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
"k8s.io/apimachinery/pkg/version"
Expand Down Expand Up @@ -65,6 +65,7 @@ import (
restclient "k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert"
"k8s.io/component-base/logs"
"k8s.io/klog"
openapicommon "k8s.io/kube-openapi/pkg/common"

// install apis
Expand Down Expand Up @@ -135,6 +136,8 @@ type Config struct {
DiscoveryAddresses discovery.Addresses
// The default set of healthz checks. There might be more added via AddHealthzChecks dynamically.
HealthzChecks []healthz.HealthzChecker
// The default set of readyz-only checks. There might be more added via AddReadyzChecks dynamically.
ReadyzChecks []healthz.HealthzChecker
// LegacyAPIGroupPrefixes is used to set up URL parsing for authorization and for validating requests
// to InstallLegacyAPIGroup. New API servers don't generally have legacy groups at all.
LegacyAPIGroupPrefixes sets.String
Expand All @@ -156,6 +159,12 @@ type Config struct {
// If specified, long running requests such as watch will be allocated a random timeout between this value, and
// twice this value. Note that it is up to the request handlers to ignore or honor this timeout. In seconds.
MinRequestTimeout int

// This represents the maximum amount of time it should take for apiserver to complete its startup
// sequence and become healthy. From apiserver's start time to when this amount of time has
// elapsed, /healthz will assume that unfinished post-start hooks will complete successfully and
// therefore return true.
MaxStartupSequenceDuration time.Duration
// The limit on the total size increase all "copy" operations in a json
// patch may cause.
// This affects all places that applies json patch in the binary.
Expand Down Expand Up @@ -256,13 +265,15 @@ type AuthorizationInfo struct {

// NewConfig returns a Config struct with the default values
func NewConfig(codecs serializer.CodecFactory) *Config {
defaultHealthChecks := []healthz.HealthzChecker{healthz.PingHealthz, healthz.LogHealthz}
return &Config{
Serializer: codecs,
BuildHandlerChainFunc: DefaultBuildHandlerChain,
HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup),
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
DisabledPostStartHooks: sets.NewString(),
HealthzChecks: []healthz.HealthzChecker{healthz.PingHealthz, healthz.LogHealthz},
HealthzChecks: append([]healthz.HealthzChecker{}, defaultHealthChecks...),
ReadyzChecks: append([]healthz.HealthzChecker{}, defaultHealthChecks...),
EnableIndex: true,
EnableDiscovery: true,
EnableProfiling: true,
Expand All @@ -271,6 +282,7 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
MaxMutatingRequestsInFlight: 200,
RequestTimeout: time.Duration(60) * time.Second,
MinRequestTimeout: 1800,
MaxStartupSequenceDuration: time.Duration(0),
// 10MB is the recommended maximum client request size in bytes
// the etcd server should accept. See
// https://github.com/etcd-io/etcd/blob/release-3.3/etcdserver/server.go#L90.
Expand Down Expand Up @@ -479,7 +491,6 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G

minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
ShutdownTimeout: c.RequestTimeout,

SecureServingInfo: c.SecureServing,
ExternalAddress: c.ExternalAddress,

Expand All @@ -493,12 +504,16 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
preShutdownHooks: map[string]preShutdownHookEntry{},
disabledPostStartHooks: c.DisabledPostStartHooks,

healthzChecks: c.HealthzChecks,
healthzChecks: c.HealthzChecks,
readyzChecks: c.ReadyzChecks,
readinessStopCh: make(chan struct{}),
maxStartupSequenceDuration: c.MaxStartupSequenceDuration,

DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer),

enableAPIResponseCompression: c.EnableAPIResponseCompression,
maxRequestBodyBytes: c.MaxRequestBodyBytes,
healthzClock: clock.RealClock{},
}

for {
Expand Down Expand Up @@ -546,6 +561,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
}

s.healthzChecks = append(s.healthzChecks, delegateCheck)
s.readyzChecks = append(s.readyzChecks, delegateCheck)
}

s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget}
Expand Down
10 changes: 9 additions & 1 deletion staging/src/k8s.io/apiserver/pkg/server/config_test.go
Expand Up @@ -115,7 +115,15 @@ func TestNewWithDelegate(t *testing.T) {
"/healthz/poststarthook/generic-apiserver-start-informers",
"/healthz/poststarthook/wrapping-post-start-hook",
"/healthz/wrapping-health",
"/metrics"
"/metrics",
"/readyz",
"/readyz/delegate-health",
"/readyz/log",
"/readyz/ping",
"/readyz/poststarthook/delegate-post-start-hook",
"/readyz/poststarthook/generic-apiserver-start-informers",
"/readyz/poststarthook/wrapping-post-start-hook",
"/readyz/shutdown"
]
}`, t)
checkPath(server.URL+"/healthz", http.StatusInternalServerError, `[+]ping ok
Expand Down
19 changes: 15 additions & 4 deletions staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
Expand Up @@ -26,13 +26,13 @@ import (

systemd "github.com/coreos/go-systemd/daemon"
"github.com/go-openapi/spec"
"k8s.io/klog"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/clock"
"k8s.io/apimachinery/pkg/util/sets"
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
"k8s.io/apiserver/pkg/admission"
Expand All @@ -45,6 +45,7 @@ import (
"k8s.io/apiserver/pkg/server/routes"
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
restclient "k8s.io/client-go/rest"
"k8s.io/klog"
openapibuilder "k8s.io/kube-openapi/pkg/builder"
openapicommon "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/handler"
Expand Down Expand Up @@ -145,9 +146,17 @@ type GenericAPIServer struct {
preShutdownHooksCalled bool

// healthz checks
healthzLock sync.Mutex
healthzChecks []healthz.HealthzChecker
healthzCreated bool
healthzLock sync.Mutex
healthzChecks []healthz.HealthzChecker
healthzChecksInstalled bool
readyzLock sync.Mutex
readyzChecks []healthz.HealthzChecker
readyzChecksInstalled bool
maxStartupSequenceDuration time.Duration
healthzClock clock.Clock
// the readiness stop channel is used to signal that the apiserver has initiated a shutdown sequence, this
// will cause readyz to return unhealthy.
readinessStopCh chan struct{}

// auditing. The backend is started after the server starts listening.
AuditBackend audit.Backend
Expand Down Expand Up @@ -259,6 +268,7 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
}

s.installHealthz()
s.installReadyz(s.readinessStopCh)

// Register audit backend preShutdownHook.
if s.AuditBackend != nil {
Expand Down Expand Up @@ -327,6 +337,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
// ensure cleanup.
go func() {
<-stopCh
close(s.readinessStopCh)
close(internalStopCh)
if stoppedCh != nil {
<-stoppedCh
Expand Down

0 comments on commit ae3c44d

Please sign in to comment.