Skip to content

Commit

Permalink
Finish init command
Browse files Browse the repository at this point in the history
  • Loading branch information
stgleb committed Apr 18, 2019
1 parent e8a6804 commit 74fddc1
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 13 deletions.
1 change: 1 addition & 0 deletions cmd/kubeadm/app/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command {
initRunner.AppendPhase(phases.NewEtcdPhase())
initRunner.AppendPhase(phases.NewWaitControlPlanePhase())
initRunner.AppendPhase(phases.NewKubeletServerCertAndKey())
initRunner.AppendPhase(phases.NewKubeletStartPhase())
initRunner.AppendPhase(phases.NewUploadConfigPhase())
initRunner.AppendPhase(phases.NewUploadCertsPhase())
initRunner.AppendPhase(phases.NewMarkControlPlanePhase())
Expand Down
8 changes: 7 additions & 1 deletion cmd/kubeadm/app/cmd/phases/init/kubelet_server.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package phases

import (
"fmt"
"path/filepath"

"github.com/pkg/errors"
certutil "k8s.io/client-go/util/cert"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeletserver"
"k8s.io/kubernetes/staging/src/k8s.io/client-go/util/keyutil"

kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
"k8s.io/kubernetes/pkg/util/normalizer"
Expand Down Expand Up @@ -40,18 +42,22 @@ func NewKubeletServerCertAndKey() workflow.Phase {

// runKubeletStart executes kubelet start logic.
func kubeletServerCerts(c workflow.RunData) error {
fmt.Println("[kubelet-server] Generate kubelet server certificates")
data, ok := c.(InitData)
if !ok {
return errors.New("kubelet-start phase invoked with an invalid data struct")
}

data.Cfg().ComponentConfigs.Kubelet.TLSCertFile = kubeadmapiv1beta1.DefaultKubeletServerCertFileName
data.Cfg().ComponentConfigs.Kubelet.TLSPrivateKeyFile = kubeadmapiv1beta1.DefaultKubeletServerKeyFileName

kubeClient, err := data.Client()

if err != nil {
return errors.Wrap(err, "error getting kubernets client")
}

certDataPem, keyDataPem, err := kubeletserver.KubeletServerCert(kubeClient, data.Cfg().NodeRegistration)
certDataPem, keyDataPem, err := kubeletserver.KubeletServerCert(kubeClient, data.Cfg().LocalAPIEndpoint, data.Cfg().NodeRegistration)

if err != nil {
return errors.Wrap(err, "init phase kubelet server cert")
Expand Down
16 changes: 10 additions & 6 deletions cmd/kubeadm/app/phases/kubelet/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ type kubeletFlagsOpts struct {
nodeRegOpts *kubeadmapi.NodeRegistrationOptions
featureGates map[string]bool
pauseImage string
tlsPrivateKey string
tlsCert string
tlsPrivateKey string
certDir string
tlsCert string
registerTaintsUsingFlags bool
execer utilsexec.Interface
pidOfFunc func(string) ([]int, error)
Expand All @@ -62,8 +63,9 @@ func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.ClusterConfiguration, nodeReg *k
execer: utilsexec.New(),
pidOfFunc: procfs.PidOf,
defaultHostname: hostName,
tlsPrivateKey: cfg.ComponentConfigs.Kubelet.TLSPrivateKeyFile,
tlsCert: cfg.ComponentConfigs.Kubelet.TLSCertFile,
tlsPrivateKey: cfg.ComponentConfigs.Kubelet.TLSPrivateKeyFile,
tlsCert: cfg.ComponentConfigs.Kubelet.TLSCertFile,
certDir: cfg.CertificatesDir,
}
stringMap := buildKubeletArgMap(flagOpts)
argList := kubeadmutil.BuildArgumentListFromMap(stringMap, nodeReg.KubeletExtraArgs)
Expand Down Expand Up @@ -114,8 +116,10 @@ func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string {
kubeletFlags["hostname-override"] = opts.nodeRegOpts.Name
}

kubeletFlags["tls-private-key-file"] = opts.tlsPrivateKey
kubeletFlags["tls-cert-file"] = opts.tlsCert
if opts.tlsPrivateKey != "" && opts.tlsCert != "" {
kubeletFlags["tls-private-key-file"] = filepath.Join(opts.certDir, opts.tlsPrivateKey)
kubeletFlags["tls-cert-file"] = filepath.Join(opts.certDir, opts.tlsCert)
}
// TODO: Conditionally set `--cgroup-driver` to either `systemd` or `cgroupfs` for CRI other than Docker

return kubeletFlags
Expand Down
45 changes: 42 additions & 3 deletions cmd/kubeadm/app/phases/kubeletserver/kubelet_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ package kubeletserver

import (
"bytes"
"crypto/x509"
"encoding/pem"
"fmt"
"net"
"time"

"github.com/pkg/errors"
certificates "k8s.io/api/certificates/v1beta1"
certs "k8s.io/api/certificates/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
certutil "k8s.io/client-go/util/cert"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
"k8s.io/kubernetes/staging/src/k8s.io/client-go/util/keyutil"
)
Expand All @@ -18,10 +24,22 @@ const (
CertificateRequestBlockType = "CERTIFICATE REQUEST"
)

func KubeletServerCert(kubeClient kubernetes.Interface, nodeRegistration kubeadm.NodeRegistrationOptions) ([]byte, []byte, error) {
var (
approveTimeout = time.Second * 30
)

func KubeletServerCert(kubeClient kubernetes.Interface, localEndpoint kubeadmapi.APIEndpoint, nodeRegistration kubeadm.NodeRegistrationOptions) ([]byte, []byte, error) {
altNames, err := getAltNames(localEndpoint, nodeRegistration)

if err != nil {
return nil, nil, err
}

csr, key, err := pkiutil.NewCSRAndKey(
&certutil.Config{
CommonName: "kubelet-worker",
CommonName: nodeRegistration.Name,
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
AltNames: *altNames,
})

block := &pem.Block{
Expand All @@ -42,7 +60,6 @@ func KubeletServerCert(kubeClient kubernetes.Interface, nodeRegistration kubeadm
}

certReq.Name = nodeRegistration.Name

req, err := kubeClient.CertificatesV1beta1().CertificateSigningRequests().Create(certReq)

if err != nil {
Expand All @@ -59,6 +76,10 @@ func KubeletServerCert(kubeClient kubernetes.Interface, nodeRegistration kubeadm
return nil, nil, errors.Wrap(err, "error getting approving certificate signing request")
}

// We need to wait some time before certificate request gets approved
fmt.Printf("[kubelet-server] Wait for certificate approve %s\n", approveTimeout)
time.Sleep(approveTimeout)

req, err = kubeClient.CertificatesV1beta1().CertificateSigningRequests().Get(req.Name, v1.GetOptions{})

if err != nil {
Expand All @@ -74,3 +95,21 @@ func KubeletServerCert(kubeClient kubernetes.Interface, nodeRegistration kubeadm

return certPem, keyPem, err
}

// getAltNames builds an AltNames object with the cfg and certName.
func getAltNames(endpoint kubeadmapi.APIEndpoint, nodeRegistration kubeadmapi.NodeRegistrationOptions) (*certutil.AltNames, error) {
// advertise address
advertiseAddress := net.ParseIP(endpoint.AdvertiseAddress)
if advertiseAddress == nil {
return nil, errors.Errorf("error parsing LocalAPIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address",
endpoint.AdvertiseAddress)
}

// create AltNames with defaults DNSNames/IPs
altNames := &certutil.AltNames{
DNSNames: []string{nodeRegistration.Name, "localhost"},
IPs: []net.IP{advertiseAddress, net.IPv4(127, 0, 0, 1), net.IPv6loopback},
}

return altNames, nil
}
3 changes: 0 additions & 3 deletions cmd/kubeadm/app/util/config/initconfiguration.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,6 @@ func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration, advertiseAd
cfg.ComponentConfigs.KubeProxy.BindAddress = kubeadmapiv1beta1.DefaultProxyBindAddressv6
}

cfg.ComponentConfigs.Kubelet.TLSCertFile = kubeadmapiv1beta1.DefaultKubeletServerCertFileName
cfg.ComponentConfigs.Kubelet.TLSPrivateKeyFile = kubeadmapiv1beta1.DefaultKubeletServerKeyFileName

// Resolve possible version labels and validate version string
if err := NormalizeKubernetesVersion(cfg); err != nil {
return err
Expand Down

0 comments on commit 74fddc1

Please sign in to comment.