diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index c3c12491625..219c4e742f5 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -148,6 +148,7 @@ type NodeConfiguration struct { FeatureGates map[string]bool } +// KubeletConfiguration contains elements describing initial remote configuration of kubelet type KubeletConfiguration struct { BaseConfig *kubeletconfigv1alpha1.KubeletConfiguration } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go index bb0099d7b2e..7227562a419 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go @@ -23,6 +23,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubernetes/cmd/kubeadm/app/constants" + kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1" + utilpointer "k8s.io/kubernetes/pkg/util/pointer" ) const ( @@ -146,3 +148,28 @@ func SetDefaultsEtcdSelfHosted(obj *MasterConfiguration) { obj.Etcd.SelfHosted.CertificatesDir = DefaultEtcdCertDir } } + +// SetDefaults_KubeletConfiguration assigns default values to kubelet +func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { + if obj.BaseConfig.PodManifestPath == "" { + obj.BaseConfig.PodManifestPath = DefaultManifestsDir + } + if obj.BaseConfig.AllowPrivileged == nil { + obj.BaseConfig.AllowPrivileged = utilpointer.BoolPtr(true) + } + if obj.BaseConfig.ClusterDNS == nil { + obj.BaseConfig.ClusterDNS = []string{DefaultClusterDNSIP} + } + if obj.BaseConfig.ClusterDomain == "" { + obj.BaseConfig.ClusterDomain = DefaultServiceDNSDomain + } + if obj.BaseConfig.Authorization.Mode == "" { + obj.BaseConfig.Authorization.Mode = kubeletconfigv1alpha1.KubeletAuthorizationModeWebhook + } + if obj.BaseConfig.Authentication.X509.ClientCAFile == "" { + obj.BaseConfig.Authentication.X509.ClientCAFile = DefaultCACertPath + } + if obj.BaseConfig.CAdvisorPort == nil { + obj.BaseConfig.CAdvisorPort = utilpointer.Int32Ptr(0) + } +} diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go index 71c780f371f..8bfd5a6349d 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go @@ -142,8 +142,9 @@ type NodeConfiguration struct { FeatureGates map[string]bool `json:"featureGates,omitempty"` } +// KubeletConfiguration contains elements describing initial remote configuration of kubelet type KubeletConfiguration struct { - BaseConfig *kubeletconfigv1alpha1.KubeletConfiguration + BaseConfig *kubeletconfigv1alpha1.KubeletConfiguration `json:"baseConfig"` } // HostPathMount contains elements describing volumes that are mounted from the diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 8e554fb5354..a41660ae5be 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -26,7 +26,6 @@ import ( "text/template" "time" - "github.com/ghodss/yaml" "github.com/renstrom/dedent" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -64,8 +63,8 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin" "k8s.io/kubernetes/pkg/api/legacyscheme" rbachelper "k8s.io/kubernetes/pkg/apis/rbac/v1" + kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme" kubeletconfigv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1alpha1" - utilpointer "k8s.io/kubernetes/pkg/util/pointer" utilsexec "k8s.io/utils/exec" ) @@ -350,45 +349,27 @@ func (i *Init) Run(out io.Writer) error { return fmt.Errorf("error creating client: %v", err) } + // NOTE: flag "--dynamic-config-dir" should be specified in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf if features.Enabled(i.cfg.FeatureGates, features.DynamicKubeletConfig) { - // NOTE: flag "--dynamic-config-dir" should be specified in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf - kubeletCfg := &kubeadmapi.KubeletConfiguration{ - BaseConfig: &kubeletconfigv1alpha1.KubeletConfiguration{ - PodManifestPath: kubeadmapiext.DefaultManifestsDir, - AllowPrivileged: utilpointer.BoolPtr(true), - ClusterDNS: []string{kubeadmapiext.DefaultClusterDNSIP}, - ClusterDomain: kubeadmapiext.DefaultServiceDNSDomain, - Authorization: kubeletconfigv1alpha1.KubeletAuthorization{ - Mode: kubeletconfigv1alpha1.KubeletAuthorizationModeWebhook, - }, - Authentication: kubeletconfigv1alpha1.KubeletAuthentication{ - X509: kubeletconfigv1alpha1.KubeletX509Authentication{ - ClientCAFile: kubeadmapiext.DefaultCACertPath, - }, - }, - CAdvisorPort: utilpointer.Int32Ptr(0), - }, + _, kubeletCodecs, err := kubeletconfigscheme.NewSchemeAndCodecs() + if err != nil { + return err } - - // Convert cfg to the external version as that's the only version of the API that can be deserialized later - externalKubeletCfg := &kubeadmapiext.KubeletConfiguration{} - legacyscheme.Scheme.Convert(kubeletCfg, externalKubeletCfg, nil) - - kubeletCfgYaml, err := yaml.Marshal(*externalKubeletCfg) + kubeletConfig := &kubeadmapiext.KubeletConfiguration{} + kubeletBytes, err := kubeadmutil.MarshalToYamlForCodecs(kubeletConfig.BaseConfig, kubeletconfigv1alpha1.SchemeGroupVersion, *kubeletCodecs) if err != nil { return err } - err = apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ + if err = apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeletBaseConfigurationConfigMap, Namespace: metav1.NamespaceSystem, }, Data: map[string]string{ - kubeadmconstants.KubeletBaseConfigurationConfigMapKey: string(kubeletCfgYaml), + kubeadmconstants.KubeletBaseConfigurationConfigMapKey: string(kubeletBytes), }, - }) - if err != nil { + }); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index 9f8e4888e95..f01fd0eab61 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -237,8 +237,8 @@ func (j *Join) Run(out io.Writer) error { return err } + // NOTE: flag "--dynamic-config-dir" should be specified in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf if features.Enabled(j.cfg.FeatureGates, features.DynamicKubeletConfig) { - // NOTE: flag "--dynamic-config-dir" should be specified in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf client, err := kubeconfigutil.ClientSetFromFile(kubeadmconstants.GetAdminKubeConfigPath()) if err != nil { return err diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go index f44180da3ac..67281d04732 100644 --- a/cmd/kubeadm/app/util/marshal.go +++ b/cmd/kubeadm/app/util/marshal.go @@ -21,17 +21,23 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" clientsetscheme "k8s.io/client-go/kubernetes/scheme" ) // MarshalToYaml marshals an object into yaml. func MarshalToYaml(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) { + return MarshalToYamlForCodecs(obj, gv, clientsetscheme.Codecs) +} + +// MarshalToYamlForCodecs marshals an object into yaml using the specified codec +func MarshalToYamlForCodecs(obj runtime.Object, gv schema.GroupVersion, codecs serializer.CodecFactory) ([]byte, error) { mediaType := "application/yaml" - info, ok := runtime.SerializerInfoForMediaType(clientsetscheme.Codecs.SupportedMediaTypes(), mediaType) + info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType) if !ok { return []byte{}, fmt.Errorf("unsupported media type %q", mediaType) } - encoder := clientsetscheme.Codecs.EncoderForVersion(info.Serializer, gv) + encoder := codecs.EncoderForVersion(info.Serializer, gv) return runtime.Encode(encoder, obj) }