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

daemon: Add option --bpf-lb-external-clusterip #15650

Merged

Conversation

joamaki
Copy link
Contributor

@joamaki joamaki commented Apr 12, 2021

Add the option --bpf-lb-external-clusterip to enable
routing to ClusterIP services from outside the cluster.

The loadbalancer routing logic is modified to only look
at the SVC_FLAG_ROUTABLE flag instead of expecting an
additional higher bit in addition to it.

The SVC_FLAG_ROUTABLE is only set for ClusterIP services
when the --bpf-lb-external-clusterip agent flag is set.

Fixes: #14581

@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Apr 12, 2021
@maintainer-s-little-helper maintainer-s-little-helper bot added this to In progress in 1.10.0 Apr 12, 2021
@joamaki joamaki added the release-note/minor This PR changes functionality that users may find relevant to operating Cilium. label Apr 12, 2021
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Apr 12, 2021
@joamaki joamaki requested a review from brb April 12, 2021 12:51
@joamaki
Copy link
Contributor Author

joamaki commented Apr 12, 2021

test-me-please

@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch 4 times, most recently from 71535e7 to 15263b0 Compare April 13, 2021 13:52
@joamaki
Copy link
Contributor Author

joamaki commented Apr 13, 2021

test-me-please

1 similar comment
@joamaki
Copy link
Contributor Author

joamaki commented Apr 13, 2021

test-me-please

@@ -74,6 +74,7 @@ cilium-agent [flags]
--enable-bpf-clock-probe Enable BPF clock source probing for more efficient tick retrieval
--enable-bpf-masquerade Masquerade packets from endpoints leaving the host with BPF instead of iptables
--enable-bpf-tproxy Enable BPF-based proxy redirection, if support available
--enable-cluster-ip-external-access Enable external access to ClusterIP services
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What other documentation related changes should be made for this change?

Copy link
Member

Choose a reason for hiding this comment

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

It'll be good to document this flag in the kube-proxy replacement getting started guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Added documentation.

