Change:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind feature What happened: Upon code inspection, found that kube-proxy server takes into consideration a bind address of 0.0.0.0 (IPv4), but does not check for a bind address of :: (all-zeros IPv6) when calculating its node IP. What you expected to happen: IPv6 address "::" should be taken into consideration when calculating node IP. How to reproduce it (as minimally and precisely as possible): Code inspection. Anything else we need to know?: Environment: Kubernetes version (use ): Latest master Cloud provider or hardware configuration**: VirtualBox cluster, Ubuntu 16.04.1 host, CentOS 7 guests OS (e.g. from /etc/os-release): CentOS 7 Kernel (e.g. ): 3.10.0-514.26.2.el7.x8664 SMP Tue Jul 4 15:04:05 UTC 2017 x8664 x8664 x8664 GNU/Linux Install tools: Others:
There are no sig labels on this issue. Please by: a sig: e.g., to notify the contributor experience sig, OR the label manually: e.g., to apply the label Note: Method 1 will trigger an email to the group. You can find the group list and label list . The in the method 1 has to be replaced with one of these: bugs, feature-requests, pr-reviews, test-failures, proposals
/area ipv6 /sig network

Discussion:
protocol := utiliptables.ProtocolIpv4 if net.ParseIP(config.BindAddress).To4() == nil { <ins> glog.V(0).Infof("IPv6 bind address (%s), assume IPv6 operation", config.BindAddress) </ins> protocol = utiliptables.ProtocolIpv6 }

proxyMode := getProxyMode(string(config.Mode), iptInterface, iptables.LinuxKernelCompatTester{}) if proxyMode == proxyModeIPTables { glog.V(0).Info("Using iptables Proxier.") <del> var nodeIP net.IP if config.BindAddress != "0.0.0.0" { nodeIP = net.ParseIP(config.BindAddress) } else { </del> <ins> nodeIP := net.ParseIP(config.BindAddress) if nodeIP.Equal(net.IPv4zero) || nodeIP.Equal(net.IPv6zero) { </ins> nodeIP = getNodeIP(client, hostname) } if config.IPTables.MasqueradeBit == nil {

// Each bind address below is a separate test case bindAddresses := []string{ "0.0.0.0", <del> "2001:db8::1", </del> <ins> "::", </ins> } for _, addr := range bindAddresses { options, err := NewOptions()

metricsBindAddress string }{ { <del> name:               "iptables mode, IPv4 config", </del> <ins> name:               "iptables mode, IPv4 all-zeros bind address", mode:               "iptables", bindAddress:        "0.0.0.0", clusterCIDR:        "1.2.3.0/24", healthzBindAddress: "1.2.3.4:12345", metricsBindAddress: "2.3.4.5:23456", }, { name:               "iptables mode, non-zeros IPv4 config", </ins> mode:               "iptables", bindAddress:        "9.8.7.6", clusterCIDR:        "1.2.3.0/24",

metricsBindAddress: "2.3.4.5:23456", }, { <ins> // Test for 'bindAddress: "::"' (IPv6 all-zeros) in kube-proxy // config file. The user will need to put quotes around '::' since // 'bindAddress: ::' is invalid yaml syntax. name:               "iptables mode, IPv6 "::" bind address", mode:               "iptables", bindAddress:        ""::"", clusterCIDR:        "fd00:1::0/64", healthzBindAddress: "[fd00:1::5]:12345", metricsBindAddress: "[fd00:2::5]:23456", }, { // Test for 'bindAddress: "[::]"' (IPv6 all-zeros in brackets) // in kube-proxy config file. The user will need to use // surrounding quotes here since 'bindAddress: [::]' is invalid // yaml syntax. name:               "iptables mode, IPv6 "[::]" bind address", mode:               "iptables", bindAddress:        ""[::]"", clusterCIDR:        "fd00:1::0/64", healthzBindAddress: "[fd00:1::5]:12345", metricsBindAddress: "[fd00:2::5]:23456", }, { // Test for 'bindAddress: ::0' (another form of IPv6 all-zeros). // No surrounding quotes are required around '::0'. name:               "iptables mode, IPv6 ::0 bind address", mode:               "iptables", bindAddress:        "::0", clusterCIDR:        "fd00:1::0/64", healthzBindAddress: "[fd00:1::5]:12345", metricsBindAddress: "[fd00:2::5]:23456", }, { </ins> name:               "ipvs mode, IPv6 config", mode:               "ipvs", bindAddress:        "2001:db8::1",

} for _, tc := range testCases { <ins> expBindAddr := tc.bindAddress if tc.bindAddress[0] == '"' { // Surrounding double quotes will get stripped by the yaml parser. expBindAddr = expBindAddr[1 : len(tc.bindAddress)-1] } </ins> expected := &componentconfig.KubeProxyConfiguration{ <del> BindAddress: tc.bindAddress, </del> <ins> BindAddress: expBindAddr, </ins> ClientConnection: componentconfig.ClientConnectionConfiguration{ AcceptContentTypes: "abc", Burst:              100,

config, err := options.loadConfig([]byte(yaml)) assert.NoError(t, err, "unexpected error for %s: %v", tc.name, err) if !reflect.DeepEqual(expected, config) { <del> t.Fatalf("unexpected config for %s test, diff = %s", tc.name, diff.ObjectDiff(config, expected)) </del> <ins> t.Fatalf("unexpected config for %s, diff = %s", tc.name, diff.ObjectDiff(config, expected)) </ins> } } }

config: "kind: KubeSchedulerConfiguration", expErr: "unexpected config type", }, <ins> { name:   "Missing quotes around :: bindAddress", config: "bindAddress: ::", expErr: "mapping values are not allowed in this context", }, </ins> } version := "apiVersion: componentconfig/v1alpha1" for _, tc := range testCases {

var zeroIPv4 = net.ParseIP("0.0.0.0") var localhostIPv4 = net.ParseIP("127.0.0.1") <del> var zeroIPv6 = net.ParseIP("::0") </del> <ins> var zeroIPv6 = net.ParseIP("::") </ins> var localhostIPv6 = net.ParseIP("::1") // Build a slice of iptables args that are common to from-container and from-host portal rules.