mirror of https://github.com/k3s-io/k3s
Merge pull request #48594 from GheRivero/kubeadm_nodename
Automatic merge from submit-queue Add node-name flag to `init` phase **What this PR does / why we need it**: Allow to specify a node-name instead of relaying in `os.Hostname()` This is useful where kubelet use the name given by the cloud-provider to register the node. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: Partially fix: kubernetes/kubeadm#64 **Release note**: ```release-note Added new flag to `kubeadm init`: --node-name, that lets you specify the name of the Node object that will be created ```pull/6/head
commit
80531ccd84
|
@ -37,6 +37,7 @@ type MasterConfiguration struct {
|
||||||
Networking Networking
|
Networking Networking
|
||||||
KubernetesVersion string
|
KubernetesVersion string
|
||||||
CloudProvider string
|
CloudProvider string
|
||||||
|
NodeName string
|
||||||
AuthorizationModes []string
|
AuthorizationModes []string
|
||||||
|
|
||||||
Token string
|
Token string
|
||||||
|
|
|
@ -30,6 +30,7 @@ type MasterConfiguration struct {
|
||||||
Networking Networking `json:"networking"`
|
Networking Networking `json:"networking"`
|
||||||
KubernetesVersion string `json:"kubernetesVersion"`
|
KubernetesVersion string `json:"kubernetesVersion"`
|
||||||
CloudProvider string `json:"cloudProvider"`
|
CloudProvider string `json:"cloudProvider"`
|
||||||
|
NodeName string `json:"nodeName"`
|
||||||
AuthorizationModes []string `json:"authorizationModes"`
|
AuthorizationModes []string `json:"authorizationModes"`
|
||||||
|
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
|
|
@ -31,6 +31,7 @@ go_library(
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||||
"//pkg/registry/core/service/ipallocator: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/github.com/spf13/pflag:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
|
|
|
@ -34,6 +34,7 @@ import (
|
||||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
"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
|
// TODO: Break out the cloudprovider functionality out of core and only support the new flow
|
||||||
|
@ -63,6 +64,7 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
|
||||||
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
|
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
|
||||||
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
|
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
|
||||||
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
|
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"))...)
|
allErrs = append(allErrs, ValidateToken(c.Token, field.NewPath("token"))...)
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
@ -237,6 +239,14 @@ func ValidateAbsolutePath(path string, fldPath *field.Path) field.ErrorList {
|
||||||
return allErrs
|
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 {
|
func ValidateCloudProvider(provider string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if len(provider) == 0 {
|
if len(provider) == 0 {
|
||||||
|
|
|
@ -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) {
|
func TestValidateCloudProvider(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
s string
|
s string
|
||||||
|
@ -177,6 +200,7 @@ func TestValidateIPNetFromString(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateMasterConfiguration(t *testing.T) {
|
func TestValidateMasterConfiguration(t *testing.T) {
|
||||||
|
nodename := "valid-nodename"
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
s *kubeadm.MasterConfiguration
|
s *kubeadm.MasterConfiguration
|
||||||
expected bool
|
expected bool
|
||||||
|
@ -189,6 +213,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
||||||
DNSDomain: "cluster.local",
|
DNSDomain: "cluster.local",
|
||||||
},
|
},
|
||||||
CertificatesDir: "/some/cert/dir",
|
CertificatesDir: "/some/cert/dir",
|
||||||
|
NodeName: nodename,
|
||||||
}, false},
|
}, false},
|
||||||
{&kubeadm.MasterConfiguration{
|
{&kubeadm.MasterConfiguration{
|
||||||
AuthorizationModes: []string{"Node", "RBAC"},
|
AuthorizationModes: []string{"Node", "RBAC"},
|
||||||
|
@ -198,6 +223,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
CertificatesDir: "/some/other/cert/dir",
|
CertificatesDir: "/some/other/cert/dir",
|
||||||
Token: "abcdef.0123456789abcdef",
|
Token: "abcdef.0123456789abcdef",
|
||||||
|
NodeName: nodename,
|
||||||
}, true},
|
}, true},
|
||||||
{&kubeadm.MasterConfiguration{
|
{&kubeadm.MasterConfiguration{
|
||||||
AuthorizationModes: []string{"Node", "RBAC"},
|
AuthorizationModes: []string{"Node", "RBAC"},
|
||||||
|
@ -206,6 +232,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
||||||
DNSDomain: "cluster.local",
|
DNSDomain: "cluster.local",
|
||||||
},
|
},
|
||||||
CertificatesDir: "/some/cert/dir",
|
CertificatesDir: "/some/cert/dir",
|
||||||
|
NodeName: nodename,
|
||||||
}, false},
|
}, false},
|
||||||
{&kubeadm.MasterConfiguration{
|
{&kubeadm.MasterConfiguration{
|
||||||
AuthorizationModes: []string{"Node", "RBAC"},
|
AuthorizationModes: []string{"Node", "RBAC"},
|
||||||
|
@ -215,6 +242,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
CertificatesDir: "/some/other/cert/dir",
|
CertificatesDir: "/some/other/cert/dir",
|
||||||
Token: "abcdef.0123456789abcdef",
|
Token: "abcdef.0123456789abcdef",
|
||||||
|
NodeName: nodename,
|
||||||
}, true},
|
}, true},
|
||||||
}
|
}
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
|
|
|
@ -45,6 +45,7 @@ go_library(
|
||||||
"//pkg/printers:go_default_library",
|
"//pkg/printers:go_default_library",
|
||||||
"//pkg/util/i18n:go_default_library",
|
"//pkg/util/i18n:go_default_library",
|
||||||
"//pkg/util/initsystem:go_default_library",
|
"//pkg/util/initsystem:go_default_library",
|
||||||
|
"//pkg/util/node:go_default_library",
|
||||||
"//pkg/util/version:go_default_library",
|
"//pkg/util/version:go_default_library",
|
||||||
"//pkg/version:go_default_library",
|
"//pkg/version:go_default_library",
|
||||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||||
|
|
|
@ -123,6 +123,10 @@ func NewCmdInit(out io.Writer) *cobra.Command {
|
||||||
&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", cfg.APIServerCertSANs,
|
&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.`,
|
`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)")
|
cmd.PersistentFlags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||||
|
|
||||||
|
@ -220,7 +224,7 @@ func (i *Init) Run(out io.Writer) error {
|
||||||
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
// 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)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -236,7 +240,7 @@ func (i *Init) Run(out io.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := apiconfigphase.UpdateMasterRoleLabelsAndTaints(client); err != nil {
|
if err := apiconfigphase.UpdateMasterRoleLabelsAndTaints(client, i.cfg.NodeName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
"github.com/renstrom/dedent"
|
||||||
|
@ -33,11 +32,12 @@ import (
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
|
"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"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -178,21 +178,16 @@ func (j *Join) Run(out io.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname := j.cfg.NodeName
|
hostname := nodeutil.GetHostname(j.cfg.NodeName)
|
||||||
if hostname == "" {
|
|
||||||
hostname, err = os.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
|
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := kubenode.ValidateAPIServer(client); err != nil {
|
if err := kubeadmnode.ValidateAPIServer(client); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := kubenode.PerformTLSBootstrap(cfg, hostname); err != nil {
|
if err := kubeadmnode.PerformTLSBootstrap(cfg, hostname); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ go_library(
|
||||||
"//pkg/apis/rbac/v1beta1:go_default_library",
|
"//pkg/apis/rbac/v1beta1:go_default_library",
|
||||||
"//pkg/bootstrap/api:go_default_library",
|
"//pkg/bootstrap/api:go_default_library",
|
||||||
"//pkg/kubelet/apis:go_default_library",
|
"//pkg/kubelet/apis:go_default_library",
|
||||||
"//pkg/util/node:go_default_library",
|
|
||||||
"//pkg/util/version:go_default_library",
|
"//pkg/util/version:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
|
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||||
|
|
|
@ -30,20 +30,19 @@ import (
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||||
"k8s.io/kubernetes/pkg/util/node"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const apiCallRetryInterval = 500 * time.Millisecond
|
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?
|
// 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
|
var n *v1.Node
|
||||||
|
|
||||||
// Wait for current node registration
|
// Wait for current node registration
|
||||||
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
wait.PollInfinite(kubeadmconstants.APICallRetryInterval, func() (bool, error) {
|
||||||
var err 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
|
return false, nil
|
||||||
}
|
}
|
||||||
// The node may appear to have no labels at first,
|
// The node may appear to have no labels at first,
|
||||||
|
@ -75,7 +74,7 @@ func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error
|
||||||
if apierrs.IsConflict(err) {
|
if apierrs.IsConflict(err) {
|
||||||
fmt.Println("[apiclient] Temporarily unable to update master node metadata due to conflict (will retry)")
|
fmt.Println("[apiclient] Temporarily unable to update master node metadata due to conflict (will retry)")
|
||||||
time.Sleep(apiCallRetryInterval)
|
time.Sleep(apiCallRetryInterval)
|
||||||
attemptToUpdateMasterRoleLabelsAndTaints(client)
|
attemptToUpdateMasterRoleLabelsAndTaints(client, nodeName)
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -95,9 +94,9 @@ func addTaintIfNotExists(n *v1.Node, t v1.Taint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMasterRoleLabelsAndTaints taints the master and sets the master label
|
// 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
|
// TODO: Use iterate instead of recursion
|
||||||
err := attemptToUpdateMasterRoleLabelsAndTaints(client)
|
err := attemptToUpdateMasterRoleLabelsAndTaints(client, nodeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update master node - [%v]", err)
|
return fmt.Errorf("failed to update master node - [%v]", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func TestUpdateMasterRoleLabelsAndTaints(t *testing.T) {
|
||||||
t.Fatalf("UpdateMasterRoleLabelsAndTaints(%s): unexpected error building clientset: %v", tc.name, err)
|
t.Fatalf("UpdateMasterRoleLabelsAndTaints(%s): unexpected error building clientset: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = UpdateMasterRoleLabelsAndTaints(cs)
|
err = UpdateMasterRoleLabelsAndTaints(cs, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("UpdateMasterRoleLabelsAndTaints(%s) returned unexpected error: %v", tc.name, err)
|
t.Errorf("UpdateMasterRoleLabelsAndTaints(%s) returned unexpected error: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
|
@ -124,12 +123,6 @@ func NewFrontProxyClientCertAndKey(frontProxyCACert *x509.Certificate, frontProx
|
||||||
// getAltNames builds an AltNames object for to be used when generating apiserver certificate
|
// getAltNames builds an AltNames object for to be used when generating apiserver certificate
|
||||||
func getAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error) {
|
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
|
// advertise address
|
||||||
advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress)
|
advertiseAddress := net.ParseIP(cfg.API.AdvertiseAddress)
|
||||||
if advertiseAddress == nil {
|
if advertiseAddress == nil {
|
||||||
|
@ -150,7 +143,7 @@ func getAltNames(cfg *kubeadmapi.MasterConfiguration) (*certutil.AltNames, error
|
||||||
// create AltNames with defaults DNSNames/IPs
|
// create AltNames with defaults DNSNames/IPs
|
||||||
altNames := &certutil.AltNames{
|
altNames := &certutil.AltNames{
|
||||||
DNSNames: []string{
|
DNSNames: []string{
|
||||||
hostname,
|
cfg.NodeName,
|
||||||
"kubernetes",
|
"kubernetes",
|
||||||
"kubernetes.default",
|
"kubernetes.default",
|
||||||
"kubernetes.default.svc",
|
"kubernetes.default.svc",
|
||||||
|
|
|
@ -19,7 +19,6 @@ package certs
|
||||||
import (
|
import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
@ -36,14 +35,13 @@ func TestNewCACertAndKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewAPIServerCertAndKey(t *testing.T) {
|
func TestNewAPIServerCertAndKey(t *testing.T) {
|
||||||
hostname, err := os.Hostname()
|
hostname := "valid-hostname"
|
||||||
if err != nil {
|
|
||||||
t.Errorf("couldn't get the hostname: %v", err)
|
|
||||||
}
|
|
||||||
advertiseIP := "1.2.3.4"
|
advertiseIP := "1.2.3.4"
|
||||||
cfg := &kubeadmapi.MasterConfiguration{
|
cfg := &kubeadmapi.MasterConfiguration{
|
||||||
API: kubeadmapi.API{AdvertiseAddress: advertiseIP},
|
API: kubeadmapi.API{AdvertiseAddress: advertiseIP},
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
|
||||||
|
NodeName: "valid-hostname",
|
||||||
}
|
}
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
caCert, caKey, err := NewCACertAndKey()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ go_library(
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/kubeconfig: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:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||||
|
|
|
@ -29,7 +29,6 @@ import (
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
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
|
// BuildConfigProperties holds some simple information about how this phase should build the KubeConfig object
|
||||||
|
@ -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
|
// /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
|
// CreateInitKubeConfigFiles is called from the main init and does the work for the default phase behaviour
|
||||||
func CreateInitKubeConfigFiles(masterEndpoint, pkiDir, outDir string) error {
|
func CreateInitKubeConfigFiles(masterEndpoint, pkiDir, outDir, nodeName string) error {
|
||||||
|
|
||||||
nodeName := node.GetHostname("")
|
|
||||||
if len(nodeName) == 0 {
|
|
||||||
return fmt.Errorf("unable to get hostname for master node")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a lightweight specification for what the files should look like
|
// Create a lightweight specification for what the files should look like
|
||||||
filesToCreateFromSpec := map[string]BuildConfigProperties{
|
filesToCreateFromSpec := map[string]BuildConfigProperties{
|
||||||
|
|
|
@ -20,7 +20,6 @@ go_library(
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||||
"//pkg/util/initsystem:go_default_library",
|
"//pkg/util/initsystem:go_default_library",
|
||||||
"//pkg/util/node:go_default_library",
|
|
||||||
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
|
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
|
||||||
"//test/e2e_node/system:go_default_library",
|
"//test/e2e_node/system:go_default_library",
|
||||||
"//vendor/github.com/PuerkitoBio/purell:go_default_library",
|
"//vendor/github.com/PuerkitoBio/purell:go_default_library",
|
||||||
|
|
|
@ -46,7 +46,6 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||||
"k8s.io/kubernetes/pkg/util/initsystem"
|
"k8s.io/kubernetes/pkg/util/initsystem"
|
||||||
"k8s.io/kubernetes/pkg/util/node"
|
|
||||||
schoptions "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options"
|
schoptions "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options"
|
||||||
"k8s.io/kubernetes/test/e2e_node/system"
|
"k8s.io/kubernetes/test/e2e_node/system"
|
||||||
)
|
)
|
||||||
|
@ -271,21 +270,22 @@ func (ipc InPathCheck) Check() (warnings, errors []error) {
|
||||||
|
|
||||||
// HostnameCheck checks if hostname match dns sub domain regex.
|
// HostnameCheck checks if hostname match dns sub domain regex.
|
||||||
// If hostname doesn't match this regex, kubelet will not launch static pods like kube-apiserver/kube-controller-manager and so on.
|
// If hostname doesn't match this regex, kubelet will not launch static pods like kube-apiserver/kube-controller-manager and so on.
|
||||||
type HostnameCheck struct{}
|
type HostnameCheck struct {
|
||||||
|
nodeName string
|
||||||
|
}
|
||||||
|
|
||||||
func (hc HostnameCheck) Check() (warnings, errors []error) {
|
func (hc HostnameCheck) Check() (warnings, errors []error) {
|
||||||
errors = []error{}
|
errors = []error{}
|
||||||
warnings = []error{}
|
warnings = []error{}
|
||||||
hostname := node.GetHostname("")
|
for _, msg := range validation.ValidateNodeName(hc.nodeName, false) {
|
||||||
for _, msg := range validation.ValidateNodeName(hostname, false) {
|
errors = append(errors, fmt.Errorf("hostname \"%s\" %s", hc.nodeName, msg))
|
||||||
errors = append(errors, fmt.Errorf("hostname \"%s\" %s", hostname, msg))
|
|
||||||
}
|
}
|
||||||
addr, err := net.LookupHost(hostname)
|
addr, err := net.LookupHost(hc.nodeName)
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
warnings = append(warnings, fmt.Errorf("hostname \"%s\" could not be reached", hostname))
|
warnings = append(warnings, fmt.Errorf("hostname \"%s\" could not be reached", hc.nodeName))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, fmt.Errorf("hostname \"%s\" %s", hostname, err))
|
warnings = append(warnings, fmt.Errorf("hostname \"%s\" %s", hc.nodeName, err))
|
||||||
}
|
}
|
||||||
return warnings, errors
|
return warnings, errors
|
||||||
}
|
}
|
||||||
|
@ -537,7 +537,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
checks := []Checker{
|
checks := []Checker{
|
||||||
SystemVerificationCheck{},
|
SystemVerificationCheck{},
|
||||||
IsRootCheck{},
|
IsRootCheck{},
|
||||||
HostnameCheck{},
|
HostnameCheck{nodeName: cfg.NodeName},
|
||||||
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
||||||
ServiceCheck{Service: "docker", CheckIfActive: true},
|
ServiceCheck{Service: "docker", CheckIfActive: true},
|
||||||
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
|
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
|
||||||
|
|
|
@ -18,6 +18,7 @@ go_library(
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/util/node:go_default_library",
|
||||||
"//pkg/util/version:go_default_library",
|
"//pkg/util/version:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/util/node"
|
||||||
"k8s.io/kubernetes/pkg/util/version"
|
"k8s.io/kubernetes/pkg/util/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,6 +66,8 @@ func SetInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.NodeName = node.GetHostname(cfg.NodeName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue