Skip to content

Commit 205570e

Browse files
authored
Merge pull request kubernetes#84614 from rphillips/fixes/add_cert_rotation_failure_metric
kubelet: add certificate rotation error metric
2 parents 4629da2 + 8e50c55 commit 205570e

File tree

2 files changed

+64
-18
lines changed

2 files changed

+64
-18
lines changed

pkg/kubelet/certificate/kubelet.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ func NewKubeletServerCertificateManager(kubeClient clientset.Interface, kubeCfg
6161
},
6262
)
6363
legacyregistry.MustRegister(certificateExpiration)
64+
var certificateRenewFailure = compbasemetrics.NewCounter(
65+
&compbasemetrics.CounterOpts{
66+
Subsystem: metrics.KubeletSubsystem,
67+
Name: "server_expiration_renew_errors",
68+
Help: "Counter of certificate renewal errors.",
69+
StabilityLevel: compbasemetrics.ALPHA,
70+
},
71+
)
72+
legacyregistry.MustRegister(certificateRenewFailure)
6473

6574
certificateRotationAge := compbasemetrics.NewHistogram(
6675
&compbasemetrics.HistogramOpts{
@@ -119,9 +128,10 @@ func NewKubeletServerCertificateManager(kubeClient clientset.Interface, kubeCfg
119128
// authenticate itself to a TLS client.
120129
certificates.UsageServerAuth,
121130
},
122-
CertificateStore: certificateStore,
123-
CertificateExpiration: certificateExpiration,
124-
CertificateRotation: certificateRotationAge,
131+
CertificateStore: certificateStore,
132+
CertificateExpiration: certificateExpiration,
133+
CertificateRotation: certificateRotationAge,
134+
CertificateRenewFailure: certificateRenewFailure,
125135
})
126136
if err != nil {
127137
return nil, fmt.Errorf("failed to initialize server certificate manager: %v", err)
@@ -199,6 +209,16 @@ func NewKubeletClientCertificateManager(
199209
},
200210
)
201211
legacyregistry.Register(certificateExpiration)
212+
var certificateRenewFailure = compbasemetrics.NewCounter(
213+
&compbasemetrics.CounterOpts{
214+
Namespace: metrics.KubeletSubsystem,
215+
Subsystem: "certificate_manager",
216+
Name: "client_expiration_renew_errors",
217+
Help: "Counter of certificate renewal errors.",
218+
StabilityLevel: compbasemetrics.ALPHA,
219+
},
220+
)
221+
legacyregistry.Register(certificateRenewFailure)
202222

