Create kubernetes CA signed kubelet certificates on activation

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-06-02 15:58:19 +02:00 committed by Daniel Weiße
parent 4d50e4c657
commit 963c6f98e5
7 changed files with 490 additions and 60 deletions

View file

@ -24,15 +24,17 @@ type Server struct {
file file.Handler
joinTokenGetter joinTokenGetter
dataKeyGetter dataKeyGetter
ca certificateAuthority
proto.UnimplementedAPIServer
}
// New initializes a new Server.
func New(fileHandler file.Handler, joinTokenGetter joinTokenGetter, dataKeyGetter dataKeyGetter) *Server {
func New(fileHandler file.Handler, ca certificateAuthority, joinTokenGetter joinTokenGetter, dataKeyGetter dataKeyGetter) *Server {
return &Server{
file: fileHandler,
joinTokenGetter: joinTokenGetter,
dataKeyGetter: dataKeyGetter,
ca: ca,
}
}
@ -59,27 +61,33 @@ func (s *Server) Run(tlsConfig *tls.Config, port string) error {
// - Kubernetes join token.
// - cluster and owner ID to taint the node as initialized.
func (s *Server) ActivateNode(ctx context.Context, req *proto.ActivateNodeRequest) (*proto.ActivateNodeResponse, error) {
klog.V(4).Infof("ActivateNode: loading IDs")
klog.V(4).Info("ActivateNode: loading IDs")
var id id
if err := s.file.ReadJSON(constants.ActivationIDFilename, &id); err != nil {
klog.Errorf("unable to load IDs: %s", err)
return nil, status.Errorf(codes.Internal, "unable to load IDs: %s", err)
}
klog.V(4).Infof("ActivateNode: requesting disk encryption key")
klog.V(4).Info("ActivateNode: requesting disk encryption key")
stateDiskKey, err := s.dataKeyGetter.GetDataKey(ctx, req.DiskUuid, constants.StateDiskKeyLength)
if err != nil {
klog.Errorf("unable to get key for stateful disk: %s", err)
return nil, status.Errorf(codes.Internal, "unable to get key for stateful disk: %s", err)
}
klog.V(4).Infof("ActivateNode: creating Kubernetes join token")
klog.V(4).Info("ActivateNode: creating Kubernetes join token")
kubeArgs, err := s.joinTokenGetter.GetJoinToken(constants.KubernetesJoinTokenTTL)
if err != nil {
klog.Errorf("unable to generate Kubernetes join arguments: %s", err)
return nil, status.Errorf(codes.Internal, "unable to generate Kubernetes join arguments: %s", err)
}
klog.V(4).Info("ActivateNode: creating signed kubelet certificate")
kubeletCert, kubeletKey, err := s.ca.GetCertificate(req.NodeName)
if err != nil {
return nil, status.Errorf(codes.Internal, "unable to generate kubelet certificate: %s", err)
}
klog.V(4).Info("ActivateNode successful")
return &proto.ActivateNodeResponse{
@ -89,6 +97,8 @@ func (s *Server) ActivateNode(ctx context.Context, req *proto.ActivateNodeReques
ApiServerEndpoint: kubeArgs.APIServerEndpoint,
Token: kubeArgs.Token,
DiscoveryTokenCaCertHash: kubeArgs.CACertHashes[0],
KubeletCert: kubeletCert,
KubeletKey: kubeletKey,
}, nil
}
@ -109,6 +119,11 @@ type dataKeyGetter interface {
GetDataKey(ctx context.Context, uuid string, length int) ([]byte, error)
}
type certificateAuthority interface {
// GetCertificate returns a certificate and private key, signed by the issuer.
GetCertificate(nodeName string) (kubeletCert []byte, kubeletKey []byte, err error)
}
type id struct {
Cluster []byte `json:"cluster"`
Owner []byte `json:"owner"`