Skip to content

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Dec 21, 2022

Currently, the inbound proxy is capable of operating in two modes: a
fixed mode, where no policy controller address is provided, and inbound
port policies are configured by the environment variables
LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION,
LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_IDENTITY, and
LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS; and a discovery-based mode,
where port policies are discovered from the policy controller. In
practice, the fixed mode is never actually used, so we probably ought to
remove it entirely in 2.13.

This branch removes the fixed mode for inbound port policy. Starting the
proxy without the LINKERD2_PROXY_POLICY_SVC_ADDR and
LINKERD2_PROXY_POLICY_SVC_IDENTITY environment variables set is now an
error. If the LINKERD2_INBOUND_PORTS_REQUIRE_IDENTITY or
LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS environment variables are
present, the proxy will now log a warning and ignore their values. The
LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION environment
variable is still supported, however, in order to allow the proxy to
avoid performing policy controller lookups when configured with a large
list of opaque ports.

The Store::spawn_fixed method on linkerd_app_inbound::policy::Store
is no longer used when running the proxy normally, but it is retained
for testing purposes, and has been made test-only.

Finally, it was necessary to add a mock implementation of the policy
controller for integration tests to pass, since a policy controller is
now required. This is based on the implementation of a mock policy
controller added in #1992, but without the outbound policy API. PR #1992
should be able to rebase cleanly once this branch merges.

Closes #2076

Currently, the inbound proxy is capable of operating in two modes: a
fixed mode, where no policy controller address is provided, and inbound
port policies are configured by the environment variables
`LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION`,
`LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_IDENTITY`, and
`LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS`; and a discovery-based mode,
where port policies are discovered from the policy controller. In
practice, the fixed mode is never actually used, so we probably ought to
remove it entirely in 2.13.

This branch removes the fixed mode for inbound port policy. Starting the
proxy without the `LINKERD2_PROXY_POLICY_SVC_ADDR` and
`LINKERD2_PROXY_POLICY_SVC_IDENTITY` environment variables set is now an
error. If the `LINKERD2_INBOUND_PORTS_REQUIRE_IDENTITY` or
`LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS` environment variables are
present, the proxy will now log a warning and ignore their values. The
`LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION` environment
variable is still supported, however, in order to allow the proxy to
avoid performing policy controller lookups when configured with a large
list of opaque ports.

The `Store::spawn_fixed` method on `linkerd_app_inbound::policy::Store`
is no longer used when running the proxy normally, but it is retained
for testing purposes, and has been made test-only.
This is necessary now that a policy controller is always required.
Otherwise, the tests all fail. :)
@hawkw hawkw marked this pull request as ready for review December 21, 2022 20:56
@hawkw hawkw requested a review from a team as a code owner December 21, 2022 20:56
@hawkw hawkw force-pushed the eliza/rm-fixed-policy branch from 377db61 to 014c443 Compare December 21, 2022 21:18
hawkw added a commit that referenced this pull request Dec 21, 2022
Depends on #2079

Currently, the `LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION`
environment variable accepts a comma-delimited list of individual port
numbers. Each of these ports is then stored as a separate cache entry in
the port policy cache to indicate that the port is opaque.

Unfortunately, this does not work well when a very large number of ports
are marked as opaque, because the proxy-injector will generate a massive
value for that environment variable, listing every individual port. This
can cause issues when this manifest becomes larger than the Kubernetes
API can reasonably handle. In addition, huge numbers of ports will all
be kept in memory as a separate cache entry by the proxy, increasing
proxy memory usage. See linkerd/linkerd2#9803 for details.

This branch changes the proxy so that the
`LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION` environment
variable may contain a list of individual port numbers *and* port
ranges, which are specified as `<low>-<high>`.

Opaque ports are now stored using a `RangeInclusiveSet` from the
`rangemap` crate, rather than by creating individual cache entries for
each port. This means we are no longer storing a separate entry in the
cache for every port in a range, reducing memory consumption when there
are very large ranges of opaque ports.

This is the proxy half of the work towards resolving
linkerd/linkerd2#9803. Once this branch lands, we'll also have to change
the proxy-injector so that it no longer handles opaque port ranges by
generating a list of all the individual ports in the range, and simply
forwards those ranges as they were specified when generating the
environment variable.
@hawkw
Copy link
Contributor Author

hawkw commented Dec 21, 2022

Copy link
Contributor

@kleimkuhler kleimkuhler left a comment

Choose a reason for hiding this comment

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

Looks good!

/// Most policies are watched dynamically from the control plane. A default
/// policy is used when the controller does not provide a policy for a given
/// port. In addition, a pre-configured list of opaque ports can be provided
/// to avoid unnecessary policy lookups for ports which will always be opaque.
Copy link
Member

@olix0r olix0r Dec 23, 2022

Choose a reason for hiding this comment

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

I don't think this is correct.

Suggested change
/// to avoid unnecessary policy lookups for ports which will always be opaque.
/// to control the proxy's default behavior before policy is synced
/// from the control plane policy.

We still lookup policies for these... What we configure here is the default behavior, i.e. on the first request before the resolution is complete.

We don't currently block inbound connections on a policy existing. That could change in the future, I guess...

@olix0r olix0r marked this pull request as draft December 28, 2022 18:03
@hawkw hawkw closed this Feb 22, 2023
@olix0r olix0r deleted the eliza/rm-fixed-policy branch March 7, 2023 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants