rancher-sandbox / rancher-desktop

Container Management and Kubernetes on the Desktop
https://rancherdesktop.io
Apache License 2.0
6.01k stars 283 forks source link

Unable to bind to address other than 127.0.0.1 or 0.0.0.0 #6760

Open HarlemSquirrel opened 6 months ago

HarlemSquirrel commented 6 months ago

Actual Behavior

Attempting to bind a container to any port loopback address other than 0.0.0.0 or 127.0.0.1 results in no ports binding at all and services are not available from the host.

This works fine with Docker Desktop on MacBook Pro Apple M3 Pro with Mac OS 14.

Steps to Reproduce

Use the following docker-compose.yml

# docker-compose.yml
services:
  db:
    container_name: db
    image: postgres:15.4
    restart: unless-stopped
    ports:
      - '127.0.0.11:15432:5432'
# Set up new alias
sudo ifconfig lo0 alias 127.0.0.11

# Start container
docker compose up -d db

Result

# Check from host for listening
sudo lsof -nP -i4TCP:15432 -sTCP:LISTEN
# nothing
grep '15432' ~/Library/Logs/rancher-desktop/lima.ha.stderr.log
{"level":"debug","msg":"guest agent event: {Time:2024-04-23 21:52:05.733361439 +0000 UTC LocalPortsAdded:[{IP:127.0.0.11 Port:15432}] LocalPortsRemoved:[] Errors:[]}","time":"2024-04-23T17:52:06-04:00"}
{"level":"info","msg":"Not forwarding TCP 127.0.0.11:15432","time":"2024-04-23T17:52:06-04:00"}

Expected Behavior

Using Docker Desktop we see the container is able to bind.

sudo lsof -nP -i4TCP:15432 -sTCP:LISTEN

COMMAND     PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.docke 30689 kmack  186u  IPv4 0x344982b0fe901de1      0t0  TCP 127.0.0.11:15432 (LISTEN)

Additional Information

No response

Rancher Desktop Version

1.13.1

Rancher Desktop K8s Version

1.29.3

Which container engine are you using?

moby (docker cli)

What operating system are you using?

macOS

Operating System / Build Version

macOS 14.3 (23D56)

What CPU architecture are you using?

arm64 (Apple Silicon)

Linux only: what package format did you use to install Rancher Desktop?

None

Windows User Only

No response

jandubois commented 6 months ago

bind a container to any port loopback address other than 0.0.0.0 or 127.0.0.1

This is indeed not currently supported and a limitation on how Lima implements port forwarding (forwarding between interfaces must be declared when the VM is started and cannot be modified at runtime).

So while this may look like a small thing, it would require changing the way port forwarding is implemented in the guest and host agents.

HarlemSquirrel commented 6 months ago

That makes sense. Is this something on the roadmap at all?

jandubois commented 6 months ago

Is this something on the roadmap at all?

It is not on the roadmap so far. It would have to be implemented in Lima first before we could enable it in Rancher Desktop. And we would have to figure out how to do the same thing on Windows.

I think it is a good idea, but the effort/benefit ratio unfortunately doesn't make it likely to be prioritized in the near future.

jandubois commented 6 months ago

I thought of a manual way to get this working: Create ~/Library/Application Support/rancher-desktop/lima/_config/override.yaml with the following content and restart Rancher Desktop:

portForwards:
- guestIP: 127.0.0.11
  hostIP: 127.0.0.11

That will tell the guest agent to forward that interface as well:

$ grep '15432' ~/Library/Logs/rancher-desktop/lima.ha.stderr.log
{"level":"debug","msg":"guest agent event: {Time:2024-04-25 16:20:37.783086267 +0000 UTC LocalPortsAdded:[{IP:127.0.0.11 Port:15432}] LocalPortsRemoved:[] Errors:[]}","time":"2024-04-25T09:20:39-07:00"}
{"level":"info","msg":"Forwarding TCP from 127.0.0.11:15432 to 127.0.0.11:15432","time":"2024-04-25T09:20:39-07:00"}

The lsof command still didn't show anything for me, but that was because the database didn't actually start properly, so the port was closed again right away:

$ docker logs db
Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

       See PostgreSQL documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html

Note that the override.yaml file will be deleted if you ever perform a factory reset, and must be recreated manually again afterwards.

HarlemSquirrel commented 6 months ago

Interesting. Would this work if we want to do this with multiple IP addresses? Ideally we want to have multiple services running on the same ports but differ IP addresses.

jandubois commented 6 months ago

Would this work if we want to do this with multiple IP addresses?

Yes, you just have to list them all:

portForwards:
- guestIP: 127.0.0.11
  hostIP: 127.0.0.11
- guestIP: 127.0.0.12
  hostIP: 127.0.0.12
- guestIP: 127.0.0.13
  hostIP: 127.0.0.13
HarlemSquirrel commented 6 months ago

It works! 🎉

dvgitit commented 1 week ago

Would this work if we want to do this with multiple IP addresses?

Yes, you just have to list them all:

portForwards:
- guestIP: 127.0.0.11
  hostIP: 127.0.0.11
- guestIP: 127.0.0.12
  hostIP: 127.0.0.12
- guestIP: 127.0.0.13
  hostIP: 127.0.0.13

Would this approach work with Rancher Desktop on Windows too and if yes, how would it be configured? Like for the use case connecting from a devcontainer (running in RD moby) connecting to RD kubernetes. Probably this does not work, because k3s binds to localhost.

jandubois commented 1 week ago

@dvgitit Unfortunately it is currently not possible on Windows to bind to any other interface, and also not easy to add this functionality either.