static __always_inline bool __lb_svc_is_routable(__u8 flags)
{
return (flags & svc_is_routable_mask()) > SVC_FLAG_ROUTABLE;
return (flags & SVC_FLAG_ROUTABLE) != 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there anything that could break with this change?

Copy link
Member

Choose a reason for hiding this comment

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

Thinking loud about the upgrade path. When cilium-agent starts, services are updated from kube-apiserver before the datapath gets regenerated. So, it means that for some time, the old code will be running with the new service flags. I think this should be fine, as for previously routable services nothing should change.

During the downgrade, we will have the old service flags (= pre your changes) with the new datapath (= with your changes) for awhile. This will allow ClusterIP access from outside. But I guess this is tolerable.

static __always_inline bool __lb_svc_is_routable(__u8 flags)
{
return (flags & svc_is_routable_mask()) > SVC_FLAG_ROUTABLE;
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be guarded by EnableClusterIPExternalAccess config?

Copy link
Contributor Author

@joamaki joamaki Apr 14, 2021

Choose a reason for hiding this comment

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

Not sure what you mean by guarded. The flag is disabled by default in which case SVC_FLAG_ROUTABLE is unset for ClusterIP services. Earlier SVC_FLAG_ROUTABLE was set for ClusterIP services, but higher bits were unset and hence this function returned false for ClusterIP services. Now we only need to check for SVC_FLAG_ROUTABLE.

Copy link
Member

Choose a reason for hiding this comment

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

Speaking of which, I can't find where, in your PR, SVC_FLAG_ROUTABLE would be set or unset depending on the value for config.ExternalClusterIP. Shouldn't there be a change to the definition of SVC_FLAG_ROUTABLE in bpf/lib/common.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The change to this logic is in the agent in updateMasterService: https://github.com/cilium/cilium/pull/15650/files#diff-8eff0d99dd1ceb7d15ce632811672e7b17a17fb5e984fafa7875d6ad2433b3d8R519. It was already set earlier and in this PR I'm turning it off for ClusterIP services unless the new external access flag is set.

Copy link
Member

Choose a reason for hiding this comment

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

Ok thank you. On my first read, I somehow understood that you would be changing the value for SVC_FLAG_ROUTABLE depending on the value of ExternalClusterIP, but I understand this is not the case - You're just changing the flags.

@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch from 15263b0 to 39b6b7a Compare April 14, 2021 12:33
@joamaki
Copy link
Contributor Author

joamaki commented Apr 14, 2021

test-me-please

Copy link
Member

@brb brb left a comment

Choose a reason for hiding this comment

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

Nice! Some comments.

pkg/option/config.go Outdated Show resolved Hide resolved
install/kubernetes/cilium/templates/cilium-configmap.yaml Outdated Show resolved Hide resolved
pkg/maps/lbmap/lbmap.go Show resolved Hide resolved
@@ -1963,6 +1971,8 @@ var (

k8sEnableLeasesFallbackDiscovery: defaults.K8sEnableLeasesFallbackDiscovery,
APIRateLimit: make(map[string]string),

EnableClusterIPExternalAccess: defaults.EnableClusterIPExternalAccess,
Copy link
Member

Choose a reason for hiding this comment

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

I think you don't need this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep it isn't strictly necessary (as it'll default to false if unspecified). I added it since there were bunch of other boolean options that defaulted to false as well and were specified here. I'm fine either way.

Outside access to ClusterIP services
************************************

By default Cilium does not route packets coming from outside the cluster to a backend exposed
Copy link
Member

Choose a reason for hiding this comment

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

We use the backend term only internally in the Cilium codebase. The k8s term is service endpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I'll change it. There's quite few other mentions of backend in the same document in similar context (e.g. in DSR section). Wonder if we should do pass over the document and make sure the naming is consistent?

Copy link
Member

Choose a reason for hiding this comment

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

Wonder if we should do pass over the document and make sure the naming is consistent?

👍

static __always_inline bool __lb_svc_is_routable(__u8 flags)
{
return (flags & svc_is_routable_mask()) > SVC_FLAG_ROUTABLE;
return (flags & SVC_FLAG_ROUTABLE) != 0;
Copy link
Member

Choose a reason for hiding this comment

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

Thinking loud about the upgrade path. When cilium-agent starts, services are updated from kube-apiserver before the datapath gets regenerated. So, it means that for some time, the old code will be running with the new service flags. I think this should be fine, as for previously routable services nothing should change.

During the downgrade, we will have the old service flags (= pre your changes) with the new datapath (= with your changes) for awhile. This will allow ClusterIP access from outside. But I guess this is tolerable.

@brb
Copy link
Member

brb commented Apr 14, 2021

Adding @borkmann to the reviewers list, as he introduced the routable concept.

@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch from 39b6b7a to 725ce3d Compare April 15, 2021 12:27

By default Cilium does not route packets coming from outside the cluster to a service endpoint
exposed with a ``ClusterIP`` service. Routing to ``ClusterIP`` services can be enabled using the
by setting ``config.enableClusterIPExternalAccess=true``.
Copy link
Member

Choose a reason for hiding this comment

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

Could we try to elaborate more on the rationale here on why we don't expose it by default? Back then we didn't expose it due to the assumption that the range would typically be non-routable, and given that, as a security measure, we also do not expect such traffic on the phys iface. (Plus there's NodePort which would accomplish similar things just in different IP/port range (if not backed by e.g. LoadBalancer). Perhaps there are additional pointers from K8s doc.)

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 added the link to k8s documentation about this (which we already had below so I just moved it here).

@borkmann
Copy link
Member

borkmann commented Apr 19, 2021

(Overall, code wise looks good to me, just few minor nits.)

@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch 2 times, most recently from fc1f551 to 2437df0 Compare April 20, 2021 12:53
@christarazi christarazi removed their assignment Apr 27, 2021
@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch from 62e13c2 to 8922607 Compare April 28, 2021 07:42
@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

test-net-next

@@ -37,6 +37,7 @@ cilium-agent [flags]
--bpf-lb-dev-ip-addr-inherit string Device name which IP addr is inherited by devices running LB BPF program (--devices)
--bpf-lb-dsr-dispatch string BPF load balancing DSR dispatch method ("opt", "ipip") (default "opt")
--bpf-lb-dsr-l4-xlate string BPF load balancing DSR L4 DNAT method for IPIP ("frontend", "backend") (default "frontend")
--bpf-lb-external-clusterip Enable external access to ClusterIP services
Copy link
Member

Choose a reason for hiding this comment

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

small doc nit, but no need to rerun ci: could we append here: (default false) ?

Add the option --bpf-lb-external-clusterip to enable
routing to ClusterIP services from outside the cluster.

The loadbalancer routing logic is modified to only look
at the SVC_FLAG_ROUTABLE flag instead of expecting an
additional higher bit in addition to it.

The SVC_FLAG_ROUTABLE is only set for ClusterIP services
when the flag is set.

Fixes: cilium#14581

Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki joamaki force-pushed the pr/joamaki/flag-external-cluster-ip-access branch from 8922607 to 215945d Compare April 28, 2021 13:40
@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

Passing test-net-next here: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.16-net-next/398/. Only changed the agent flag help so I'll kick off the other checks, but not test-net-next.

@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

test-runtime

@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

test-1.20-4.19

@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

test-gke

@joamaki
Copy link
Contributor Author

joamaki commented Apr 28, 2021

test-1.21-4.9

@joamaki joamaki added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Apr 28, 2021
@rolinh rolinh merged commit c7a4272 into cilium:master Apr 29, 2021
1.10.0 automation moved this from In progress to Done Apr 29, 2021
@rpthms
Copy link

rpthms commented Jun 27, 2021

This PR is marked for 1.10.0 but I don't see this option in the 1.10.1 Cilium image. Are there any plans to backport this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/minor This PR changes functionality that users may find relevant to operating Cilium. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. upgrade-impact This PR has potential upgrade or downgrade impact.
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Allow ClusterIP access from outside