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

@ -97,10 +97,7 @@ func NewDynamicCAFromConfigMapController(purpose, namespace, name, key string, k
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("DynamicConfigMapCABundle-%s", purpose)),
preRunCaches: []cache.InformerSynced{uncastConfigmapInformer.HasSynced},
}
if err := c.loadCABundle(); err != nil {
// don't fail, but do print out a message
klog.Warningf("unable to load initial CA bundle for: %q due to: %s", c.name, err)
}
uncastConfigmapInformer.AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: func(obj interface{}) bool {
if cast, ok := obj.(*corev1.ConfigMap); ok {
@ -217,7 +214,7 @@ func (c *ConfigMapCAController) Run(workers int, stopCh <-chan struct{}) {
go wait.Until(c.runWorker, time.Second, stopCh)
// start timer that rechecks every minute, just in case. this also serves to prime the controller quickly.
_ = wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
go wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
c.queue.Add(workItemKey)
return false, nil
}, stopCh)

View file

@ -126,6 +126,7 @@ func (c *DynamicFileCAContent) loadCABundle() error {
return err
}
c.caBundle.Store(caBundleAndVerifier)
klog.V(2).Infof("Loaded a new CA Bundle and Verifier for %q", c.Name())
for _, listener := range c.listeners {
listener.Enqueue()
@ -170,7 +171,7 @@ func (c *DynamicFileCAContent) Run(workers int, stopCh <-chan struct{}) {
go wait.Until(c.runWorker, time.Second, stopCh)
// start timer that rechecks every minute, just in case. this also serves to prime the controller quickly.
_ = wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
go wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
c.queue.Add(workItemKey)
return false, nil
}, stopCh)

View file

@ -29,8 +29,8 @@ import (
"k8s.io/klog"
)
// DynamicFileServingContent provides a CertKeyContentProvider that can dynamically react to new file content
type DynamicFileServingContent struct {
// DynamicCertKeyPairContent provides a CertKeyContentProvider that can dynamically react to new file content
type DynamicCertKeyPairContent struct {
name string
// certFile is the name of the certificate file to read.
@ -39,7 +39,7 @@ type DynamicFileServingContent struct {
keyFile string
// servingCert is a certKeyContent that contains the last read, non-zero length content of the key and cert
servingCert atomic.Value
certKeyPair atomic.Value
listeners []Listener
@ -47,24 +47,24 @@ type DynamicFileServingContent struct {
queue workqueue.RateLimitingInterface
}
var _ Notifier = &DynamicFileServingContent{}
var _ CertKeyContentProvider = &DynamicFileServingContent{}
var _ ControllerRunner = &DynamicFileServingContent{}
var _ Notifier = &DynamicCertKeyPairContent{}
var _ CertKeyContentProvider = &DynamicCertKeyPairContent{}
var _ ControllerRunner = &DynamicCertKeyPairContent{}
// NewDynamicServingContentFromFiles returns a dynamic CertKeyContentProvider based on a cert and key filename
func NewDynamicServingContentFromFiles(purpose, certFile, keyFile string) (*DynamicFileServingContent, error) {
func NewDynamicServingContentFromFiles(purpose, certFile, keyFile string) (*DynamicCertKeyPairContent, error) {
if len(certFile) == 0 || len(keyFile) == 0 {
return nil, fmt.Errorf("missing filename for serving cert")
}
name := fmt.Sprintf("%s::%s::%s", purpose, certFile, keyFile)
ret := &DynamicFileServingContent{
ret := &DynamicCertKeyPairContent{
name: name,
certFile: certFile,
keyFile: keyFile,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("DynamicCABundle-%s", purpose)),
}
if err := ret.loadServingCert(); err != nil {
if err := ret.loadCertKeyPair(); err != nil {
return nil, err
}
@ -72,12 +72,12 @@ func NewDynamicServingContentFromFiles(purpose, certFile, keyFile string) (*Dyna
}
// AddListener adds a listener to be notified when the serving cert content changes.
func (c *DynamicFileServingContent) AddListener(listener Listener) {
func (c *DynamicCertKeyPairContent) AddListener(listener Listener) {
c.listeners = append(c.listeners, listener)
}
// loadServingCert determines the next set of content for the file.
func (c *DynamicFileServingContent) loadServingCert() error {
func (c *DynamicCertKeyPairContent) loadCertKeyPair() error {
cert, err := ioutil.ReadFile(c.certFile)
if err != nil {
return err
@ -102,12 +102,13 @@ func (c *DynamicFileServingContent) loadServingCert() error {
}
// check to see if we have a change. If the values are the same, do nothing.
existing, ok := c.servingCert.Load().(*certKeyContent)
existing, ok := c.certKeyPair.Load().(*certKeyContent)
if ok && existing != nil && existing.Equal(newCertKey) {
return nil
}
c.servingCert.Store(newCertKey)
c.certKeyPair.Store(newCertKey)
klog.V(2).Infof("Loaded a new cert/key pair for %q", c.Name())
for _, listener := range c.listeners {
listener.Enqueue()
@ -117,12 +118,12 @@ func (c *DynamicFileServingContent) loadServingCert() error {
}
// RunOnce runs a single sync loop
func (c *DynamicFileServingContent) RunOnce() error {
return c.loadServingCert()
func (c *DynamicCertKeyPairContent) RunOnce() error {
return c.loadCertKeyPair()
}
// Run starts the controller and blocks until stopCh is closed.
func (c *DynamicFileServingContent) Run(workers int, stopCh <-chan struct{}) {
func (c *DynamicCertKeyPairContent) Run(workers int, stopCh <-chan struct{}) {
defer utilruntime.HandleCrash()
defer c.queue.ShutDown()
@ -133,7 +134,7 @@ func (c *DynamicFileServingContent) Run(workers int, stopCh <-chan struct{}) {
go wait.Until(c.runWorker, time.Second, stopCh)
// start timer that rechecks every minute, just in case. this also serves to prime the controller quickly.
_ = wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
go wait.PollImmediateUntil(FileRefreshDuration, func() (bool, error) {
c.queue.Add(workItemKey)
return false, nil
}, stopCh)
@ -143,19 +144,19 @@ func (c *DynamicFileServingContent) Run(workers int, stopCh <-chan struct{}) {
<-stopCh
}
func (c *DynamicFileServingContent) runWorker() {
func (c *DynamicCertKeyPairContent) runWorker() {
for c.processNextWorkItem() {
}
}
func (c *DynamicFileServingContent) processNextWorkItem() bool {
func (c *DynamicCertKeyPairContent) processNextWorkItem() bool {
dsKey, quit := c.queue.Get()
if quit {
return false
}
defer c.queue.Done(dsKey)
err := c.loadServingCert()
err := c.loadCertKeyPair()
if err == nil {
c.queue.Forget(dsKey)
return true
@ -168,12 +169,12 @@ func (c *DynamicFileServingContent) processNextWorkItem() bool {
}
// Name is just an identifier
func (c *DynamicFileServingContent) Name() string {
func (c *DynamicCertKeyPairContent) Name() string {
return c.name
}
// CurrentCertKeyContent provides serving cert byte content
func (c *DynamicFileServingContent) CurrentCertKeyContent() ([]byte, []byte) {
certKeyContent := c.servingCert.Load().(*certKeyContent)
// CurrentCertKeyContent provides cert and key byte content
func (c *DynamicCertKeyPairContent) CurrentCertKeyContent() ([]byte, []byte) {
certKeyContent := c.certKeyPair.Load().(*certKeyContent)
return certKeyContent.cert, certKeyContent.key
}

View file

@ -18,7 +18,7 @@ package dynamiccertificates
// DynamicFileSNIContent provides a SNICertKeyContentProvider that can dynamically react to new file content
type DynamicFileSNIContent struct {
*DynamicFileServingContent
*DynamicCertKeyPairContent
sniNames []string
}
@ -34,10 +34,10 @@ func NewDynamicSNIContentFromFiles(purpose, certFile, keyFile string, sniNames .
}
ret := &DynamicFileSNIContent{
DynamicFileServingContent: servingContent,
DynamicCertKeyPairContent: servingContent,
sniNames: sniNames,
}
if err := ret.loadServingCert(); err != nil {
if err := ret.loadCertKeyPair(); err != nil {
return nil, err
}

View file

@ -20,9 +20,10 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"strings"
v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/klog"
)
@ -51,7 +52,7 @@ func (c *DynamicServingCertificateController) BuildNamedCertificates(sniCerts []
klog.V(2).Infof("loaded SNI cert [%d/%q]: %s", i, c.sniCerts[i].Name(), GetHumanCertDetail(x509Cert))
if c.eventRecorder != nil {
c.eventRecorder.Eventf(nil, nil, v1.EventTypeWarning, "TLSConfigChanged", "SNICertificateReload", "loaded SNI cert [%d/%q]: %s with explicit names %v", i, c.sniCerts[i].Name(), GetHumanCertDetail(x509Cert), names)
c.eventRecorder.Eventf(&corev1.ObjectReference{Name: c.sniCerts[i].Name()}, nil, corev1.EventTypeWarning, "TLSConfigChanged", "SNICertificateReload", "loaded SNI cert [%d/%q]: %s with explicit names %v", i, c.sniCerts[i].Name(), GetHumanCertDetail(x509Cert), names)
}
if len(names) == 0 {
@ -76,7 +77,10 @@ func getCertificateNames(cert *x509.Certificate) []string {
var names []string
cn := cert.Subject.CommonName
if cn == "*" || len(validation.IsDNS1123Subdomain(strings.TrimPrefix(cn, "*."))) == 0 {
cnIsIP := net.ParseIP(cn) != nil
cnIsValidDomain := cn == "*" || len(validation.IsDNS1123Subdomain(strings.TrimPrefix(cn, "*."))) == 0
// don't use the CN if it is a valid IP because our IP serving detection may unexpectedly use it to terminate the connection.
if !cnIsIP && cnIsValidDomain {
names = append(names, cn)
}
for _, san := range cert.DNSNames {

View file

@ -19,8 +19,6 @@ package dynamiccertificates
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
)
type staticCAContent struct {
@ -30,19 +28,6 @@ type staticCAContent struct {
var _ CAContentProvider = &staticCAContent{}
// NewStaticCAContentFromFile returns a CAContentProvider based on a filename
func NewStaticCAContentFromFile(filename string) (CAContentProvider, error) {
if len(filename) == 0 {
return nil, fmt.Errorf("missing filename for ca bundle")
}
caBundle, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewStaticCAContent(filename, caBundle)
}
// NewStaticCAContent returns a CAContentProvider that always returns the same value
func NewStaticCAContent(name string, caBundle []byte) (CAContentProvider, error) {
caBundleAndVerifier, err := newCABundleAndVerifier(name, caBundle)
@ -81,48 +66,6 @@ type staticSNICertKeyContent struct {
sniNames []string
}
// NewStaticCertKeyContentFromFiles returns a CertKeyContentProvider based on a filename
func NewStaticCertKeyContentFromFiles(certFile, keyFile string) (CertKeyContentProvider, error) {
if len(certFile) == 0 {
return nil, fmt.Errorf("missing filename for certificate")
}
if len(keyFile) == 0 {
return nil, fmt.Errorf("missing filename for key")
}
certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
}
keyPEMBlock, err := ioutil.ReadFile(keyFile)
if err != nil {
return nil, err
}
return NewStaticCertKeyContent(fmt.Sprintf("cert: %s, key: %s", certFile, keyFile), certPEMBlock, keyPEMBlock)
}
// NewStaticSNICertKeyContentFromFiles returns a SNICertKeyContentProvider based on a filename
func NewStaticSNICertKeyContentFromFiles(certFile, keyFile string, sniNames ...string) (SNICertKeyContentProvider, error) {
if len(certFile) == 0 {
return nil, fmt.Errorf("missing filename for certificate")
}
if len(keyFile) == 0 {
return nil, fmt.Errorf("missing filename for key")
}
certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
}
keyPEMBlock, err := ioutil.ReadFile(keyFile)
if err != nil {
return nil, err
}
return NewStaticSNICertKeyContent(fmt.Sprintf("cert: %s, key: %s", certFile, keyFile), certPEMBlock, keyPEMBlock, sniNames...)
}
// NewStaticCertKeyContent returns a CertKeyContentProvider that always returns the same value
func NewStaticCertKeyContent(name string, cert, key []byte) (CertKeyContentProvider, error) {
// Ensure that the key matches the cert and both are valid

View file

@ -21,11 +21,11 @@ import (
"crypto/x509"
"errors"
"fmt"
"net"
"sync/atomic"
"time"
v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/events"
@ -40,7 +40,7 @@ const workItemKey = "key"
type DynamicServingCertificateController struct {
// baseTLSConfig is the static portion of the tlsConfig for serving to clients. It is copied and the copy is mutated
// based on the dynamic cert state.
baseTLSConfig tls.Config
baseTLSConfig *tls.Config
// clientCA provides the very latest content of the ca bundle
clientCA CAContentProvider
@ -64,7 +64,7 @@ var _ Listener = &DynamicServingCertificateController{}
// NewDynamicServingCertificateController returns a controller that can be used to keep a TLSConfig up to date.
func NewDynamicServingCertificateController(
baseTLSConfig tls.Config,
baseTLSConfig *tls.Config,
clientCA CAContentProvider,
servingCert CertKeyContentProvider,
sniCerts []SNICertKeyContentProvider,
@ -94,7 +94,28 @@ func (c *DynamicServingCertificateController) GetConfigForClient(clientHello *tl
return nil, errors.New("dynamiccertificates: unexpected config type")
}
return tlsConfig.Clone(), nil
tlsConfigCopy := tlsConfig.Clone()
// if the client set SNI information, just use our "normal" SNI flow
if len(clientHello.ServerName) > 0 {
return tlsConfigCopy, nil
}
// if the client didn't set SNI, then we need to inspect the requested IP so that we can choose
// a certificate from our list if we specifically handle that IP. This can happen when an IP is specifically mapped by name.
host, _, err := net.SplitHostPort(clientHello.Conn.LocalAddr().String())
if err != nil {
return tlsConfigCopy, nil
}
ipCert, ok := tlsConfigCopy.NameToCertificate[host]
if !ok {
return tlsConfigCopy, nil
}
tlsConfigCopy.Certificates = []tls.Certificate{*ipCert}
tlsConfigCopy.NameToCertificate = nil
return tlsConfigCopy, nil
}
// newTLSContent determines the next set of content for overriding the baseTLSConfig.
@ -156,7 +177,7 @@ func (c *DynamicServingCertificateController) syncCerts() error {
for i, cert := range newClientCAs {
klog.V(2).Infof("loaded client CA [%d/%q]: %s", i, c.clientCA.Name(), GetHumanCertDetail(cert))
if c.eventRecorder != nil {
c.eventRecorder.Eventf(nil, nil, v1.EventTypeWarning, "TLSConfigChanged", "CACertificateReload", "loaded client CA [%d/%q]: %s", i, c.clientCA.Name(), GetHumanCertDetail(cert))
c.eventRecorder.Eventf(&corev1.ObjectReference{Name: c.clientCA.Name()}, nil, corev1.EventTypeWarning, "TLSConfigChanged", "CACertificateReload", "loaded client CA [%d/%q]: %s", i, c.clientCA.Name(), GetHumanCertDetail(cert))
}
newClientCAPool.AddCert(cert)
@ -178,7 +199,7 @@ func (c *DynamicServingCertificateController) syncCerts() error {
klog.V(2).Infof("loaded serving cert [%q]: %s", c.servingCert.Name(), GetHumanCertDetail(x509Cert))
if c.eventRecorder != nil {
c.eventRecorder.Eventf(nil, nil, v1.EventTypeWarning, "TLSConfigChanged", "ServingCertificateReload", "loaded serving cert [%q]: %s", c.clientCA.Name(), GetHumanCertDetail(x509Cert))
c.eventRecorder.Eventf(&corev1.ObjectReference{Name: c.servingCert.Name()}, nil, corev1.EventTypeWarning, "TLSConfigChanged", "ServingCertificateReload", "loaded serving cert [%q]: %s", c.servingCert.Name(), GetHumanCertDetail(x509Cert))
}
newTLSConfigCopy.Certificates = []tls.Certificate{cert}