Update custom-metrics-apiserver and metrics-server

This commit is contained in:
Johannes Würbach 2020-09-27 22:14:53 +02:00
parent 4c673534f2
commit b480e45a67
No known key found for this signature in database
GPG key ID: 74DB0F4D956CCCE3
915 changed files with 63694 additions and 106514 deletions

View file

@ -112,7 +112,7 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
}
// ApplyTo adds the admission chain to the server configuration.
// In case admission plugin names were not provided by a custer-admin they will be prepared from the recommended/default values.
// In case admission plugin names were not provided by a cluster-admin they will be prepared from the recommended/default values.
// In addition the method lazily initializes a generic plugin that is appended to the list of pluginInitializers
// note this method uses:
// genericconfig.Authorizer

View file

@ -29,6 +29,7 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
utilnet "k8s.io/apimachinery/pkg/util/net"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
auditv1 "k8s.io/apiserver/pkg/apis/audit/v1"
auditv1alpha1 "k8s.io/apiserver/pkg/apis/audit/v1alpha1"
@ -37,6 +38,7 @@ import (
"k8s.io/apiserver/pkg/audit/policy"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/egressselector"
utilfeature "k8s.io/apiserver/pkg/util/feature"
pluginbuffered "k8s.io/apiserver/plugin/pkg/audit/buffered"
plugindynamic "k8s.io/apiserver/plugin/pkg/audit/dynamic"
@ -323,7 +325,15 @@ func (o *AuditOptions) ApplyTo(
if checker == nil {
klog.V(2).Info("No audit policy file provided, no events will be recorded for webhook backend")
} else {
webhookBackend, err = o.WebhookOptions.newUntruncatedBackend()
if c.EgressSelector != nil {
egressDialer, err := c.EgressSelector.Lookup(egressselector.Master.AsNetworkContext())
if err != nil {
return err
}
webhookBackend, err = o.WebhookOptions.newUntruncatedBackend(egressDialer)
} else {
webhookBackend, err = o.WebhookOptions.newUntruncatedBackend(nil)
}
if err != nil {
return err
}
@ -590,9 +600,9 @@ func (o *AuditWebhookOptions) enabled() bool {
// newUntruncatedBackend returns a webhook backend without the truncate options applied
// this is done so that the same trucate backend can wrap both the webhook and dynamic backends
func (o *AuditWebhookOptions) newUntruncatedBackend() (audit.Backend, error) {
func (o *AuditWebhookOptions) newUntruncatedBackend(customDial utilnet.DialFunc) (audit.Backend, error) {
groupVersion, _ := schema.ParseGroupVersion(o.GroupVersionString)
webhook, err := pluginwebhook.NewBackend(o.ConfigFile, groupVersion, o.InitialBackoff)
webhook, err := pluginwebhook.NewBackend(o.ConfigFile, groupVersion, o.InitialBackoff, customDial)
if err != nil {
return nil, fmt.Errorf("initializing audit webhook: %v", err)
}

View file

@ -17,6 +17,7 @@ limitations under the License.
package options
import (
"context"
"encoding/json"
"fmt"
"strings"
@ -212,7 +213,7 @@ func (s *DelegatingAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
}
fs.StringVar(&s.RemoteKubeConfigFile, "authentication-kubeconfig", s.RemoteKubeConfigFile, ""+
"kubeconfig file pointing at the 'core' kubernetes server with enough rights to create "+
"tokenaccessreviews.authentication.k8s.io."+optionalKubeConfigSentence)
"tokenreviews.authentication.k8s.io."+optionalKubeConfigSentence)
fs.DurationVar(&s.CacheTTL, "authentication-token-webhook-cache-ttl", s.CacheTTL,
"The duration to cache responses from the webhook token authenticator.")
@ -339,7 +340,7 @@ func (s *DelegatingAuthenticationOptions) createRequestHeaderConfig(client kuber
return nil, fmt.Errorf("unable to create request header authentication config: %v", err)
}
authConfigMap, err := client.CoreV1().ConfigMaps(authenticationConfigMapNamespace).Get(authenticationConfigMapName, metav1.GetOptions{})
authConfigMap, err := client.CoreV1().ConfigMaps(authenticationConfigMapNamespace).Get(context.TODO(), authenticationConfigMapName, metav1.GetOptions{})
switch {
case errors.IsNotFound(err):
// ignore, authConfigMap is nil now

View file

@ -20,6 +20,7 @@ import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
"fmt"
"io"
"io/ioutil"
@ -33,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer"
apiserverconfig "k8s.io/apiserver/pkg/apis/config"
apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
"k8s.io/apiserver/pkg/apis/config/validation"
"k8s.io/apiserver/pkg/server/healthz"
"k8s.io/apiserver/pkg/storage/value"
aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes"
@ -46,8 +48,8 @@ const (
aesGCMTransformerPrefixV1 = "k8s:enc:aesgcm:v1:"
secretboxTransformerPrefixV1 = "k8s:enc:secretbox:v1:"
kmsTransformerPrefixV1 = "k8s:enc:kms:v1:"
kmsPluginConnectionTimeout = 3 * time.Second
kmsPluginHealthzTTL = 3 * time.Second
kmsPluginHealthzNegativeTTL = 3 * time.Second
kmsPluginHealthzPositiveTTL = 20 * time.Second
)
type kmsPluginHealthzResponse struct {
@ -57,6 +59,7 @@ type kmsPluginHealthzResponse struct {
type kmsPluginProbe struct {
name string
ttl time.Duration
envelope.Service
lastResponse *kmsPluginHealthzResponse
l *sync.Mutex
@ -104,21 +107,14 @@ func getKMSPluginProbes(reader io.Reader) ([]*kmsPluginProbe, error) {
for _, r := range config.Resources {
for _, p := range r.Providers {
if p.KMS != nil {
timeout := kmsPluginConnectionTimeout
if p.KMS.Timeout != nil {
if p.KMS.Timeout.Duration <= 0 {
return nil, fmt.Errorf("could not configure KMS-Plugin's probe %q, timeout should be a positive value", p.KMS.Name)
}
timeout = p.KMS.Timeout.Duration
}
s, err := envelope.NewGRPCService(p.KMS.Endpoint, timeout)
s, err := envelope.NewGRPCService(p.KMS.Endpoint, p.KMS.Timeout.Duration)
if err != nil {
return nil, fmt.Errorf("could not configure KMS-Plugin's probe %q, error: %v", p.KMS.Name, err)
}
result = append(result, &kmsPluginProbe{
name: p.KMS.Name,
ttl: kmsPluginHealthzNegativeTTL,
Service: s,
l: &sync.Mutex{},
lastResponse: &kmsPluginHealthzResponse{},
@ -135,22 +131,25 @@ func (h *kmsPluginProbe) Check() error {
h.l.Lock()
defer h.l.Unlock()
if (time.Since(h.lastResponse.received)) < kmsPluginHealthzTTL {
if (time.Since(h.lastResponse.received)) < h.ttl {
return h.lastResponse.err
}
p, err := h.Service.Encrypt([]byte("ping"))
if err != nil {
h.lastResponse = &kmsPluginHealthzResponse{err: err, received: time.Now()}
h.ttl = kmsPluginHealthzNegativeTTL
return fmt.Errorf("failed to perform encrypt section of the healthz check for KMS Provider %s, error: %v", h.name, err)
}
if _, err := h.Service.Decrypt(p); err != nil {
h.lastResponse = &kmsPluginHealthzResponse{err: err, received: time.Now()}
h.ttl = kmsPluginHealthzNegativeTTL
return fmt.Errorf("failed to perform decrypt section of the healthz check for KMS Provider %s, error: %v", h.name, err)
}
h.lastResponse = &kmsPluginHealthzResponse{err: nil, received: time.Now()}
h.ttl = kmsPluginHealthzPositiveTTL
return nil
}
@ -221,7 +220,8 @@ func loadConfig(data []byte) (*apiserverconfig.EncryptionConfiguration, error) {
if !ok {
return nil, fmt.Errorf("got unexpected config type: %v", gvk)
}
return config, nil
return config, validation.ValidateEncryptionConfiguration(config).ToAggregate()
}
// The factory to create kms service. This is to make writing test easier.
@ -231,82 +231,38 @@ var envelopeServiceFactory = envelope.NewGRPCService
func GetPrefixTransformers(config *apiserverconfig.ResourceConfiguration) ([]value.PrefixTransformer, error) {
var result []value.PrefixTransformer
for _, provider := range config.Providers {
found := false
var (
transformer value.PrefixTransformer
err error
)
var transformer value.PrefixTransformer
var err error
if provider.AESGCM != nil {
switch {
case provider.AESGCM != nil:
transformer, err = GetAESPrefixTransformer(provider.AESGCM, aestransformer.NewGCMTransformer, aesGCMTransformerPrefixV1)
if err != nil {
return result, err
}
found = true
}
if provider.AESCBC != nil {
if found == true {
return result, fmt.Errorf("more than one provider specified in a single element, should split into different list elements")
}
case provider.AESCBC != nil:
transformer, err = GetAESPrefixTransformer(provider.AESCBC, aestransformer.NewCBCTransformer, aesCBCTransformerPrefixV1)
found = true
}
if provider.Secretbox != nil {
if found == true {
return result, fmt.Errorf("more than one provider specified in a single element, should split into different list elements")
}
case provider.Secretbox != nil:
transformer, err = GetSecretboxPrefixTransformer(provider.Secretbox)
found = true
}
if provider.Identity != nil {
if found == true {
return result, fmt.Errorf("more than one provider specified in a single element, should split into different list elements")
}
transformer = value.PrefixTransformer{
Transformer: identity.NewEncryptCheckTransformer(),
Prefix: []byte{},
}
found = true
}
if provider.KMS != nil {
if found == true {
return nil, fmt.Errorf("more than one provider specified in a single element, should split into different list elements")
}
// Ensure the endpoint is provided.
if len(provider.KMS.Endpoint) == 0 {
return nil, fmt.Errorf("remote KMS provider can't use empty string as endpoint")
}
timeout := kmsPluginConnectionTimeout
if provider.KMS.Timeout != nil {
if provider.KMS.Timeout.Duration <= 0 {
return nil, fmt.Errorf("could not configure KMS plugin %q, timeout should be a positive value", provider.KMS.Name)
}
timeout = provider.KMS.Timeout.Duration
}
// Get gRPC client service with endpoint.
envelopeService, err := envelopeServiceFactory(provider.KMS.Endpoint, timeout)
case provider.KMS != nil:
envelopeService, err := envelopeServiceFactory(provider.KMS.Endpoint, provider.KMS.Timeout.Duration)
if err != nil {
return nil, fmt.Errorf("could not configure KMS plugin %q, error: %v", provider.KMS.Name, err)
}
transformer, err = getEnvelopePrefixTransformer(provider.KMS, envelopeService, kmsTransformerPrefixV1)
found = true
case provider.Identity != nil:
transformer = value.PrefixTransformer{
Transformer: identity.NewEncryptCheckTransformer(),
Prefix: []byte{},
}
default:
return nil, errors.New("provider does not contain any of the expected providers: KMS, AESGCM, AESCBC, Secretbox, Identity")
}
if err != nil {
return result, err
}
result = append(result, transformer)
if found == false {
return result, fmt.Errorf("invalid provider configuration: at least one provider must be specified")
}
}
return result, nil
}
@ -417,7 +373,7 @@ func GetSecretboxPrefixTransformer(config *apiserverconfig.SecretboxConfiguratio
// getEnvelopePrefixTransformer returns a prefix transformer from the provided config.
// envelopeService is used as the root of trust.
func getEnvelopePrefixTransformer(config *apiserverconfig.KMSConfiguration, envelopeService envelope.Service, prefix string) (value.PrefixTransformer, error) {
envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, int(config.CacheSize), aestransformer.NewCBCTransformer)
envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, int(*config.CacheSize), aestransformer.NewCBCTransformer)
if err != nil {
return value.PrefixTransformer{}, err
}

View file

@ -18,12 +18,15 @@ package options
import (
"github.com/spf13/pflag"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/apiserver/pkg/util/feature"
utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol"
"k8s.io/client-go/kubernetes"
"k8s.io/component-base/featuregate"
)
@ -125,7 +128,14 @@ func (o *RecommendedOptions) ApplyTo(config *server.RecommendedConfig) error {
if err := o.EgressSelector.ApplyTo(&config.Config); err != nil {
return err
}
if feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
config.FlowControl = utilflowcontrol.New(
config.SharedInformerFactory,
kubernetes.NewForConfigOrDie(config.ClientConfig).FlowcontrolV1alpha1(),
config.MaxRequestsInFlight+config.MaxMutatingRequestsInFlight,
config.RequestTimeout/4,
)
}
return nil
}

View file

@ -26,9 +26,6 @@ import (
"k8s.io/apiserver/pkg/server"
utilfeature "k8s.io/apiserver/pkg/util/feature"
// add the generic feature gates
"k8s.io/apiserver/pkg/features"
"github.com/spf13/pflag"
)
@ -41,6 +38,7 @@ type ServerRunOptions struct {
MaxRequestsInFlight int
MaxMutatingRequestsInFlight int
RequestTimeout time.Duration
GoawayChance float64
LivezGracePeriod time.Duration
MinRequestTimeout int
ShutdownDelayDuration time.Duration
@ -51,9 +49,9 @@ type ServerRunOptions struct {
// decoded in a write request. 0 means no limit.
// We intentionally did not add a flag for this option. Users of the
// apiserver library can wire it to a flag.
MaxRequestBodyBytes int64
TargetRAMMB int
EnableInflightQuotaHandler bool
MaxRequestBodyBytes int64
TargetRAMMB int
EnablePriorityAndFairness bool
}
func NewServerRunOptions() *ServerRunOptions {
@ -67,6 +65,7 @@ func NewServerRunOptions() *ServerRunOptions {
ShutdownDelayDuration: defaults.ShutdownDelayDuration,
JSONPatchMaxCopyBytes: defaults.JSONPatchMaxCopyBytes,
MaxRequestBodyBytes: defaults.MaxRequestBodyBytes,
EnablePriorityAndFairness: true,
}
}
@ -78,6 +77,7 @@ func (s *ServerRunOptions) ApplyTo(c *server.Config) error {
c.MaxMutatingRequestsInFlight = s.MaxMutatingRequestsInFlight
c.LivezGracePeriod = s.LivezGracePeriod
c.RequestTimeout = s.RequestTimeout
c.GoawayChance = s.GoawayChance
c.MinRequestTimeout = s.MinRequestTimeout
c.ShutdownDelayDuration = s.ShutdownDelayDuration
c.JSONPatchMaxCopyBytes = s.JSONPatchMaxCopyBytes
@ -116,32 +116,21 @@ func (s *ServerRunOptions) Validate() []error {
errors = append(errors, fmt.Errorf("--livez-grace-period can not be a negative value"))
}
if s.EnableInflightQuotaHandler {
if !utilfeature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
errors = append(errors, fmt.Errorf("--enable-inflight-quota-handler can not be set if feature "+
"gate APIPriorityAndFairness is disabled"))
}
if s.MaxMutatingRequestsInFlight != 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight=%v "+
"can not be set if enabled inflight quota handler", s.MaxMutatingRequestsInFlight))
}
if s.MaxRequestsInFlight != 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight=%v "+
"can not be set if enabled inflight quota handler", s.MaxRequestsInFlight))
}
} else {
if s.MaxRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight can not be negative value"))
}
if s.MaxMutatingRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight can not be negative value"))
}
if s.MaxRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-requests-inflight can not be negative value"))
}
if s.MaxMutatingRequestsInFlight < 0 {
errors = append(errors, fmt.Errorf("--max-mutating-requests-inflight can not be negative value"))
}
if s.RequestTimeout.Nanoseconds() < 0 {
errors = append(errors, fmt.Errorf("--request-timeout can not be negative value"))
}
if s.GoawayChance < 0 || s.GoawayChance > 0.02 {
errors = append(errors, fmt.Errorf("--goaway-chance can not be less than 0 or greater than 0.02"))
}
if s.MinRequestTimeout < 0 {
errors = append(errors, fmt.Errorf("--min-request-timeout can not be negative value"))
}
@ -180,11 +169,11 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"Memory limit for apiserver in MB (used to configure sizes of caches, etc.)")
fs.StringVar(&s.ExternalHost, "external-hostname", s.ExternalHost,
"The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs).")
"The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs or OpenID Discovery).")
deprecatedMasterServiceNamespace := metav1.NamespaceDefault
fs.StringVar(&deprecatedMasterServiceNamespace, "master-service-namespace", deprecatedMasterServiceNamespace, ""+
"DEPRECATED: the namespace from which the kubernetes master services should be injected into pods.")
"DEPRECATED: the namespace from which the Kubernetes master services should be injected into pods.")
fs.IntVar(&s.MaxRequestsInFlight, "max-requests-inflight", s.MaxRequestsInFlight, ""+
"The maximum number of non-mutating requests in flight at a given time. When the server exceeds this, "+
@ -199,6 +188,12 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"it out. This is the default request timeout for requests but may be overridden by flags such as "+
"--min-request-timeout for specific types of requests.")
fs.Float64Var(&s.GoawayChance, "goaway-chance", s.GoawayChance, ""+
"To prevent HTTP/2 clients from getting stuck on a single apiserver, randomly close a connection (GOAWAY). "+
"The client's other in-flight requests won't be affected, and the client will reconnect, likely landing on a different apiserver after going through the load balancer again. "+
"This argument sets the fraction of requests that will be sent a GOAWAY. Clusters with single apiservers, or which don't use a load balancer, should NOT enable this. "+
"Min is 0 (off), Max is .02 (1/50 requests); .001 (1/1000) is a recommended starting point.")
fs.DurationVar(&s.LivezGracePeriod, "livez-grace-period", s.LivezGracePeriod, ""+
"This option represents the maximum amount of time it should take for apiserver to complete its startup sequence "+
"and become live. From apiserver's start time to when this amount of time has elapsed, /livez will assume "+
@ -210,8 +205,8 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"handler, which picks a randomized value above this number as the connection timeout, "+
"to spread out load.")
fs.BoolVar(&s.EnableInflightQuotaHandler, "enable-inflight-quota-handler", s.EnableInflightQuotaHandler, ""+
"If true, replace the max-in-flight handler with an enhanced one that queues and dispatches with priority and fairness")
fs.BoolVar(&s.EnablePriorityAndFairness, "enable-priority-and-fairness", s.EnablePriorityAndFairness, ""+
"If true and the APIPriorityAndFairness feature gate is enabled, replace the max-in-flight handler with an enhanced one that queues and dispatches with priority and fairness")
fs.DurationVar(&s.ShutdownDelayDuration, "shutdown-delay-duration", s.ShutdownDelayDuration, ""+
"Time to delay the termination. During that time the server keeps serving requests normally and /healthz "+

View file

@ -143,13 +143,13 @@ func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.BindAddress, "bind-address", s.BindAddress, ""+
"The IP address on which to listen for the --secure-port port. The "+
"associated interface(s) must be reachable by the rest of the cluster, and by CLI/web "+
"clients. If blank, all interfaces will be used (0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).")
"clients. If blank or an unspecified address (0.0.0.0 or ::), all interfaces will be used.")
desc := "The port on which to serve HTTPS with authentication and authorization."
if s.Required {
desc += "It cannot be switched off with 0."
desc += " It cannot be switched off with 0."
} else {
desc += "If 0, don't serve HTTPS at all."
desc += " If 0, don't serve HTTPS at all."
}
fs.IntVar(&s.BindPort, "secure-port", s.BindPort, desc)
@ -180,7 +180,9 @@ func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
fs.Var(cliflag.NewNamedCertKeyArray(&s.SNICertKeys), "tls-sni-cert-key", ""+
"A pair of x509 certificate and private key file paths, optionally suffixed with a list of "+
"domain patterns which are fully qualified domain names, possibly with prefixed wildcard "+
"segments. If no domain patterns are provided, the names of the certificate are "+
"segments. The domain patterns also allow IP addresses, but IPs should only be used if "+
"the apiserver has visibility to the IP address requested by a client. "+
"If no domain patterns are provided, the names of the certificate are "+
"extracted. Non-wildcard matches trump over wildcard matches, explicit domain patterns "+
"trump over extracted names. For multiple key/certificate pairs, use the "+
"--tls-sni-cert-key multiple times. "+
@ -287,8 +289,7 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str
if !canReadCertAndKey {
// add either the bind address or localhost to the valid alternates
bindIP := s.BindAddress.String()
if bindIP == "0.0.0.0" {
if s.BindAddress.IsUnspecified() {
alternateDNS = append(alternateDNS, "localhost")
} else {
alternateIPs = append(alternateIPs, s.BindAddress)