This post is older than a year. Consider some information might not be accurate anymore.
Used: Docker version 18.06.1-ce, build e68fc7a RedHat 7.5 (Maipo)
Docker has its strength by isolating applications through containers. Each container has its namespace and a network subsystem. Starting with Docker containers there is a different approach to check connections for your running application.
Scenario
In this scenario, I arranged a Linux Server having an application running on the Linux host and in a docker container.
The current Java EE application is running on port 8443. To check existing connections to the JBoss Server, I use netstat
.
netstat -na | grep :8443
tcp 0 0 10.22.176.73:8443 0.0.0.0:* LISTEN
tcp 0 0 10.22.176.73:8443 10.22.10.215:21004 ESTABLISHED
tcp 0 0 10.22.176.73:8443 10.22.10.210:18678 ESTABLISHED
The most common mistake is to assume it works equally for the application running in a Docker container. The check with netstat
.
netstat -na | grep :8443
tcp 0 0 10.22.62.135:8443 0.0.0.0:* LISTEN
Network Mode Bridge
Docker’s networking subsystem default driver is bridge
. The network of the container is isolated from the host. The connection check for the application has to happen inside the namespace of the container.
docker inspect value-mapper | tail -n 20
"MacAddress": "04:42:ac:11:af:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "4f9c22c415bade83bd4aa16ab6b2446f9b86a3575545fcc0d3302de6c1dd306b",
"EndpointID": "c0e2f79e2a0303def85b9c792880af3583ce83b7212270f660794eeb5064097f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "04:42:ac:11:af:03"
}
}
}
}
]
Solutions
There are several solutions I would like to illustrate. In my favoured order:
- Use the command
nsenter
on Linux - Use
netstat
inside the container - Use network mode
host
nsenter
The command nsenter
runs a program with namespaces of other processes. It is part of the util-linux
package and thus should be available for most Linux flavours.
To use nsenter
, we need to determine the process id of the Docker container. Following command with docker inspect
illustrates a natural way. The Docker container is named value-mapper
.
docker inspect -f '{{.State.Pid}}' value-mapper
242973
Now we use the obtained process id, to enter the namespace of the Docker container process and run netstat
on it.
nsenter -t 242973 -n netstat -na | grep :8443
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN
tcp 0 0 172.17.0.3:8443 10.152.10.212:39063 FIN_WAIT2
tcp 0 0 172.17.0.3:8443 10.152.10.217:54538 ESTABLISHED
tcp 0 0 172.17.0.3:8443 10.152.10.221:52932 ESTABLISHED
netstat
If nsenter
is not available, like on a Mac OS, you still can enter the docker container and execute netstat
. It requires to install netstat
on the running Docker container or add it to your Docker base image.
My need was operational, so I did it live. The Docker base was RHEL 7.5, so I needed the rpm net-tools
, that contains netstat
.
Download rpm from CentOS repository
Copy it into Docker container.
docker cp /tmp/net-tools-2.0-0.22.20131004git.el7.x86_64.rpm value-mapper:/root/
Login into Docker container as root.
docker exec -it -u root value-mapper /bin/bash
Install it with yum and exit the container.
yum install net-tools-2.0-0.22.20131004git.el7.x86_64.rpm
exit
Log in as the regular user and use netstat in the docker container.
docker exec -it value-mapper /bin/bash
netstat -na | grep 8443
Network Mode host
For standalone containers, remove network isolation between the container and the Docker host, and use the host’s networking directly. So you can use netstat like before. All you have to do is to start the docker container in host mode.
Summary
Depending on your case there are several solutions to check connections for a Docker container. Independent on which environment you work, you can always use netstat
within the container.