203223
m, err := certificate.NewManager(&certificate.Config{
204224
ClientFn: clientFn,
@@ -231,8 +251,9 @@ func NewKubeletClientCertificateManager(
231251
BootstrapCertificatePEM: bootstrapCertData,
232252
BootstrapKeyPEM: bootstrapKeyData,
233253

234-
CertificateStore: certificateStore,
235-
CertificateExpiration: certificateExpiration,
254+
CertificateStore: certificateStore,
255+
CertificateExpiration: certificateExpiration,
256+
CertificateRenewFailure: certificateRenewFailure,
236257
})
237258
if err != nil {
238259
return nil, fmt.Errorf("failed to initialize client certificate manager: %v", err)

staging/src/k8s.io/client-go/util/certificate/certificate_manager.go

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ type Config struct {
124124
// allows one to setup monitoring and alerting of unexpected rotation
125125
// behavior and track trends in rotation frequency.
126126
CertificateRotation Histogram
127+
// CertifcateRenewFailure will record a metric that keeps track of
128+
// certificate renewal failures.
129+
CertificateRenewFailure Counter
127130
}
128131

129132
// Store is responsible for getting and updating the current certificate.
@@ -154,6 +157,11 @@ type Histogram interface {
154157
Observe(float64)
155158
}
156159

160+
// Counter will wrap a counter with labels
161+
type Counter interface {
162+
Inc()
163+
}
164+
157165
// NoCertKeyError indicates there is no cert/key currently available.
158166
type NoCertKeyError string
159167

@@ -177,8 +185,9 @@ type manager struct {
177185

178186
certStore Store
179187

180-
certificateExpiration Gauge
181-
certificateRotation Histogram
188+
certificateExpiration Gauge
189+
certificateRotation Histogram
190+
certificateRenewFailure Counter
182191

183192
// the following variables must only be accessed under certAccessLock
184193
certAccessLock sync.RWMutex
@@ -213,17 +222,18 @@ func NewManager(config *Config) (Manager, error) {
213222
}
214223

215224
m := manager{
216-
stopCh: make(chan struct{}),
217-
clientFn: config.ClientFn,
218-
getTemplate: getTemplate,
219-
dynamicTemplate: config.GetTemplate != nil,
220-
usages: config.Usages,
221-
certStore: config.CertificateStore,
222-
cert: cert,
223-
forceRotation: forceRotation,
224-
certificateExpiration: config.CertificateExpiration,
225-
certificateRotation: config.CertificateRotation,
226-
now: time.Now,
225+
stopCh: make(chan struct{}),
226+
clientFn: config.ClientFn,
227+
getTemplate: getTemplate,
228+
dynamicTemplate: config.GetTemplate != nil,
229+
usages: config.Usages,
230+
certStore: config.CertificateStore,
231+
cert: cert,
232+
forceRotation: forceRotation,
233+
certificateExpiration: config.CertificateExpiration,
234+
certificateRotation: config.CertificateRotation,
235+
certificateRenewFailure: config.CertificateRenewFailure,
236+
now: time.Now,
227237
}
228238

229239
return &m, nil
@@ -404,13 +414,19 @@ func (m *manager) rotateCerts() (bool, error) {
404414
template, csrPEM, keyPEM, privateKey, err := m.generateCSR()
405415
if err != nil {
406416
utilruntime.HandleError(fmt.Errorf("Unable to generate a certificate signing request: %v", err))
417+
if m.certificateRenewFailure != nil {
418+
m.certificateRenewFailure.Inc()
419+
}
407420
return false, nil
408421
}
409422

410423
// request the client each time
411424
client, err := m.getClient()
412425
if err != nil {
413426
utilruntime.HandleError(fmt.Errorf("Unable to load a client to request certificates: %v", err))
427+
if m.certificateRenewFailure != nil {
428+
m.certificateRenewFailure.Inc()
429+
}
414430
return false, nil
415431
}
416432

@@ -419,6 +435,9 @@ func (m *manager) rotateCerts() (bool, error) {
419435
req, err := csr.RequestCertificate(client, csrPEM, "", m.usages, privateKey)
420436
if err != nil {
421437
utilruntime.HandleError(fmt.Errorf("Failed while requesting a signed certificate from the master: %v", err))
438+
if m.certificateRenewFailure != nil {
439+
m.certificateRenewFailure.Inc()
440+
}
422441
return false, m.updateServerError(err)
423442
}
424443

@@ -433,12 +452,18 @@ func (m *manager) rotateCerts() (bool, error) {
433452
crtPEM, err := csr.WaitForCertificate(ctx, client, req)
434453
if err != nil {
435454
utilruntime.HandleError(fmt.Errorf("certificate request was not signed: %v", err))
455+
if m.certificateRenewFailure != nil {
456+
m.certificateRenewFailure.Inc()
457+
}
436458
return false, nil
437459
}
438460

439461
cert, err := m.certStore.Update(crtPEM, keyPEM)
440462
if err != nil {
441463
utilruntime.HandleError(fmt.Errorf("Unable to store the new cert/key pair: %v", err))
464+
if m.certificateRenewFailure != nil {
465+
m.certificateRenewFailure.Inc()
466+
}
442467
return false, nil
443468
}
444469

0 commit comments

Comments
 (0)