diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
index 344ffaffb6f8b..9122ec10096ea 100644
--- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
+++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
@@ -98,7 +98,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
 			componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil)
 			componentconfigs.DefaultKubeProxyConfiguration(obj)
 		},
-		func(obj *kubeadm.NodeConfiguration, c fuzz.Continue) {
+		func(obj *kubeadm.JoinConfiguration, c fuzz.Continue) {
 			c.FuzzNoCustom(obj)
 			obj.CACertPath = "foo"
 			obj.DiscoveryFile = "foo"
diff --git a/cmd/kubeadm/app/apis/kubeadm/register.go b/cmd/kubeadm/app/apis/kubeadm/register.go
index 93d0280a36090..e5b84abd16006 100644
--- a/cmd/kubeadm/app/apis/kubeadm/register.go
+++ b/cmd/kubeadm/app/apis/kubeadm/register.go
@@ -47,7 +47,7 @@ func Resource(resource string) schema.GroupResource {
 func addKnownTypes(scheme *runtime.Scheme) error {
 	scheme.AddKnownTypes(SchemeGroupVersion,
 		&InitConfiguration{},
-		&NodeConfiguration{},
+		&JoinConfiguration{},
 	)
 	return nil
 }
diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go
index 971857323ec41..fe8509e20f0d2 100644
--- a/cmd/kubeadm/app/apis/kubeadm/types.go
+++ b/cmd/kubeadm/app/apis/kubeadm/types.go
@@ -253,9 +253,9 @@ type ExternalEtcd struct {
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
-// NodeConfiguration contains elements describing a particular node.
+// JoinConfiguration contains elements describing a particular node.
 // TODO: This struct should be replaced by dynamic kubelet configuration.
-type NodeConfiguration struct {
+type JoinConfiguration struct {
 	metav1.TypeMeta
 
 	// NodeRegistration holds fields that relate to registering the new master node to the cluster
@@ -344,7 +344,7 @@ type AuditPolicyConfiguration struct {
 }
 
 // CommonConfiguration defines the list of common configuration elements and the getter
-// methods that must exist for both the InitConfiguration and NodeConfiguration objects.
+// methods that must exist for both the InitConfiguration and JoinConfiguration objects.
 // This is used internally to deduplicate the kubeadm preflight checks.
 type CommonConfiguration interface {
 	GetCRISocket() string
@@ -370,22 +370,22 @@ func (cfg *InitConfiguration) GetKubernetesVersion() string {
 	return cfg.KubernetesVersion
 }
 
-// GetCRISocket will return the CRISocket that is defined for the NodeConfiguration.
+// GetCRISocket will return the CRISocket that is defined for the JoinConfiguration.
 // This is used internally to deduplicate the kubeadm preflight checks.
-func (cfg *NodeConfiguration) GetCRISocket() string {
+func (cfg *JoinConfiguration) GetCRISocket() string {
 	return cfg.NodeRegistration.CRISocket
 }
 
-// GetNodeName will return the NodeName that is defined for the NodeConfiguration.
+// GetNodeName will return the NodeName that is defined for the JoinConfiguration.
 // This is used internally to deduplicate the kubeadm preflight checks.
-func (cfg *NodeConfiguration) GetNodeName() string {
+func (cfg *JoinConfiguration) GetNodeName() string {
 	return cfg.NodeRegistration.Name
 }
 
 // GetKubernetesVersion will return an empty string since KubernetesVersion is not a
-// defined property for NodeConfiguration. This will just cause the regex validation
+// defined property for JoinConfiguration. This will just cause the regex validation
 // of the defined version to be skipped during the preflight checks.
 // This is used internally to deduplicate the kubeadm preflight checks.
-func (cfg *NodeConfiguration) GetKubernetesVersion() string {
+func (cfg *JoinConfiguration) GetKubernetesVersion() string {
 	return ""
 }
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
index c8a6101d5f13c..c39b8b2d4d7b2 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
@@ -61,7 +61,7 @@ const (
 	// KubeproxyKubeConfigFileName defines the file name for the kube-proxy's KubeConfig file
 	KubeproxyKubeConfigFileName = "/var/lib/kube-proxy/kubeconfig.conf"
 
-	// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the NodeConfiguration)
+	// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the JoinConfiguration)
 	DefaultDiscoveryTimeout = 5 * time.Minute
 )
 
@@ -143,8 +143,8 @@ func SetDefaults_ProxyConfiguration(obj *InitConfiguration) {
 	kubeproxyscheme.Scheme.Default(obj.KubeProxy.Config)
 }
 
-// SetDefaults_NodeConfiguration assigns default values to a regular node
-func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
+// SetDefaults_JoinConfiguration assigns default values to a regular node
+func SetDefaults_JoinConfiguration(obj *JoinConfiguration) {
 	if obj.CACertPath == "" {
 		obj.CACertPath = DefaultCACertPath
 	}
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/register.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/register.go
index 1a36910961fdc..d5cc0bc0d2be0 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/register.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/register.go
@@ -57,10 +57,8 @@ func Resource(resource string) schema.GroupResource {
 }
 
 func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(SchemeGroupVersion,
-		&NodeConfiguration{},
-	)
 	scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("MasterConfiguration"), &InitConfiguration{})
+	scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("NodeConfiguration"), &JoinConfiguration{})
 	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 	return nil
 }
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/types.go
index 2b2f6d6238407..613e66371af23 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/types.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/types.go
@@ -229,9 +229,9 @@ type ExternalEtcd struct {
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
-// NodeConfiguration contains elements describing a particular node.
+// JoinConfiguration contains elements describing a particular node.
 // TODO: This struct should be replaced by dynamic kubelet configuration.
-type NodeConfiguration struct {
+type JoinConfiguration struct {
 	metav1.TypeMeta `json:",inline"`
 
 	// NodeRegistration holds fields that relate to registering the new master node to the cluster
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go
index 90efbf5079027..03a199d5a6059 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go
@@ -54,12 +54,12 @@ func RegisterConversions(scheme *runtime.Scheme) error {
 		Convert_kubeadm_HostPathMount_To_v1alpha2_HostPathMount,
 		Convert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration,
 		Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration,
+		Convert_v1alpha2_JoinConfiguration_To_kubeadm_JoinConfiguration,
+		Convert_kubeadm_JoinConfiguration_To_v1alpha2_JoinConfiguration,
 		Convert_v1alpha2_LocalEtcd_To_kubeadm_LocalEtcd,
 		Convert_kubeadm_LocalEtcd_To_v1alpha2_LocalEtcd,
 		Convert_v1alpha2_Networking_To_kubeadm_Networking,
 		Convert_kubeadm_Networking_To_v1alpha2_Networking,
-		Convert_v1alpha2_NodeConfiguration_To_kubeadm_NodeConfiguration,
-		Convert_kubeadm_NodeConfiguration_To_v1alpha2_NodeConfiguration,
 		Convert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions,
 		Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions,
 	)
@@ -311,6 +311,52 @@ func autoConvert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kub
 	return nil
 }
 
+func autoConvert_v1alpha2_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
+	if err := Convert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
+		return err
+	}
+	out.CACertPath = in.CACertPath
+	out.DiscoveryFile = in.DiscoveryFile
+	out.DiscoveryToken = in.DiscoveryToken
+	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
+	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
+	out.TLSBootstrapToken = in.TLSBootstrapToken
+	out.Token = in.Token
+	out.ClusterName = in.ClusterName
+	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
+	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
+	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
+	return nil
+}
+
+// Convert_v1alpha2_JoinConfiguration_To_kubeadm_JoinConfiguration is an autogenerated conversion function.
+func Convert_v1alpha2_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
+	return autoConvert_v1alpha2_JoinConfiguration_To_kubeadm_JoinConfiguration(in, out, s)
+}
+
+func autoConvert_kubeadm_JoinConfiguration_To_v1alpha2_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
+	if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
+		return err
+	}
+	out.CACertPath = in.CACertPath
+	out.DiscoveryFile = in.DiscoveryFile
+	out.DiscoveryToken = in.DiscoveryToken
+	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
+	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
+	out.TLSBootstrapToken = in.TLSBootstrapToken
+	out.Token = in.Token
+	out.ClusterName = in.ClusterName
+	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
+	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
+	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
+	return nil
+}
+
+// Convert_kubeadm_JoinConfiguration_To_v1alpha2_JoinConfiguration is an autogenerated conversion function.
+func Convert_kubeadm_JoinConfiguration_To_v1alpha2_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
+	return autoConvert_kubeadm_JoinConfiguration_To_v1alpha2_JoinConfiguration(in, out, s)
+}
+
 func autoConvert_v1alpha2_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kubeadm.LocalEtcd, s conversion.Scope) error {
 	out.Image = in.Image
 	out.DataDir = in.DataDir
@@ -363,52 +409,6 @@ func Convert_kubeadm_Networking_To_v1alpha2_Networking(in *kubeadm.Networking, o
 	return autoConvert_kubeadm_Networking_To_v1alpha2_Networking(in, out, s)
 }
 
-func autoConvert_v1alpha2_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
-	if err := Convert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
-		return err
-	}
-	out.CACertPath = in.CACertPath
-	out.DiscoveryFile = in.DiscoveryFile
-	out.DiscoveryToken = in.DiscoveryToken
-	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
-	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
-	out.TLSBootstrapToken = in.TLSBootstrapToken
-	out.Token = in.Token
-	out.ClusterName = in.ClusterName
-	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
-	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
-	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
-	return nil
-}
-
-// Convert_v1alpha2_NodeConfiguration_To_kubeadm_NodeConfiguration is an autogenerated conversion function.
-func Convert_v1alpha2_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
-	return autoConvert_v1alpha2_NodeConfiguration_To_kubeadm_NodeConfiguration(in, out, s)
-}
-
-func autoConvert_kubeadm_NodeConfiguration_To_v1alpha2_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
-	if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
-		return err
-	}
-	out.CACertPath = in.CACertPath
-	out.DiscoveryFile = in.DiscoveryFile
-	out.DiscoveryToken = in.DiscoveryToken
-	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
-	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
-	out.TLSBootstrapToken = in.TLSBootstrapToken
-	out.Token = in.Token
-	out.ClusterName = in.ClusterName
-	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
-	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
-	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
-	return nil
-}
-
-// Convert_kubeadm_NodeConfiguration_To_v1alpha2_NodeConfiguration is an autogenerated conversion function.
-func Convert_kubeadm_NodeConfiguration_To_v1alpha2_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
-	return autoConvert_kubeadm_NodeConfiguration_To_v1alpha2_NodeConfiguration(in, out, s)
-}
-
 func autoConvert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(in *NodeRegistrationOptions, out *kubeadm.NodeRegistrationOptions, s conversion.Scope) error {
 	out.Name = in.Name
 	out.CRISocket = in.CRISocket
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.deepcopy.go
index f69ec802575c8..3d2beaccab535 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.deepcopy.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.deepcopy.go
@@ -271,6 +271,54 @@ func (in *InitConfiguration) DeepCopyObject() runtime.Object {
 	return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JoinConfiguration) DeepCopyInto(out *JoinConfiguration) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
+	if in.DiscoveryTokenAPIServers != nil {
+		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.DiscoveryTimeout != nil {
+		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
+		*out = new(v1.Duration)
+		**out = **in
+	}
+	if in.DiscoveryTokenCACertHashes != nil {
+		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.FeatureGates != nil {
+		in, out := &in.FeatureGates, &out.FeatureGates
+		*out = make(map[string]bool, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinConfiguration.
+func (in *JoinConfiguration) DeepCopy() *JoinConfiguration {
+	if in == nil {
+		return nil
+	}
+	out := new(JoinConfiguration)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *JoinConfiguration) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *KubeProxy) DeepCopyInto(out *KubeProxy) {
 	*out = *in
@@ -362,54 +410,6 @@ func (in *Networking) DeepCopy() *Networking {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
-	if in.DiscoveryTokenAPIServers != nil {
-		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.DiscoveryTimeout != nil {
-		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
-		*out = new(v1.Duration)
-		**out = **in
-	}
-	if in.DiscoveryTokenCACertHashes != nil {
-		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.FeatureGates != nil {
-		in, out := &in.FeatureGates, &out.FeatureGates
-		*out = make(map[string]bool, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeConfiguration.
-func (in *NodeConfiguration) DeepCopy() *NodeConfiguration {
-	if in == nil {
-		return nil
-	}
-	out := new(NodeConfiguration)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *NodeConfiguration) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *NodeRegistrationOptions) DeepCopyInto(out *NodeRegistrationOptions) {
 	*out = *in
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.defaults.go
index e5bdc810d80b3..9a4d6d861e330 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.defaults.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.defaults.go
@@ -31,7 +31,7 @@ import (
 // All generated defaulters are covering - they call all nested defaulters.
 func RegisterDefaults(scheme *runtime.Scheme) error {
 	scheme.AddTypeDefaultingFunc(&InitConfiguration{}, func(obj interface{}) { SetObjectDefaults_InitConfiguration(obj.(*InitConfiguration)) })
-	scheme.AddTypeDefaultingFunc(&NodeConfiguration{}, func(obj interface{}) { SetObjectDefaults_NodeConfiguration(obj.(*NodeConfiguration)) })
+	scheme.AddTypeDefaultingFunc(&JoinConfiguration{}, func(obj interface{}) { SetObjectDefaults_JoinConfiguration(obj.(*JoinConfiguration)) })
 	return nil
 }
 
@@ -50,7 +50,7 @@ func SetObjectDefaults_InitConfiguration(in *InitConfiguration) {
 	}
 }
 
-func SetObjectDefaults_NodeConfiguration(in *NodeConfiguration) {
-	SetDefaults_NodeConfiguration(in)
+func SetObjectDefaults_JoinConfiguration(in *JoinConfiguration) {
+	SetDefaults_JoinConfiguration(in)
 	SetDefaults_NodeRegistrationOptions(&in.NodeRegistration)
 }
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go
index 930cd6fdf9439..9faa837795383 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go
@@ -53,7 +53,7 @@ const (
 	DefaultProxyBindAddressv4 = "0.0.0.0"
 	// DefaultProxyBindAddressv6 is the default bind address when the advertise address is v6
 	DefaultProxyBindAddressv6 = "::"
-	// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the NodeConfiguration)
+	// DefaultDiscoveryTimeout specifies the default discovery timeout for kubeadm (used unless one is specified in the JoinConfiguration)
 	DefaultDiscoveryTimeout = 5 * time.Minute
 )
 
@@ -115,8 +115,8 @@ func SetDefaults_Etcd(obj *InitConfiguration) {
 	}
 }
 
-// SetDefaults_NodeConfiguration assigns default values to a regular node
-func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
+// SetDefaults_JoinConfiguration assigns default values to a regular node
+func SetDefaults_JoinConfiguration(obj *JoinConfiguration) {
 	if obj.CACertPath == "" {
 		obj.CACertPath = DefaultCACertPath
 	}
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go
index 4821f7bd37b76..dd8c4d6279315 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go
@@ -59,7 +59,7 @@ func Resource(resource string) schema.GroupResource {
 func addKnownTypes(scheme *runtime.Scheme) error {
 	scheme.AddKnownTypes(SchemeGroupVersion,
 		&InitConfiguration{},
-		&NodeConfiguration{},
+		&JoinConfiguration{},
 	)
 	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 	return nil
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go
index 5dcbf8d47f439..17442a406e123 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go
@@ -223,9 +223,9 @@ type ExternalEtcd struct {
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
-// NodeConfiguration contains elements describing a particular node.
+// JoinConfiguration contains elements describing a particular node.
 // TODO: This struct should be replaced by dynamic kubelet configuration.
-type NodeConfiguration struct {
+type JoinConfiguration struct {
 	metav1.TypeMeta `json:",inline"`
 
 	// NodeRegistration holds fields that relate to registering the new master node to the cluster
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go
index b54a2758a9a5e..d6953258fdb25 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go
@@ -54,12 +54,12 @@ func RegisterConversions(scheme *runtime.Scheme) error {
 		Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount,
 		Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration,
 		Convert_kubeadm_InitConfiguration_To_v1alpha3_InitConfiguration,
+		Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration,
+		Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration,
 		Convert_v1alpha3_LocalEtcd_To_kubeadm_LocalEtcd,
 		Convert_kubeadm_LocalEtcd_To_v1alpha3_LocalEtcd,
 		Convert_v1alpha3_Networking_To_kubeadm_Networking,
 		Convert_kubeadm_Networking_To_v1alpha3_Networking,
-		Convert_v1alpha3_NodeConfiguration_To_kubeadm_NodeConfiguration,
-		Convert_kubeadm_NodeConfiguration_To_v1alpha3_NodeConfiguration,
 		Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions,
 		Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions,
 	)
@@ -314,6 +314,52 @@ func Convert_kubeadm_InitConfiguration_To_v1alpha3_InitConfiguration(in *kubeadm
 	return autoConvert_kubeadm_InitConfiguration_To_v1alpha3_InitConfiguration(in, out, s)
 }
 
+func autoConvert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
+	if err := Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
+		return err
+	}
+	out.CACertPath = in.CACertPath
+	out.DiscoveryFile = in.DiscoveryFile
+	out.DiscoveryToken = in.DiscoveryToken
+	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
+	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
+	out.TLSBootstrapToken = in.TLSBootstrapToken
+	out.Token = in.Token
+	out.ClusterName = in.ClusterName
+	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
+	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
+	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
+	return nil
+}
+
+// Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration is an autogenerated conversion function.
+func Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
+	return autoConvert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(in, out, s)
+}
+
+func autoConvert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
+	if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
+		return err
+	}
+	out.CACertPath = in.CACertPath
+	out.DiscoveryFile = in.DiscoveryFile
+	out.DiscoveryToken = in.DiscoveryToken
+	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
+	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
+	out.TLSBootstrapToken = in.TLSBootstrapToken
+	out.Token = in.Token
+	out.ClusterName = in.ClusterName
+	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
+	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
+	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
+	return nil
+}
+
+// Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration is an autogenerated conversion function.
+func Convert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error {
+	return autoConvert_kubeadm_JoinConfiguration_To_v1alpha3_JoinConfiguration(in, out, s)
+}
+
 func autoConvert_v1alpha3_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kubeadm.LocalEtcd, s conversion.Scope) error {
 	out.Image = in.Image
 	out.DataDir = in.DataDir
@@ -366,52 +412,6 @@ func Convert_kubeadm_Networking_To_v1alpha3_Networking(in *kubeadm.Networking, o
 	return autoConvert_kubeadm_Networking_To_v1alpha3_Networking(in, out, s)
 }
 
-func autoConvert_v1alpha3_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
-	if err := Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
-		return err
-	}
-	out.CACertPath = in.CACertPath
-	out.DiscoveryFile = in.DiscoveryFile
-	out.DiscoveryToken = in.DiscoveryToken
-	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
-	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
-	out.TLSBootstrapToken = in.TLSBootstrapToken
-	out.Token = in.Token
-	out.ClusterName = in.ClusterName
-	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
-	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
-	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
-	return nil
-}
-
-// Convert_v1alpha3_NodeConfiguration_To_kubeadm_NodeConfiguration is an autogenerated conversion function.
-func Convert_v1alpha3_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
-	return autoConvert_v1alpha3_NodeConfiguration_To_kubeadm_NodeConfiguration(in, out, s)
-}
-
-func autoConvert_kubeadm_NodeConfiguration_To_v1alpha3_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
-	if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
-		return err
-	}
-	out.CACertPath = in.CACertPath
-	out.DiscoveryFile = in.DiscoveryFile
-	out.DiscoveryToken = in.DiscoveryToken
-	out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
-	out.DiscoveryTimeout = (*v1.Duration)(unsafe.Pointer(in.DiscoveryTimeout))
-	out.TLSBootstrapToken = in.TLSBootstrapToken
-	out.Token = in.Token
-	out.ClusterName = in.ClusterName
-	out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
-	out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
-	out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
-	return nil
-}
-
-// Convert_kubeadm_NodeConfiguration_To_v1alpha3_NodeConfiguration is an autogenerated conversion function.
-func Convert_kubeadm_NodeConfiguration_To_v1alpha3_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
-	return autoConvert_kubeadm_NodeConfiguration_To_v1alpha3_NodeConfiguration(in, out, s)
-}
-
 func autoConvert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(in *NodeRegistrationOptions, out *kubeadm.NodeRegistrationOptions, s conversion.Scope) error {
 	out.Name = in.Name
 	out.CRISocket = in.CRISocket
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go
index 76fcaead5d22a..1a4d6c7c14d26 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go
@@ -267,6 +267,54 @@ func (in *InitConfiguration) DeepCopyObject() runtime.Object {
 	return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JoinConfiguration) DeepCopyInto(out *JoinConfiguration) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
+	if in.DiscoveryTokenAPIServers != nil {
+		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.DiscoveryTimeout != nil {
+		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
+		*out = new(v1.Duration)
+		**out = **in
+	}
+	if in.DiscoveryTokenCACertHashes != nil {
+		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.FeatureGates != nil {
+		in, out := &in.FeatureGates, &out.FeatureGates
+		*out = make(map[string]bool, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinConfiguration.
+func (in *JoinConfiguration) DeepCopy() *JoinConfiguration {
+	if in == nil {
+		return nil
+	}
+	out := new(JoinConfiguration)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *JoinConfiguration) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
 	*out = *in
@@ -316,54 +364,6 @@ func (in *Networking) DeepCopy() *Networking {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
-	if in.DiscoveryTokenAPIServers != nil {
-		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.DiscoveryTimeout != nil {
-		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
-		*out = new(v1.Duration)
-		**out = **in
-	}
-	if in.DiscoveryTokenCACertHashes != nil {
-		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.FeatureGates != nil {
-		in, out := &in.FeatureGates, &out.FeatureGates
-		*out = make(map[string]bool, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeConfiguration.
-func (in *NodeConfiguration) DeepCopy() *NodeConfiguration {
-	if in == nil {
-		return nil
-	}
-	out := new(NodeConfiguration)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *NodeConfiguration) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *NodeRegistrationOptions) DeepCopyInto(out *NodeRegistrationOptions) {
 	*out = *in
diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go
index e0fe752478146..e614395b6c32d 100644
--- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go
+++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go
@@ -29,7 +29,7 @@ import (
 // All generated defaulters are covering - they call all nested defaulters.
 func RegisterDefaults(scheme *runtime.Scheme) error {
 	scheme.AddTypeDefaultingFunc(&InitConfiguration{}, func(obj interface{}) { SetObjectDefaults_InitConfiguration(obj.(*InitConfiguration)) })
-	scheme.AddTypeDefaultingFunc(&NodeConfiguration{}, func(obj interface{}) { SetObjectDefaults_NodeConfiguration(obj.(*NodeConfiguration)) })
+	scheme.AddTypeDefaultingFunc(&JoinConfiguration{}, func(obj interface{}) { SetObjectDefaults_JoinConfiguration(obj.(*JoinConfiguration)) })
 	return nil
 }
 
@@ -42,7 +42,7 @@ func SetObjectDefaults_InitConfiguration(in *InitConfiguration) {
 	SetDefaults_NodeRegistrationOptions(&in.NodeRegistration)
 }
 
-func SetObjectDefaults_NodeConfiguration(in *NodeConfiguration) {
-	SetDefaults_NodeConfiguration(in)
+func SetObjectDefaults_JoinConfiguration(in *JoinConfiguration) {
+	SetDefaults_JoinConfiguration(in)
 	SetDefaults_NodeRegistrationOptions(&in.NodeRegistration)
 }
diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go
index d83019ca50bd0..2094732229828 100644
--- a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go
+++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go
@@ -56,8 +56,8 @@ func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList {
 	return allErrs
 }
 
-// ValidateNodeConfiguration validates node configuration and collects all encountered errors
-func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
+// ValidateJoinConfiguration validates node configuration and collects all encountered errors
+func ValidateJoinConfiguration(c *kubeadm.JoinConfiguration) field.ErrorList {
 	allErrs := field.ErrorList{}
 	allErrs = append(allErrs, ValidateDiscovery(c)...)
 	allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...)
@@ -82,7 +82,7 @@ func ValidateNodeRegistrationOptions(nro *kubeadm.NodeRegistrationOptions, fldPa
 }
 
 // ValidateDiscovery validates discovery related configuration and collects all encountered errors
-func ValidateDiscovery(c *kubeadm.NodeConfiguration) field.ErrorList {
+func ValidateDiscovery(c *kubeadm.JoinConfiguration) field.ErrorList {
 	allErrs := field.ErrorList{}
 	if len(c.DiscoveryToken) != 0 {
 		allErrs = append(allErrs, ValidateToken(c.DiscoveryToken, field.NewPath("discoveryToken"))...)
@@ -98,7 +98,7 @@ func ValidateDiscovery(c *kubeadm.NodeConfiguration) field.ErrorList {
 }
 
 // ValidateArgSelection validates discovery related configuration and collects all encountered errors
-func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
+func ValidateArgSelection(cfg *kubeadm.JoinConfiguration, fldPath *field.Path) field.ErrorList {
 	allErrs := field.ErrorList{}
 	if len(cfg.DiscoveryToken) != 0 && len(cfg.DiscoveryFile) != 0 {
 		allErrs = append(allErrs, field.Invalid(fldPath, "", "discoveryToken and discoveryFile cannot both be set"))
diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
index 2641f1ea158ec..05006f9ac0b69 100644
--- a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
+++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
@@ -34,17 +34,17 @@ import (
 
 func TestValidateToken(t *testing.T) {
 	var tests = []struct {
-		c        *kubeadm.NodeConfiguration
+		c        *kubeadm.JoinConfiguration
 		f        *field.Path
 		expected bool
 	}{
-		{&kubeadm.NodeConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, true},
-		{&kubeadm.NodeConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
-		{&kubeadm.NodeConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
-		{&kubeadm.NodeConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, true},
-		{&kubeadm.NodeConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, false},
-		{&kubeadm.NodeConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, false},
-		{&kubeadm.NodeConfiguration{Token: "abcdef.1234567890123456@foobar", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
+		{&kubeadm.JoinConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, true},
+		{&kubeadm.JoinConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
+		{&kubeadm.JoinConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
+		{&kubeadm.JoinConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, true},
+		{&kubeadm.JoinConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, false},
+		{&kubeadm.JoinConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"2001:db8::100:6443"}}, nil, false},
+		{&kubeadm.JoinConfiguration{Token: "abcdef.1234567890123456@foobar", DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"}}, nil, false},
 	}
 	for _, rt := range tests {
 		err := ValidateToken(rt.c.Token, rt.f).ToAggregate()
@@ -559,23 +559,23 @@ func TestValidateInitConfiguration(t *testing.T) {
 	}
 }
 
-func TestValidateNodeConfiguration(t *testing.T) {
+func TestValidateJoinConfiguration(t *testing.T) {
 	var tests = []struct {
-		s        *kubeadm.NodeConfiguration
+		s        *kubeadm.JoinConfiguration
 		expected bool
 	}{
-		{&kubeadm.NodeConfiguration{}, false},
-		{&kubeadm.NodeConfiguration{
+		{&kubeadm.JoinConfiguration{}, false},
+		{&kubeadm.JoinConfiguration{
 			DiscoveryFile:  "foo",
 			DiscoveryToken: "abcdef.1234567890123456@foobar",
 			CACertPath:     "/some/cert.crt",
 		}, false},
 	}
 	for _, rt := range tests {
-		actual := ValidateNodeConfiguration(rt.s)
+		actual := ValidateJoinConfiguration(rt.s)
 		if (len(actual) == 0) != rt.expected {
 			t.Errorf(
-				"failed ValidateNodeConfiguration:\n\texpected: %t\n\t  actual: %t",
+				"failed ValidateJoinConfiguration:\n\texpected: %t\n\t  actual: %t",
 				rt.expected,
 				(len(actual) == 0),
 			)
@@ -681,12 +681,12 @@ func TestValidateIgnorePreflightErrors(t *testing.T) {
 func TestValidateArgSelection(t *testing.T) {
 	var tests = []struct {
 		name     string
-		c        *kubeadm.NodeConfiguration
+		c        *kubeadm.JoinConfiguration
 		expected bool
 	}{
 		{
 			"invalid: DiscoveryToken and DiscoveryFile cannot both be set",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryFile:  "https://url/file.conf",
 				DiscoveryToken: "abcdef.1234567890123456",
 			},
@@ -694,7 +694,7 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"invalid: DiscoveryToken or DiscoveryFile must be set",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryFile:  "",
 				DiscoveryToken: "",
 			},
@@ -702,14 +702,14 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"invalid: DiscoveryTokenAPIServers not set",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryToken: "abcdef.1234567890123456",
 			},
 			false,
 		},
 		{
 			"invalid: DiscoveryTokenCACertHashes cannot be used with DiscoveryFile",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryFile:              "https://url/file.conf",
 				DiscoveryTokenCACertHashes: []string{"sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
 			},
@@ -717,7 +717,7 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"invalid: using token-based discovery without DiscoveryTokenCACertHashes and DiscoveryTokenUnsafeSkipCAVerification",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryToken:                         "abcdef.1234567890123456",
 				DiscoveryTokenUnsafeSkipCAVerification: false,
 				DiscoveryTokenAPIServers:               []string{"192.168.122.100:6443"},
@@ -726,7 +726,7 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"WARNING: kubeadm doesn't fully support multiple API Servers yet",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryToken:                         "abcdef.1234567890123456",
 				DiscoveryTokenUnsafeSkipCAVerification: true,
 				DiscoveryTokenAPIServers:               []string{"192.168.122.100:6443", "192.168.122.88:6443"},
@@ -735,7 +735,7 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"valid: DiscoveryFile with DiscoveryTokenAPIServers",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryFile:            "https://url/file.conf",
 				DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"},
 			},
@@ -743,14 +743,14 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"valid: DiscoveryFile without DiscoveryTokenAPIServers",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryFile: "https://url/file.conf",
 			},
 			true,
 		},
 		{
 			"valid: using token-based discovery with DiscoveryTokenCACertHashes",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryToken:                         "abcdef.1234567890123456",
 				DiscoveryTokenAPIServers:               []string{"192.168.122.100:6443"},
 				DiscoveryTokenCACertHashes:             []string{"sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
@@ -760,7 +760,7 @@ func TestValidateArgSelection(t *testing.T) {
 		},
 		{
 			"valid: using token-based discovery with DiscoveryTokenCACertHashe but skip ca verification",
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryToken:                         "abcdef.1234567890123456",
 				DiscoveryTokenAPIServers:               []string{"192.168.122.100:6443"},
 				DiscoveryTokenCACertHashes:             []string{"sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc"},
@@ -784,17 +784,17 @@ func TestValidateArgSelection(t *testing.T) {
 
 func TestValidateJoinDiscoveryTokenAPIServer(t *testing.T) {
 	var tests = []struct {
-		s        *kubeadm.NodeConfiguration
+		s        *kubeadm.JoinConfiguration
 		expected bool
 	}{
 		{
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryTokenAPIServers: []string{"192.168.122.100"},
 			},
 			false,
 		},
 		{
-			&kubeadm.NodeConfiguration{
+			&kubeadm.JoinConfiguration{
 				DiscoveryTokenAPIServers: []string{"192.168.122.100:6443"},
 			},
 			true,
diff --git a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
index ad187d775120c..0cd56658ca2f3 100644
--- a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
+++ b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
@@ -296,6 +296,54 @@ func (in *InitConfiguration) DeepCopyObject() runtime.Object {
 	return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JoinConfiguration) DeepCopyInto(out *JoinConfiguration) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
+	if in.DiscoveryTokenAPIServers != nil {
+		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.DiscoveryTimeout != nil {
+		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
+		*out = new(v1.Duration)
+		**out = **in
+	}
+	if in.DiscoveryTokenCACertHashes != nil {
+		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.FeatureGates != nil {
+		in, out := &in.FeatureGates, &out.FeatureGates
+		*out = make(map[string]bool, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinConfiguration.
+func (in *JoinConfiguration) DeepCopy() *JoinConfiguration {
+	if in == nil {
+		return nil
+	}
+	out := new(JoinConfiguration)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *JoinConfiguration) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) {
 	*out = *in
@@ -345,54 +393,6 @@ func (in *Networking) DeepCopy() *Networking {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
-	if in.DiscoveryTokenAPIServers != nil {
-		in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.DiscoveryTimeout != nil {
-		in, out := &in.DiscoveryTimeout, &out.DiscoveryTimeout
-		*out = new(v1.Duration)
-		**out = **in
-	}
-	if in.DiscoveryTokenCACertHashes != nil {
-		in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.FeatureGates != nil {
-		in, out := &in.FeatureGates, &out.FeatureGates
-		*out = make(map[string]bool, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeConfiguration.
-func (in *NodeConfiguration) DeepCopy() *NodeConfiguration {
-	if in == nil {
-		return nil
-	}
-	out := new(NodeConfiguration)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *NodeConfiguration) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *NodeRegistrationOptions) DeepCopyInto(out *NodeRegistrationOptions) {
 	*out = *in
diff --git a/cmd/kubeadm/app/cmd/config.go b/cmd/kubeadm/app/cmd/config.go
index 127267b5ca9e8..d2cece6fcd3cd 100644
--- a/cmd/kubeadm/app/cmd/config.go
+++ b/cmd/kubeadm/app/cmd/config.go
@@ -96,7 +96,7 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
 		Short:   "Print the default values for a kubeadm configuration object.",
 		Long: fmt.Sprintf(dedent.Dedent(`
 			This command prints the default InitConfiguration object that is used for 'kubeadm init' and 'kubeadm upgrade',
-			and the default NodeConfiguration object that is used for 'kubeadm join'.
+			and the default JoinConfiguration object that is used for 'kubeadm join'.
 
 			Note that sensitive values like the Bootstrap Token fields are replaced with silly values like %q in order to pass validation but
 			not perform the real computation for creating a token.
@@ -124,7 +124,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
 	case constants.InitConfigurationKind, constants.MasterConfigurationKind:
 		return getDefaultInitConfigBytes()
 
-	case constants.NodeConfigurationKind:
+	case constants.JoinConfigurationKind, constants.NodeConfigurationKind:
 		return getDefaultNodeConfigBytes()
 
 	default:
@@ -139,7 +139,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
 
 // getSupportedAPIObjects returns all currently supported API object names
 func getSupportedAPIObjects() []string {
-	objects := []string{constants.InitConfigurationKind, constants.NodeConfigurationKind}
+	objects := []string{constants.InitConfigurationKind, constants.JoinConfigurationKind}
 	for componentType := range componentconfigs.Known {
 		objects = append(objects, string(componentType))
 	}
@@ -172,7 +172,7 @@ func getDefaultInitConfigBytes() ([]byte, error) {
 }
 
 func getDefaultNodeConfigBytes() ([]byte, error) {
-	internalcfg, err := configutil.NodeConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1alpha3.NodeConfiguration{
+	internalcfg, err := configutil.NodeConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1alpha3.JoinConfiguration{
 		Token: sillyToken.Token.String(),
 		DiscoveryTokenAPIServers:               []string{"kube-apiserver:6443"},
 		DiscoveryTokenUnsafeSkipCAVerification: true, // TODO: DiscoveryTokenUnsafeSkipCAVerification: true needs to be set for validation to pass, but shouldn't be recommended as the default
diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go
index 387dedcae4217..2188a751c858a 100644
--- a/cmd/kubeadm/app/cmd/join.go
+++ b/cmd/kubeadm/app/cmd/join.go
@@ -117,7 +117,7 @@ var (
 
 // NewCmdJoin returns "kubeadm join" command.
 func NewCmdJoin(out io.Writer) *cobra.Command {
-	cfg := &kubeadmapiv1alpha3.NodeConfiguration{}
+	cfg := &kubeadmapiv1alpha3.JoinConfiguration{}
 	kubeadmscheme.Scheme.Default(cfg)
 
 	var skipPreFlight bool
@@ -143,7 +143,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
 }
 
 // NewValidJoin validates the command line that are passed to the cobra command
-func NewValidJoin(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.NodeConfiguration, args []string, skipPreFlight bool, cfgPath, featureGatesString string, ignorePreflightErrors []string) (*Join, error) {
+func NewValidJoin(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.JoinConfiguration, args []string, skipPreFlight bool, cfgPath, featureGatesString string, ignorePreflightErrors []string) (*Join, error) {
 	cfg.DiscoveryTokenAPIServers = args
 
 	var err error
@@ -164,7 +164,7 @@ func NewValidJoin(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.NodeConfigurati
 }
 
 // AddJoinConfigFlags adds join flags bound to the config to the specified flagset
-func AddJoinConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.NodeConfiguration, featureGatesString *string) {
+func AddJoinConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.JoinConfiguration, featureGatesString *string) {
 	flagSet.StringVar(
 		&cfg.DiscoveryFile, "discovery-file", "",
 		"A file or url from which to load cluster information.")
@@ -215,12 +215,12 @@ func AddJoinOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight *bo
 
 // Join defines struct used by kubeadm join command
 type Join struct {
-	cfg                   *kubeadmapi.NodeConfiguration
+	cfg                   *kubeadmapi.JoinConfiguration
 	ignorePreflightErrors sets.String
 }
 
 // NewJoin instantiates Join struct with given arguments
-func NewJoin(cfgPath string, args []string, defaultcfg *kubeadmapiv1alpha3.NodeConfiguration, ignorePreflightErrors sets.String) (*Join, error) {
+func NewJoin(cfgPath string, args []string, defaultcfg *kubeadmapiv1alpha3.JoinConfiguration, ignorePreflightErrors sets.String) (*Join, error) {
 
 	if defaultcfg.NodeRegistration.Name == "" {
 		glog.V(1).Infoln("[join] found NodeName empty")
diff --git a/cmd/kubeadm/app/cmd/join_test.go b/cmd/kubeadm/app/cmd/join_test.go
index 313a022d18880..32dd31a04166e 100644
--- a/cmd/kubeadm/app/cmd/join_test.go
+++ b/cmd/kubeadm/app/cmd/join_test.go
@@ -79,7 +79,7 @@ func TestNewValidJoin(t *testing.T) {
 		testJoinValidate      bool
 		testJoinRun           bool
 		cmdPersistentFlags    map[string]string
-		nodeConfig            *kubeadm.NodeConfiguration
+		nodeConfig            *kubeadm.JoinConfiguration
 		expectedError         bool
 	}{
 		{
@@ -146,7 +146,7 @@ func TestNewValidJoin(t *testing.T) {
 	}
 
 	var out bytes.Buffer
-	cfg := &kubeadmapiv1alpha3.NodeConfiguration{}
+	cfg := &kubeadmapiv1alpha3.JoinConfiguration{}
 	kubeadmscheme.Scheme.Default(cfg)
 
 	errorFormat := "Test case %q: NewValidJoin expected error: %v, saw: %v, error: %v"
diff --git a/cmd/kubeadm/app/cmd/phases/kubelet.go b/cmd/kubeadm/app/cmd/phases/kubelet.go
index 7e200f71bb2b6..91c87dd855c45 100644
--- a/cmd/kubeadm/app/cmd/phases/kubelet.go
+++ b/cmd/kubeadm/app/cmd/phases/kubelet.go
@@ -39,7 +39,7 @@ import (
 var (
 	kubeletWriteEnvFileLongDesc = normalizer.LongDesc(`
 		Writes an environment file with flags that should be passed to the kubelet executing on the master or node.
-		This --config flag can either consume a InitConfiguration object or a NodeConfiguration one, as this
+		This --config flag can either consume a InitConfiguration object or a JoinConfiguration one, as this
 		function is used for both "kubeadm init" and "kubeadm join".
 		` + cmdutil.AlphaDisclaimer)
 
@@ -47,7 +47,7 @@ var (
 		# Writes a dynamic environment file with kubelet flags from a InitConfiguration file.
 		kubeadm alpha phase kubelet write-env-file --config masterconfig.yaml
 
-		# Writes a dynamic environment file with kubelet flags from a NodeConfiguration file.
+		# Writes a dynamic environment file with kubelet flags from a JoinConfiguration file.
 		kubeadm alpha phase kubelet write-env-file --config nodeconfig.yaml
 		`)
 
@@ -115,7 +115,7 @@ func NewCmdKubelet() *cobra.Command {
 	return cmd
 }
 
-// NewCmdKubeletWriteEnvFile calls cobra.Command for writing the dynamic kubelet env file based on a InitConfiguration or NodeConfiguration object
+// NewCmdKubeletWriteEnvFile calls cobra.Command for writing the dynamic kubelet env file based on a InitConfiguration or JoinConfiguration object
 func NewCmdKubeletWriteEnvFile() *cobra.Command {
 	var cfgPath string
 
@@ -150,7 +150,7 @@ func RunKubeletWriteEnvFile(cfgPath string) error {
 		nodeRegistrationObj = &cfg.NodeRegistration
 		featureGates = cfg.FeatureGates
 		registerWithTaints = false
-	case *kubeadmapi.NodeConfiguration:
+	case *kubeadmapi.JoinConfiguration:
 		nodeRegistrationObj = &cfg.NodeRegistration
 		featureGates = cfg.FeatureGates
 		registerWithTaints = true
diff --git a/cmd/kubeadm/app/cmd/phases/preflight.go b/cmd/kubeadm/app/cmd/phases/preflight.go
index 3acaf81c4771c..0644ecbce93b2 100644
--- a/cmd/kubeadm/app/cmd/phases/preflight.go
+++ b/cmd/kubeadm/app/cmd/phases/preflight.go
@@ -86,7 +86,7 @@ func NewCmdPreFlightNode() *cobra.Command {
 		Long:    nodePreflightLongDesc,
 		Example: nodePreflightExample,
 		Run: func(cmd *cobra.Command, args []string) {
-			cfg := &kubeadmapi.NodeConfiguration{}
+			cfg := &kubeadmapi.JoinConfiguration{}
 			err := preflight.RunJoinNodeChecks(utilsexec.New(), cfg, sets.NewString())
 			kubeadmutil.CheckErr(err)
 		},
diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go
index 96a67d0942c16..4ff4e8eee11f3 100644
--- a/cmd/kubeadm/app/constants/constants.go
+++ b/cmd/kubeadm/app/constants/constants.go
@@ -293,7 +293,11 @@ const (
 	// In v1alpha3 and higher, this struct is now named InitConfiguration
 	MasterConfigurationKind = "MasterConfiguration"
 
-	// NodeConfigurationKind is the string kind value for the InitConfiguration struct
+	// JoinConfigurationKind is the string kind value for the JoinConfiguration struct
+	JoinConfigurationKind = "JoinConfiguration"
+
+	// NodeConfigurationKind is the string kind value for the v1alpha2-named NodeConfiguration struct
+	// In v1alpha3 and higher, this struct is now named JoinConfiguration
 	NodeConfigurationKind = "NodeConfiguration"
 
 	// YAMLDocumentSeparator is the separator for YAML documents
diff --git a/cmd/kubeadm/app/discovery/discovery.go b/cmd/kubeadm/app/discovery/discovery.go
index de5a31f16e227..8d50137ef8b94 100644
--- a/cmd/kubeadm/app/discovery/discovery.go
+++ b/cmd/kubeadm/app/discovery/discovery.go
@@ -33,7 +33,7 @@ const TokenUser = "tls-bootstrap-token-user"
 
 // For returns a KubeConfig object that can be used for doing the TLS Bootstrap with the right credentials
 // Also, before returning anything, it makes sure it can trust the API Server
-func For(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Config, error) {
+func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) {
 	// TODO: Print summary info about the CA certificate, along with the checksum signature
 	// we also need an ability for the user to configure the client to validate received CA cert against a checksum
 	clusterinfo, err := GetValidatedClusterInfoObject(cfg)
@@ -51,7 +51,7 @@ func For(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Config, error) {
 }
 
 // GetValidatedClusterInfoObject returns a validated Cluster object that specifies where the cluster is and the CA cert to trust
-func GetValidatedClusterInfoObject(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Cluster, error) {
+func GetValidatedClusterInfoObject(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Cluster, error) {
 	switch {
 	case len(cfg.DiscoveryFile) != 0:
 		if isHTTPSURL(cfg.DiscoveryFile) {
diff --git a/cmd/kubeadm/app/discovery/discovery_test.go b/cmd/kubeadm/app/discovery/discovery_test.go
index 159a626b3e7d0..42ecc03c10354 100644
--- a/cmd/kubeadm/app/discovery/discovery_test.go
+++ b/cmd/kubeadm/app/discovery/discovery_test.go
@@ -24,30 +24,30 @@ import (
 
 func TestFor(t *testing.T) {
 	tests := []struct {
-		d      kubeadm.NodeConfiguration
+		d      kubeadm.JoinConfiguration
 		expect bool
 	}{
-		{d: kubeadm.NodeConfiguration{}, expect: false},
+		{d: kubeadm.JoinConfiguration{}, expect: false},
 		{
-			d: kubeadm.NodeConfiguration{
+			d: kubeadm.JoinConfiguration{
 				DiscoveryFile: "notnil",
 			},
 			expect: false,
 		},
 		{
-			d: kubeadm.NodeConfiguration{
+			d: kubeadm.JoinConfiguration{
 				DiscoveryFile: "https://localhost",
 			},
 			expect: false,
 		},
 		{
-			d: kubeadm.NodeConfiguration{
+			d: kubeadm.JoinConfiguration{
 				DiscoveryFile: "notnil",
 			},
 			expect: false,
 		},
 		{
-			d: kubeadm.NodeConfiguration{
+			d: kubeadm.JoinConfiguration{
 				DiscoveryToken: "foo.bar@foobar",
 			},
 			expect: false,
diff --git a/cmd/kubeadm/app/discovery/token/token.go b/cmd/kubeadm/app/discovery/token/token.go
index bd2d3b88a62f6..37832433dac40 100644
--- a/cmd/kubeadm/app/discovery/token/token.go
+++ b/cmd/kubeadm/app/discovery/token/token.go
@@ -43,7 +43,7 @@ const BootstrapUser = "token-bootstrap-client"
 // RetrieveValidatedClusterInfo connects to the API Server and tries to fetch the cluster-info ConfigMap
 // It then makes sure it can trust the API Server by looking at the JWS-signed tokens and (if cfg.DiscoveryTokenCACertHashes is not empty)
 // validating the cluster CA against a set of pinned public keys
-func RetrieveValidatedClusterInfo(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Cluster, error) {
+func RetrieveValidatedClusterInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Cluster, error) {
 	token, err := kubeadmapi.NewBootstrapTokenString(cfg.DiscoveryToken)
 	if err != nil {
 		return nil, err
diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go
index 88dfbba76b479..cb4263e0155a9 100644
--- a/cmd/kubeadm/app/preflight/checks.go
+++ b/cmd/kubeadm/app/preflight/checks.go
@@ -913,7 +913,7 @@ func RunInitMasterChecks(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigu
 }
 
 // RunJoinNodeChecks executes all individual, applicable to node checks.
-func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.NodeConfiguration, ignorePreflightErrors sets.String) error {
+func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfiguration, ignorePreflightErrors sets.String) error {
 	// First, check if we're root separately from the other preflight checks and fail fast
 	if err := RunRootCheckOnly(ignorePreflightErrors); err != nil {
 		return err
diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go
index 6b32143dfda20..cd4c8d392666b 100644
--- a/cmd/kubeadm/app/preflight/checks_test.go
+++ b/cmd/kubeadm/app/preflight/checks_test.go
@@ -238,21 +238,21 @@ func TestRunInitMasterChecks(t *testing.T) {
 
 func TestRunJoinNodeChecks(t *testing.T) {
 	var tests = []struct {
-		cfg      *kubeadmapi.NodeConfiguration
+		cfg      *kubeadmapi.JoinConfiguration
 		expected bool
 	}{
 		{
-			cfg:      &kubeadmapi.NodeConfiguration{},
+			cfg:      &kubeadmapi.JoinConfiguration{},
 			expected: false,
 		},
 		{
-			cfg: &kubeadmapi.NodeConfiguration{
+			cfg: &kubeadmapi.JoinConfiguration{
 				DiscoveryTokenAPIServers: []string{"192.168.1.15"},
 			},
 			expected: false,
 		},
 		{
-			cfg: &kubeadmapi.NodeConfiguration{
+			cfg: &kubeadmapi.JoinConfiguration{
 				DiscoveryTokenAPIServers: []string{"2001:1234::1:15"},
 			},
 			expected: false,
diff --git a/cmd/kubeadm/app/util/config/common.go b/cmd/kubeadm/app/util/config/common.go
index 5e2a6a86df125..ee842dd60601d 100644
--- a/cmd/kubeadm/app/util/config/common.go
+++ b/cmd/kubeadm/app/util/config/common.go
@@ -32,7 +32,7 @@ import (
 	"k8s.io/kubernetes/pkg/util/version"
 )
 
-// AnyConfigFileAndDefaultsToInternal reads either a InitConfiguration or NodeConfiguration and unmarshals it
+// AnyConfigFileAndDefaultsToInternal reads either a InitConfiguration or JoinConfiguration and unmarshals it
 func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error) {
 	b, err := ioutil.ReadFile(cfgPath)
 	if err != nil {
@@ -48,8 +48,8 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error)
 	if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) {
 		return ConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1alpha3.InitConfiguration{})
 	}
-	if kubeadmutil.GroupVersionKindsHasNodeConfiguration(gvks) {
-		return NodeConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1alpha3.NodeConfiguration{})
+	if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
+		return NodeConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1alpha3.JoinConfiguration{})
 	}
 	return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
 }
diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go
index 93031e1071080..2227a175a8bfa 100644
--- a/cmd/kubeadm/app/util/config/common_test.go
+++ b/cmd/kubeadm/app/util/config/common_test.go
@@ -31,7 +31,7 @@ kind: InitConfiguration
 `),
 	"Node_v1alpha1": []byte(`
 apiVersion: kubeadm.k8s.io/v1alpha1
-kind: NodeConfiguration
+kind: JoinConfiguration
 `),
 	"Master_v1alpha3": []byte(`
 apiVersion: kubeadm.k8s.io/v1alpha3
@@ -39,7 +39,7 @@ kind: InitConfiguration
 `),
 	"Node_v1alpha3": []byte(`
 apiVersion: kubeadm.k8s.io/v1alpha3
-kind: NodeConfiguration
+kind: JoinConfiguration
 `),
 	"NoKind": []byte(`
 apiVersion: baz.k8s.io/v1
diff --git a/cmd/kubeadm/app/util/config/nodeconfig.go b/cmd/kubeadm/app/util/config/nodeconfig.go
index be7edded4b489..9fec26e1a6a61 100644
--- a/cmd/kubeadm/app/util/config/nodeconfig.go
+++ b/cmd/kubeadm/app/util/config/nodeconfig.go
@@ -30,15 +30,15 @@ import (
 	"k8s.io/kubernetes/pkg/util/node"
 )
 
-// SetJoinDynamicDefaults checks and sets configuration values for the NodeConfiguration object
-func SetJoinDynamicDefaults(cfg *kubeadmapi.NodeConfiguration) error {
+// SetJoinDynamicDefaults checks and sets configuration values for the JoinConfiguration object
+func SetJoinDynamicDefaults(cfg *kubeadmapi.JoinConfiguration) error {
 	cfg.NodeRegistration.Name = node.GetHostname(cfg.NodeRegistration.Name)
 	return nil
 }
 
 // NodeConfigFileAndDefaultsToInternalConfig
-func NodeConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *kubeadmapiv1alpha3.NodeConfiguration) (*kubeadmapi.NodeConfiguration, error) {
-	internalcfg := &kubeadmapi.NodeConfiguration{}
+func NodeConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *kubeadmapiv1alpha3.JoinConfiguration) (*kubeadmapi.JoinConfiguration, error) {
+	internalcfg := &kubeadmapi.JoinConfiguration{}
 
 	if cfgPath != "" {
 		// Loads configuration from config file, if provided
@@ -69,7 +69,7 @@ func NodeConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedc
 		return nil, err
 	}
 	// Validates cfg (flags/configs + defaults)
-	if err := validation.ValidateNodeConfiguration(internalcfg).ToAggregate(); err != nil {
+	if err := validation.ValidateJoinConfiguration(internalcfg).ToAggregate(); err != nil {
 		return nil, err
 	}
 
diff --git a/cmd/kubeadm/app/util/config/nodeconfig_test.go b/cmd/kubeadm/app/util/config/nodeconfig_test.go
index 1b2e3f1c25fde..cda3ac945da63 100644
--- a/cmd/kubeadm/app/util/config/nodeconfig_test.go
+++ b/cmd/kubeadm/app/util/config/nodeconfig_test.go
@@ -87,7 +87,7 @@ func TestNodeConfigFileAndDefaultsToInternalConfig(t *testing.T) {
 	for _, rt := range tests {
 		t.Run(rt.name, func(t2 *testing.T) {
 
-			internalcfg, err := NodeConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1alpha3.NodeConfiguration{})
+			internalcfg, err := NodeConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1alpha3.JoinConfiguration{})
 			if err != nil {
 				if rt.expectedErr {
 					return
diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/node/v1alpha3.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1alpha3.yaml
index c6f19d0485be1..b43cb33085e84 100644
--- a/cmd/kubeadm/app/util/config/testdata/conversion/node/v1alpha3.yaml
+++ b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1alpha3.yaml
@@ -7,7 +7,7 @@ discoveryToken: abcdef.0123456789abcdef
 discoveryTokenAPIServers:
 - kube-apiserver:6443
 discoveryTokenUnsafeSkipCAVerification: true
-kind: NodeConfiguration
+kind: JoinConfiguration
 nodeRegistration:
   criSocket: /var/run/dockershim.sock
   name: master-1
diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml
index 562f32632a181..05a6c7302fb7b 100644
--- a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml
+++ b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml
@@ -7,7 +7,7 @@ discoveryToken: abcdef.0123456789abcdef
 discoveryTokenAPIServers:
 - kube-apiserver:6443
 discoveryTokenUnsafeSkipCAVerification: true
-kind: NodeConfiguration
+kind: JoinConfiguration
 nodeRegistration:
   criSocket: /var/run/dockershim.sock
   name: thegopher
diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go
index 23bf655213749..19998df65e2d0 100644
--- a/cmd/kubeadm/app/util/marshal.go
+++ b/cmd/kubeadm/app/util/marshal.go
@@ -154,7 +154,7 @@ func GroupVersionKindsHasInitConfiguration(gvks ...schema.GroupVersionKind) bool
 	return GroupVersionKindsHasKind(gvks, constants.InitConfigurationKind) || GroupVersionKindsHasKind(gvks, constants.MasterConfigurationKind)
 }
 
-// GroupVersionKindsHasNodeConfiguration returns whether the following gvk slice contains a NodeConfiguration object
-func GroupVersionKindsHasNodeConfiguration(gvks []schema.GroupVersionKind) bool {
-	return GroupVersionKindsHasKind(gvks, constants.NodeConfigurationKind)
+// GroupVersionKindsHasJoinConfiguration returns whether the following gvk slice contains a JoinConfiguration object
+func GroupVersionKindsHasJoinConfiguration(gvks ...schema.GroupVersionKind) bool {
+	return GroupVersionKindsHasKind(gvks, constants.JoinConfigurationKind) || GroupVersionKindsHasKind(gvks, constants.NodeConfigurationKind)
 }
diff --git a/cmd/kubeadm/app/util/marshal_test.go b/cmd/kubeadm/app/util/marshal_test.go
index 8952f34cfe14b..d1ce35b227498 100644
--- a/cmd/kubeadm/app/util/marshal_test.go
+++ b/cmd/kubeadm/app/util/marshal_test.go
@@ -374,7 +374,7 @@ func TestGroupVersionKindsHasInitConfiguration(t *testing.T) {
 	}
 }
 
-func TestGroupVersionKindsHasNodeConfiguration(t *testing.T) {
+func TestGroupVersionKindsHasJoinConfiguration(t *testing.T) {
 	var tests = []struct {
 		name     string
 		gvks     []schema.GroupVersionKind
@@ -382,17 +382,17 @@ func TestGroupVersionKindsHasNodeConfiguration(t *testing.T) {
 		expected bool
 	}{
 		{
-			name: "NoNodeConfiguration",
+			name: "NoJoinConfiguration",
 			gvks: []schema.GroupVersionKind{
 				{Group: "foo.k8s.io", Version: "v1", Kind: "Foo"},
 			},
 			expected: false,
 		},
 		{
-			name: "NodeConfigurationFound",
+			name: "JoinConfigurationFound",
 			gvks: []schema.GroupVersionKind{
 				{Group: "foo.k8s.io", Version: "v1", Kind: "Foo"},
-				{Group: "bar.k8s.io", Version: "v2", Kind: "NodeConfiguration"},
+				{Group: "bar.k8s.io", Version: "v2", Kind: "JoinConfiguration"},
 			},
 			expected: true,
 		},
@@ -401,9 +401,9 @@ func TestGroupVersionKindsHasNodeConfiguration(t *testing.T) {
 	for _, rt := range tests {
 		t.Run(rt.name, func(t2 *testing.T) {
 
-			actual := GroupVersionKindsHasNodeConfiguration(rt.gvks)
+			actual := GroupVersionKindsHasJoinConfiguration(rt.gvks...)
 			if rt.expected != actual {
-				t2.Errorf("expected gvks has NodeConfiguration: %t\n\tactual: %t\n", rt.expected, actual)
+				t2.Errorf("expected gvks has JoinConfiguration: %t\n\tactual: %t\n", rt.expected, actual)
 			}
 		})
 	}