Change:
kubelet.kubeClient = nil // ensure only the heartbeat client is used kubelet.hostname = testKubeletHostname <del> existingNode := v1.Node{ ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname, Annotations: make(map[string]string)}, Spec:       v1.NodeSpec{}, } // TODO : is it possible to mock validateNodeIP() to avoid relying on the host interface addresses ? addrs, err := net.InterfaceAddrs() assert.NoError(t, err) for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip != nil && !ip.IsLoopback() && ip.To4() != nil { kubelet.nodeIP = ip break } } assert.NotNil(t, kubelet.nodeIP) fakeCloud := &fakecloud.FakeCloud{ Addresses: []v1.NodeAddress{ { Type:    v1.NodeExternalIP, Address: "132.143.154.163", </del> <ins> cases := []struct { name              string nodeIP            net.IP nodeAddresses     []v1.NodeAddress expectedAddresses []v1.NodeAddress shouldError       bool }{ { name:   "A single InternalIP", nodeIP: net.ParseIP("10.1.1.1"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <del> { Type:    v1.NodeExternalIP, Address: kubelet.nodeIP.String(), </del> <ins> expectedAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <del> { Type:    v1.NodeInternalIP, Address: "132.143.154.164", </del> <ins> shouldError: false, }, { name:   "NodeIP is external", nodeIP: net.ParseIP("55.55.55.55"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <del> { Type:    v1.NodeInternalIP, Address: kubelet.nodeIP.String(), </del> <ins> expectedAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <del> { Type:    v1.NodeInternalIP, Address: "132.143.154.165", </del> <ins> shouldError: false, }, { // Accommodating #45201 and #49202 name:   "InternalIP and ExternalIP are the same", nodeIP: net.ParseIP("55.55.55.55"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "55.55.55.55"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <del> { Type:    v1.NodeHostName, Address: testKubeletHostname, </del> <ins> expectedAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "55.55.55.55"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, </ins> }, <ins> shouldError: false, </ins> }, <del> Err: nil, } kubelet.cloud = fakeCloud kubelet.cloudproviderRequestParallelism = make(chan int, 1) kubelet.cloudproviderRequestSync = make(chan int) kubelet.cloudproviderRequestTimeout = 10 * time.Second kubelet.setNodeAddress(&existingNode) expectedAddresses := []v1.NodeAddress{ </del> { <del> Type:    v1.NodeExternalIP, Address: kubelet.nodeIP.String(), </del> <ins> name:   "An Internal/ExternalIP, an Internal/ExternalDNS", nodeIP: net.ParseIP("10.1.1.1"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeInternalDNS, Address: "ip-10-1-1-1.us-west-2.compute.internal"}, {Type: v1.NodeExternalDNS, Address: "ec2-55-55-55-55.us-west-2.compute.amazonaws.com"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, }, expectedAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeInternalDNS, Address: "ip-10-1-1-1.us-west-2.compute.internal"}, {Type: v1.NodeExternalDNS, Address: "ec2-55-55-55-55.us-west-2.compute.amazonaws.com"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, }, shouldError: false, </ins> }, { <del> Type:    v1.NodeInternalIP, Address: kubelet.nodeIP.String(), </del> <ins> name:   "An Internal with multiple internal IPs", nodeIP: net.ParseIP("10.1.1.1"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeInternalIP, Address: "10.2.2.2"}, {Type: v1.NodeInternalIP, Address: "10.3.3.3"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, }, expectedAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, }, shouldError: false, </ins> }, { <del> Type:    v1.NodeHostName, Address: testKubeletHostname, </del> <ins> name:   "An InternalIP that isn't valid: should error", nodeIP: net.ParseIP("10.2.2.2"), nodeAddresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.1.1.1"}, {Type: v1.NodeExternalIP, Address: "55.55.55.55"}, {Type: v1.NodeHostName, Address: testKubeletHostname}, }, expectedAddresses: nil, shouldError:       true, </ins> }, } <del> assert.True(t, apiequality.Semantic.DeepEqual(expectedAddresses, existingNode.Status.Addresses), "%s", diff.ObjectDiff(expectedAddresses, existingNode.Status.Addresses)) </del> <ins> for _, testCase := range cases { // testCase setup existingNode := v1.Node{ ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname, Annotations: make(map[string]string)}, Spec:       v1.NodeSpec{}, } kubelet.nodeIP = testCase.nodeIP fakeCloud := &fakecloud.FakeCloud{ Addresses: testCase.nodeAddresses, Err:       nil, } kubelet.cloud = fakeCloud kubelet.cloudproviderRequestParallelism = make(chan int, 1) kubelet.cloudproviderRequestSync = make(chan int) kubelet.cloudproviderRequestTimeout = 10 * time.Second kubelet.nodeIPValidator = func(nodeIP net.IP) error { return nil } // execute method err := kubelet.setNodeAddress(&existingNode) if err != nil && !testCase.shouldError { t.Errorf("Unexpected error for test %s: %q", testCase.name, err) continue } else if err != nil && testCase.shouldError { // expected an error continue } // Sort both sets for consistent equality sortNodeAddresses(testCase.expectedAddresses) sortNodeAddresses(existingNode.Status.Addresses) assert.True( t, apiequality.Semantic.DeepEqual( testCase.expectedAddresses, existingNode.Status.Addresses, ), fmt.Sprintf("Test %s failed %%s", testCase.name), diff.ObjectDiff(testCase.expectedAddresses, existingNode.Status.Addresses), ) } } // sortableNodeAddress is a type for sorting []v1.NodeAddress type sortableNodeAddress []v1.NodeAddress func (s sortableNodeAddress) Len() int { return len(s) } func (s sortableNodeAddress) Less(i, j int) bool { return (string(s[i].Type) + s[i].Address) < (string(s[j].Type) + s[j].Address) } func (s sortableNodeAddress) Swap(i, j int) { s[j], s[i] = s[i], s[j] } func sortNodeAddresses(addrs sortableNodeAddress) { sort.Sort(addrs) </ins> } func TestUpdateNewNodeStatus(t *testing.T) {

Discussion:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . If this may be security issue, please disclose it privately via --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: When using the flag on the kubelet, the node's list no longer reports , , addresses. What you expected to happen: That I can explicitly set to an IP, but the other addresses will still show up. How to reproduce it (as minimally and precisely as possible): Create a new kops cluster, modify the kubelet to use the flag with the eth0 on the node. Run Anything else we need to know?: This change will probably take place in  This came up as a result of Environment: Kubernetes version (use ): 1.9.x Cloud provider or hardware configuration: AWS OS (e.g. from /etc/os-release): any Kernel (e.g. ): any Install tools: kops /sig network /sig node I'll make a PR for this change shortly