kubelet: add certificate rotation error metric

This commit is contained in:
Ryan Phillips 2019-11-05 16:51:40 -06:00
parent 75aca1fe03
commit 8e50c55e6b
2 changed files with 64 additions and 18 deletions

View File

@ -61,6 +61,15 @@ func NewKubeletServerCertificateManager(kubeClient clientset.Interface, kubeCfg
}, },
) )
legacyregistry.MustRegister(certificateExpiration) legacyregistry.MustRegister(certificateExpiration)
var certificateRenewFailure = compbasemetrics.NewCounter(
&compbasemetrics.CounterOpts{
Subsystem: metrics.KubeletSubsystem,
Name: "server_expiration_renew_errors",
Help: "Counter of certificate renewal errors.",
StabilityLevel: compbasemetrics.ALPHA,
},
)
legacyregistry.MustRegister(certificateRenewFailure)
certificateRotationAge := compbasemetrics.NewHistogram( certificateRotationAge := compbasemetrics.NewHistogram(
&compbasemetrics.HistogramOpts{ &compbasemetrics.HistogramOpts{
@ -119,9 +128,10 @@ func NewKubeletServerCertificateManager(kubeClient clientset.Interface, kubeCfg
// authenticate itself to a TLS client. // authenticate itself to a TLS client.
certificates.UsageServerAuth, certificates.UsageServerAuth,
}, },
CertificateStore: certificateStore, CertificateStore: certificateStore,
CertificateExpiration: certificateExpiration, CertificateExpiration: certificateExpiration,
CertificateRotation: certificateRotationAge, CertificateRotation: certificateRotationAge,
CertificateRenewFailure: certificateRenewFailure,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize server certificate manager: %v", err) return nil, fmt.Errorf("failed to initialize server certificate manager: %v", err)
@ -199,6 +209,16 @@ func NewKubeletClientCertificateManager(
}, },
) )
legacyregistry.Register(certificateExpiration) legacyregistry.Register(certificateExpiration)
var certificateRenewFailure = compbasemetrics.NewCounter(
&compbasemetrics.CounterOpts{
Namespace: metrics.KubeletSubsystem,
Subsystem: "certificate_manager",
Name: "client_expiration_renew_errors",
Help: "Counter of certificate renewal errors.",
StabilityLevel: compbasemetrics.ALPHA,
},
)
legacyregistry.Register(certificateRenewFailure)
m, err := certificate.NewManager(&certificate.Config{ m, err := certificate.NewManager(&certificate.Config{
ClientFn: clientFn, ClientFn: clientFn,
@ -231,8 +251,9 @@ func NewKubeletClientCertificateManager(
BootstrapCertificatePEM: bootstrapCertData, BootstrapCertificatePEM: bootstrapCertData,
BootstrapKeyPEM: bootstrapKeyData, BootstrapKeyPEM: bootstrapKeyData,
CertificateStore: certificateStore, CertificateStore: certificateStore,
CertificateExpiration: certificateExpiration, CertificateExpiration: certificateExpiration,
CertificateRenewFailure: certificateRenewFailure,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize client certificate manager: %v", err) return nil, fmt.Errorf("failed to initialize client certificate manager: %v", err)

View File

@ -124,6 +124,9 @@ type Config struct {
// allows one to setup monitoring and alerting of unexpected rotation // allows one to setup monitoring and alerting of unexpected rotation
// behavior and track trends in rotation frequency. // behavior and track trends in rotation frequency.
CertificateRotation Histogram CertificateRotation Histogram
// CertifcateRenewFailure will record a metric that keeps track of
// certificate renewal failures.
CertificateRenewFailure Counter
} }
// Store is responsible for getting and updating the current certificate. // Store is responsible for getting and updating the current certificate.
@ -154,6 +157,11 @@ type Histogram interface {
Observe(float64) Observe(float64)
} }
// Counter will wrap a counter with labels
type Counter interface {
Inc()
}
// NoCertKeyError indicates there is no cert/key currently available. // NoCertKeyError indicates there is no cert/key currently available.
type NoCertKeyError string type NoCertKeyError string
@ -177,8 +185,9 @@ type manager struct {
certStore Store certStore Store
certificateExpiration Gauge certificateExpiration Gauge
certificateRotation Histogram certificateRotation Histogram
certificateRenewFailure Counter
// the following variables must only be accessed under certAccessLock // the following variables must only be accessed under certAccessLock
certAccessLock sync.RWMutex certAccessLock sync.RWMutex
@ -213,17 +222,18 @@ func NewManager(config *Config) (Manager, error) {
} }
m := manager{ m := manager{
stopCh: make(chan struct{}), stopCh: make(chan struct{}),
clientFn: config.ClientFn, clientFn: config.ClientFn,
getTemplate: getTemplate, getTemplate: getTemplate,
dynamicTemplate: config.GetTemplate != nil, dynamicTemplate: config.GetTemplate != nil,
usages: config.Usages, usages: config.Usages,
certStore: config.CertificateStore, certStore: config.CertificateStore,
cert: cert, cert: cert,
forceRotation: forceRotation, forceRotation: forceRotation,
certificateExpiration: config.CertificateExpiration, certificateExpiration: config.CertificateExpiration,
certificateRotation: config.CertificateRotation, certificateRotation: config.CertificateRotation,
now: time.Now, certificateRenewFailure: config.CertificateRenewFailure,
now: time.Now,
} }
return &m, nil return &m, nil
@ -404,6 +414,9 @@ func (m *manager) rotateCerts() (bool, error) {
template, csrPEM, keyPEM, privateKey, err := m.generateCSR() template, csrPEM, keyPEM, privateKey, err := m.generateCSR()
if err != nil { if err != nil {
utilruntime.HandleError(fmt.Errorf("Unable to generate a certificate signing request: %v", err)) utilruntime.HandleError(fmt.Errorf("Unable to generate a certificate signing request: %v", err))
if m.certificateRenewFailure != nil {
m.certificateRenewFailure.Inc()
}
return false, nil return false, nil
} }
@ -411,6 +424,9 @@ func (m *manager) rotateCerts() (bool, error) {
client, err := m.getClient() client, err := m.getClient()
if err != nil { if err != nil {
utilruntime.HandleError(fmt.Errorf("Unable to load a client to request certificates: %v", err)) utilruntime.HandleError(fmt.Errorf("Unable to load a client to request certificates: %v", err))
if m.certificateRenewFailure != nil {
m.certificateRenewFailure.Inc()
}
return false, nil return false, nil
} }
@ -419,6 +435,9 @@ func (m *manager) rotateCerts() (bool, error) {
req, err := csr.RequestCertificate(client, csrPEM, "", m.usages, privateKey) req, err := csr.RequestCertificate(client, csrPEM, "", m.usages, privateKey)
if err != nil { if err != nil {
utilruntime.HandleError(fmt.Errorf("Failed while requesting a signed certificate from the master: %v", err)) utilruntime.HandleError(fmt.Errorf("Failed while requesting a signed certificate from the master: %v", err))
if m.certificateRenewFailure != nil {
m.certificateRenewFailure.Inc()
}
return false, m.updateServerError(err) return false, m.updateServerError(err)
} }
@ -433,12 +452,18 @@ func (m *manager) rotateCerts() (bool, error) {
crtPEM, err := csr.WaitForCertificate(ctx, client, req) crtPEM, err := csr.WaitForCertificate(ctx, client, req)
if err != nil { if err != nil {
utilruntime.HandleError(fmt.Errorf("certificate request was not signed: %v", err)) utilruntime.HandleError(fmt.Errorf("certificate request was not signed: %v", err))
if m.certificateRenewFailure != nil {
m.certificateRenewFailure.Inc()
}
return false, nil return false, nil
} }
cert, err := m.certStore.Update(crtPEM, keyPEM) cert, err := m.certStore.Update(crtPEM, keyPEM)
if err != nil { if err != nil {
utilruntime.HandleError(fmt.Errorf("Unable to store the new cert/key pair: %v", err)) utilruntime.HandleError(fmt.Errorf("Unable to store the new cert/key pair: %v", err))
if m.certificateRenewFailure != nil {
m.certificateRenewFailure.Inc()
}
return false, nil return false, nil
} }