Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Service loadBalancerSourceRanges in AntreaProxy #6181

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hongliangl
Copy link
Contributor

@hongliangl hongliangl commented Apr 2, 2024

Fix #5493

This commit introduces support for loadBalancerSourceRanges for LoadBalancer
Services.

Here is an example of a LoadBalancer Service configuration allowing access
from specific CIDRs:

apiVersion: v1
kind: Service
metadata:
  name: sample-loadbalancer-source-ranges
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "192.168.77.0/24"
    - "192.168.78.0/24"
status:
  loadBalancer:
    ingress:
      - ip: 192.168.77.150

[New] Here are the corresponding flows:

1. table=ServiceMark, priority=200,tcp,nw_src=192.168.77.0/24,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x20000000/0x60000000->reg4",
2. table=ServiceMark, priority=200,tcp,nw_src=192.168.78.0/24,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x20000000/0x60000000->reg4",
3. table=ServiceMark, priority=190,tcp,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x40000000/0x60000000->reg4",
4. table=ServiceLB, priority=200,tcp,reg4=0x0x20010000/0x0x60070000,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x200/0x200->reg0,set_field:0x20000/0x70000->reg4,set_field:0xe->reg7,group:14
5. table=ServiceLB, priority=190,reg4=0x40000000/0x60000000 actions=drop
  • Flow 1 is to match packets from allowed CIDR 192.168.77.0/24, marking them with
    LoadBalancerSourceRangesAllowRegMark.
  • Flow 2 is similar to flow 1 but for CIDR 192.168.78.0/24.
  • Flow 3 is to match packets not from allowed CIDRs, marking with
    LoadBalancerSourceRangesDropRegMark.
  • Flow 4 is to match allowed packets with LoadBalancerSourceRangesAllowRegMark and
    perform load balancing.
  • Flow 5 is to match not allowed packets with LoadBalancerSourceRangesDropRegMark and
    drop.

@hongliangl hongliangl added area/proxy Issues or PRs related to proxy functions in Antrea action/release-note Indicates a PR that should be included in release notes. labels Apr 2, 2024
@hongliangl hongliangl requested review from tnqn and wenyingd April 7, 2024 03:14
@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch 2 times, most recently from c1e1141 to 779e504 Compare April 29, 2024 02:33
Copy link
Contributor

This PR is stale because it has been open 90 days with no activity. Remove stale label or comment, or this will be closed in 90 days

@github-actions github-actions bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 29, 2024
@tnqn tnqn removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 29, 2024
@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch from 779e504 to 7387fd3 Compare September 3, 2024 07:20
@hongliangl hongliangl added this to the Antrea v2.2 release milestone Sep 3, 2024
@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch from 7387fd3 to 78ec531 Compare September 3, 2024 07:43
@hongliangl
Copy link
Contributor Author

@tnqn @wenyingd @antoninbas Could you help have a look at this PR? Thanks a lot

Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick review, but @tnqn and @wenyingd should definitely take a look if possible.

I wonder if we should have some e2e test coverage for this?
One edge case I can think of would be a NodePort Service with loadBalancerSourceRanges; according to the kube-proxy code base, loadBalancerSourceRanges should not apply to NodePort traffic.

Comment on lines 953 to 955
3. table=ServiceMark, priority=200,tcp,nw_src=192.168.77.0/24,nw_dst=192.168.77.152,tp_dst=80 actions=set_field:0x20000000/0x20000000->reg4",
4. table=ServiceMark, priority=200,tcp,nw_src=192.168.78.0/24,nw_dst=192.168.77.152,tp_dst=80 actions=set_field:0x20000000/0x20000000->reg4",
5. table=ServiceMark, priority=190,tcp,nw_dst=192.168.77.152,tp_dst=80 actions=set_field:0x4000/0x4000->reg0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am probably missing something obvious, but what is the point of setting LoadBalancerSourceRangesRegMark in flows 3 and 4? If the source IP doesn't fall in the correct range, we mark the packet for rejection in flow 5, so it doesn't seem that we need to remember that the source IP was in the correct range?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the commit message. Maybe it can help.

Comment on lines 1094 to 1095
Service `loadBalancerSourceRanges`. It's worth noting that `loadBalancerSourceRanges` only exclusively influences the
traffic from the external network as `LoadBalancerSourceRangesRegMark` is not used in flow 10.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this match the kube-proxy behavior? I took a quick look and it seems that even when traffic comes from local Pods, loadBalancerSourceRanges is enforced

https://github.com/kubernetes/kubernetes/blob/8119e57c070d21f2a7ff37fa7b02f7f74331e393/pkg/proxy/iptables/proxier_test.go#L2192-L2205

I may be misunderstanding the comment / implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Since K8s 1.25, the Pod CIDR is not allowed by default. I have updated the implementation.

@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch 4 times, most recently from e8dd1ba to edba464 Compare September 13, 2024 10:59
@hongliangl
Copy link
Contributor Author

I wonder if we should have some e2e test coverage for this?

Added

One edge case I can think of would be a NodePort Service with loadBalancerSourceRanges; according to the kube-proxy code base, loadBalancerSourceRanges should not apply to NodePort traffic.

In the current implementation, loadBalancerSourceRanges only applies to LoadBalancer ingress IPs.

docs/design/ovs-pipeline.md Outdated Show resolved Hide resolved
If you dump the flows of this table, you may see the following:

```text
1. table=LoadBalancerSourceRanges, priority=200,tcp,nw_src=192.168.77.0/24,nw_dst=192.168.77.152,tp_dst=80 actions=goto_table:SessionAffinity",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When reading the CR example, the thought in my mind is to use OVS conjunction, do you think that works?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In current design, we can leverage most code of pkg/agent/proxier.go and pkg/agent/openflow. For example, like InstallServiceFlows in pkg/agent/openflow/client.go, installing a single ClusterIP, LoadBalancerIP, externalIP or NodePort of a Service. If we use conjunction, at least we may add a new function or enhance InstallServiceFlows to install multiple LoadBalancerIPs. Besides, we may also need a conjunction id allocator.

```text
1. table=LoadBalancerSourceRanges, priority=200,tcp,nw_src=192.168.77.0/24,nw_dst=192.168.77.152,tp_dst=80 actions=goto_table:SessionAffinity",
2. table=LoadBalancerSourceRanges, priority=200,tcp,nw_src=192.168.78.0/24,nw_dst=192.168.77.152,tp_dst=80 actions=goto_table:SessionAffinity",
3. table=LoadBalancerSourceRanges, priority=190,tcp,nw_dst=192.168.77.152,tp_dst=80 actions=drop",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the packets that don't locate in the source range, is the "Drop" action or "Reject" action expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop is expected, as kube-proxy's behavior.

pkg/agent/openflow/framework.go Outdated Show resolved Hide resolved
pkg/agent/openflow/pipeline.go Outdated Show resolved Hide resolved
@@ -799,6 +799,9 @@ func (c *client) InstallServiceFlows(config *types.ServiceConfig) error {
if config.IsDSR {
flows = append(flows, c.featureService.dsrServiceMarkFlow(config))
}
if len(config.LoadBalancerSourceRanges) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, does it need to be scope with condition proxyLoadBalancerIPs==true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the function will be call in pkg/agent/proxier.go when proxyLoadBalancerIPs==true.

@@ -3106,6 +3107,34 @@ func (f *featureService) gatewaySNATFlows() []binding.Flow {
return flows
}

func (f *featureService) loadBalancerSourceRangesMarkFlows(config *types.ServiceConfig) []binding.Flow {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't introduce any register mark for LoadBalancer traffic with the check on the source range, and we don't add mark on the packet via the flows built in this function, so maybe remove word "Mark" from the function name? Or rename it as loadBalancerSourceRangesValidateFlows?

Copy link
Contributor Author

@hongliangl hongliangl Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the designed back because I found the drop action doesn't take effect. For example:

table=1, priority=200,ip actions=resubmit(,2),resubmit(,3),resubmit(,4),resubmit(,5)
table=2, priority=0, actions=goto_tables:3
table=3, priority=190,tcp,nw_dst=169.254.169.1,tp_dst=8080 actions=drop
table=4, priority=0,actions=load:0x1->NXM_NX_REG4[19]
table=5, ......

In above flows, the packet destined for 169.254.169.1 matched by the flow in table 3 will not be dropped when I made some tests.

@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch 2 times, most recently from 647e567 to f4f330a Compare September 30, 2024 07:30
@antrea-bot
Copy link
Collaborator

Can one of the admins verify this patch?

@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch 2 times, most recently from 4547344 to c76dd8e Compare September 30, 2024 08:42
For antrea-io#5493

This commit introduces support for loadBalancerSourceRanges for LoadBalancer
Services.

Here is an example of a LoadBalancer Service configuration allowing access
from specific CIDRs:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-loadbalancer-source-ranges
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "192.168.77.0/24"
    - "192.168.78.0/24"
status:
  loadBalancer:
    ingress:
      - ip: 192.168.77.150
```

[New] Here are the corresponding flows:

```text
1. table=ServiceMark, priority=200,tcp,nw_src=192.168.77.0/24,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x20000000/0x60000000->reg4",
2. table=ServiceMark, priority=200,tcp,nw_src=192.168.78.0/24,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x20000000/0x60000000->reg4",
3. table=ServiceMark, priority=190,tcp,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x40000000/0x60000000->reg4",
4. table=ServiceLB, priority=200,tcp,reg4=0x0x20010000/0x0x60070000,nw_dst=192.168.77.150,tp_dst=80 actions=set_field:0x200/0x200->reg0,set_field:0x20000/0x70000->reg4,set_field:0xe->reg7,group:14
5. table=ServiceLB, priority=190,reg4=0x40000000/0x60000000 actions=drop
```

- Flow 1 is to match packets from allowed CIDR `192.168.77.0/24`, marking them with
  `LoadBalancerSourceRangesAllowRegMark`.
- Flow 2 is similar to flow 1 but for CIDR `192.168.78.0/24`.
- Flow 3 is to match packets not from allowed CIDRs, marking with
  `LoadBalancerSourceRangesDropRegMark`.
- Flow 4 is to match allowed packets with `LoadBalancerSourceRangesAllowRegMark` and
  perform load balancing.
- Flow 5 is to match not allowed packets with `LoadBalancerSourceRangesDropRegMark` and
  drop.

Signed-off-by: Hongliang Liu <[email protected]>
@hongliangl hongliangl force-pushed the 20240402-support-lb-source-range branch from c76dd8e to 695df4b Compare October 8, 2024 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action/release-note Indicates a PR that should be included in release notes. area/proxy Issues or PRs related to proxy functions in Antrea
Projects
None yet
Development

Successfully merging this pull request may close these issues.

loadBalancerSourceRanges not supported in AntreaProxy
6 participants