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

Fix port forwarding not working for non-127.0.0.1 localhost in rootless #3831

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

haytok
Copy link
Contributor

@haytok haytok commented Jan 22, 2025

When running a rootless container, specifying an address such as 127.0.0.2
for the -p option, we will not be able to access the published container
through that address.

This behavior is reported in the following issue:

This behavior is caused by the behavior in rootlesskit, and the following
pull request has been made to improve the behavior.

Therefore, this PR adds a test to ensure that the behavior of the
issue has been improved.

Also, this PR updates docs for propagations the address specified in the -p option

@haytok
Copy link
Contributor Author

haytok commented Jan 22, 2025

I'm checking for failing tests ...

@haytok
Copy link
Contributor Author

haytok commented Jan 25, 2025

First, the following three test failures are considered to have the same cause (exit status 56).

Results of CI failure in docker

Details

=== Failed
=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost/Issue_#3539_-_Access_to_a_container_running_when_127.0.0.2_is_specified_in_-p_in_rootless_mode. (2.00s)
    container_run_linux_test.go:607: ======================== Pre-test cleanup ========================
    command.go:112: /usr/bin/docker rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab
    container_run_linux_test.go:607: ======================== Test setup ========================
    command.go:112: /usr/bin/docker run -d --name testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab -p 127.0.0.2:8080:80 ghcr.io/stargz-containers/nginx:1.19-alpine-org
    container_run_linux_test.go:607: ======================== Test Run ========================
    container_run_linux_test.go:607: curl -s 127.0.0.2:8080
    container_run_linux_test.go:607: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  curl -s 127.0.0.2:8080
        ExitCode: 56
        Error:    exit status 56
        Stdout:   
        Stderr:   
        Env:
        LANG=C.UTF-8
        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
        MAIL=/var/mail/root
        LOGNAME=root
        USER=root
        HOME=/root
        SHELL=/bin/bash
        TERM=unknown
        SUDO_COMMAND=/tmp/go-build2958126014/b853/container.test -test.paniconexit0 -test.v=test2json -test.timeout=1h0m0s -test.allow-kill-daemon -test.target=docker
        SUDO_USER=runner
        SUDO_UID=1001
        SUDO_GID=118
        ImageVersion=20250105.1.0
        ImageOS=ubuntu24
        ACCEPT_EULA=Y
        XDG_CONFIG_HOME=/home/runner/.config
        AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache
        RUNNER_TOOL_CACHE=/opt/hostedtoolcache
        ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE=/opt/actionarchivecache
        AZURE_EXTENSION_DIR=/opt/az/azcliextensions
        SWIFT_PATH=/usr/share/swift/usr/bin
        DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
        DOTNET_NOLOGO=1
        DOTNET_MULTILEVEL_LOOKUP=0
        EDGEWEBDRIVER=/usr/local/share/edge_driver
        GECKOWEBDRIVER=/usr/local/share/gecko_driver
        CHROME_BIN=/usr/bin/google-chrome
        CHROMEWEBDRIVER=/usr/local/share/chromedriver-linux64
        BOOTSTRAP_HASKELL_NONINTERACTIVE=1
        GHCUP_INSTALL_BASE_PREFIX=/usr/local
        JAVA_HOME_8_X64=/usr/lib/jvm/temurin-8-jdk-amd64
        JAVA_HOME_11_X64=/usr/lib/jvm/temurin-11-jdk-amd64
        JAVA_HOME=/usr/lib/jvm/temurin-17-jdk-amd64
        JAVA_HOME_17_X64=/usr/lib/jvm/temurin-17-jdk-amd64
        JAVA_HOME_21_X64=/usr/lib/jvm/temurin-21-jdk-amd64
        ANT_HOME=/usr/share/ant
        GRADLE_HOME=/usr/share/gradle-8.12
        CONDA=/usr/share/miniconda
        NVM_DIR=/home/runner/.nvm
        SELENIUM_JAR_PATH=/usr/share/java/selenium-server.jar
        VCPKG_INSTALLATION_ROOT=/usr/local/share/vcpkg
        DEBIAN_FRONTEND=noninteractive
        ANDROID_SDK_ROOT=/usr/local/lib/android/sdk
        ANDROID_HOME=/usr/local/lib/android/sdk
        ANDROID_NDK=/usr/local/lib/android/sdk/ndk/27.2.12479018
        ANDROID_NDK_HOME=/usr/local/lib/android/sdk/ndk/27.2.12479018
        ANDROID_NDK_ROOT=/usr/local/lib/android/sdk/ndk/27.2.12479018
        ANDROID_NDK_LATEST_HOME=/usr/local/lib/android/sdk/ndk/27.2.12479018
        PIPX_BIN_DIR=/opt/pipx_bin
        PIPX_HOME=/opt/pipx
        GOROOT_1_21_X64=/opt/hostedtoolcache/go/1.21.13/x64
        GOROOT_1_22_X64=/opt/hostedtoolcache/go/1.22.10/x64
        GOROOT_1_23_X64=/opt/hostedtoolcache/go/1.23.4/x64
        HOMEBREW_NO_AUTO_UPDATE=1
        HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS=3650
        RUNNER_USER=runner
        DEPLOYMENT_BASEPATH=/opt/runner
        PERFLOG_LOCATION_SETTING=RUNNER_PERFLOG
        POWERSHELL_DISTRIBUTION_CHANNEL=GitHub-Actions-ubuntu24
        XDG_RUNTIME_DIR=/run/user/1001
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/bin/docker rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab

