I'm trying to get the internal (container level) IP from a service that is deployed globally on several swarm nodes.
Something similar to this.
docker node ls -q | xargs docker node inspect -f '{{ .ID }} [{{ .Description.Hostname }}]: {{ .Spec.Labels }} {{ .Status.Addr }}'
This returns the host IP for every node and the labels on those hosts.
I began retrieving all the IDs for a specific service across all nodes using:
docker service ps [swarm_task] -q
And then inspect each one of it like this:
docker service ps [swarm_task] -q | xargs docker inspect -f '{{ .NetworksAttachments.Addresses }}'
But the IP Address is in a different format and I get this error:
Template parsing error: template: :1:23: executing "" at <.NetworksAttachments...>: can't evaluate field Addresses in type interface {}
The format inside the inspect is this:
"Addresses": [
"10.0.0.187/24"
]
The argument to docker --format
is a standard go text/template expression.
As NetworksAttachments
is an array, you may have to iterate on NetworksAttachments
to get a valid output.
The range
keyword is designed to do that:
$ docker service ps [swarm service name] -q --filter "desired-state=Running" \
| xargs docker inspect --format '{{range .NetworksAttachments}}{{.Addresses}}{{end}}'
My docker engine output is :
[10.x.x.y/16]
[10.x.x.z/16]
I added the --filter "desired-state=Running"
to docker service ps
to focus on running containers only.
You can refer to Go text/template documentation:
{{range pipeline}} T1 {{end}}
The value of the pipeline must be an array, slice, map, or channel. If the value of the pipeline has length zero, nothing is output; otherwise, dot is set to the successive elements of the array, slice, or map and T1 is executed. If the value is a map and the keys are of basic type with a defined order ("comparable"), the elements will be visited in sorted key order.