diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 995a567b11b..4d67bbb1d7c 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -565,7 +565,27 @@ func SimpleKubelet(client *client.Client, // Eventually, #2 will be replaced with instances of #3 func RunKubelet(kcfg *KubeletConfig, builder KubeletBuilder) error { kcfg.Hostname = nodeutil.GetHostname(kcfg.HostnameOverride) - kcfg.NodeName = kcfg.Hostname + + if kcfg.NodeName == "" { + // Query the cloud provider for our node name, default to Hostname + nodeName := kcfg.Hostname + if kcfg.Cloud != nil { + var err error + instances, ok := kcfg.Cloud.Instances() + if !ok { + return fmt.Errorf("failed to get instances from cloud provider") + } + + nodeName, err = instances.CurrentNodeName(kcfg.Hostname) + if err != nil { + return fmt.Errorf("error fetching current instance name from cloud provider: %v", err) + } + + glog.V(2).Infof("cloud provider determined current node name to be %s", nodeName) + } + + kcfg.NodeName = nodeName + } eventBroadcaster := record.NewBroadcaster() kcfg.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: "kubelet", Host: kcfg.NodeName}) diff --git a/pkg/cloudprovider/aws/aws.go b/pkg/cloudprovider/aws/aws.go index 4a899966b42..c6a9d099ebf 100644 --- a/pkg/cloudprovider/aws/aws.go +++ b/pkg/cloudprovider/aws/aws.go @@ -234,6 +234,10 @@ func (self *AWSCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error return errors.New("unimplemented") } +func (a *AWSCloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + // Implementation of EC2.Instances func (self *awsSdkEC2) DescribeInstances(request *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { // Instances are paged diff --git a/pkg/cloudprovider/cloud.go b/pkg/cloudprovider/cloud.go index e5d371ffeb3..3e0d50086ab 100644 --- a/pkg/cloudprovider/cloud.go +++ b/pkg/cloudprovider/cloud.go @@ -111,6 +111,9 @@ type Instances interface { // AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances // expected format for the key is standard ssh-keygen format: AddSSHKeyToAllInstances(user string, keyData []byte) error + // Returns the name of the node we are currently running on + // On most clouds (e.g. GCE) this is the hostname, so we provide the hostname + CurrentNodeName(hostname string) (string, error) } // Route is a representation of an advanced routing rule. diff --git a/pkg/cloudprovider/fake/fake.go b/pkg/cloudprovider/fake/fake.go index ed81d523899..96f39e3abde 100644 --- a/pkg/cloudprovider/fake/fake.go +++ b/pkg/cloudprovider/fake/fake.go @@ -149,6 +149,11 @@ func (f *FakeCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } +// Implementation of Instances.CurrentNodeName +func (f *FakeCloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + // NodeAddresses is a test-spy implementation of Instances.NodeAddresses. // It adds an entry "node-addresses" into the internal method call record. func (f *FakeCloud) NodeAddresses(instance string) ([]api.NodeAddress, error) { diff --git a/pkg/cloudprovider/gce/gce.go b/pkg/cloudprovider/gce/gce.go index d7cdb8a8d05..13be7164bb0 100644 --- a/pkg/cloudprovider/gce/gce.go +++ b/pkg/cloudprovider/gce/gce.go @@ -483,6 +483,11 @@ func (gce *GCECloud) getInstanceByName(name string) (*compute.Instance, error) { return res, nil } +// Implementation of Instances.CurrentNodeName +func (gce *GCECloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + func (gce *GCECloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { return wait.Poll(2*time.Second, 30*time.Second, func() (bool, error) { project, err := gce.service.Projects.Get(gce.projectID).Do() diff --git a/pkg/cloudprovider/mesos/mesos.go b/pkg/cloudprovider/mesos/mesos.go index 600c9050ac3..266fd80f989 100644 --- a/pkg/cloudprovider/mesos/mesos.go +++ b/pkg/cloudprovider/mesos/mesos.go @@ -78,6 +78,11 @@ func newMesosCloud(configReader io.Reader) (*MesosCloud, error) { } } +// Implementation of Instances.CurrentNodeName +func (c *MesosCloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + func (c *MesosCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } diff --git a/pkg/cloudprovider/openstack/openstack.go b/pkg/cloudprovider/openstack/openstack.go index c4349ebf09d..f0ed6f0e7d7 100644 --- a/pkg/cloudprovider/openstack/openstack.go +++ b/pkg/cloudprovider/openstack/openstack.go @@ -317,6 +317,11 @@ func getAddressByName(api *gophercloud.ServiceClient, name string) (string, erro return s, nil } +// Implementation of Instances.CurrentNodeName +func (i *Instances) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } diff --git a/pkg/cloudprovider/ovirt/ovirt.go b/pkg/cloudprovider/ovirt/ovirt.go index abcfff64539..6b4682411df 100644 --- a/pkg/cloudprovider/ovirt/ovirt.go +++ b/pkg/cloudprovider/ovirt/ovirt.go @@ -275,6 +275,11 @@ func (v *OVirtCloud) GetNodeResources(name string) (*api.NodeResources, error) { return nil, nil } +// Implementation of Instances.CurrentNodeName +func (v *OVirtCloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + func (v *OVirtCloud) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } diff --git a/pkg/cloudprovider/rackspace/rackspace.go b/pkg/cloudprovider/rackspace/rackspace.go index 38f2c25ebaf..e3fc2b4f3b2 100644 --- a/pkg/cloudprovider/rackspace/rackspace.go +++ b/pkg/cloudprovider/rackspace/rackspace.go @@ -380,6 +380,11 @@ func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { return errors.New("unimplemented") } +// Implementation of Instances.CurrentNodeName +func (i *Instances) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + func (i *Instances) GetNodeResources(name string) (*api.NodeResources, error) { glog.V(2).Infof("GetNodeResources(%v) called", name) diff --git a/pkg/cloudprovider/vagrant/vagrant.go b/pkg/cloudprovider/vagrant/vagrant.go index e4e89ed453e..ed0bf2c91e9 100644 --- a/pkg/cloudprovider/vagrant/vagrant.go +++ b/pkg/cloudprovider/vagrant/vagrant.go @@ -135,6 +135,11 @@ func (v *VagrantCloud) AddSSHKeyToAllInstances(user string, keyData []byte) erro return errors.New("unimplemented") } +// Implementation of Instances.CurrentNodeName +func (v *VagrantCloud) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + // NodeAddresses returns the NodeAddresses of a particular machine instance. func (v *VagrantCloud) NodeAddresses(instance string) ([]api.NodeAddress, error) { // Due to vagrant not running with a dedicated DNS setup, we return the IP address of a minion as its hostname at this time diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index d1070cc390b..7a6b5c40983 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1849,6 +1849,7 @@ func (kl *Kubelet) setNodeStatus(node *api.Node) error { } // TODO(roberthbailey): Can we do this without having credentials to talk // to the cloud provider? + // TODO(justinsb): We can if CurrentNodeName() was actually CurrentNode() and returned an interface nodeAddresses, err := instances.NodeAddresses(kl.nodeName) if err != nil { return fmt.Errorf("failed to get node address from cloud provider: %v", err)