Search code examples
rhelpodman

Expose ports with rootless podman


I am trying to expose port 8080 using rootless podman on RHEL 8.3.

The podman version I am using is:

$ podman --version
podman version 2.2.1

I am using a simple Flask API to test it:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello():
    return "Hello from the container!\n"


if __name__ == "__main__":
    app.run(host="0.0.0.0")

The Containerfile looks like this:

FROM python:3.6-alpine

RUN pip3 install flask

COPY app.py app.py

EXPOSE 5000

ENTRYPOINT python3 app.py

I am building the image using:

$ podman build -t testapi .

I am creating a pod and start a container within that pod

$ podman pod create --name testpod -p 8080:5000
$
$ podman run -d --rm --name testapi --pod testpod testapi 

All containers are running as expected:

$ podman ps
CONTAINER ID  IMAGE                     COMMAND  CREATED             STATUS            PORTS                   NAMES
85289290cc7a  localhost/testapi:latest           3 seconds ago       Up 2 seconds ago  0.0.0.0:8080->5000/tcp  testapi
4b1ac2354a1a  k8s.gcr.io/pause:3.2               About a minute ago  Up 3 seconds ago  0.0.0.0:8080->5000/tcp  81aa31a38084-infra

However, I cannot connect to the port:

$ telnet <IP> 8080
Trying <IP>...
telnet: Unable to connect to remote host: No route to host

When I use netstat to see which port are in use I get this:

$ netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::8080                 :::*                    LISTEN      638593/containers-r 
tcp6       0      0 :::22                   :::*                    LISTEN      -                   

And using lsof I get:

$ lsof -i -P -n | grep LISTEN
exe     638593   ds   13u  IPv6 593362      0t0  TCP *:8080 (LISTEN)

When I do the same thing using rootfull podman, it works, i.e.:

$ sudo podman pod create --name testpod -p 8080:5000 
$ sudo podman run -d --rm --name testapi --pod testpod testapi

Now the response is:

$ telnet 10.100.2.220 8080
Trying 10.100.2.220...
Connected to 10.100.2.220.

netstat returns:

$ netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -      

and lsof:

$ sudo lsof -i -P -n | grep LISTEN
conmon  639312   root    5u  IPv4 590239      0t0  TCP *:8080 (LISTEN)

Is there a way to expose a port using rootless podman so I can access it away from the podman host?


Solution

  • Double check this step when using rootless pod:

    $ telnet 8080 Trying ... telnet: Unable to connect to remote host: No route to host

    I have reproduced your environnement and your image, and I didn't found any problems.

    PS: it may be something related to firewalld, try to open port 8080.

    # firewall-cmd --add-port=8080/tcp --permanent 
    # firewall-cmd --reload