Kubelet should exit if the current client cert has expired

The client cert manager uses the most recent cert to request new
certificates. If that certificate is expired, it will be unable to
complete new CSR requests. This commit alters the manager to force
process exit if no further client cert rotation is possible, which
is expected to trigger a restart of the kubelet and either a
re-bootstrap from the bootstrap kubeconfig or a re-read of the
current disk state (assuming that some other agent is managing the
bootstrap configuration).

This prevents the Kubelet from wedging in a state where it cannot make
API calls.
This commit is contained in:
Clayton Coleman 2017-10-01 16:52:07 -04:00
parent c3bea24ab6
commit 7555dec82e
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
3 changed files with 10 additions and 5 deletions

View File

@ -342,7 +342,9 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies) (err error) {
if err != nil {
return err
}
if err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager); err != nil {
// we set exitIfExpired to true because we use this client configuration to request new certs - if we are unable
// to request new certs, we will be unable to continue normal operation
if err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager, true); err != nil {
return err
}
}

View File

@ -45,13 +45,13 @@ import (
//
// stopCh should be used to indicate when the transport is unused and doesn't need
// to continue checking the manager.
func UpdateTransport(stopCh <-chan struct{}, clientConfig *restclient.Config, clientCertificateManager certificate.Manager) error {
return updateTransport(stopCh, 10*time.Second, clientConfig, clientCertificateManager)
func UpdateTransport(stopCh <-chan struct{}, clientConfig *restclient.Config, clientCertificateManager certificate.Manager, exitIfExpired bool) error {
return updateTransport(stopCh, 10*time.Second, clientConfig, clientCertificateManager, exitIfExpired)
}
// updateTransport is an internal method that exposes how often this method checks that the
// client cert has changed. Intended for testing.
func updateTransport(stopCh <-chan struct{}, period time.Duration, clientConfig *restclient.Config, clientCertificateManager certificate.Manager) error {
func updateTransport(stopCh <-chan struct{}, period time.Duration, clientConfig *restclient.Config, clientCertificateManager certificate.Manager, exitIfExpired bool) error {
if clientConfig.Transport != nil {
return fmt.Errorf("there is already a transport configured")
}
@ -80,6 +80,9 @@ func updateTransport(stopCh <-chan struct{}, period time.Duration, clientConfig
lastCert := clientCertificateManager.Current()
go wait.Until(func() {
curr := clientCertificateManager.Current()
if exitIfExpired && curr != nil && time.Now().After(curr.Leaf.NotAfter) {
glog.Fatalf("The currently active client certificate has expired, exiting.")
}
if curr == nil || lastCert == curr {
// Cert hasn't been rotated.
return

View File

@ -184,7 +184,7 @@ func TestRotateShutsDownConnections(t *testing.T) {
}
// Check for a new cert every 10 milliseconds
if err := updateTransport(stop, 10*time.Millisecond, c, m); err != nil {
if err := updateTransport(stop, 10*time.Millisecond, c, m, false); err != nil {
t.Fatal(err)
}