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

[🚀 Feature]: Make external URI configurable #12491

Closed
utamas opened this issue Aug 4, 2023 · 9 comments · Fixed by #12508
Closed

[🚀 Feature]: Make external URI configurable #12491

utamas opened this issue Aug 4, 2023 · 9 comments · Fixed by #12508

Comments

@utamas
Copy link
Contributor

utamas commented Aug 4, 2023

Feature and motivation

Feature

Add --external-uri configuration parameter to server section. This will allow nodes to provide a URI to hub (or distributor) which is route-able when SE node is running behind some sort proxy.

Motivation

There are cases when nodes cannot report self URI that is route-able from hub during node registration process in which case the node get's stuck in Sending registration event... loop, while the hub logs will show connection timeouts or unknown host exceptions.

I believe this can be easily fixed in org.openqa.selenium.grid.server.BaseServerOptions#getExternalUri by first reading this newly added external-uri parameter. When empty, implementation can fall back to the current one otherwise it could just use the provided value.

Our concrete use case:

We run ~5000 selenium tests. For performance reasons we deploy ~60 instances of our app each bundled with a SE node across ~20 single node k8s clusters (so each cluster runs 3 apps each with a chrome SE node). One extra k8s cluster runs on the CI agent itself where SE hub is running. For various reasons - which for brevity I don't want to detail - these clusters communicate with each other via node ports (on private IPs).

So I end up in a situation where I can configure SE node so it can reach SE hub via (let's say 192.168.1.2:30027-30030) and I can configure it to report its own IP correctly (let's say 192.168.1.3, via --host), but I get into a problem with --port.
If I leave it on it's default (5555), then hub will try to connect to it on 192.168.1.3:5555 (but that is not route-able). One solution that works is picking a port from node port range and use that port both for node port and start SE node on that port inside the container but this has an unwanted administration overhead as well as adding non deterministic behavior as static node port range is only available on k8s version 1.27 in a feature that is not generally available yet.

It is a lot simpler if this feature is added.

Usage example

Until docker part is updated we could use SE_OPTS to supply --external-uri=http://<node-ip>:<node-port>.

@github-actions
Copy link

github-actions bot commented Aug 4, 2023

@utamas, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

utamas added a commit to utamas/selenium that referenced this issue Aug 7, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 7, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 7, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 7, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 8, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
@diemol
Copy link
Member

diemol commented Aug 8, 2023

Have you tried the --bind-host flag?

@utamas
Copy link
Contributor Author

utamas commented Aug 8, 2023

That flag is set by docker packaging to false by default. I didn't try to change that for two reasons:

  • It would bind to the container IP (which is not resolvable for hub, cause they are on completely different networks
  • it would only solve half of my problem, cause I cannot expose the service on 5555 to hub

Or am I missing something?

utamas added a commit to utamas/selenium that referenced this issue Aug 10, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
@diemol
Copy link
Member

diemol commented Aug 11, 2023

If you set it to false you can set any host/port you need to be reported. As long as it maps with the host where the container is running. Have you tried it?

@utamas
Copy link
Contributor Author

utamas commented Aug 11, 2023

Sorry, I didn't answer with yes or no.

So, yes. I tried. While it works this approach has a couple of downsides:

  • it forces me to use kubernetes version 1.27 (at least) in order to have a more or less stable deployment,
  • even then I would rely on a feature that is not generally available yet and finally,
  • it would add complexity to my deployment code as I would have to associate ports to certain SE nodes manually and make sure it does not collide with other services.

What I'm doing ATM is I create a node port type k8s service that points to 5555 before actually applying deployment that runs SE nodes. This way when I apply the deployment I already know what port value I need to set to --external-uri. The reason why I can't set the port with a similar trick is that when I create the k8s service I would already need to know what node port I would get (dynamically) which introduces a chicken and egg problem.

I hope I'm not very cryptic.

@utamas
Copy link
Contributor Author

utamas commented Aug 11, 2023

Here is a snippet from my code:

resource "kubernetes_service_v1" "to_hub" {
  metadata {
    // redacted for brevity 
  }
  spec {
    type     = "NodePort"
    // redacted for brevity 

    port {
      port        = 5555
      target_port = 5555
      // by not picking a value for node_port, I always get an available one by random
    }
  }
}

resource "kubernetes_deployment_v1" "main" {
  // this is important, cause it makes sure that a node port is allocated and known by the time terraform starts to create this deployment
  depends_on = [kubernetes_service_v1.to_hub]

  metadata {
    // redacted for brevity 
  }
  spec {
    // redacted for brevity 
    template {
      // redacted for brevity 
      spec {
        // redacted for brevity 
        container {
          image = "${var.image_registry}/node-chrome:114.0-chromedriver-114.0-grid-4.10.0-20230614-patched"

          dynamic "env" {
            for_each = {
              SE_NODE_GRID_URL            = "http://${var.hub_host}:${var.hub_port}"
              SE_EVENT_BUS_HOST           = var.hub_host
              SE_EVENT_BUS_PUBLISH_PORT   = var.event_bus_publish_port
              SE_EVENT_BUS_SUBSCRIBE_PORT = var.event_bus_subscribe_port
              SE_NODE_SESSION_TIMEOUT     = 7200

              SE_NODE_HOST = var.cluster_address
              SE_OPTS = "--external-uri http://${var.cluster_address}:${kubernetes_service_v1.to_hub.spec.0.port.0.node_port}"
            }
            content {
              name  = env.key
              value = env.value
            }
          }

          port {
            container_port = 5555
          }

utamas added a commit to utamas/selenium that referenced this issue Aug 11, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 14, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 15, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 15, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
@utamas
Copy link
Contributor Author

utamas commented Aug 22, 2023

@diemol could you please remote the awaiting answer tag?

utamas added a commit to utamas/selenium that referenced this issue Aug 25, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Aug 30, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Sep 8, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Sep 14, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
@titusfortner titusfortner added this to the 4.13 milestone Sep 15, 2023
@titusfortner
Copy link
Member

@diemol could you please remote the awaiting answer tag?

We use that tag to know which items to see if we need to follow up on. Hard to juggle 200 open issues. 😄
Diego has been traveling this week.

Either he or maybe @pujagani will hopefully be able to verify #12508 soon.

@titusfortner titusfortner modified the milestones: 4.13, 4.14 Sep 27, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Oct 6, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 10, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Oct 10, 2023
@titusfortner titusfortner modified the milestones: 4.14, 4.15 Oct 10, 2023
utamas added a commit to utamas/selenium that referenced this issue Oct 27, 2023
…ver functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes SeleniumHQ#12491
utamas added a commit to utamas/selenium that referenced this issue Oct 27, 2023
@titusfortner titusfortner modified the milestones: 4.15, 4.16 Nov 1, 2023
diemol added a commit that referenced this issue Nov 6, 2023
…ver functionality - #12491 (#12508)

* Allow external uri to be configurable for components that support server functionality.

SE nodes might be behind some sort of proxy exposed to hub on a
different hostname(/ip) and/or port than component would by default
report themselves (e.g.: hub and nodes are in different k8s clusters
 and services are exposed via node ports).

Fixes #12491

* Rename external-uri to external-url.

#12508 (review)

Fixes #12491

* fix linting issues

---------

Co-authored-by: titusfortner <[email protected]>
Co-authored-by: Diego Molina <[email protected]>
Co-authored-by: Titus Fortner <[email protected]>
Copy link

github-actions bot commented Dec 7, 2023

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants