Search code examples
dockerdocker-composedocker-swarmdocker-network

how does docker-swarm expose port?


After I deploy a docker application using docker-swarm, the application is accessible from $mac-host-ip:8481, and then I noticed the following from my host (Mac),

$ sudo lsof -PiTCP -sTCP:LISTEN |grep 8481
dockerd   1882   root   97u  IPv6 287775      0t0  TCP *:8481 (LISTEN)

$ docker ps --filter publish=8481
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$ docker ps --filter expose=8481
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

is this expected for compose applications?

thanks!


Solution

  • When ingress is used, the port gets published directly on the service, you'll see that under docker service ls under the ports column. The published port is forwarded to the VIP assigned to the service, which (at last check, it's been a while since I've dug) is then forwarded to one of the containers in the service using IPVS.

    $ docker service create -p 8080:80 --name nginx-test nginx
    mvwgqaolsjbiqsoo4d1ett20v
    overall progress: 1 out of 1 tasks    
    1/1: running   [==================================================>]                                                                                                                                               
    verify: Service converged                  
    
    $ docker service ls | grep nginx-test                                                                     
    mvwgqaolsjbi        nginx-test                 replicated          1/1                 nginx:latest                                       *:8080->80/tcp
    

    You can also go see published ports with a service inspect, e.g. the following loops through all services to show their ports:

    docker service ls -q | while read service_id; do
      docker service inspect $service_id -f \
        '{{.Spec.Name}} - {{range .Spec.EndpointSpec.Ports}}{{.PublishedPort}} {{end}}'
    done | sort