mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-28 16:07:29 +00:00
When bootstrapping a client cert, store it with other client certs
The kubelet uses two different locations to store certificates on initial bootstrap and then on subsequent rotation: * bootstrap: certDir/kubelet-client.(crt|key) * rotation: certDir/kubelet-client-(DATE|current).pem Bootstrap also creates an initial node.kubeconfig that points to the certs. Unfortunately, with short rotation the node.kubeconfig then becomes out of date because it points to the initial cert/key, not the rotated cert key. Alter the bootstrap code to store client certs exactly as if they would be rotated (using the same cert Store code), and reference the PEM file containing cert/key from node.kubeconfig, which is supported by kubectl and other Go tooling. This ensures that the node.kubeconfig continues to be valid past the first expiration. Kubernetes-commit: 368959346af6e06085c63a4cc7c37839f262f636
This commit is contained in:
parent
7455e67b76
commit
caf2e70aa1
@ -17,7 +17,11 @@ limitations under the License.
|
||||
package cert
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -101,6 +105,27 @@ func LoadOrGenerateKeyFile(keyPath string) (data []byte, wasGenerated bool, err
|
||||
return generatedData, true, nil
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyToPEM converts a known private key type of RSA or ECDSA to
|
||||
// a PEM encoded block or returns an error.
|
||||
func MarshalPrivateKeyToPEM(privateKey crypto.PrivateKey) ([]byte, error) {
|
||||
switch t := privateKey.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
derBytes, err := x509.MarshalECPrivateKey(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
privateKeyPemBlock := &pem.Block{
|
||||
Type: ECPrivateKeyBlockType,
|
||||
Bytes: derBytes,
|
||||
}
|
||||
return pem.EncodeToMemory(privateKeyPemBlock), nil
|
||||
case *rsa.PrivateKey:
|
||||
return EncodePrivateKeyPEM(t), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("private key is not a recognized type: %T", privateKey)
|
||||
}
|
||||
}
|
||||
|
||||
// NewPool returns an x509.CertPool containing the certificates in the given PEM-encoded file.
|
||||
// Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
|
||||
func NewPool(filename string) (*x509.CertPool, error) {
|
||||
|
@ -46,6 +46,15 @@ type fileStore struct {
|
||||
keyFile string
|
||||
}
|
||||
|
||||
// FileStore is a store that provides certificate retrieval as well as
|
||||
// the path on disk of the current PEM.
|
||||
type FileStore interface {
|
||||
Store
|
||||
// CurrentPath returns the path on disk of the current certificate/key
|
||||
// pair encoded as PEM files.
|
||||
CurrentPath() string
|
||||
}
|
||||
|
||||
// NewFileStore returns a concrete implementation of a Store that is based on
|
||||
// storing the cert/key pairs in a single file per pair on disk in the
|
||||
// designated directory. When starting up it will look for the currently
|
||||
@ -64,7 +73,7 @@ func NewFileStore(
|
||||
certDirectory string,
|
||||
keyDirectory string,
|
||||
certFile string,
|
||||
keyFile string) (Store, error) {
|
||||
keyFile string) (FileStore, error) {
|
||||
|
||||
s := fileStore{
|
||||
pairNamePrefix: pairNamePrefix,
|
||||
@ -79,6 +88,11 @@ func NewFileStore(
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
// CurrentPath returns the path to the current version of these certificates.
|
||||
func (s *fileStore) CurrentPath() string {
|
||||
return filepath.Join(s.certDirectory, s.filename(currentPair))
|
||||
}
|
||||
|
||||
// recover checks if there is a certificate rotation that was interrupted while
|
||||
// progress, and if so, attempts to recover to a good state.
|
||||
func (s *fileStore) recover() error {
|
||||
|
Loading…
Reference in New Issue
Block a user