mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-11 04:52:08 +00:00
Merge the ExternalTrafficPolicy: Local
tests together
Merge TestOnlyLocalExternalIPs, TestOnlyLocalLoadBalancing, and TestOnlyLocalNodePorts together into TestExternalTrafficPolicyLocal. Drop the assertIPTablesRulesEqual tests in favor of runPacketFlowTests. Remove TestOnlyLocalNodePortsNoClusterCIDR; the relevant bits of the "no local detector" case are already fully covered by TestInternalExternalMasquerade.
This commit is contained in:
parent
ff5f5bc161
commit
19f19e2f4f
@ -2864,12 +2864,20 @@ func TestMasqueradeRule(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnlyLocalExternalIPs(t *testing.T) {
|
||||
// TestExternalTrafficPolicyLocal tests that traffic to externally-facing IPs does not get
|
||||
// masqueraded when using Local traffic policy. For traffic from external sources, that
|
||||
// means it can also only be routed to local endpoints, but for traffic from internal
|
||||
// sources, it gets routed to all endpoints.
|
||||
func TestExternalTrafficPolicyLocal(t *testing.T) {
|
||||
ipt := iptablestest.NewFake()
|
||||
fp := NewFakeProxier(ipt)
|
||||
|
||||
svcIP := "172.30.0.41"
|
||||
svcPort := 80
|
||||
svcNodePort := 3001
|
||||
svcHealthCheckNodePort := 30000
|
||||
svcExternalIPs := "192.168.99.11"
|
||||
svcLBIP := "1.2.3.4"
|
||||
svcPortName := proxy.ServicePortName{
|
||||
NamespacedName: makeNSN("ns1", "svc1"),
|
||||
Port: "p80",
|
||||
@ -2877,7 +2885,7 @@ func TestOnlyLocalExternalIPs(t *testing.T) {
|
||||
|
||||
makeServiceMap(fp,
|
||||
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
|
||||
svc.Spec.Type = "NodePort"
|
||||
svc.Spec.Type = v1.ServiceTypeLoadBalancer
|
||||
svc.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyLocal
|
||||
svc.Spec.ClusterIP = svcIP
|
||||
svc.Spec.ExternalIPs = []string{svcExternalIPs}
|
||||
@ -2885,10 +2893,16 @@ func TestOnlyLocalExternalIPs(t *testing.T) {
|
||||
Name: svcPortName.Port,
|
||||
Port: int32(svcPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
NodePort: int32(svcNodePort),
|
||||
TargetPort: intstr.FromInt32(int32(svcPort)),
|
||||
}}
|
||||
svc.Spec.HealthCheckNodePort = int32(svcHealthCheckNodePort)
|
||||
svc.Status.LoadBalancer.Ingress = []v1.LoadBalancerIngress{{
|
||||
IP: svcLBIP,
|
||||
}}
|
||||
}),
|
||||
)
|
||||
|
||||
epIP1 := "10.180.0.1"
|
||||
epIP2 := "10.180.2.1"
|
||||
populateEndpointSlices(fp,
|
||||
@ -2910,55 +2924,9 @@ func TestOnlyLocalExternalIPs(t *testing.T) {
|
||||
|
||||
fp.syncProxyRules()
|
||||
|
||||
expected := dedent.Dedent(`
|
||||
*filter
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXTERNAL-SERVICES - [0:0]
|
||||
:KUBE-FIREWALL - [0:0]
|
||||
:KUBE-FORWARD - [0:0]
|
||||
:KUBE-PROXY-FIREWALL - [0:0]
|
||||
-A KUBE-FIREWALL -m comment --comment "block incoming localnet connections" -d 127.0.0.0/8 ! -s 127.0.0.0/8 -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT -j DROP
|
||||
-A KUBE-FORWARD -m conntrack --ctstate INVALID -j DROP
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding conntrack rule" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXT-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-MARK-MASQ - [0:0]
|
||||
:KUBE-POSTROUTING - [0:0]
|
||||
:KUBE-SEP-SXIVWICOYRO3J4NJ - [0:0]
|
||||
:KUBE-SEP-ZX7GRIZKSNUQ3LAJ - [0:0]
|
||||
:KUBE-SVC-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-SVL-XPGD46QRK7WJZT7O - [0:0]
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 external IP" -m tcp -p tcp -d 192.168.99.11 --dport 80 -j KUBE-EXT-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "pod traffic for ns1/svc1:p80 external destinations" -s 10.0.0.0/8 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "masquerade LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "route LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -j KUBE-SVL-XPGD46QRK7WJZT7O
|
||||
-A KUBE-MARK-MASQ -j MARK --or-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
|
||||
-A KUBE-POSTROUTING -j MARK --xor-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.0.1:80
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -s 10.180.2.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.2.1:80
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 ! -s 10.0.0.0/8 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -m statistic --mode random --probability 0.5000000000 -j KUBE-SEP-SXIVWICOYRO3J4NJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVL-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
COMMIT
|
||||
`)
|
||||
assertIPTablesRulesEqual(t, getLine(), true, expected, fp.iptablesData.String())
|
||||
|
||||
runPacketFlowTests(t, getLine(), ipt, testNodeIPs, []packetFlowTest{
|
||||
{
|
||||
name: "cluster IP hits both endpoints",
|
||||
name: "pod to cluster IP hits both endpoints, unmasqueraded",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: svcIP,
|
||||
destPort: svcPort,
|
||||
@ -2966,13 +2934,53 @@ func TestOnlyLocalExternalIPs(t *testing.T) {
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external IP hits only local endpoint, unmasqueraded",
|
||||
name: "pod to external IP hits both endpoints, unmasqueraded",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: svcExternalIPs,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to external IP hits only local endpoint, unmasqueraded",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: svcExternalIPs,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "pod to LB IP hits only both endpoints, unmasqueraded",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: svcLBIP,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to LB IP hits only local endpoint, unmasqueraded",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: svcLBIP,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "pod to NodePort hits both endpoints, unmasqueraded",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to NodePort hits only local endpoint, unmasqueraded",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -3085,346 +3093,6 @@ func TestNonLocalExternalIPs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestOnlyLocalLoadBalancing(t *testing.T) {
|
||||
ipt := iptablestest.NewFake()
|
||||
fp := NewFakeProxier(ipt)
|
||||
svcIP := "172.30.0.41"
|
||||
svcPort := 80
|
||||
svcNodePort := 3001
|
||||
svcHealthCheckNodePort := 30000
|
||||
svcLBIP := "1.2.3.4"
|
||||
svcPortName := proxy.ServicePortName{
|
||||
NamespacedName: makeNSN("ns1", "svc1"),
|
||||
Port: "p80",
|
||||
Protocol: v1.ProtocolTCP,
|
||||
}
|
||||
svcSessionAffinityTimeout := int32(10800)
|
||||
|
||||
makeServiceMap(fp,
|
||||
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
|
||||
svc.Spec.Type = "LoadBalancer"
|
||||
svc.Spec.ClusterIP = svcIP
|
||||
svc.Spec.Ports = []v1.ServicePort{{
|
||||
Name: svcPortName.Port,
|
||||
Port: int32(svcPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
NodePort: int32(svcNodePort),
|
||||
}}
|
||||
svc.Spec.HealthCheckNodePort = int32(svcHealthCheckNodePort)
|
||||
svc.Status.LoadBalancer.Ingress = []v1.LoadBalancerIngress{{
|
||||
IP: svcLBIP,
|
||||
}}
|
||||
svc.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyLocal
|
||||
svc.Spec.SessionAffinity = v1.ServiceAffinityClientIP
|
||||
svc.Spec.SessionAffinityConfig = &v1.SessionAffinityConfig{
|
||||
ClientIP: &v1.ClientIPConfig{TimeoutSeconds: &svcSessionAffinityTimeout},
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
epIP1 := "10.180.0.1"
|
||||
epIP2 := "10.180.2.1"
|
||||
populateEndpointSlices(fp,
|
||||
makeTestEndpointSlice(svcPortName.Namespace, svcPortName.Name, 1, func(eps *discovery.EndpointSlice) {
|
||||
eps.AddressType = discovery.AddressTypeIPv4
|
||||
eps.Endpoints = []discovery.Endpoint{{
|
||||
Addresses: []string{epIP1},
|
||||
}, {
|
||||
Addresses: []string{epIP2},
|
||||
NodeName: pointer.String(testHostname),
|
||||
}}
|
||||
eps.Ports = []discovery.EndpointPort{{
|
||||
Name: pointer.String(svcPortName.Port),
|
||||
Port: pointer.Int32(int32(svcPort)),
|
||||
Protocol: &tcpProtocol,
|
||||
}}
|
||||
}),
|
||||
)
|
||||
|
||||
fp.syncProxyRules()
|
||||
|
||||
expected := dedent.Dedent(`
|
||||
*filter
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXTERNAL-SERVICES - [0:0]
|
||||
:KUBE-FIREWALL - [0:0]
|
||||
:KUBE-FORWARD - [0:0]
|
||||
:KUBE-PROXY-FIREWALL - [0:0]
|
||||
-A KUBE-NODEPORTS -m comment --comment "ns1/svc1:p80 health check node port" -m tcp -p tcp --dport 30000 -j ACCEPT
|
||||
-A KUBE-FIREWALL -m comment --comment "block incoming localnet connections" -d 127.0.0.0/8 ! -s 127.0.0.0/8 -m conntrack ! --ctstate RELATED,ESTABLISHED,DNAT -j DROP
|
||||
-A KUBE-FORWARD -m conntrack --ctstate INVALID -j DROP
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding conntrack rule" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXT-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-MARK-MASQ - [0:0]
|
||||
:KUBE-POSTROUTING - [0:0]
|
||||
:KUBE-SEP-SXIVWICOYRO3J4NJ - [0:0]
|
||||
:KUBE-SEP-ZX7GRIZKSNUQ3LAJ - [0:0]
|
||||
:KUBE-SVC-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-SVL-XPGD46QRK7WJZT7O - [0:0]
|
||||
-A KUBE-NODEPORTS -m comment --comment ns1/svc1:p80 -m tcp -p tcp --dport 3001 -j KUBE-EXT-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 loadbalancer IP" -m tcp -p tcp -d 1.2.3.4 --dport 80 -j KUBE-EXT-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "pod traffic for ns1/svc1:p80 external destinations" -s 10.0.0.0/8 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "masquerade LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "route LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -j KUBE-SVL-XPGD46QRK7WJZT7O
|
||||
-A KUBE-MARK-MASQ -j MARK --or-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
|
||||
-A KUBE-POSTROUTING -j MARK --xor-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -m recent --name KUBE-SEP-SXIVWICOYRO3J4NJ --set -m tcp -p tcp -j DNAT --to-destination 10.180.0.1:80
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -s 10.180.2.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -m recent --name KUBE-SEP-ZX7GRIZKSNUQ3LAJ --set -m tcp -p tcp -j DNAT --to-destination 10.180.2.1:80
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 ! -s 10.0.0.0/8 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -m recent --name KUBE-SEP-SXIVWICOYRO3J4NJ --rcheck --seconds 10800 --reap -j KUBE-SEP-SXIVWICOYRO3J4NJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -m recent --name KUBE-SEP-ZX7GRIZKSNUQ3LAJ --rcheck --seconds 10800 --reap -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -m statistic --mode random --probability 0.5000000000 -j KUBE-SEP-SXIVWICOYRO3J4NJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVL-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -m recent --name KUBE-SEP-ZX7GRIZKSNUQ3LAJ --rcheck --seconds 10800 --reap -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVL-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
COMMIT
|
||||
`)
|
||||
assertIPTablesRulesEqual(t, getLine(), true, expected, fp.iptablesData.String())
|
||||
|
||||
runPacketFlowTests(t, getLine(), ipt, testNodeIPs, []packetFlowTest{
|
||||
{
|
||||
name: "pod to cluster IP hits both endpoints",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: svcIP,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to LB IP hits only local endpoint, unmasqueraded",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: svcLBIP,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to NodePort hits only local endpoint, unmasqueraded",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestOnlyLocalNodePortsNoClusterCIDR(t *testing.T) {
|
||||
ipt := iptablestest.NewFake()
|
||||
fp := NewFakeProxier(ipt)
|
||||
fp.localDetector = proxyutiliptables.NewNoOpLocalDetector()
|
||||
fp.nodePortAddresses = proxyutil.NewNodePortAddresses(v1.IPv4Protocol, []string{"192.168.0.0/24", "2001:db8::/64"})
|
||||
fp.localhostNodePorts = false
|
||||
|
||||
expected := dedent.Dedent(`
|
||||
*filter
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXTERNAL-SERVICES - [0:0]
|
||||
:KUBE-FORWARD - [0:0]
|
||||
:KUBE-PROXY-FIREWALL - [0:0]
|
||||
-A KUBE-FORWARD -m conntrack --ctstate INVALID -j DROP
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding conntrack rule" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXT-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-MARK-MASQ - [0:0]
|
||||
:KUBE-POSTROUTING - [0:0]
|
||||
:KUBE-SEP-SXIVWICOYRO3J4NJ - [0:0]
|
||||
:KUBE-SEP-ZX7GRIZKSNUQ3LAJ - [0:0]
|
||||
:KUBE-SVC-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-SVL-XPGD46QRK7WJZT7O - [0:0]
|
||||
-A KUBE-NODEPORTS -m comment --comment ns1/svc1:p80 -m tcp -p tcp --dport 3001 -j KUBE-EXT-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -d 192.168.0.2 -j KUBE-NODEPORTS
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "masquerade LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "route LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -j KUBE-SVL-XPGD46QRK7WJZT7O
|
||||
-A KUBE-MARK-MASQ -j MARK --or-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
|
||||
-A KUBE-POSTROUTING -j MARK --xor-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.0.1:80
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -s 10.180.2.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.2.1:80
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -m statistic --mode random --probability 0.5000000000 -j KUBE-SEP-SXIVWICOYRO3J4NJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVL-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
COMMIT
|
||||
`)
|
||||
onlyLocalNodePorts(t, fp, ipt, expected, getLine())
|
||||
}
|
||||
|
||||
func TestOnlyLocalNodePorts(t *testing.T) {
|
||||
ipt := iptablestest.NewFake()
|
||||
fp := NewFakeProxier(ipt)
|
||||
fp.nodePortAddresses = proxyutil.NewNodePortAddresses(v1.IPv4Protocol, []string{"192.168.0.0/24", "2001:db8::/64"})
|
||||
fp.localhostNodePorts = false
|
||||
|
||||
expected := dedent.Dedent(`
|
||||
*filter
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXTERNAL-SERVICES - [0:0]
|
||||
:KUBE-FORWARD - [0:0]
|
||||
:KUBE-PROXY-FIREWALL - [0:0]
|
||||
-A KUBE-FORWARD -m conntrack --ctstate INVALID -j DROP
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
|
||||
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding conntrack rule" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:KUBE-NODEPORTS - [0:0]
|
||||
:KUBE-SERVICES - [0:0]
|
||||
:KUBE-EXT-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-MARK-MASQ - [0:0]
|
||||
:KUBE-POSTROUTING - [0:0]
|
||||
:KUBE-SEP-SXIVWICOYRO3J4NJ - [0:0]
|
||||
:KUBE-SEP-ZX7GRIZKSNUQ3LAJ - [0:0]
|
||||
:KUBE-SVC-XPGD46QRK7WJZT7O - [0:0]
|
||||
:KUBE-SVL-XPGD46QRK7WJZT7O - [0:0]
|
||||
-A KUBE-NODEPORTS -m comment --comment ns1/svc1:p80 -m tcp -p tcp --dport 3001 -j KUBE-EXT-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -d 192.168.0.2 -j KUBE-NODEPORTS
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "pod traffic for ns1/svc1:p80 external destinations" -s 10.0.0.0/8 -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "masquerade LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -m comment --comment "route LOCAL traffic for ns1/svc1:p80 external destinations" -m addrtype --src-type LOCAL -j KUBE-SVC-XPGD46QRK7WJZT7O
|
||||
-A KUBE-EXT-XPGD46QRK7WJZT7O -j KUBE-SVL-XPGD46QRK7WJZT7O
|
||||
-A KUBE-MARK-MASQ -j MARK --or-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
|
||||
-A KUBE-POSTROUTING -j MARK --xor-mark 0x4000
|
||||
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -s 10.180.0.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-SXIVWICOYRO3J4NJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.0.1:80
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -s 10.180.2.1 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SEP-ZX7GRIZKSNUQ3LAJ -m comment --comment ns1/svc1:p80 -m tcp -p tcp -j DNAT --to-destination 10.180.2.1:80
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 cluster IP" -m tcp -p tcp -d 172.30.0.41 --dport 80 ! -s 10.0.0.0/8 -j KUBE-MARK-MASQ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.0.1:80" -m statistic --mode random --probability 0.5000000000 -j KUBE-SEP-SXIVWICOYRO3J4NJ
|
||||
-A KUBE-SVC-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
-A KUBE-SVL-XPGD46QRK7WJZT7O -m comment --comment "ns1/svc1:p80 -> 10.180.2.1:80" -j KUBE-SEP-ZX7GRIZKSNUQ3LAJ
|
||||
COMMIT
|
||||
`)
|
||||
onlyLocalNodePorts(t, fp, ipt, expected, getLine())
|
||||
}
|
||||
|
||||
func onlyLocalNodePorts(t *testing.T, fp *Proxier, ipt *iptablestest.FakeIPTables, expected string, line int) {
|
||||
svcIP := "172.30.0.41"
|
||||
svcPort := 80
|
||||
svcNodePort := 3001
|
||||
svcPortName := proxy.ServicePortName{
|
||||
NamespacedName: makeNSN("ns1", "svc1"),
|
||||
Port: "p80",
|
||||
Protocol: v1.ProtocolTCP,
|
||||
}
|
||||
|
||||
makeServiceMap(fp,
|
||||
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
|
||||
svc.Spec.Type = "NodePort"
|
||||
svc.Spec.ClusterIP = svcIP
|
||||
svc.Spec.Ports = []v1.ServicePort{{
|
||||
Name: svcPortName.Port,
|
||||
Port: int32(svcPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
NodePort: int32(svcNodePort),
|
||||
}}
|
||||
svc.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyLocal
|
||||
}),
|
||||
)
|
||||
|
||||
epIP1 := "10.180.0.1"
|
||||
epIP2 := "10.180.2.1"
|
||||
populateEndpointSlices(fp,
|
||||
makeTestEndpointSlice(svcPortName.Namespace, svcPortName.Name, 1, func(eps *discovery.EndpointSlice) {
|
||||
eps.AddressType = discovery.AddressTypeIPv4
|
||||
eps.Endpoints = []discovery.Endpoint{{
|
||||
Addresses: []string{epIP1},
|
||||
NodeName: nil,
|
||||
}, {
|
||||
Addresses: []string{epIP2},
|
||||
NodeName: pointer.String(testHostname),
|
||||
}}
|
||||
eps.Ports = []discovery.EndpointPort{{
|
||||
Name: pointer.String(svcPortName.Port),
|
||||
Port: pointer.Int32(int32(svcPort)),
|
||||
Protocol: &tcpProtocol,
|
||||
}}
|
||||
}),
|
||||
)
|
||||
|
||||
fp.syncProxyRules()
|
||||
|
||||
assertIPTablesRulesEqual(t, line, true, expected, fp.iptablesData.String())
|
||||
|
||||
runPacketFlowTests(t, line, ipt, testNodeIPs, []packetFlowTest{
|
||||
{
|
||||
name: "pod to cluster IP hit both endpoints",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: svcIP,
|
||||
destPort: svcPort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "external to NodePort hits only local endpoint",
|
||||
sourceIP: testExternalClient,
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
{
|
||||
name: "pod to localhost doesn't work because localhost is not in nodePortAddresses",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: "127.0.0.1",
|
||||
destPort: svcNodePort,
|
||||
output: "",
|
||||
},
|
||||
})
|
||||
|
||||
if fp.localDetector.IsImplemented() {
|
||||
// pod-to-NodePort is treated as internal traffic, so we see both endpoints
|
||||
runPacketFlowTests(t, line, ipt, testNodeIPs, []packetFlowTest{
|
||||
{
|
||||
name: "pod to NodePort hits both endpoints",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d, %s:%d", epIP1, svcPort, epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
// pod-to-NodePort is (incorrectly) treated as external traffic
|
||||
// when there is no LocalTrafficDetector.
|
||||
runPacketFlowTests(t, line, ipt, testNodeIPs, []packetFlowTest{
|
||||
{
|
||||
name: "pod to NodePort hits only local endpoint",
|
||||
sourceIP: "10.0.0.2",
|
||||
destIP: testNodeIP,
|
||||
destPort: svcNodePort,
|
||||
output: fmt.Sprintf("%s:%d", epIP2, svcPort),
|
||||
masq: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeProbability(t *testing.T) {
|
||||
expectedProbabilities := map[int]string{
|
||||
1: "1.0000000000",
|
||||
|
Loading…
Reference in New Issue
Block a user