=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost (0.16s)

Results of CI failure in rootless | v1.6.36 | v1.1.1 | 20.04

Details

=== Failed
=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost/Issue_#3539_-_Access_to_a_container_running_when_127.0.0.2_is_specified_in_-p_in_rootless_mode. (2.62s)
    container_run_linux_test.go:607: ======================== Pre-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab
    container_run_linux_test.go:607: ======================== Test setup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run -d --name testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab -p 127.0.0.2:8080:80 ghcr.io/stargz-containers/nginx:1.19-alpine-org
    container_run_linux_test.go:607: ======================== Test Run ========================
    container_run_linux_test.go:607: curl -s 127.0.0.2:8080
    container_run_linux_test.go:607: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  curl -s 127.0.0.2:8080
        ExitCode: 56
        Error:    exit status 56
        Stdout:   
        Stderr:   
        Env:
        SHELL=/bin/bash
        LOGNAME=rootless
        XDG_SESSION_TYPE=tty
        MOTD_SHOWN=pam
        HOME=/home/rootless
        LANG=C.UTF-8
        SSH_CONNECTION=::1 52844 ::1 22
        XDG_SESSION_CLASS=user
        IPFS_PATH=/home/rootless/.local/share/ipfs
        USER=rootless
        SHLVL=1
        XDG_SESSION_ID=3
        XDG_RUNTIME_DIR=/run/user/1000
        SSH_CLIENT=::1 52844 22
        DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
        OLDPWD=/home/rootless
        _=/usr/local/bin/gotestsum
        PATH=/usr/local/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
        ***
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab

=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost (0.00s)

Results of CI failure in rootless-port-slirp4netns | v1.7.25 | v2.3.2 | 24.04

Details

=== Failed
=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost/Issue_#3539_-_Access_to_a_container_running_when_127.0.0.2_is_specified_in_-p_in_rootless_mode. (4.56s)
    container_run_linux_test.go:607: ======================== Pre-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab
    container_run_linux_test.go:607: ======================== Test setup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run -d --name testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab -p 127.0.0.2:8080:80 ghcr.io/stargz-containers/nginx:1.19-alpine-org
    container_run_linux_test.go:607: ======================== Test Run ========================
    container_run_linux_test.go:607: curl -s 127.0.0.2:8080
    container_run_linux_test.go:607: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  curl -s 127.0.0.2:8080
        ExitCode: 56
        Error:    exit status 56
        Stdout:   
        Stderr:   
        Env:
        SHELL=/bin/bash
        LOGNAME=rootless
        XDG_SESSION_TYPE=tty
        HOME=/home/rootless
        LANG=C.UTF-8
        SSH_CONNECTION=::1 37286 ::1 22
        XDG_SESSION_CLASS=user
        IPFS_PATH=/home/rootless/.local/share/ipfs
        USER=rootless
        SHLVL=1
        XDG_SESSION_ID=3
        XDG_RUNTIME_DIR=/run/user/1001
        SSH_CLIENT=::1 37286 22
        DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
        OLDPWD=/home/rootless
        _=/usr/local/bin/gotestsum
        PATH=/usr/local/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
        ***
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab

=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost (0.00s)

I was able to reproduce this error on my dev env.

It seems that the exit status 56 error occurs when the curl command is executed before the container is started.

After further investigation, I confirmed that adding about 3 second delay before return helpers.Custom(“curl”, “-s”, address) stopped the exit status 56 error from occurring on our environment.

Therefore, I'll add 3 seconds of delay before return helpers.Custom(“curl”, “-s”, address) in the test.

@haytok
Copy link
Contributor Author

haytok commented Jan 25, 2025

Second, the following two test failures are considered to be caused by the same reason (exit status 7).

Results of CI failure in rootful | v2.0.2 | ubuntu-24.04

Details

=== Failed
=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost/Issue_#3539_-_Access_to_a_container_running_when_127.0.0.2_is_specified_in_-p_in_rootless_mode. (3.01s)
    container_run_linux_test.go:607: ======================== Pre-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab
    container_run_linux_test.go:607: ======================== Test setup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run -d --name testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab -p 127.0.0.2:8080:80 ghcr.io/stargz-containers/nginx:1.19-alpine-org
    container_run_linux_test.go:607: ======================== Test Run ========================
    container_run_linux_test.go:607: curl -s 127.0.0.2:8080
    container_run_linux_test.go:607: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  curl -s 127.0.0.2:8080
        ExitCode: 7
        Error:    exit status 7
        Stdout:   
        Stderr:   
        Env:
        HOSTNAME=6f426726a331
        MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
        SYSTEMD_EXEC_PID=80
        container=docker
        HOME=/root
        LANG=C.UTF-8
        MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/docker-entrypoint.service/memory.pressure
        INVOCATION_ID=31a8810f02834667ac36744777de50fa
        TERM=xterm
        USER=root
        SHLVL=3
        CGO_ENABLED=0
        _=/usr/local/bin/gotestsum
        PATH=/usr/local/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        ***
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab

=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost (0.00s)

Results of CI failure in rootful | v2.0.2 | arm64-8core-32gb

Details

=== Failed
=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost/Issue_#3539_-_Access_to_a_container_running_when_127.0.0.2_is_specified_in_-p_in_rootless_mode. (4.86s)
    container_run_linux_test.go:607: ======================== Pre-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab
    container_run_linux_test.go:607: ======================== Test setup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run -d --name testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab -p 127.0.0.2:8080:80 ghcr.io/stargz-containers/nginx:1.19-alpine-org
    container_run_linux_test.go:607: ======================== Test Run ========================
    container_run_linux_test.go:607: curl -s 127.0.0.2:8080
    container_run_linux_test.go:607: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  curl -s 127.0.0.2:8080
        ExitCode: 7
        Error:    exit status 7
        Stdout:   
        Stderr:   
        Env:
        HOSTNAME=a704b2140057
        MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
        SYSTEMD_EXEC_PID=80
        container=docker
        HOME=/root
        LANG=C.UTF-8
        MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/docker-entrypoint.service/memory.pressure
        INVOCATION_ID=a284212de7f04c0486973691405a636c
        TERM=xterm
        USER=root
        SHLVL=3
        CGO_ENABLED=0
        _=/usr/local/bin/gotestsum
        PATH=/usr/local/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        ***
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test rm -f testportbindingwithcustomhost-issue-3539-access-to-a-container-runn-4739b1ab

=== FAIL: cmd/nerdctl/container TestPortBindingWithCustomHost (0.00s)

The cause of these test failures is not clear at this time ...
When tested locally as shown below, it behaves as expected and the newly added TestPortBindingWithCustomHost passes.

Details

$ sudo nerdctl run -d --name test -p 127.0.0.2:8080:80 nginx
ec1f74248d83c40b3c3e4da20e3bf0fb64d4b1fefa8c64bc914569b857e28d34

$ sudo nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                     NAMES
ec1f74248d83    docker.io/library/nginx:latest    "/docker-entrypoint.…"    4 seconds ago    Up        127.0.0.2:8080->80/tcp    test

$ curl 127.0.0.2:8080
<!DOCTYPE html>
...

$ sudo go test -p 1 ./cmd/nerdctl/... -run "TestPortBindingWithCustomHost.*" -count=1
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl	0.012s [no tests to run]
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/apparmor	0.012s [no tests to run]
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/builder	0.013s [no tests to run]
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/completion	0.014s [no tests to run]
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/compose	0.010s [no tests to run]
ok  	github.com/containerd/nerdctl/v2/cmd/nerdctl/container	4.085s
..

@haytok haytok force-pushed the nerdctl_issue_3539 branch from 3250f8b to d1b7eea Compare January 25, 2025 06:31
@apostasie
Copy link
Contributor

Hey @haytok.

Happy new year!

I would suggest that you first use nerdtest.EnsureContainerStarted(helpers, identifier).
That will at least make sure the container is up.

Then, instead of curl, just use nettestutil.HTTPGet instead. It has retries and waits - and since it is go, it will be easier to debug than curl.

Hope that helps!

