Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/kubeadm/app/apis/kubeadm/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type MasterConfiguration struct {
Networking Networking
KubernetesVersion string
CloudProvider string
NodeName string
AuthorizationModes []string

Token string
Expand Down
1 change: 1 addition & 0 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type MasterConfiguration struct {
Networking Networking `json:"networking"`
KubernetesVersion string `json:"kubernetesVersion"`
CloudProvider string `json:"cloudProvider"`
NodeName string `json:"nodeName"`
AuthorizationModes []string `json:"authorizationModes"`

Token string `json:"token"`
Expand Down
1 change: 1 addition & 0 deletions cmd/kubeadm/app/apis/kubeadm/validation/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ go_library(
"//pkg/api/validation:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library",
"//pkg/util/node:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
Expand Down
10 changes: 10 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
apivalidation "k8s.io/kubernetes/pkg/api/validation"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
"k8s.io/kubernetes/pkg/util/node"
)

// TODO: Break out the cloudprovider functionality out of core and only support the new flow
Expand Down Expand Up @@ -63,6 +64,7 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
allErrs = append(allErrs, ValidateNodeName(c.NodeName, field.NewPath("node-name"))...)
allErrs = append(allErrs, ValidateToken(c.Token, field.NewPath("token"))...)
return allErrs
}
Expand Down Expand Up @@ -237,6 +239,14 @@ func ValidateAbsolutePath(path string, fldPath *field.Path) field.ErrorList {
return allErrs
}

func ValidateNodeName(nodename string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if node.GetHostname(nodename) != nodename {
allErrs = append(allErrs, field.Invalid(fldPath, nodename, "nodename is not valid, must be lower case"))
}
return allErrs
}

func ValidateCloudProvider(provider string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(provider) == 0 {
Expand Down
28 changes: 28 additions & 0 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,29 @@ func TestValidateAuthorizationModes(t *testing.T) {
}
}

func TestValidateNodeName(t *testing.T) {
var tests = []struct {
s string
f *field.Path
expected bool
}{
{"", nil, false}, // ok if not provided
{"1234", nil, true}, // supported
{"valid-nodename", nil, true}, // supported
{"INVALID-NODENAME", nil, false}, // Upper cases is invalid
}
for _, rt := range tests {
actual := ValidateNodeName(rt.s, rt.f)
if (len(actual) == 0) != rt.expected {
t.Errorf(
"failed ValidateNodeName:\n\texpected: %t\n\t actual: %t",
rt.expected,
(len(actual) == 0),
)
}
}
}

func TestValidateCloudProvider(t *testing.T) {
var tests = []struct {
s string
Expand Down Expand Up @@ -177,6 +200,7 @@ func TestValidateIPNetFromString(t *testing.T) {
}

func TestValidateMasterConfiguration(t *testing.T) {
nodename := "valid-nodename"
var tests = []struct {
s *kubeadm.MasterConfiguration
expected bool
Expand All @@ -189,6 +213,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
NodeName: nodename,
}, false},
{&kubeadm.MasterConfiguration{
AuthorizationModes: []string{"Node", "RBAC"},
Expand All @@ -198,6 +223,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
},
CertificatesDir: "/some/other/cert/dir",
Token: "abcdef.0123456789abcdef",
NodeName: nodename,
}, true},
{&kubeadm.MasterConfiguration{
AuthorizationModes: []string{"Node", "RBAC"},
Expand All @@ -206,6 +232,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
NodeName: nodename,
}, false},
{&kubeadm.MasterConfiguration{
AuthorizationModes: []string{"Node", "RBAC"},
Expand All @@ -215,6 +242,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
},
CertificatesDir: "/some/other/cert/dir",
Token: "abcdef.0123456789abcdef",
NodeName: nodename,
}, true},
}
for _, rt := range tests {
Expand Down
1 change: 1 addition & 0 deletions cmd/kubeadm/app/cmd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ go_library(
"//pkg/printers:go_default_library",
"//pkg/util/i18n:go_default_library",
"//pkg/util/initsystem:go_default_library",
"//pkg/util/node:go_default_library",
"//pkg/util/version:go_default_library",
"//pkg/version:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
Expand Down
8 changes: 6 additions & 2 deletions cmd/kubeadm/app/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ func NewCmdInit(out io.Writer) *cobra.Command {
&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", cfg.APIServerCertSANs,
`Optional extra altnames to use for the API Server serving cert. Can be both IP addresses and dns names.`,
)
cmd.PersistentFlags().StringVar(
&cfg.NodeName, "node-name", cfg.NodeName,
`Specify the node name`,
)

cmd.PersistentFlags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")

Expand Down Expand Up @@ -220,7 +224,7 @@ func (i *Init) Run(out io.Writer) error {
// PHASE 2: Generate kubeconfig files for the admin and the kubelet

masterEndpoint := fmt.Sprintf("https://%s:%d", i.cfg.API.AdvertiseAddress, i.cfg.API.BindPort)
err = kubeconfigphase.CreateInitKubeConfigFiles(masterEndpoint, i.cfg.CertificatesDir, kubeadmapi.GlobalEnvParams.KubernetesDir)
err = kubeconfigphase.CreateInitKubeConfigFiles(masterEndpoint, i.cfg.CertificatesDir, kubeadmapi.GlobalEnvParams.KubernetesDir, i.cfg.NodeName)
if err != nil {
return err
}
Expand All @@ -236,7 +240,7 @@ func (i *Init) Run(out io.Writer) error {
return err
}

if err := apiconfigphase.UpdateMasterRoleLabelsAndTaints(client); err != nil {
if err := apiconfigphase.UpdateMasterRoleLabelsAndTaints(client, i.cfg.NodeName); err != nil {
return err
}

Expand Down
17 changes: 6 additions & 11 deletions cmd/kubeadm/app/cmd/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"

"github.com/renstrom/dedent"
Expand All @@ -33,11 +32,12 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
kubenode "k8s.io/kubernetes/cmd/kubeadm/app/node"
kubeadmnode "k8s.io/kubernetes/cmd/kubeadm/app/node"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/api"
nodeutil "k8s.io/kubernetes/pkg/util/node"
)

var (
Expand Down Expand Up @@ -178,21 +178,16 @@ func (j *Join) Run(out io.Writer) error {
return err
}

hostname := j.cfg.NodeName
if hostname == "" {
hostname, err = os.Hostname()
if err != nil {
return err
}
}
hostname := nodeutil.GetHostname(j.cfg.NodeName)

client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
if err != nil {
return err
}
if err := kubenode.ValidateAPIServer(client); err != nil {
if err := kubeadmnode.ValidateAPIServer(client); err != nil {
return err
}
if err := kubenode.PerformTLSBootstrap(cfg, hostname); err != nil {
if err := kubeadmnode.PerformTLSBootstrap(cfg, hostname); err != nil {
return err
}

Expand Down
1 change: 0 additions & 1 deletion cmd/kubeadm/app/phases/apiconfig/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ go_library(
"//pkg/apis/rbac/v1beta1:go_default_library",
"//pkg/bootstrap/api:go_default_library",
"//pkg/kubelet/apis:go_default_library",
"//pkg/util/node:go_default_library",
"//pkg/util/version:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
Expand Down
11 changes: 5 additions & 6 deletions cmd/kubeadm/app/phases/apiconfig/setupmaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,19 @@ import (
clientset "k8s.io/client-go/kubernetes"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
"k8s.io/kubernetes/pkg/util/node"
)

const apiCallRetryInterval = 500 * time.Millisecond

// TODO: Can we think of any unit tests here? Or should this code just be covered through integration/e2e tests?

func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error {
func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, nodeName string) error {
var n *v1.Node

// Wait for current node registration
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
var err error
if n, err = client.Nodes().Get(node.GetHostname(""), metav1.GetOptions{}); err != nil {
if n, err = client.Nodes().Get(nodeName, metav1.GetOptions{}); err != nil {
return false, nil
}
// The node may appear to have no labels at first,
Expand Down Expand Up @@ -75,7 +74,7 @@ func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error
if apierrs.IsConflict(err) {
fmt.Println("[apiclient] Temporarily unable to update master node metadata due to conflict (will retry)")
time.Sleep(apiCallRetryInterval)
attemptToUpdateMasterRoleLabelsAndTaints(client)
attemptToUpdateMasterRoleLabelsAndTaints(client, nodeName)
} else {
return err
}
Expand All @@ -95,9 +94,9 @@ func addTaintIfNotExists(n *v1.Node, t v1.Taint) {
}

// UpdateMasterRoleLabelsAndTaints taints the master and sets the master label
func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error {
func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, nodeName string) error {
// TODO: Use iterate instead of recursion
err := attemptToUpdateMasterRoleLabelsAndTaints(client)
err := attemptToUpdateMasterRoleLabelsAndTaints(client, nodeName)
if err != nil {
return fmt.Errorf("failed to update master node - [%v]", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/phases/apiconfig/setupmaster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func TestUpdateMasterRoleLabelsAndTaints(t *testing.T) {
t.Fatalf("UpdateMasterRoleLabelsAndTaints(%s): unexpected error building clientset: %v", tc.name, err)
}

err = UpdateMasterRoleLabelsAndTaints(cs)
err = UpdateMasterRoleLabelsAndTaints(cs, hostname)
if err != nil {
t.Errorf("UpdateMasterRoleLabelsAndTaints(%s) returned unexpected error: %v", tc.name, err)
}
Expand Down
9 changes: 1 addition & 8 deletions cmd/kubeadm/app/phases/certs/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"crypto/x509"
"fmt"
"net"
"os"

"k8s.io/apimachinery/pkg/util/validation"
certutil "k8s.io/client-go/util/cert"
Expand Down Expand Up @@ -124,12 +123,6 @@ func NewFrontProxyClientCertAndKey(frontProxyCACert *x509.Certificate, frontProx
// getAltNames builds an AltNames object for to be used when generating apiserver certificate
func getAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) {

// host name
hostname, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("couldn't get the hostname: %v", err)
}

// advertise address
advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress)
if advertiseAddress == nil {
Expand All @@ -150,7 +143,7 @@ func getAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error
// create AltNames with defaults DNSNames/IPs
altNames := &certutil.AltNames{
DNSNames: []string{
hostname,
cfg.NodeName,
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
Expand Down
8 changes: 3 additions & 5 deletions cmd/kubeadm/app/phases/certs/certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package certs
import (
"crypto/x509"
"net"
"os"
"testing"

kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
Expand All @@ -36,14 +35,13 @@ func TestNewCACertAndKey(t *testing.T) {
}

func TestNewAPIServerCertAndKey(t *testing.T) {
hostname, err := os.Hostname()
if err != nil {
t.Errorf("couldn't get the hostname: %v", err)
}
hostname := "valid-hostname"

advertiseIP := "1.2.3.4"
cfg := &kubeadmapi.MasterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: advertiseIP},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
NodeName: "valid-hostname",
}
caCert, caKey, err := NewCACertAndKey()

Expand Down
1 change: 0 additions & 1 deletion cmd/kubeadm/app/phases/kubeconfig/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ go_library(
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//pkg/util/node:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
"//vendor/k8s.io/client-go/util/cert:go_default_library",
Expand Down
8 changes: 1 addition & 7 deletions cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/pkg/util/node"
)

// BuildConfigProperties holds some simple information about how this phase should build the KubeConfig object
Expand All @@ -53,12 +52,7 @@ type BuildConfigProperties struct {
// /etc/kubernetes/{admin,kubelet}.conf exist but not certs => certs will be generated and conflict with the kubeconfig files => error

// CreateInitKubeConfigFiles is called from the main init and does the work for the default phase behaviour
func CreateInitKubeConfigFiles(masterEndpoint, pkiDir, outDir string) error {

nodeName := node.GetHostname("")
if len(nodeName) == 0 {
return fmt.Errorf("unable to get hostname for master node")
}
func CreateInitKubeConfigFiles(masterEndpoint, pkiDir, outDir, nodeName string) error {

// Create a lightweight specification for what the files should look like
filesToCreateFromSpec := map[string]BuildConfigProperties{
Expand Down
1 change: 0 additions & 1 deletion cmd/kubeadm/app/preflight/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ go_library(
"//pkg/api/validation:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//pkg/util/initsystem:go_default_library",
"//pkg/util/node:go_default_library",
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
"//test/e2e_node/system:go_default_library",
"//vendor/github.com/PuerkitoBio/purell:go_default_library",
Expand Down
Loading