mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-09 03:57:41 +00:00
Merge pull request #118513 from danwinship/proxy-node-ip
kube-proxy startup node IP detection
This commit is contained in:
commit
577d524f08
@ -513,13 +513,14 @@ with the apiserver API to configure the proxy.`,
|
|||||||
type ProxyServer struct {
|
type ProxyServer struct {
|
||||||
Config *kubeproxyconfig.KubeProxyConfiguration
|
Config *kubeproxyconfig.KubeProxyConfiguration
|
||||||
|
|
||||||
Client clientset.Interface
|
Client clientset.Interface
|
||||||
Broadcaster events.EventBroadcaster
|
Broadcaster events.EventBroadcaster
|
||||||
Recorder events.EventRecorder
|
Recorder events.EventRecorder
|
||||||
NodeRef *v1.ObjectReference
|
NodeRef *v1.ObjectReference
|
||||||
HealthzServer healthcheck.ProxierHealthUpdater
|
HealthzServer healthcheck.ProxierHealthUpdater
|
||||||
Hostname string
|
Hostname string
|
||||||
NodeIP net.IP
|
PrimaryIPFamily v1.IPFamily
|
||||||
|
NodeIPs map[v1.IPFamily]net.IP
|
||||||
|
|
||||||
podCIDRs []string // only used for LocalModeNodeCIDR
|
podCIDRs []string // only used for LocalModeNodeCIDR
|
||||||
|
|
||||||
@ -550,8 +551,7 @@ func newProxyServer(config *kubeproxyconfig.KubeProxyConfiguration, master strin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.NodeIP = detectNodeIP(s.Client, s.Hostname, config.BindAddress)
|
s.PrimaryIPFamily, s.NodeIPs = detectNodeIPs(s.Client, s.Hostname, config.BindAddress)
|
||||||
klog.InfoS("Detected node IP", "address", s.NodeIP.String())
|
|
||||||
|
|
||||||
s.Broadcaster = events.NewBroadcaster(&events.EventSinkImpl{Interface: s.Client.EventsV1()})
|
s.Broadcaster = events.NewBroadcaster(&events.EventSinkImpl{Interface: s.Client.EventsV1()})
|
||||||
s.Recorder = s.Broadcaster.NewRecorder(proxyconfigscheme.Scheme, "kube-proxy")
|
s.Recorder = s.Broadcaster.NewRecorder(proxyconfigscheme.Scheme, "kube-proxy")
|
||||||
@ -777,12 +777,23 @@ func (s *ProxyServer) birthCry() {
|
|||||||
s.Recorder.Eventf(s.NodeRef, nil, api.EventTypeNormal, "Starting", "StartKubeProxy", "")
|
s.Recorder.Eventf(s.NodeRef, nil, api.EventTypeNormal, "Starting", "StartKubeProxy", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// detectNodeIP returns the nodeIP used by the proxier
|
// detectNodeIPs returns the proxier's "node IP" or IPs, and the IP family to use if the
|
||||||
|
// node turns out to be incapable of dual-stack. (Note that kube-proxy normally runs as
|
||||||
|
// dual-stack if the backend is capable of supporting both IP families, regardless of
|
||||||
|
// whether the node is *actually* configured as dual-stack or not.)
|
||||||
|
|
||||||
|
// (Note that on Linux, the node IPs are used only to determine whether a given
|
||||||
|
// LoadBalancerSourceRanges value matches the node or not. In particular, they are *not*
|
||||||
|
// used for NodePort handling.)
|
||||||
|
//
|
||||||
// The order of precedence is:
|
// The order of precedence is:
|
||||||
// 1. config.bindAddress if bindAddress is not 0.0.0.0 or ::
|
// 1. if bindAddress is not 0.0.0.0 or ::, then it is used as the primary IP.
|
||||||
// 2. the primary IP from the Node object, if set
|
// 2. if the Node object can be fetched, then its primary IP is used as the primary IP
|
||||||
// 3. if no IP is found it defaults to 127.0.0.1 and IPv4
|
// (and its secondary IP, if any, is just ignored).
|
||||||
func detectNodeIP(client clientset.Interface, hostname, bindAddress string) net.IP {
|
// 3. otherwise the primary node IP is 127.0.0.1.
|
||||||
|
//
|
||||||
|
// In all cases, the secondary IP is the zero IP of the other IP family.
|
||||||
|
func detectNodeIPs(client clientset.Interface, hostname, bindAddress string) (v1.IPFamily, map[v1.IPFamily]net.IP) {
|
||||||
nodeIP := netutils.ParseIPSloppy(bindAddress)
|
nodeIP := netutils.ParseIPSloppy(bindAddress)
|
||||||
if nodeIP.IsUnspecified() {
|
if nodeIP.IsUnspecified() {
|
||||||
nodeIP = utilnode.GetNodeIP(client, hostname)
|
nodeIP = utilnode.GetNodeIP(client, hostname)
|
||||||
@ -791,21 +802,16 @@ func detectNodeIP(client clientset.Interface, hostname, bindAddress string) net.
|
|||||||
klog.InfoS("Can't determine this node's IP, assuming 127.0.0.1; if this is incorrect, please set the --bind-address flag")
|
klog.InfoS("Can't determine this node's IP, assuming 127.0.0.1; if this is incorrect, please set the --bind-address flag")
|
||||||
nodeIP = netutils.ParseIPSloppy("127.0.0.1")
|
nodeIP = netutils.ParseIPSloppy("127.0.0.1")
|
||||||
}
|
}
|
||||||
return nodeIP
|
|
||||||
}
|
|
||||||
|
|
||||||
// nodeIPTuple takes an addresses and return a tuple (ipv4,ipv6)
|
if netutils.IsIPv4(nodeIP) {
|
||||||
// The returned tuple is guaranteed to have the order (ipv4,ipv6). The address NOT of the passed address
|
return v1.IPv4Protocol, map[v1.IPFamily]net.IP{
|
||||||
// will have "any" address (0.0.0.0 or ::) inserted.
|
v1.IPv4Protocol: nodeIP,
|
||||||
func nodeIPTuple(bindAddress string) [2]net.IP {
|
v1.IPv6Protocol: net.IPv6zero,
|
||||||
nodes := [2]net.IP{net.IPv4zero, net.IPv6zero}
|
}
|
||||||
|
|
||||||
adr := netutils.ParseIPSloppy(bindAddress)
|
|
||||||
if netutils.IsIPv6(adr) {
|
|
||||||
nodes[1] = adr
|
|
||||||
} else {
|
} else {
|
||||||
nodes[0] = adr
|
return v1.IPv6Protocol, map[v1.IPFamily]net.IP{
|
||||||
|
v1.IPv4Protocol: net.IPv4zero,
|
||||||
|
v1.IPv6Protocol: nodeIP,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes
|
|
||||||
}
|
}
|
||||||
|
@ -92,10 +92,8 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
klog.InfoS("NodeInfo", "podCIDR", nodeInfo.Spec.PodCIDR, "podCIDRs", nodeInfo.Spec.PodCIDRs)
|
klog.InfoS("NodeInfo", "podCIDR", nodeInfo.Spec.PodCIDR, "podCIDRs", nodeInfo.Spec.PodCIDRs)
|
||||||
}
|
}
|
||||||
|
|
||||||
primaryFamily := v1.IPv4Protocol
|
|
||||||
primaryProtocol := utiliptables.ProtocolIPv4
|
primaryProtocol := utiliptables.ProtocolIPv4
|
||||||
if netutils.IsIPv6(s.NodeIP) {
|
if s.PrimaryIPFamily == v1.IPv6Protocol {
|
||||||
primaryFamily = v1.IPv6Protocol
|
|
||||||
primaryProtocol = utiliptables.ProtocolIPv6
|
primaryProtocol = utiliptables.ProtocolIPv6
|
||||||
}
|
}
|
||||||
execer := exec.New()
|
execer := exec.New()
|
||||||
@ -124,11 +122,11 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
|
|
||||||
// Validate NodePortAddresses is single-stack
|
// Validate NodePortAddresses is single-stack
|
||||||
npaByFamily := proxyutil.MapCIDRsByIPFamily(config.NodePortAddresses)
|
npaByFamily := proxyutil.MapCIDRsByIPFamily(config.NodePortAddresses)
|
||||||
secondaryFamily := proxyutil.OtherIPFamily(primaryFamily)
|
secondaryFamily := proxyutil.OtherIPFamily(s.PrimaryIPFamily)
|
||||||
badAddrs := npaByFamily[secondaryFamily]
|
badAddrs := npaByFamily[secondaryFamily]
|
||||||
if len(badAddrs) > 0 {
|
if len(badAddrs) > 0 {
|
||||||
klog.InfoS("Ignoring --nodeport-addresses of the wrong family", "ipFamily", secondaryFamily, "addresses", badAddrs)
|
klog.InfoS("Ignoring --nodeport-addresses of the wrong family", "ipFamily", secondaryFamily, "addresses", badAddrs)
|
||||||
nodePortAddresses = npaByFamily[primaryFamily]
|
nodePortAddresses = npaByFamily[s.PrimaryIPFamily]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +155,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
int(*config.IPTables.MasqueradeBit),
|
int(*config.IPTables.MasqueradeBit),
|
||||||
localDetectors,
|
localDetectors,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
nodeIPTuple(config.BindAddress),
|
s.NodeIPs,
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
nodePortAddresses,
|
nodePortAddresses,
|
||||||
@ -172,7 +170,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
|
|
||||||
// TODO this has side effects that should only happen when Run() is invoked.
|
// TODO this has side effects that should only happen when Run() is invoked.
|
||||||
proxier, err = iptables.NewProxier(
|
proxier, err = iptables.NewProxier(
|
||||||
primaryFamily,
|
s.PrimaryIPFamily,
|
||||||
iptInterface,
|
iptInterface,
|
||||||
utilsysctl.New(),
|
utilsysctl.New(),
|
||||||
execer,
|
execer,
|
||||||
@ -183,7 +181,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
int(*config.IPTables.MasqueradeBit),
|
int(*config.IPTables.MasqueradeBit),
|
||||||
localDetector,
|
localDetector,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
s.NodeIP,
|
s.NodeIPs[s.PrimaryIPFamily],
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
nodePortAddresses,
|
nodePortAddresses,
|
||||||
@ -205,8 +203,6 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
if dualStack {
|
if dualStack {
|
||||||
klog.InfoS("Creating dualStackProxier for ipvs")
|
klog.InfoS("Creating dualStackProxier for ipvs")
|
||||||
|
|
||||||
nodeIPs := nodeIPTuple(config.BindAddress)
|
|
||||||
|
|
||||||
// Always ordered to match []ipt
|
// Always ordered to match []ipt
|
||||||
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
|
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
|
||||||
localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, nodeInfo)
|
localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, nodeInfo)
|
||||||
@ -231,7 +227,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
int(*config.IPTables.MasqueradeBit),
|
int(*config.IPTables.MasqueradeBit),
|
||||||
localDetectors,
|
localDetectors,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
nodeIPs,
|
s.NodeIPs,
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
config.IPVS.Scheduler,
|
config.IPVS.Scheduler,
|
||||||
@ -246,7 +242,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxier, err = ipvs.NewProxier(
|
proxier, err = ipvs.NewProxier(
|
||||||
primaryFamily,
|
s.PrimaryIPFamily,
|
||||||
iptInterface,
|
iptInterface,
|
||||||
ipvsInterface,
|
ipvsInterface,
|
||||||
ipsetInterface,
|
ipsetInterface,
|
||||||
@ -263,7 +259,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
int(*config.IPTables.MasqueradeBit),
|
int(*config.IPTables.MasqueradeBit),
|
||||||
localDetector,
|
localDetector,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
s.NodeIP,
|
s.NodeIPs[s.PrimaryIPFamily],
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
config.IPVS.Scheduler,
|
config.IPVS.Scheduler,
|
||||||
|
@ -107,111 +107,6 @@ func Test_platformApplyDefaults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_detectNodeIP(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
name string
|
|
||||||
nodeInfo *v1.Node
|
|
||||||
hostname string
|
|
||||||
bindAddress string
|
|
||||||
expectedIP net.IP
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Bind address IPv4 unicast address and no Node object",
|
|
||||||
nodeInfo: makeNodeWithAddresses("", "", ""),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "10.0.0.1",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("10.0.0.1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address IPv6 unicast address and no Node object",
|
|
||||||
nodeInfo: makeNodeWithAddresses("", "", ""),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "fd00:4321::2",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("fd00:4321::2"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "No Valid IP found",
|
|
||||||
nodeInfo: makeNodeWithAddresses("", "", ""),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("127.0.0.1"),
|
|
||||||
},
|
|
||||||
// Disabled because the GetNodeIP method has a backoff retry mechanism
|
|
||||||
// and the test takes more than 30 seconds
|
|
||||||
// ok k8s.io/kubernetes/cmd/kube-proxy/app 34.136s
|
|
||||||
// {
|
|
||||||
// name: "No Valid IP found and unspecified bind address",
|
|
||||||
// nodeInfo: makeNodeWithAddresses("", "", ""),
|
|
||||||
// hostname: "fakeHost",
|
|
||||||
// bindAddress: "0.0.0.0",
|
|
||||||
// expectedIP: net.IP{127,0,0,1),
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
name: "Bind address 0.0.0.0 and node with IPv4 InternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "192.168.1.1", "90.90.90.90"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "0.0.0.0",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("192.168.1.1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address :: and node with IPv4 InternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "192.168.1.1", "90.90.90.90"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "::",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("192.168.1.1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address 0.0.0.0 and node with IPv6 InternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "fd00:1234::1", "2001:db8::2"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "0.0.0.0",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("fd00:1234::1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address :: and node with IPv6 InternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "fd00:1234::1", "2001:db8::2"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "::",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("fd00:1234::1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address 0.0.0.0 and node with only IPv4 ExternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "", "90.90.90.90"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "0.0.0.0",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("90.90.90.90"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address :: and node with only IPv4 ExternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "", "90.90.90.90"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "::",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("90.90.90.90"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address 0.0.0.0 and node with only IPv6 ExternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "", "2001:db8::2"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "0.0.0.0",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("2001:db8::2"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bind address :: and node with only IPv6 ExternalIP set",
|
|
||||||
nodeInfo: makeNodeWithAddresses("fakeHost", "", "2001:db8::2"),
|
|
||||||
hostname: "fakeHost",
|
|
||||||
bindAddress: "::",
|
|
||||||
expectedIP: netutils.ParseIPSloppy("2001:db8::2"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
client := clientsetfake.NewSimpleClientset(c.nodeInfo)
|
|
||||||
ip := detectNodeIP(client, c.hostname, c.bindAddress)
|
|
||||||
if !ip.Equal(c.expectedIP) {
|
|
||||||
t.Errorf("Case[%s] Expected IP %q got %q", c.name, c.expectedIP, ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_getLocalDetector(t *testing.T) {
|
func Test_getLocalDetector(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
mode proxyconfigapi.LocalMode
|
mode proxyconfigapi.LocalMode
|
||||||
@ -502,35 +397,6 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeNodeWithAddresses(name, internal, external string) *v1.Node {
|
|
||||||
if name == "" {
|
|
||||||
return &v1.Node{}
|
|
||||||
}
|
|
||||||
|
|
||||||
node := &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: name,
|
|
||||||
},
|
|
||||||
Status: v1.NodeStatus{
|
|
||||||
Addresses: []v1.NodeAddress{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if internal != "" {
|
|
||||||
node.Status.Addresses = append(node.Status.Addresses,
|
|
||||||
v1.NodeAddress{Type: v1.NodeInternalIP, Address: internal},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if external != "" {
|
|
||||||
node.Status.Addresses = append(node.Status.Addresses,
|
|
||||||
v1.NodeAddress{Type: v1.NodeExternalIP, Address: external},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeNodeWithPodCIDRs(cidrs ...string) *v1.Node {
|
func makeNodeWithPodCIDRs(cidrs ...string) *v1.Node {
|
||||||
if len(cidrs) == 0 {
|
if len(cidrs) == 0 {
|
||||||
return &v1.Node{}
|
return &v1.Node{}
|
||||||
@ -812,7 +678,10 @@ func TestProxyServer_createProxier(t *testing.T) {
|
|||||||
Config: tt.config,
|
Config: tt.config,
|
||||||
Client: client,
|
Client: client,
|
||||||
Hostname: "nodename",
|
Hostname: "nodename",
|
||||||
NodeIP: netutils.ParseIPSloppy("127.0.0.1"),
|
NodeIPs: map[v1.IPFamily]net.IP{
|
||||||
|
v1.IPv4Protocol: netutils.ParseIPSloppy("127.0.0.1"),
|
||||||
|
v1.IPv6Protocol: net.IPv6zero,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_, err := s.createProxier(tt.config)
|
_, err := s.createProxier(tt.config)
|
||||||
// TODO: mock the exec.Interface to not fail probing iptables
|
// TODO: mock the exec.Interface to not fail probing iptables
|
||||||
|
@ -24,14 +24,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"k8s.io/utils/pointer"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||||
componentbaseconfig "k8s.io/component-base/config"
|
componentbaseconfig "k8s.io/component-base/config"
|
||||||
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
|
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
|
||||||
|
"k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestLoadConfig tests proper operation of loadConfig()
|
// TestLoadConfig tests proper operation of loadConfig()
|
||||||
@ -464,3 +464,171 @@ func TestAddressFromDeprecatedFlags(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeNodeWithAddresses(name, internal, external string) *v1.Node {
|
||||||
|
if name == "" {
|
||||||
|
return &v1.Node{}
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &v1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
|
Status: v1.NodeStatus{
|
||||||
|
Addresses: []v1.NodeAddress{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if internal != "" {
|
||||||
|
node.Status.Addresses = append(node.Status.Addresses,
|
||||||
|
v1.NodeAddress{Type: v1.NodeInternalIP, Address: internal},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if external != "" {
|
||||||
|
node.Status.Addresses = append(node.Status.Addresses,
|
||||||
|
v1.NodeAddress{Type: v1.NodeExternalIP, Address: external},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_detectNodeIPs(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
nodeInfo *v1.Node
|
||||||
|
hostname string
|
||||||
|
bindAddress string
|
||||||
|
expectedFamily v1.IPFamily
|
||||||
|
expectedIPv4 string
|
||||||
|
expectedIPv6 string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Bind address IPv4 unicast address and no Node object",
|
||||||
|
nodeInfo: makeNodeWithAddresses("", "", ""),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "10.0.0.1",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "10.0.0.1",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address IPv6 unicast address and no Node object",
|
||||||
|
nodeInfo: makeNodeWithAddresses("", "", ""),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "fd00:4321::2",
|
||||||
|
expectedFamily: v1.IPv6Protocol,
|
||||||
|
expectedIPv4: "0.0.0.0",
|
||||||
|
expectedIPv6: "fd00:4321::2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "No Valid IP found",
|
||||||
|
nodeInfo: makeNodeWithAddresses("", "", ""),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "127.0.0.1",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
// Disabled because the GetNodeIP method has a backoff retry mechanism
|
||||||
|
// and the test takes more than 30 seconds
|
||||||
|
// ok k8s.io/kubernetes/cmd/kube-proxy/app 34.136s
|
||||||
|
// {
|
||||||
|
// name: "No Valid IP found and unspecified bind address",
|
||||||
|
// nodeInfo: makeNodeWithAddresses("", "", ""),
|
||||||
|
// hostname: "fakeHost",
|
||||||
|
// bindAddress: "0.0.0.0",
|
||||||
|
// expectedFamily: v1.IPv4Protocol,
|
||||||
|
// expectedIPv4: "127.0.0.1",
|
||||||
|
// expectedIPv6: "::",
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name: "Bind address 0.0.0.0 and node with IPv4 InternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "192.168.1.1", "90.90.90.90"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "0.0.0.0",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "192.168.1.1",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address :: and node with IPv4 InternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "192.168.1.1", "90.90.90.90"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "::",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "192.168.1.1",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address 0.0.0.0 and node with IPv6 InternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "fd00:1234::1", "2001:db8::2"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "0.0.0.0",
|
||||||
|
expectedFamily: v1.IPv6Protocol,
|
||||||
|
expectedIPv4: "0.0.0.0",
|
||||||
|
expectedIPv6: "fd00:1234::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address :: and node with IPv6 InternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "fd00:1234::1", "2001:db8::2"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "::",
|
||||||
|
expectedFamily: v1.IPv6Protocol,
|
||||||
|
expectedIPv4: "0.0.0.0",
|
||||||
|
expectedIPv6: "fd00:1234::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address 0.0.0.0 and node with only IPv4 ExternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "", "90.90.90.90"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "0.0.0.0",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "90.90.90.90",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address :: and node with only IPv4 ExternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "", "90.90.90.90"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "::",
|
||||||
|
expectedFamily: v1.IPv4Protocol,
|
||||||
|
expectedIPv4: "90.90.90.90",
|
||||||
|
expectedIPv6: "::",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address 0.0.0.0 and node with only IPv6 ExternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "", "2001:db8::2"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "0.0.0.0",
|
||||||
|
expectedFamily: v1.IPv6Protocol,
|
||||||
|
expectedIPv4: "0.0.0.0",
|
||||||
|
expectedIPv6: "2001:db8::2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bind address :: and node with only IPv6 ExternalIP set",
|
||||||
|
nodeInfo: makeNodeWithAddresses("fakeHost", "", "2001:db8::2"),
|
||||||
|
hostname: "fakeHost",
|
||||||
|
bindAddress: "::",
|
||||||
|
expectedFamily: v1.IPv6Protocol,
|
||||||
|
expectedIPv4: "0.0.0.0",
|
||||||
|
expectedIPv6: "2001:db8::2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
client := clientsetfake.NewSimpleClientset(c.nodeInfo)
|
||||||
|
primaryFamily, ips := detectNodeIPs(client, c.hostname, c.bindAddress)
|
||||||
|
if primaryFamily != c.expectedFamily {
|
||||||
|
t.Errorf("Expected family %q got %q", c.expectedFamily, primaryFamily)
|
||||||
|
}
|
||||||
|
if ips[v1.IPv4Protocol].String() != c.expectedIPv4 {
|
||||||
|
t.Errorf("Expected IPv4 %q got %q", c.expectedIPv4, ips[v1.IPv4Protocol].String())
|
||||||
|
}
|
||||||
|
if ips[v1.IPv6Protocol].String() != c.expectedIPv6 {
|
||||||
|
t.Errorf("Expected IPv6 %q got %q", c.expectedIPv6, ips[v1.IPv6Protocol].String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -67,7 +67,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
config.IPTables.MinSyncPeriod.Duration,
|
config.IPTables.MinSyncPeriod.Duration,
|
||||||
config.ClusterCIDR,
|
config.ClusterCIDR,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
nodeIPTuple(config.BindAddress),
|
s.NodeIPs,
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
config.Winkernel,
|
config.Winkernel,
|
||||||
@ -79,7 +79,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
|||||||
config.IPTables.MinSyncPeriod.Duration,
|
config.IPTables.MinSyncPeriod.Duration,
|
||||||
config.ClusterCIDR,
|
config.ClusterCIDR,
|
||||||
s.Hostname,
|
s.Hostname,
|
||||||
s.NodeIP,
|
s.NodeIPs[s.PrimaryIPFamily],
|
||||||
s.Recorder,
|
s.Recorder,
|
||||||
s.HealthzServer,
|
s.HealthzServer,
|
||||||
config.Winkernel,
|
config.Winkernel,
|
||||||
|
@ -328,7 +328,7 @@ func NewDualStackProxier(
|
|||||||
masqueradeBit int,
|
masqueradeBit int,
|
||||||
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
|
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
|
||||||
hostname string,
|
hostname string,
|
||||||
nodeIP [2]net.IP,
|
nodeIPs map[v1.IPFamily]net.IP,
|
||||||
recorder events.EventRecorder,
|
recorder events.EventRecorder,
|
||||||
healthzServer healthcheck.ProxierHealthUpdater,
|
healthzServer healthcheck.ProxierHealthUpdater,
|
||||||
nodePortAddresses []string,
|
nodePortAddresses []string,
|
||||||
@ -336,14 +336,14 @@ func NewDualStackProxier(
|
|||||||
// Create an ipv4 instance of the single-stack proxier
|
// Create an ipv4 instance of the single-stack proxier
|
||||||
ipv4Proxier, err := NewProxier(v1.IPv4Protocol, ipt[0], sysctl,
|
ipv4Proxier, err := NewProxier(v1.IPv4Protocol, ipt[0], sysctl,
|
||||||
exec, syncPeriod, minSyncPeriod, masqueradeAll, localhostNodePorts, masqueradeBit, localDetectors[0], hostname,
|
exec, syncPeriod, minSyncPeriod, masqueradeAll, localhostNodePorts, masqueradeBit, localDetectors[0], hostname,
|
||||||
nodeIP[0], recorder, healthzServer, nodePortAddresses)
|
nodeIPs[v1.IPv4Protocol], recorder, healthzServer, nodePortAddresses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv4 proxier: %v", err)
|
return nil, fmt.Errorf("unable to create ipv4 proxier: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Proxier, err := NewProxier(v1.IPv6Protocol, ipt[1], sysctl,
|
ipv6Proxier, err := NewProxier(v1.IPv6Protocol, ipt[1], sysctl,
|
||||||
exec, syncPeriod, minSyncPeriod, masqueradeAll, false, masqueradeBit, localDetectors[1], hostname,
|
exec, syncPeriod, minSyncPeriod, masqueradeAll, false, masqueradeBit, localDetectors[1], hostname,
|
||||||
nodeIP[1], recorder, healthzServer, nodePortAddresses)
|
nodeIPs[v1.IPv6Protocol], recorder, healthzServer, nodePortAddresses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv6 proxier: %v", err)
|
return nil, fmt.Errorf("unable to create ipv6 proxier: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,7 @@ func NewDualStackProxier(
|
|||||||
masqueradeBit int,
|
masqueradeBit int,
|
||||||
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
|
localDetectors [2]proxyutiliptables.LocalTrafficDetector,
|
||||||
hostname string,
|
hostname string,
|
||||||
nodeIP [2]net.IP,
|
nodeIPs map[v1.IPFamily]net.IP,
|
||||||
recorder events.EventRecorder,
|
recorder events.EventRecorder,
|
||||||
healthzServer healthcheck.ProxierHealthUpdater,
|
healthzServer healthcheck.ProxierHealthUpdater,
|
||||||
scheduler string,
|
scheduler string,
|
||||||
@ -494,7 +494,7 @@ func NewDualStackProxier(
|
|||||||
ipv4Proxier, err := NewProxier(v1.IPv4Protocol, ipt[0], ipvs, safeIpset, sysctl,
|
ipv4Proxier, err := NewProxier(v1.IPv4Protocol, ipt[0], ipvs, safeIpset, sysctl,
|
||||||
exec, syncPeriod, minSyncPeriod, filterCIDRs(false, excludeCIDRs), strictARP,
|
exec, syncPeriod, minSyncPeriod, filterCIDRs(false, excludeCIDRs), strictARP,
|
||||||
tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit,
|
tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit,
|
||||||
localDetectors[0], hostname, nodeIP[0],
|
localDetectors[0], hostname, nodeIPs[v1.IPv4Protocol],
|
||||||
recorder, healthzServer, scheduler, nodePortAddresses, kernelHandler)
|
recorder, healthzServer, scheduler, nodePortAddresses, kernelHandler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv4 proxier: %v", err)
|
return nil, fmt.Errorf("unable to create ipv4 proxier: %v", err)
|
||||||
@ -503,7 +503,7 @@ func NewDualStackProxier(
|
|||||||
ipv6Proxier, err := NewProxier(v1.IPv6Protocol, ipt[1], ipvs, safeIpset, sysctl,
|
ipv6Proxier, err := NewProxier(v1.IPv6Protocol, ipt[1], ipvs, safeIpset, sysctl,
|
||||||
exec, syncPeriod, minSyncPeriod, filterCIDRs(true, excludeCIDRs), strictARP,
|
exec, syncPeriod, minSyncPeriod, filterCIDRs(true, excludeCIDRs), strictARP,
|
||||||
tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit,
|
tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit,
|
||||||
localDetectors[1], hostname, nodeIP[1],
|
localDetectors[1], hostname, nodeIPs[v1.IPv6Protocol],
|
||||||
recorder, healthzServer, scheduler, nodePortAddresses, kernelHandler)
|
recorder, healthzServer, scheduler, nodePortAddresses, kernelHandler)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv6 proxier: %v", err)
|
return nil, fmt.Errorf("unable to create ipv6 proxier: %v", err)
|
||||||
|
@ -809,7 +809,7 @@ func NewDualStackProxier(
|
|||||||
minSyncPeriod time.Duration,
|
minSyncPeriod time.Duration,
|
||||||
clusterCIDR string,
|
clusterCIDR string,
|
||||||
hostname string,
|
hostname string,
|
||||||
nodeIP [2]net.IP,
|
nodeIPs map[v1.IPFamily]net.IP,
|
||||||
recorder events.EventRecorder,
|
recorder events.EventRecorder,
|
||||||
healthzServer healthcheck.ProxierHealthUpdater,
|
healthzServer healthcheck.ProxierHealthUpdater,
|
||||||
config config.KubeProxyWinkernelConfiguration,
|
config config.KubeProxyWinkernelConfiguration,
|
||||||
@ -818,16 +818,18 @@ func NewDualStackProxier(
|
|||||||
|
|
||||||
// Create an ipv4 instance of the single-stack proxier
|
// Create an ipv4 instance of the single-stack proxier
|
||||||
ipv4Proxier, err := NewProxier(syncPeriod, minSyncPeriod,
|
ipv4Proxier, err := NewProxier(syncPeriod, minSyncPeriod,
|
||||||
clusterCIDR, hostname, nodeIP[0], recorder, healthzServer, config, healthzPort)
|
clusterCIDR, hostname, nodeIPs[v1.IPv4Protocol], recorder, healthzServer,
|
||||||
|
config, healthzPort)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv4 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v", err, hostname, clusterCIDR, nodeIP[0])
|
return nil, fmt.Errorf("unable to create ipv4 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v", err, hostname, clusterCIDR, nodeIPs[v1.IPv4Protocol])
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Proxier, err := NewProxier(syncPeriod, minSyncPeriod,
|
ipv6Proxier, err := NewProxier(syncPeriod, minSyncPeriod,
|
||||||
clusterCIDR, hostname, nodeIP[1], recorder, healthzServer, config, healthzPort)
|
clusterCIDR, hostname, nodeIPs[v1.IPv6Protocol], recorder, healthzServer,
|
||||||
|
config, healthzPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create ipv6 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v", err, hostname, clusterCIDR, nodeIP[1])
|
return nil, fmt.Errorf("unable to create ipv6 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v", err, hostname, clusterCIDR, nodeIPs[v1.IPv6Protocol])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a meta-proxier that dispatch calls between the two
|
// Return a meta-proxier that dispatch calls between the two
|
||||||
|
Loading…
Reference in New Issue
Block a user