@haytok
Copy link
Contributor Author

haytok commented Jan 25, 2025

HI, @apostasie

Happy New Year :)

Thanks for advice !!!
I didn't know about nerdtest.EnsureContainerStarted(helpers, identifier) and nettestutil.HTTPGet, so I will use them!

…in rootless mode

When running a rootless container, specifying an address such as 127.0.0.2
for the -p option, we will not be able to access the published container
through that address.

This behavior is reported in the following issue:

- containerd#3539

This behavior is caused by the behavior in rootlesskit, and the following
pull request has been made to improve the behavior.

- rootless-containers/rootlesskit#477

Therefore, this commit adds a test to ensure that the behavior of the
issue has been improved.

Signed-off-by: Hayato Kiwata <[email protected]>
@haytok haytok force-pushed the nerdctl_issue_3539 branch from d1b7eea to 2cf7f38 Compare January 25, 2025 08:48
@haytok
Copy link
Contributor Author

haytok commented Jan 25, 2025

Hi @apostasie !

The failed test that I added passes thanks to apostasie's advice!!!

However, the test TestNetworkCreate/vanilla on rootful | v2.0.2 | ubuntu-24.04, which does not seem to be related to the test I added, is failing.
I have no idea why this test is failing ..., but if you know anything about it, could you please advise me 🙏🙏🙏

Details

=== Failed
=== FAIL: cmd/nerdctl/network TestNetworkCreate/vanilla (0.72s)
    network_create_linux_test.go:109: ======================== Pre-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network rm testnetworkcreate-vanilla-04e3e2c1
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network rm testnetworkcreate-vanilla-1-b457605f
    network_create_linux_test.go:109: ======================== Test setup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network create testnetworkcreate-vanilla-04e3e2c1
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network inspect testnetworkcreate-vanilla-04e3e2c1
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network create testnetworkcreate-vanilla-1-b457605f
    network_create_linux_test.go:109: ======================== Test Run ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run --rm --net testnetworkcreate-vanilla-1-b457605f ghcr.io/stargz-containers/alpine:3.13-org ip route
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test run --rm --net testnetworkcreate-vanilla-04e3e2c1 ghcr.io/stargz-containers/alpine:3.13-org ip route
    command.go:112: assertion failed: expect.ExitCode is not result.ExitCode: Expected exit code: 0
        
        Command:  /usr/local/bin/nerdctl --namespace=nerdctl-test run --rm --net testnetworkcreate-vanilla-04e3e2c1 ghcr.io/stargz-containers/alpine:3.13-org ip route
        ExitCode: 1
        Error:    exit status 1
        Stdout:   
        Stderr:   time="2025-01-25T08:56:05Z" level=fatal msg="failed to verify networking settings: failed to check for default network: error reading /etc/cni/net.d/nerdctl-test/nerdctl-testnetworkremove-simple-network-remove-18ffb7c0.conflist: open /etc/cni/net.d/nerdctl-test/nerdctl-testnetworkremove-simple-network-remove-18ffb7c0.conflist: no such file or directory"
        
        Env:
        HOSTNAME=ac302ccb3750
        MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
        SYSTEMD_EXEC_PID=80
        container=docker
        HOME=/root
        LANG=C.UTF-8
        MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/docker-entrypoint.service/memory.pressure
        INVOCATION_ID=eec04bac366b4a928afafe861cd5bb3f
        TERM=xterm
        USER=root
        SHLVL=3
        CGO_ENABLED=0
        _=/usr/local/bin/gotestsum
        PATH=/usr/local/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        ***
        DOCKER_CONFIG=/tmp/TestNetworkCreatevanilla3056642071/001
        NERDCTL_TOML=/tmp/TestNetworkCreatevanilla3056642071/001/nerdctl.toml
    case.go:164: ======================== Post-test cleanup ========================
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network rm testnetworkcreate-vanilla-04e3e2c1
    command.go:112: /usr/local/bin/nerdctl --namespace=nerdctl-test network rm testnetworkcreate-vanilla-1-b457605f

=== FAIL: cmd/nerdctl/network TestNetworkCreate (0.00s)

@apostasie
Copy link
Contributor

Your last failure is #3556 - unrelated to your PR I think.

Maybe a maintainer can bump the CI to re-run.

Poke @AkihiroSuda @djdongjin ^

@djdongjin djdongjin changed the title Nerdctl issue 3539 Fix port forwarding not working for non-127.0.0.1 localhost in rootless Jan 26, 2025
@djdongjin
Copy link
Member

The PR doesn't seem to have a fix (except test change and doc change)?

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.

3 participants