Merge pull request #29907 from luxas/lookup_ip_better
Automatic merge from submit-queue [kubelet] Auto-discover node IP if neither cloud provider exists and IP is not explicitly specified One example where the earlier implementation failed is when running kubelet on CoreOS (bare-metal), where the nameserver is set to `8.8.8.8`. kubelet tries to lookup the node name agains Google DNS, which obviously fails. The kubelet won't recover after that. The workaround hsa been to set `--hostname-override` to an IP address, but it's quite annoying to try to make a multi-distro way of getting the IP in bash for example. This way is much cleaner. Refactored the function a little bit at the same time @vishh @yujuhong @resouer @Random-Liu
This commit is contained in:
		| @@ -282,9 +282,9 @@ func (kl *Kubelet) recordNodeStatusEvent(eventtype, event string) { | |||||||
| 	kl.recorder.Eventf(kl.nodeRef, eventtype, event, "Node %s status is now: %s", kl.nodeName, event) | 	kl.recorder.Eventf(kl.nodeRef, eventtype, event, "Node %s status is now: %s", kl.nodeName, event) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Set addresses for the node. | // Set IP addresses for the node. | ||||||
| func (kl *Kubelet) setNodeAddress(node *api.Node) error { | func (kl *Kubelet) setNodeAddress(node *api.Node) error { | ||||||
| 	// Set addresses for the node. |  | ||||||
| 	if kl.cloud != nil { | 	if kl.cloud != nil { | ||||||
| 		instances, ok := kl.cloud.Instances() | 		instances, ok := kl.cloud.Instances() | ||||||
| 		if !ok { | 		if !ok { | ||||||
| @@ -293,56 +293,46 @@ func (kl *Kubelet) setNodeAddress(node *api.Node) error { | |||||||
| 		// TODO(roberthbailey): Can we do this without having credentials to talk | 		// TODO(roberthbailey): Can we do this without having credentials to talk | ||||||
| 		// to the cloud provider? | 		// to the cloud provider? | ||||||
| 		// TODO(justinsb): We can if CurrentNodeName() was actually CurrentNode() and returned an interface | 		// TODO(justinsb): We can if CurrentNodeName() was actually CurrentNode() and returned an interface | ||||||
|  | 		// TODO: If IP addresses couldn't be fetched from the cloud provider, should kubelet fallback on the other methods for getting the IP below? | ||||||
| 		nodeAddresses, err := instances.NodeAddresses(kl.nodeName) | 		nodeAddresses, err := instances.NodeAddresses(kl.nodeName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to get node address from cloud provider: %v", err) | 			return fmt.Errorf("failed to get node address from cloud provider: %v", err) | ||||||
| 		} | 		} | ||||||
| 		node.Status.Addresses = nodeAddresses | 		node.Status.Addresses = nodeAddresses | ||||||
| 	} else { | 	} else { | ||||||
|  | 		var ipAddr net.IP | ||||||
|  | 		var err error | ||||||
|  |  | ||||||
|  | 		// 1) Use nodeIP if set | ||||||
|  | 		// 2) If the user has specified an IP to HostnameOverride, use it | ||||||
|  | 		// 3) Lookup the IP from node name by DNS and use the first non-loopback ipv4 address | ||||||
|  | 		// 4) Try to get the IP from the network interface used as default gateway | ||||||
| 		if kl.nodeIP != nil { | 		if kl.nodeIP != nil { | ||||||
| 			node.Status.Addresses = []api.NodeAddress{ | 			ipAddr = kl.nodeIP | ||||||
| 				{Type: api.NodeLegacyHostIP, Address: kl.nodeIP.String()}, |  | ||||||
| 				{Type: api.NodeInternalIP, Address: kl.nodeIP.String()}, |  | ||||||
| 			} |  | ||||||
| 		} else if addr := net.ParseIP(kl.hostname); addr != nil { | 		} else if addr := net.ParseIP(kl.hostname); addr != nil { | ||||||
| 			node.Status.Addresses = []api.NodeAddress{ | 			ipAddr = addr | ||||||
| 				{Type: api.NodeLegacyHostIP, Address: addr.String()}, |  | ||||||
| 				{Type: api.NodeInternalIP, Address: addr.String()}, |  | ||||||
| 			} |  | ||||||
| 		} else { | 		} else { | ||||||
| 			addrs, err := net.LookupIP(node.Name) | 			var addrs []net.IP | ||||||
| 			if err != nil { | 			addrs, err = net.LookupIP(node.Name) | ||||||
| 				return fmt.Errorf("can't get ip address of node %s: %v", node.Name, err) | 			for _, addr := range addrs { | ||||||
| 			} else if len(addrs) == 0 { | 				if !addr.IsLoopback() && addr.To4() != nil { | ||||||
| 				return fmt.Errorf("no ip address for node %v", node.Name) | 					ipAddr = addr | ||||||
| 			} else { | 					break | ||||||
| 				// check all ip addresses for this node.Name and try to find the first non-loopback IPv4 address. |  | ||||||
| 				// If no match is found, it uses the IP of the interface with gateway on it. |  | ||||||
| 				for _, ip := range addrs { |  | ||||||
| 					if ip.IsLoopback() { |  | ||||||
| 						continue |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					if ip.To4() != nil { |  | ||||||
| 						node.Status.Addresses = []api.NodeAddress{ |  | ||||||
| 							{Type: api.NodeLegacyHostIP, Address: ip.String()}, |  | ||||||
| 							{Type: api.NodeInternalIP, Address: ip.String()}, |  | ||||||
| 						} |  | ||||||
| 						break |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 				if len(node.Status.Addresses) == 0 { | 			if ipAddr == nil { | ||||||
| 					ip, err := utilnet.ChooseHostInterface() | 				ipAddr, err = utilnet.ChooseHostInterface() | ||||||
| 					if err != nil { | 			} | ||||||
| 						return err | 		} | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					node.Status.Addresses = []api.NodeAddress{ | 		if ipAddr == nil { | ||||||
| 						{Type: api.NodeLegacyHostIP, Address: ip.String()}, | 			// We tried everything we could, but the IP address wasn't fetchable; error out | ||||||
| 						{Type: api.NodeInternalIP, Address: ip.String()}, | 			return fmt.Errorf("can't get ip address of node %s. error: %v", node.Name, err) | ||||||
| 					} | 		} else { | ||||||
| 				} | 			node.Status.Addresses = []api.NodeAddress{ | ||||||
|  | 				{Type: api.NodeLegacyHostIP, Address: ipAddr.String()}, | ||||||
|  | 				{Type: api.NodeInternalIP, Address: ipAddr.String()}, | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Submit Queue
					Kubernetes Submit Queue