Skip to content

Commit

Permalink
Merge pull request #66683 from awly/automated-cherry-pick-of-#66395-u…
Browse files Browse the repository at this point in the history
…pstream-release-1.11

Automatic merge from submit-queue.

Automated cherry pick of #66395: Set connrotation dialer via restclient.Config.Dialer

Cherry pick of #66395 on release-1.11.

#66395: Set connrotation dialer via restclient.Config.Dialer
  • Loading branch information
Kubernetes Submit Queue committed Jul 31, 2018
2 parents 6de9973 + 89322ec commit 7755525
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 63 deletions.
108 changes: 59 additions & 49 deletions pkg/kubelet/certificate/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,74 +65,84 @@ func updateTransport(stopCh <-chan struct{}, period time.Duration, clientConfig

d := connrotation.NewDialer((&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext)

if clientCertificateManager != nil {
if err := addCertRotation(stopCh, period, clientConfig, clientCertificateManager, exitAfter, d); err != nil {
return nil, err
}
} else {
clientConfig.Dial = d.DialContext
}

return d.CloseAll, nil
}

func addCertRotation(stopCh <-chan struct{}, period time.Duration, clientConfig *restclient.Config, clientCertificateManager certificate.Manager, exitAfter time.Duration, d *connrotation.Dialer) error {
tlsConfig, err := restclient.TLSConfigFor(clientConfig)
if err != nil {
return nil, fmt.Errorf("unable to configure TLS for the rest client: %v", err)
return fmt.Errorf("unable to configure TLS for the rest client: %v", err)
}
if tlsConfig == nil {
tlsConfig = &tls.Config{}
}

if clientCertificateManager != nil {
tlsConfig.Certificates = nil
tlsConfig.GetClientCertificate = func(requestInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) {
cert := clientCertificateManager.Current()
if cert == nil {
return &tls.Certificate{Certificate: nil}, nil
}
return cert, nil
tlsConfig.Certificates = nil
tlsConfig.GetClientCertificate = func(requestInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) {
cert := clientCertificateManager.Current()
if cert == nil {
return &tls.Certificate{Certificate: nil}, nil
}
return cert, nil
}

lastCertAvailable := time.Now()
lastCert := clientCertificateManager.Current()
go wait.Until(func() {
curr := clientCertificateManager.Current()

if exitAfter > 0 {
now := time.Now()
if curr == nil {
// the certificate has been deleted from disk or is otherwise corrupt
if now.After(lastCertAvailable.Add(exitAfter)) {
if clientCertificateManager.ServerHealthy() {
glog.Fatalf("It has been %s since a valid client cert was found and the server is responsive, exiting.", exitAfter)
} else {
glog.Errorf("It has been %s since a valid client cert was found, but the server is not responsive. A restart may be necessary to retrieve new initial credentials.", exitAfter)
}
lastCertAvailable := time.Now()
lastCert := clientCertificateManager.Current()
go wait.Until(func() {
curr := clientCertificateManager.Current()

if exitAfter > 0 {
now := time.Now()
if curr == nil {
// the certificate has been deleted from disk or is otherwise corrupt
if now.After(lastCertAvailable.Add(exitAfter)) {
if clientCertificateManager.ServerHealthy() {
glog.Fatalf("It has been %s since a valid client cert was found and the server is responsive, exiting.", exitAfter)
} else {
glog.Errorf("It has been %s since a valid client cert was found, but the server is not responsive. A restart may be necessary to retrieve new initial credentials.", exitAfter)
}
} else {
// the certificate is expired
if now.After(curr.Leaf.NotAfter) {
if clientCertificateManager.ServerHealthy() {
glog.Fatalf("The currently active client certificate has expired and the server is responsive, exiting.")
} else {
glog.Errorf("The currently active client certificate has expired, but the server is not responsive. A restart may be necessary to retrieve new initial credentials.")
}
}
} else {
// the certificate is expired
if now.After(curr.Leaf.NotAfter) {
if clientCertificateManager.ServerHealthy() {
glog.Fatalf("The currently active client certificate has expired and the server is responsive, exiting.")
} else {
glog.Errorf("The currently active client certificate has expired, but the server is not responsive. A restart may be necessary to retrieve new initial credentials.")
}
lastCertAvailable = now
}
lastCertAvailable = now
}
}

if curr == nil || lastCert == curr {
// Cert hasn't been rotated.
return
}
lastCert = curr

glog.Infof("certificate rotation detected, shutting down client connections to start using new credentials")
// The cert has been rotated. Close all existing connections to force the client
// to reperform its TLS handshake with new cert.
//
// See: https://github.com/kubernetes-incubator/bootkube/pull/663#issuecomment-318506493
d.CloseAll()
}, period, stopCh)
}
if curr == nil || lastCert == curr {
// Cert hasn't been rotated.
return
}
lastCert = curr

glog.Infof("certificate rotation detected, shutting down client connections to start using new credentials")
// The cert has been rotated. Close all existing connections to force the client
// to reperform its TLS handshake with new cert.
//
// See: https://github.com/kubernetes-incubator/bootkube/pull/663#issuecomment-318506493
d.CloseAll()
}, period, stopCh)

clientConfig.Transport = utilnet.SetTransportDefaults(&http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: tlsConfig,
MaxIdleConnsPerHost: 25,
DialContext: d.DialContext, // Use custom dialer.
DialContext: d.DialContext,
})

// Zero out all existing TLS options since our new transport enforces them.
Expand All @@ -144,5 +154,5 @@ func updateTransport(stopCh <-chan struct{}, period time.Duration, clientConfig
clientConfig.CAFile = ""
clientConfig.Insecure = false

return d.CloseAll, nil
return nil
}
18 changes: 4 additions & 14 deletions staging/src/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -178,21 +179,10 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error {
return &roundTripper{a, rt}
}

getCert := c.TLS.GetCert
c.TLS.GetCert = func() (*tls.Certificate, error) {
// If previous GetCert is present and returns a valid non-nil
// certificate, use that. Otherwise use cert from exec plugin.
if getCert != nil {
cert, err := getCert()
if err != nil {
return nil, err
}
if cert != nil {
return cert, nil
}
}
return a.cert()
if c.TLS.GetCert != nil {
return errors.New("can't add TLS certificate callback: transport.Config.TLS.GetCert already set")
}
c.TLS.GetCert = a.cert

var dial func(ctx context.Context, network, addr string) (net.Conn, error)
if c.Dial != nil {
Expand Down

0 comments on commit 7755525

Please sign in to comment.