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

Use a per-hcp router for all hcp ingress traffic #1614

Merged
merged 8 commits into from
Aug 3, 2022

Conversation

alvaroaleman
Copy link
Contributor

This change adds a new mode to the cpo where it will set up a router and use it for all controlplane traffic, ref: https://issues.redhat.com/browse/HOSTEDCP-485

This is done by:

  • Making the CLI decide based on the presence of a value for --external-dns-domain if it configures Route or the existing LoadBalancer as publishingStrategy for the KAS
  • If the KAS publishing strategy is route, the CPO will:
    • Not set up a LB but a clusterIP service for the KAS
    • Create an external route if the cluster is public
    • Create an internal route
    • Configure the router with a custom template that uses the KAS as default backend, this is needed because in-cluster traffic accesses the KAS through an IP, but SNI does not support IP addreses
    • If the cluster is private, the AWS private link controller will set up two hypershift.local DNS entries for the router, one for the KAS, one for the apps domain

/label tide/merge-method-squash

@openshift-ci openshift-ci bot added the tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. label Jul 25, 2022
@openshift-ci openshift-ci bot requested review from csrwng and sjenning July 25, 2022 21:41
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jul 25, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alvaroaleman

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 25, 2022
@@ -51,6 +51,10 @@ type AWSEndpointServiceStatus struct {
// +optional
DNSName string `json:"dnsName,omitempty"`

// DNSName are the names for the records created in the hypershift private zone
Copy link
Member

@enxebre enxebre Jul 26, 2022

Choose a reason for hiding this comment

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

how is this different from the above field? does the above needs to be dropped/deprecated?

Copy link
Contributor Author

@alvaroaleman alvaroaleman Jul 26, 2022

Choose a reason for hiding this comment

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

It is different in that it can hold more than one value ([]string vs string)

Copy link
Member

@enxebre enxebre Jul 26, 2022

Choose a reason for hiding this comment

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

so the semantic is the same, I don't think we need two different fields to represent 1 vs multiple, do we? Can we drop DNSName and keep only []DNSName where you can have 1..N?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the semantic is the same. We can deprecate the field, but we have to keep it around for or as long as we support an OCP version where the HCP controller does not have this change

Copy link
Contributor

Choose a reason for hiding this comment

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

If you are deprecating the single field you should add a // Deprecated comment to it.

@enxebre
Copy link
Member

enxebre commented Jul 26, 2022

Making the CLI decide based on the presence of a value for --external-dns-domain if it configures Route or the existing LoadBalancer as publishingStrategy for the KAS

Why is external dns the discriminator, why don't always go router?

Can we please capture this in https://github.com/openshift/enhancements/tree/master/enhancements/hypershift/networking

@alvaroaleman
Copy link
Contributor Author

Why is external dns the discriminator, why don't always go router?

Because it is not going to work without external DNS, as we need it to be able to do name based virtual hosting

Copy link
Contributor

@csrwng csrwng left a comment

Choose a reason for hiding this comment

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

did an initial pass, testing to better understand new behavior

@@ -51,6 +51,10 @@ type AWSEndpointServiceStatus struct {
// +optional
DNSName string `json:"dnsName,omitempty"`

// DNSName are the names for the records created in the hypershift private zone
Copy link
Contributor

Choose a reason for hiding this comment

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

If you are deprecating the single field you should add a // Deprecated comment to it.

@@ -302,15 +302,15 @@ func (r *AWSEndpointServiceReconciler) reconcileAWSEndpointServiceStatus(ctx con
hasPrivateRouterEPService := false
hasPrivateIngressControllerEPService := false
for _, eps := range endpointServices.Items {
// If a private-router AWSEndpointService exists, it means that
// If a router AWSEndpointService exists, it means that
Copy link
Contributor

Choose a reason for hiding this comment

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

it means that ?

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 idea, I had just deleted the reference to private, whoever originally created the comment forgot to finish the sentence 🙃

@csrwng
Copy link
Contributor

csrwng commented Jul 26, 2022

@alvaroaleman so in the public use case I would still expect the ignition, konnectivity, oauth and ovnsdb routes to go through the one router as long as a hostname is specified for them. That doesn't look to be the case with the current code.

@alvaroaleman
Copy link
Contributor Author

@alvaroaleman so in the public use case I would still expect the ignition, konnectivity, oauth and ovnsdb routes to go through the one router as long as a hostname is specified for them. That doesn't look to be the case with the current code.

Updated that and added an e2e verification.The only exception for this is currently the ovn route, which is managed by the CNO. I will fix it there once this has merged.

@netlify
Copy link

netlify bot commented Jul 28, 2022

Deploy Preview for hypershift-docs ready!

Name Link
🔨 Latest commit 70f0406
🔍 Latest deploy log https://app.netlify.com/sites/hypershift-docs/deploys/62e9258dba03c20008ae408b
😎 Deploy Preview https://deploy-preview-1614--hypershift-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@alvaroaleman
Copy link
Contributor Author

/retest-required

1 similar comment
@alvaroaleman
Copy link
Contributor Author

/retest-required

@alvaroaleman
Copy link
Contributor Author

alvaroaleman commented Jul 29, 2022

@csrwng @sjenning so in order to save on LB ports to in turn save on security group rules I added defaulting for the KAS to listen on port 443 when the Route strategy is used. This required to:

  • Change things to hardcode the kas to listen on 6443 and do the 443->6443 translation in the Service object, because the KAS can not bind to 443 as it doesn't run as root
  • Make the internal LB in private clusters respect the apiserver port, everything that uses it is hardcoded to use port 6443

Those two changes could be extracted from this PR, should I do that?

@alvaroaleman
Copy link
Contributor Author

/retest-required

@csrwng
Copy link
Contributor

csrwng commented Jul 29, 2022

Those two changes could be extracted from this PR, should I do that?

Only if you think it will help to make progress quicker. I wouldn't spend too much time extracting it from here.

@alvaroaleman
Copy link
Contributor Author

Tests are finally green 🎉

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 31, 2022
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 31, 2022
@@ -818,10 +822,36 @@ func (r *HostedControlPlaneReconciler) reconcileAPIServerService(ctx context.Con
return fmt.Errorf("failed to reconcile API server service: %w", err)
}

if util.IsPrivateHCP(hcp) {
if serviceStrategy.Type == hyperv1.Route {
Copy link
Member

Choose a reason for hiding this comment

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

nit: I'd find easier to read and understand all the possible casuistic with a swtich case for serviceStrategy.Type here, then in default with util.IsPrivateHCP(hcp) {...

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 issue is that we have three logical branches:

  • Uses hyperv1. Router: Always create internal route.
    • subbranch is public: Create public route
  • Uses hyperv1.LB and is private: Create private LB

The hyperv1.LB for the last condition is implicit, because private AWS clusters can only have route or LB apiserver expose strategy. I've added it explicitly to the condition to make that more obvious, the check doesn't really cost anything.

kasServiceStrategy := servicePublishingStrategyByType(hostedControlPlane, hyperv1.APIServer)
if util.IsPrivateHCP(hostedControlPlane) || kasServiceStrategy.Type == hyperv1.Route {
r.Log.Info("Reconciling router")
if err = r.reconcileRouter(ctx, hostedControlPlane, releaseImage, createOrUpdate); err != nil {
Copy link
Member

@enxebre enxebre Aug 1, 2022

Choose a reason for hiding this comment

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

why does this only happen when is private || kasServiceStrategy.Type == hyperv1.Route? I though part of the goal was "The per-hostedcluster router is always created, not only in the private case"

I.e shouldn't the other components also be accounted for, e.g konnectivity serviceStrategy...?

Also does it makes sense to let the HC backend validate and reject if the combination of serviceStrategy is not supported?

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'll respond below

@enxebre
Copy link
Member

enxebre commented Aug 1, 2022

Why is external dns the discriminator, why don't always go router?
Because it is not going to work without external DNS, as we need it to be able to do name based virtual hosting

Would it work if management cluster DNS is used when no-external DNS is set?

To keep solidifying and simplifying this, I'd expect:

  • We agree on more opinionated valid setups and let the HC backend validate input and fail early in condition otherwise. E.g all components can be set to strategy router but not only some...
  • Always create the router (regardless private or public setup).
  • Let the CLI always set router strategy (regardless external DNS).

PR lgtm overall, dropped some nits and questions but no objections to proceed and follow up later.

This entails having to listen on a different port than what is used
externally, as the KAS doesn't run as route and thus can not bind to a
port < 1025.
@alvaroaleman
Copy link
Contributor Author

We agree on more opinionated valid setups and let the HC backend validate input and fail early in condition otherwise. E.g all components can be set to strategy router but not only some...

No objections to that, but so far we didn't make any statements about which combination of publishing strategies we do or do not support

Always create the router (regardless private or public setup).

We can not do that, because there are existing clusters that use the LB strategy, which is why we have to keep supporting it. This entail that we need a feature gating mechanism that tells us if a cluster is a LB cluster or a route cluster. I went for using the api server expose strategy itself to detect that.

On top of needing to support existing clusters, the other advantage of keeping on supporting it is that we have fewer dependencies, as the route strategy can not work without external DNS. This doesn't matter for the SD use case, but might be nice for the ACM use case.

Let the CLI always set router strategy (regardless external DNS).

This will result in a broken cluster if there is no external DNS. We need at minimum DNS entries for ignition, oauth and the KAS. Without distinct SNI/Host headers, the router can not do name based virtual hosting.

@enxebre
Copy link
Member

enxebre commented Aug 2, 2022

/lgtm
/hold
for @csrwng to have the chance to have another look

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 2, 2022
@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Aug 2, 2022
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Aug 2, 2022

@alvaroaleman: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws 2104ac0 link false /test e2e-aws
ci/prow/capi-provider-agent-sanity 70f0406 link false /test capi-provider-agent-sanity
ci/prow/e2e-kubevirt-gcp-ovn 70f0406 link false /test e2e-kubevirt-gcp-ovn

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@alvaroaleman
Copy link
Contributor Author

@csrwng could you have a look, please?

@csrwng
Copy link
Contributor

csrwng commented Aug 3, 2022

/hold cancel
/lgtm

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 3, 2022
@openshift-ci openshift-ci bot merged commit 0b95b70 into openshift:main Aug 3, 2022
alvaroaleman added a commit to alvaroaleman/hypershift that referenced this pull request Aug 18, 2022
In openshift#1614 the KAS was changed
to always listen on port 6443 in oder to support privileged external
ports by doing the mapping external port -> internal port in the service
object.

This resulted in an invalid KAS networkpolicy if the external port is
not 6443, as it would allowlist the external port rather than 6443 where
the KAS is actually listening.
alvaroaleman added a commit to alvaroaleman/hypershift that referenced this pull request Aug 18, 2022
In openshift#1614 the KAS was changed
to always listen on port 6443 in oder to support privileged external
ports by doing the mapping external port -> internal port in the service
object.

This resulted in an invalid KAS networkpolicy if the external port is
not 6443, as it would allowlist the external port rather than 6443 where
the KAS is actually listening.
alvaroaleman added a commit to alvaroaleman/hypershift that referenced this pull request Aug 18, 2022
In openshift#1614 the KAS was changed
to always listen on port 6443 in oder to support privileged external
ports by doing the mapping external port -> internal port in the service
object.

This resulted in an invalid KAS networkpolicy if the external port is
not 6443, as it would allowlist the external port rather than 6443 where
the KAS is actually listening.
a-dsouza pushed a commit to a-dsouza/hypershift that referenced this pull request Apr 11, 2023
* Expose through router

* KAS service reporting: Report on router service if exposed through route

* Revert "KAS service reporting: Report on router service if exposed through route"

This reverts commit 219b149.

* Default KAS port to 443 when exposing through router

This entails having to listen on a different port than what is used
externally, as the KAS doesn't run as route and thus can not bind to a
port < 1025.

* Create router earlier so lb services get provisioned asap

* Revert "Revert "KAS service reporting: Report on router service if exposed through route""

This reverts commit 9f52874.

* Rebase

* Be a bit more explicit
hasueki pushed a commit to hasueki/hypershift that referenced this pull request Jul 21, 2023
* Expose through router

* KAS service reporting: Report on router service if exposed through route

* Revert "KAS service reporting: Report on router service if exposed through route"

This reverts commit 219b149.

* Default KAS port to 443 when exposing through router

This entails having to listen on a different port than what is used
externally, as the KAS doesn't run as route and thus can not bind to a
port < 1025.

* Create router earlier so lb services get provisioned asap

* Revert "Revert "KAS service reporting: Report on router service if exposed through route""

This reverts commit 9f52874.

* Rebase

* Be a bit more explicit
a-dsouza pushed a commit to a-dsouza/hypershift that referenced this pull request Jul 21, 2023
* Expose through router

* KAS service reporting: Report on router service if exposed through route

* Revert "KAS service reporting: Report on router service if exposed through route"

This reverts commit 219b149.

* Default KAS port to 443 when exposing through router

This entails having to listen on a different port than what is used
externally, as the KAS doesn't run as route and thus can not bind to a
port < 1025.

* Create router earlier so lb services get provisioned asap

* Revert "Revert "KAS service reporting: Report on router service if exposed through route""

This reverts commit 9f52874.

* Rebase

* Be a bit more explicit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants