How to mimic 'docker service ps' on a multi host swarm using dockerode or docker api?

424 views Asked by At

I'm trying to use dockerode to access the Docker API.

My goal is to get container data for all containers in the multi node swarm.

It appears that docker.listContainers( {all: true } ) is scoped to only returns containers running on the calling node, in my case my manager node. https://docs.docker.com/engine/api/v1.37/#operation/ContainerList

  1. How do we use dockerode to get a list of all the containers in a swarm?

  2. How do we use dockerode to get a list of all the containers associated with a service?

On the command line, you can get the container id using docker service ps <service_name> to get the container id, and then call inspect on container.

$ docker service ps classifier_8
ID                  NAME                IMAGE                                 NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
m1x8e2w5dyvr        classifier_8.1      scuba:qa-latest  master         Running             Running 26 minutes ago
8a04d2e18ee9        classifier_8.2      scuba:qa-latest  worker-0         Running             Running 26 minutes ago
a6b48751780b        classifier_8.3      scuba:qa-latest  worker-1         Running             Running 26 minutes ago

$ docker inspect a6b48751780b
[{...}]

Even a simple example of calling dockerode.getContainer(a6b48751780b) returns a 404. Calling m1x8e2w5dyvr returns the expected data as its on the manager node.

1

There are 1 answers

0
programmerq On BEST ANSWER

The docker API will only return locally running containers when using the GET /containers/json endpoint, so a 404 is expected when trying to return a container on another docker engine. Swarm managers are only able to return swarm objects for the whole cluster. Regular containers are not swarm objects.

When interacting with swarm mode, you can list swarm services and swarm tasks. GET /services and GET /tasks. Since tasks are indeed a swarm mode object, you can list all tasks for the whole swarm from any manager.

Tasks do then go on to create containers on the various nodes in the swarm. If you want to list containers across the whole swarm, you must use the GET /containers/json API endpoint directly on each node.

These API endpoints are analogous to the following commands:

  • GET /containers/json - docker container ls
  • GET /services - docker service ls
  • GET /tasks?filter=... - docker service ps ... (see documentation for the correct filtering syntax)

I have answered this in the context of the Docker API instead of in the context of any one docker API library for increased readability.